commit c70248a520408d876a49d9b428b5f4313b34fcea
Author: Devin Jankowski
+ This is the version using unrolled loops.
+
+ * Remark: you can't add ListItems, Rows, Cells,
+ * JPEGs, GIFs or PNGs to a Cell.
+ *
+ * @param element The Element to add
+ * @throws BadElementException if the method was called with a ListItem, Row or Cell
+ */
+ ///
+ * Note: it will not work with {@link Table}.
+ *
+ * @param marginMirroring
+ *
+ * The default implementation is:
+ *
+ *
+ * If the numberdepth is 0, the sections will not be numbered. If the numberdepth
+ * is 1, the section will be numbered with their own number. If the numberdepth is
+ * higher (for instance x > 1), the numbers of x - 1 parents will be shown.
+ *
+ * @param numberDepth the new numberDepth
+ */
+ public int NumberDepth {
+ set {
+ ((Section)element).NumberDepth = value;
+ }
+ }
+
+ /**
+ * Sets the indentation of this
+ * To convert the
+ * Example:
+ *
+ * for more info: see O'Reilly; "HTML: The Definitive Guide" (page 164)
+ *
+ * @author mario.maccarini@rug.ac.be
+ */
+
+ public sealed class HtmlEncoder {
+
+ // membervariables
+
+ /** List with the HTML translation of all the characters. */
+ private static String[] htmlCode = new String[256];
+
+ static HtmlEncoder() {
+ for (int i = 0; i < 10; i++) {
+ htmlCode[i] = "" + i + ";";
+ }
+
+ for (int i = 10; i < 32; i++) {
+ htmlCode[i] = "" + i + ";";
+ }
+
+ for (int i = 32; i < 128; i++) {
+ htmlCode[i] = ((char)i).ToString();
+ }
+
+ // Special characters
+ htmlCode['\t'] = "\t";
+ htmlCode['\n'] = "<" + HtmlTags.NEWLINE + " />\n";
+ htmlCode['\"'] = """; // double quote
+ htmlCode['&'] = "&"; // ampersand
+ htmlCode['<'] = "<"; // lower than
+ htmlCode['>'] = ">"; // greater than
+
+ for (int i = 128; i < 256; i++) {
+ htmlCode[i] = "" + i + ";";
+ }
+ }
+
+
+ // constructors
+
+ /**
+ * This class will never be constructed.
+ *
+ * HtmlEncoder only contains static methods.
+ */
+
+ private HtmlEncoder () { }
+
+ // methods
+
+ /**
+ * Converts a
+ * An
+ * Example:
+ *
+ * The
+ * This method writes some comment.
+ *
+ * @param comment the comment that has to be written
+ * @throws IOException
+ */
+
+ protected void WriteComment(String comment) {
+ AddTabs(2);
+ os.Write(BEGINCOMMENT, 0, BEGINCOMMENT.Length);
+ Write(comment);
+ os.Write(ENDCOMMENT, 0, ENDCOMMENT.Length);
+ }
+
+ // public methods
+
+ /**
+ * Changes the standardfont.
+ *
+ * @param standardFont The font
+ */
+
+ public void SetStandardFont(Font standardFont) {
+ this.standardfont = standardFont;
+ }
+
+ /**
+ * Checks if a given font is the same as the font that was last used.
+ *
+ * @param font the font of an object
+ * @return true if the font differs
+ */
+
+ public bool IsOtherFont(Font font) {
+ try {
+ Font cFont = (Font) currentfont.Peek();
+ if (cFont.CompareTo(font) == 0) return false;
+ return true;
+ }
+ catch (InvalidOperationException) {
+ if (standardfont.CompareTo(font) == 0) return false;
+ return true;
+ }
+ }
+
+ /**
+ * Sets the basepath for images.
+ *
+ * This is especially useful if you add images using a file,
+ * rather than an URL. In PDF there is no problem, since
+ * the images are added inline, but in HTML it is sometimes
+ * necessary to use a relative path or a special path to some
+ * images directory.
+ *
+ * @param imagepath the new imagepath
+ */
+
+ public void SetImagepath(String imagepath) {
+ this.imagepath = imagepath;
+ }
+
+ /**
+ * Resets the imagepath.
+ */
+
+ public void ResetImagepath() {
+ imagepath = null;
+ }
+
+ /**
+ * Changes the header of this document.
+ *
+ * @param header the new header
+ */
+
+ public void SetHeader(HeaderFooter header) {
+ this.header = header;
+ }
+
+ /**
+ * Changes the footer of this document.
+ *
+ * @param footer the new footer
+ */
+
+ public void SetFooter(HeaderFooter footer) {
+ this.footer = footer;
+ }
+
+ /**
+ * Signals that a
+ * An example:
+ *
+ *
+ * If the field does not exist or is invalid it returns
+ *
+ *
+ *
+ *
+ *
+ * The bars and text are written in the following colors:
+ * Result bars and text painted with current fill color bars and text painted with bars painted with current color bars painted with
+ * The code types allowed are:
+ * The bars and text are written in the following colors:
+ * Result bars and text painted with current fill color bars and text painted with bars painted with current color bars painted with
+ *
+ * The bars and text are written in the following colors:
+ * Result bars and text painted with current fill color bars and text painted with bars painted with current color bars painted with
+ * The bars and text are written in the following colors:
+ * Result bars and text painted with current fill color bars and text painted with bars painted with current color bars painted with
+ *
+ *
+ * The allowed dimensions are (height, width):
+ * 10, 10
+ * The allowed dimensions are (height, width):
+ * 10, 10
+ * One of:
+ * One of:
+ * exxxxxx - ECI number xxxxxx
+ * Example for a structured append, symbol 2 of 6, with FNC1 and ECI 000005. The actual text is "Hello".
+ * s020600075fe000005.Hello
+ * One of:
+ * The bars and text are written in the following colors:
+ * Result bars and text painted with current fill color bars and text painted with bars painted with current color bars painted with
+ * The default parameters are:
+ *
+ * The bars and text are written in the following colors:
+ * Result bars and text painted with current fill color bars and text painted with bars painted with current color bars painted with
+ * The bars and text are written in the following colors:
+ * Result bars and text painted with current fill color bars and text painted with bars painted with current color bars painted with
+ * The bars and text are written in the following colors:
+ * Result bars and text painted with current fill color bars and text painted with bars painted with current color bars painted with
+ * The fonts are cached and if they already exist they are extracted from the cache,
+ * not parsed again.
+ *
+ * Besides the common encodings described by name, custom encodings
+ * can also be made. These encodings will only work for the single byte fonts
+ * Type1 and TrueType. The encoding string starts with a '#'
+ * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list
+ * of hex values representing the Unicode codes that compose that encoding.
+ * Example for a "simple" encoding that includes the Unicode
+ * character space, A, B and ecyrillic:
+ *
+ * Example for a "full" encoding for a Type1 Tex font:
+ *
+ * This method calls:
+ * The fonts may or may not be cached depending on the flag
+ * Besides the common encodings described by name, custom encodings
+ * can also be made. These encodings will only work for the single byte fonts
+ * Type1 and TrueType. The encoding string starts with a '#'
+ * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list
+ * of hex values representing the Unicode codes that compose that encoding.
+ * Example for a "simple" encoding that includes the Unicode
+ * character space, A, B and ecyrillic:
+ *
+ * Example for a "full" encoding for a Type1 Tex font:
+ *
+ * The fonts may or may not be cached depending on the flag
+ * Besides the common encodings described by name, custom encodings
+ * can also be made. These encodings will only work for the single byte fonts
+ * Type1 and TrueType. The encoding string starts with a '#'
+ * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list
+ * of hex values representing the Unicode codes that compose that encoding.
+ * Example for a "simple" encoding that includes the Unicode
+ * character space, A, B and ecyrillic:
+ *
+ * Example for a "full" encoding for a Type1 Tex font:
+ *
+ * This implementation is not optimized for performance. It is intended
+ * as a reference implementation that closely follows the specification
+ * of the Bidirectional Algorithm in The Unicode Standard version 3.0.
+ *
+ * Input: Output:
+ * As the algorithm is defined to operate on a single paragraph at a time,
+ * this implementation is written to handle single paragraphs. Thus
+ * rule P1 is presumed by this implementation-- the data provided to the
+ * implementation is assumed to be a single paragraph, and either contains no
+ * 'B' codes, or a single 'B' code at the end of the input. 'B' is allowed
+ * as input to illustrate how the algorithm assigns it a level.
+ *
+ * Also note that rules L3 and L4 depend on the rendering engine that uses
+ * the result of the bidi algorithm. This implementation assumes that the
+ * rendering engine expects combining marks in visual order (e.g. to the
+ * left of their base character in RTL runs) and that it adjust the glyphs
+ * used to render mirrored characters that are in RTL runs so that they
+ * render appropriately.
+ *
+ * @author Doug Felt
+ */
+
+namespace iTextSharp.text.pdf {
+ public sealed class BidiOrder {
+ private sbyte[] initialTypes;
+ private sbyte[] embeddings; // generated from processing format codes
+ private sbyte paragraphEmbeddingLevel = -1; // undefined
+
+ private int textLength; // for convenience
+ private sbyte[] resultTypes; // for paragraph, not lines
+ private sbyte[] resultLevels; // for paragraph, not lines
+
+ // The bidi types
+
+ /** Left-to-right*/
+ public const sbyte L = 0;
+
+ /** Left-to-Right Embedding */
+ public const sbyte LRE = 1;
+
+ /** Left-to-Right Override */
+ public const sbyte LRO = 2;
+
+ /** Right-to-Left */
+ public const sbyte R = 3;
+
+ /** Right-to-Left Arabic */
+ public const sbyte AL = 4;
+
+ /** Right-to-Left Embedding */
+ public const sbyte RLE = 5;
+
+ /** Right-to-Left Override */
+ public const sbyte RLO = 6;
+
+ /** Pop Directional Format */
+ public const sbyte PDF = 7;
+
+ /** European Number */
+ public const sbyte EN = 8;
+
+ /** European Number Separator */
+ public const sbyte ES = 9;
+
+ /** European Number Terminator */
+ public const sbyte ET = 10;
+
+ /** Arabic Number */
+ public const sbyte AN = 11;
+
+ /** Common Number Separator */
+ public const sbyte CS = 12;
+
+ /** Non-Spacing Mark */
+ public const sbyte NSM = 13;
+
+ /** Boundary Neutral */
+ public const sbyte BN = 14;
+
+ /** Paragraph Separator */
+ public const sbyte B = 15;
+
+ /** Segment Separator */
+ public const sbyte S = 16;
+
+ /** Whitespace */
+ public const sbyte WS = 17;
+
+ /** Other Neutrals */
+ public const sbyte ON = 18;
+
+ /** Minimum bidi type value. */
+ public const sbyte TYPE_MIN = 0;
+
+ /** Maximum bidi type value. */
+ public const sbyte TYPE_MAX = 18;
+
+ //
+ // Input
+ //
+
+ /**
+ * Initialize using an array of direction types. Types range from TYPE_MIN to TYPE_MAX inclusive
+ * and represent the direction codes of the characters in the text.
+ *
+ * @param types the types array
+ */
+ public BidiOrder(sbyte[] types) {
+ ValidateTypes(types);
+
+ this.initialTypes = (sbyte[])types.Clone(); // client type array remains unchanged
+
+ RunAlgorithm();
+ }
+
+ /**
+ * Initialize using an array of direction types and an externally supplied paragraph embedding level.
+ * The embedding level may be -1, 0, or 1. -1 means to apply the default algorithm (rules P2 and P3),
+ * 0 is for LTR paragraphs, and 1 is for RTL paragraphs.
+ *
+ * @param types the types array
+ * @param paragraphEmbeddingLevel the externally supplied paragraph embedding level.
+ */
+ public BidiOrder(sbyte[] types, sbyte paragraphEmbeddingLevel) {
+ ValidateTypes(types);
+ ValidateParagraphEmbeddingLevel(paragraphEmbeddingLevel);
+
+ this.initialTypes = (sbyte[])types.Clone(); // client type array remains unchanged
+ this.paragraphEmbeddingLevel = paragraphEmbeddingLevel;
+
+ RunAlgorithm();
+ }
+
+ public BidiOrder(char[] text, int offset, int length, sbyte paragraphEmbeddingLevel) {
+ initialTypes = new sbyte[length];
+ for (int k = 0; k < length; ++k) {
+ initialTypes[k] = rtypes[text[offset + k]];
+ }
+ ValidateParagraphEmbeddingLevel(paragraphEmbeddingLevel);
+
+ this.paragraphEmbeddingLevel = paragraphEmbeddingLevel;
+
+ RunAlgorithm();
+ }
+
+ public static sbyte GetDirection(char c) {
+ return rtypes[c];
+ }
+
+ /**
+ * The algorithm.
+ * Does not include line-based processing (Rules L1, L2).
+ * These are applied later in the line-based phase of the algorithm.
+ */
+ private void RunAlgorithm() {
+ textLength = initialTypes.Length;
+
+ // Initialize output types.
+ // Result types initialized to input types.
+ resultTypes = (sbyte[])initialTypes.Clone();
+
+
+ // 1) determining the paragraph level
+ // Rule P1 is the requirement for entering this algorithm.
+ // Rules P2, P3.
+ // If no externally supplied paragraph embedding level, use default.
+ if (paragraphEmbeddingLevel == -1) {
+ DetermineParagraphEmbeddingLevel();
+ }
+
+ // Initialize result levels to paragraph embedding level.
+ resultLevels = new sbyte[textLength];
+ SetLevels(0, textLength, paragraphEmbeddingLevel);
+
+ // 2) Explicit levels and directions
+ // Rules X1-X8.
+ DetermineExplicitEmbeddingLevels();
+
+ // Rule X9.
+ textLength = RemoveExplicitCodes();
+
+ // Rule X10.
+ // Run remainder of algorithm one level run at a time
+ sbyte prevLevel = paragraphEmbeddingLevel;
+ int start = 0;
+ while (start < textLength) {
+ sbyte level = resultLevels[start];
+ sbyte prevType = TypeForLevel(Math.Max(prevLevel, level));
+
+ int limit = start + 1;
+ while (limit < textLength && resultLevels[limit] == level) {
+ ++limit;
+ }
+
+ sbyte succLevel = limit < textLength ? resultLevels[limit] : paragraphEmbeddingLevel;
+ sbyte succType = TypeForLevel(Math.Max(succLevel, level));
+
+ // 3) resolving weak types
+ // Rules W1-W7.
+ ResolveWeakTypes(start, limit, level, prevType, succType);
+
+ // 4) resolving neutral types
+ // Rules N1-N3.
+ ResolveNeutralTypes(start, limit, level, prevType, succType);
+
+ // 5) resolving implicit embedding levels
+ // Rules I1, I2.
+ ResolveImplicitLevels(start, limit, level, prevType, succType);
+
+ prevLevel = level;
+ start = limit;
+ }
+
+ // Reinsert explicit codes and assign appropriate levels to 'hide' them.
+ // This is for convenience, so the resulting level array maps 1-1
+ // with the initial array.
+ // See the implementation suggestions section of TR#9 for guidelines on
+ // how to implement the algorithm without removing and reinserting the codes.
+ textLength = ReinsertExplicitCodes(textLength);
+ }
+
+ /**
+ * 1) determining the paragraph level.
+ *
+ * Rules P2, P3.
+ *
+ * At the end of this function, the member variable paragraphEmbeddingLevel is set to either 0 or 1.
+ */
+ private void DetermineParagraphEmbeddingLevel() {
+ sbyte strongType = -1; // unknown
+
+ // Rule P2.
+ for (int i = 0; i < textLength; ++i) {
+ sbyte t = resultTypes[i];
+ if (t == L || t == AL || t == R) {
+ strongType = t;
+ break;
+ }
+ }
+
+ // Rule P3.
+ if (strongType == -1) { // none found
+ // default embedding level when no strong types found is 0.
+ paragraphEmbeddingLevel = 0;
+ } else if (strongType == L) {
+ paragraphEmbeddingLevel = 0;
+ } else { // AL, R
+ paragraphEmbeddingLevel = 1;
+ }
+ }
+
+ /**
+ * Process embedding format codes.
+ *
+ * Calls processEmbeddings to generate an embedding array from the explicit format codes. The
+ * embedding overrides in the array are then applied to the result types, and the result levels are
+ * initialized.
+ * @see #processEmbeddings
+ */
+ private void DetermineExplicitEmbeddingLevels() {
+ embeddings = ProcessEmbeddings(resultTypes, paragraphEmbeddingLevel);
+
+ for (int i = 0; i < textLength; ++i) {
+ sbyte level = embeddings[i];
+ if ((level & 0x80) != 0) {
+ level &= 0x7f;
+ resultTypes[i] = TypeForLevel(level);
+ }
+ resultLevels[i] = level;
+ }
+ }
+
+ /**
+ * Rules X9.
+ * Remove explicit codes so that they may be ignored during the remainder
+ * of the main portion of the algorithm. The length of the resulting text
+ * is returned.
+ * @return the length of the data excluding explicit codes and BN.
+ */
+ private int RemoveExplicitCodes() {
+ int w = 0;
+ for (int i = 0; i < textLength; ++i) {
+ sbyte t = initialTypes[i];
+ if (!(t == LRE || t == RLE || t == LRO || t == RLO || t == PDF || t == BN)) {
+ embeddings[w] = embeddings[i];
+ resultTypes[w] = resultTypes[i];
+ resultLevels[w] = resultLevels[i];
+ w++;
+ }
+ }
+ return w; // new textLength while explicit levels are removed
+ }
+
+ /**
+ * Reinsert levels information for explicit codes.
+ * This is for ease of relating the level information
+ * to the original input data. Note that the levels
+ * assigned to these codes are arbitrary, they're
+ * chosen so as to avoid breaking level runs.
+ * @param textLength the length of the data after compression
+ * @return the length of the data (original length of
+ * types array supplied to constructor)
+ */
+ private int ReinsertExplicitCodes(int textLength) {
+ for (int i = initialTypes.Length; --i >= 0;) {
+ sbyte t = initialTypes[i];
+ if (t == LRE || t == RLE || t == LRO || t == RLO || t == PDF || t == BN) {
+ embeddings[i] = 0;
+ resultTypes[i] = t;
+ resultLevels[i] = -1;
+ } else {
+ --textLength;
+ embeddings[i] = embeddings[textLength];
+ resultTypes[i] = resultTypes[textLength];
+ resultLevels[i] = resultLevels[textLength];
+ }
+ }
+
+ // now propagate forward the levels information (could have
+ // propagated backward, the main thing is not to introduce a level
+ // break where one doesn't already exist).
+
+ if (resultLevels[0] == -1) {
+ resultLevels[0] = paragraphEmbeddingLevel;
+ }
+ for (int i = 1; i < initialTypes.Length; ++i) {
+ if (resultLevels[i] == -1) {
+ resultLevels[i] = resultLevels[i-1];
+ }
+ }
+
+ // Embedding information is for informational purposes only
+ // so need not be adjusted.
+
+ return initialTypes.Length;
+ }
+
+ /**
+ * 2) determining explicit levels
+ * Rules X1 - X8
+ *
+ * The interaction of these rules makes handling them a bit complex.
+ * This examines resultTypes but does not modify it. It returns embedding and
+ * override information in the result array. The low 7 bits are the level, the high
+ * bit is set if the level is an override, and clear if it is an embedding.
+ */
+ private static sbyte[] ProcessEmbeddings(sbyte[] resultTypes, sbyte paragraphEmbeddingLevel) {
+ int EXPLICIT_LEVEL_LIMIT = 62;
+
+ int textLength = resultTypes.Length;
+ sbyte[] embeddings = new sbyte[textLength];
+
+ // This stack will store the embedding levels and override status in a single sbyte
+ // as described above.
+ sbyte[] embeddingValueStack = new sbyte[EXPLICIT_LEVEL_LIMIT];
+ int stackCounter = 0;
+
+ // An LRE or LRO at level 60 is invalid, since the new level 62 is invalid. But
+ // an RLE at level 60 is valid, since the new level 61 is valid. The current wording
+ // of the rules requires that the RLE remain valid even if a previous LRE is invalid.
+ // This keeps track of ignored LRE or LRO codes at level 60, so that the matching PDFs
+ // will not try to pop the stack.
+ int overflowAlmostCounter = 0;
+
+ // This keeps track of ignored pushes at level 61 or higher, so that matching PDFs will
+ // not try to pop the stack.
+ int overflowCounter = 0;
+
+ // Rule X1.
+
+ // Keep the level separate from the value (level | override status flag) for ease of access.
+ sbyte currentEmbeddingLevel = paragraphEmbeddingLevel;
+ sbyte currentEmbeddingValue = paragraphEmbeddingLevel;
+
+ // Loop through types, handling all remaining rules
+ for (int i = 0; i < textLength; ++i) {
+
+ embeddings[i] = currentEmbeddingValue;
+
+ sbyte t = resultTypes[i];
+
+ // Rules X2, X3, X4, X5
+ switch (t) {
+ case RLE:
+ case LRE:
+ case RLO:
+ case LRO:
+ // Only need to compute new level if current level is valid
+ if (overflowCounter == 0) {
+ sbyte newLevel;
+ if (t == RLE || t == RLO) {
+ newLevel = (sbyte)((currentEmbeddingLevel + 1) | 1); // least greater odd
+ } else { // t == LRE || t == LRO
+ newLevel = (sbyte)((currentEmbeddingLevel + 2) & ~1); // least greater even
+ }
+
+ // If the new level is valid, push old embedding level and override status
+ // No check for valid stack counter, since the level check suffices.
+ if (newLevel < EXPLICIT_LEVEL_LIMIT) {
+ embeddingValueStack[stackCounter] = currentEmbeddingValue;
+ stackCounter++;
+
+ currentEmbeddingLevel = newLevel;
+ if (t == LRO || t == RLO) { // override
+ currentEmbeddingValue = (sbyte)((byte)newLevel | 0x80);
+ } else {
+ currentEmbeddingValue = newLevel;
+ }
+
+ // Adjust level of format mark (for expositional purposes only, this gets
+ // removed later).
+ embeddings[i] = currentEmbeddingValue;
+ break;
+ }
+
+ // Otherwise new level is invalid, but a valid level can still be achieved if this
+ // level is 60 and we encounter an RLE or RLO further on. So record that we
+ // 'almost' overflowed.
+ if (currentEmbeddingLevel == 60) {
+ overflowAlmostCounter++;
+ break;
+ }
+ }
+
+ // Otherwise old or new level is invalid.
+ overflowCounter++;
+ break;
+
+ case PDF:
+ // The only case where this did not actually overflow but may have almost overflowed
+ // is when there was an RLE or RLO on level 60, which would result in level 61. So we
+ // only test the almost overflow condition in that case.
+ //
+ // Also note that there may be a PDF without any pushes at all.
+
+ if (overflowCounter > 0) {
+ --overflowCounter;
+ } else if (overflowAlmostCounter > 0 && currentEmbeddingLevel != 61) {
+ --overflowAlmostCounter;
+ } else if (stackCounter > 0) {
+ --stackCounter;
+ currentEmbeddingValue = embeddingValueStack[stackCounter];
+ currentEmbeddingLevel = (sbyte)(currentEmbeddingValue & 0x7f);
+ }
+ break;
+
+ case B:
+ // Rule X8.
+
+ // These values are reset for clarity, in this implementation B can only
+ // occur as the last code in the array.
+ stackCounter = 0;
+ overflowCounter = 0;
+ overflowAlmostCounter = 0;
+ currentEmbeddingLevel = paragraphEmbeddingLevel;
+ currentEmbeddingValue = paragraphEmbeddingLevel;
+
+ embeddings[i] = paragraphEmbeddingLevel;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return embeddings;
+ }
+
+
+ /**
+ * 3) resolving weak types
+ * Rules W1-W7.
+ *
+ * Note that some weak types (EN, AN) remain after this processing is complete.
+ */
+ private void ResolveWeakTypes(int start, int limit, sbyte level, sbyte sor, sbyte eor) {
+
+ // Rule W1.
+ // Changes all NSMs.
+ sbyte preceedingCharacterType = sor;
+ for (int i = start; i < limit; ++i) {
+ sbyte t = resultTypes[i];
+ if (t == NSM) {
+ resultTypes[i] = preceedingCharacterType;
+ } else {
+ preceedingCharacterType = t;
+ }
+ }
+
+ // Rule W2.
+ // EN does not change at the start of the run, because sor != AL.
+ for (int i = start; i < limit; ++i) {
+ if (resultTypes[i] == EN) {
+ for (int j = i - 1; j >= start; --j) {
+ sbyte t = resultTypes[j];
+ if (t == L || t == R || t == AL) {
+ if (t == AL) {
+ resultTypes[i] = AN;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // Rule W3.
+ for (int i = start; i < limit; ++i) {
+ if (resultTypes[i] == AL) {
+ resultTypes[i] = R;
+ }
+ }
+
+ // Rule W4.
+ // Since there must be values on both sides for this rule to have an
+ // effect, the scan skips the first and last value.
+ //
+ // Although the scan proceeds left to right, and changes the type values
+ // in a way that would appear to affect the computations later in the scan,
+ // there is actually no problem. A change in the current value can only
+ // affect the value to its immediate right, and only affect it if it is
+ // ES or CS. But the current value can only change if the value to its
+ // right is not ES or CS. Thus either the current value will not change,
+ // or its change will have no effect on the remainder of the analysis.
+
+ for (int i = start + 1; i < limit - 1; ++i) {
+ if (resultTypes[i] == ES || resultTypes[i] == CS) {
+ sbyte prevSepType = resultTypes[i-1];
+ sbyte succSepType = resultTypes[i+1];
+ if (prevSepType == EN && succSepType == EN) {
+ resultTypes[i] = EN;
+ } else if (resultTypes[i] == CS && prevSepType == AN && succSepType == AN) {
+ resultTypes[i] = AN;
+ }
+ }
+ }
+
+ // Rule W5.
+ for (int i = start; i < limit; ++i) {
+ if (resultTypes[i] == ET) {
+ // locate end of sequence
+ int runstart = i;
+ int runlimit = FindRunLimit(runstart, limit, new sbyte[] { ET });
+
+ // check values at ends of sequence
+ sbyte t = runstart == start ? sor : resultTypes[runstart - 1];
+
+ if (t != EN) {
+ t = runlimit == limit ? eor : resultTypes[runlimit];
+ }
+
+ if (t == EN) {
+ SetTypes(runstart, runlimit, EN);
+ }
+
+ // continue at end of sequence
+ i = runlimit;
+ }
+ }
+
+ // Rule W6.
+ for (int i = start; i < limit; ++i) {
+ sbyte t = resultTypes[i];
+ if (t == ES || t == ET || t == CS) {
+ resultTypes[i] = ON;
+ }
+ }
+
+ // Rule W7.
+ for (int i = start; i < limit; ++i) {
+ if (resultTypes[i] == EN) {
+ // set default if we reach start of run
+ sbyte prevStrongType = sor;
+ for (int j = i - 1; j >= start; --j) {
+ sbyte t = resultTypes[j];
+ if (t == L || t == R) { // AL's have been removed
+ prevStrongType = t;
+ break;
+ }
+ }
+ if (prevStrongType == L) {
+ resultTypes[i] = L;
+ }
+ }
+ }
+ }
+
+ /**
+ * 6) resolving neutral types
+ * Rules N1-N2.
+ */
+ private void ResolveNeutralTypes(int start, int limit, sbyte level, sbyte sor, sbyte eor) {
+
+ for (int i = start; i < limit; ++i) {
+ sbyte t = resultTypes[i];
+ if (t == WS || t == ON || t == B || t == S) {
+ // find bounds of run of neutrals
+ int runstart = i;
+ int runlimit = FindRunLimit(runstart, limit, new sbyte[] {B, S, WS, ON});
+
+ // determine effective types at ends of run
+ sbyte leadingType;
+ sbyte trailingType;
+
+ if (runstart == start) {
+ leadingType = sor;
+ } else {
+ leadingType = resultTypes[runstart - 1];
+ if (leadingType == L || leadingType == R) {
+ // found the strong type
+ } else if (leadingType == AN) {
+ leadingType = R;
+ } else if (leadingType == EN) {
+ // Since EN's with previous strong L types have been changed
+ // to L in W7, the leadingType must be R.
+ leadingType = R;
+ }
+ }
+
+ if (runlimit == limit) {
+ trailingType = eor;
+ } else {
+ trailingType = resultTypes[runlimit];
+ if (trailingType == L || trailingType == R) {
+ // found the strong type
+ } else if (trailingType == AN) {
+ trailingType = R;
+ } else if (trailingType == EN) {
+ trailingType = R;
+ }
+ }
+
+ sbyte resolvedType;
+ if (leadingType == trailingType) {
+ // Rule N1.
+ resolvedType = leadingType;
+ } else {
+ // Rule N2.
+ // Notice the embedding level of the run is used, not
+ // the paragraph embedding level.
+ resolvedType = TypeForLevel(level);
+ }
+
+ SetTypes(runstart, runlimit, resolvedType);
+
+ // skip over run of (former) neutrals
+ i = runlimit;
+ }
+ }
+ }
+
+ /**
+ * 7) resolving implicit embedding levels
+ * Rules I1, I2.
+ */
+ private void ResolveImplicitLevels(int start, int limit, sbyte level, sbyte sor, sbyte eor) {
+ if ((level & 1) == 0) { // even level
+ for (int i = start; i < limit; ++i) {
+ sbyte t = resultTypes[i];
+ // Rule I1.
+ if (t == L ) {
+ // no change
+ } else if (t == R) {
+ resultLevels[i] += 1;
+ } else { // t == AN || t == EN
+ resultLevels[i] += 2;
+ }
+ }
+ } else { // odd level
+ for (int i = start; i < limit; ++i) {
+ sbyte t = resultTypes[i];
+ // Rule I2.
+ if (t == R) {
+ // no change
+ } else { // t == L || t == AN || t == EN
+ resultLevels[i] += 1;
+ }
+ }
+ }
+ }
+
+ //
+ // Output
+ //
+
+ public byte[] GetLevels() {
+ return GetLevels(new int[]{textLength});
+ }
+
+ /**
+ * Return levels array breaking lines at offsets in linebreaks.
+ * The returned levels array contains the resolved level for each
+ * bidi code passed to the constructor.
+ *
+ * The linebreaks array must include at least one value.
+ * The values must be in strictly increasing order (no duplicates)
+ * between 1 and the length of the text, inclusive. The last value
+ * must be the length of the text.
+ *
+ * @param linebreaks the offsets at which to break the paragraph
+ * @return the resolved levels of the text
+ */
+ public byte[] GetLevels(int[] linebreaks) {
+
+ // Note that since the previous processing has removed all
+ // P, S, and WS values from resultTypes, the values referred to
+ // in these rules are the initial types, before any processing
+ // has been applied (including processing of overrides).
+ //
+ // This example implementation has reinserted explicit format codes
+ // and BN, in order that the levels array correspond to the
+ // initial text. Their final placement is not normative.
+ // These codes are treated like WS in this implementation,
+ // so they don't interrupt sequences of WS.
+
+ ValidateLineBreaks(linebreaks, textLength);
+
+ byte[] result = new byte[resultLevels.Length];
+ for (int k = 0; k < resultLevels.Length; ++k)
+ result[k] = (byte)resultLevels[k];
+
+ // don't worry about linebreaks since if there is a break within
+ // a series of WS values preceeding S, the linebreak itself
+ // causes the reset.
+ for (int i = 0; i < result.Length; ++i) {
+ sbyte t = initialTypes[i];
+ if (t == B || t == S) {
+ // Rule L1, clauses one and two.
+ result[i] = (byte)paragraphEmbeddingLevel;
+
+ // Rule L1, clause three.
+ for (int j = i - 1; j >= 0; --j) {
+ if (IsWhitespace(initialTypes[j])) { // including format codes
+ result[j] = (byte)paragraphEmbeddingLevel;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ // Rule L1, clause four.
+ int start = 0;
+ for (int i = 0; i < linebreaks.Length; ++i) {
+ int limit = linebreaks[i];
+ for (int j = limit - 1; j >= start; --j) {
+ if (IsWhitespace(initialTypes[j])) { // including format codes
+ result[j] = (byte)paragraphEmbeddingLevel;
+ } else {
+ break;
+ }
+ }
+
+ start = limit;
+ }
+
+ return result;
+ }
+
+ /**
+ * Return reordering array breaking lines at offsets in linebreaks.
+ *
+ * The reordering array maps from a visual index to a logical index.
+ * Lines are concatenated from left to right. So for example, the
+ * fifth character from the left on the third line is
+ *
+ * The linebreaks array must include at least one value.
+ * The values must be in strictly increasing order (no duplicates)
+ * between 1 and the length of the text, inclusive. The last value
+ * must be the length of the text.
+ *
+ * @param linebreaks the offsets at which to break the paragraph.
+ */
+/* public int[] GetReordering(int[] linebreaks) {
+ ValidateLineBreaks(linebreaks, textLength);
+
+ sbyte[] levels = GetLevels(linebreaks);
+
+ return ComputeMultilineReordering(levels, linebreaks);
+ }*/
+
+ /**
+ * Return multiline reordering array for a given level array.
+ * Reordering does not occur across a line break.
+ */
+ private static int[] ComputeMultilineReordering(sbyte[] levels, int[] linebreaks) {
+ int[] result = new int[levels.Length];
+
+ int start = 0;
+ for (int i = 0; i < linebreaks.Length; ++i) {
+ int limit = linebreaks[i];
+
+ sbyte[] templevels = new sbyte[limit - start];
+ Array.Copy(levels, start, templevels, 0, templevels.Length);
+
+ int[] temporder = ComputeReordering(templevels);
+ for (int j = 0; j < temporder.Length; ++j) {
+ result[start + j] = temporder[j] + start;
+ }
+
+ start = limit;
+ }
+
+ return result;
+ }
+
+ /**
+ * Return reordering array for a given level array. This reorders a single line.
+ * The reordering is a visual to logical map. For example,
+ * the leftmost char is string.CharAt(order[0]).
+ * Rule L2.
+ */
+ private static int[] ComputeReordering(sbyte[] levels) {
+ int lineLength = levels.Length;
+
+ int[] result = new int[lineLength];
+
+ // initialize order
+ for (int i = 0; i < lineLength; ++i) {
+ result[i] = i;
+ }
+
+ // locate highest level found on line.
+ // Note the rules say text, but no reordering across line bounds is performed,
+ // so this is sufficient.
+ sbyte highestLevel = 0;
+ sbyte lowestOddLevel = 63;
+ for (int i = 0; i < lineLength; ++i) {
+ sbyte level = levels[i];
+ if (level > highestLevel) {
+ highestLevel = level;
+ }
+ if (((level & 1) != 0) && level < lowestOddLevel) {
+ lowestOddLevel = level;
+ }
+ }
+
+ for (int level = highestLevel; level >= lowestOddLevel; --level) {
+ for (int i = 0; i < lineLength; ++i) {
+ if (levels[i] >= level) {
+ // find range of text at or above this level
+ int start = i;
+ int limit = i + 1;
+ while (limit < lineLength && levels[limit] >= level) {
+ ++limit;
+ }
+
+ // reverse run
+ for (int j = start, k = limit - 1; j < k; ++j, --k) {
+ int temp = result[j];
+ result[j] = result[k];
+ result[k] = temp;
+ }
+
+ // skip to end of level run
+ i = limit;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Return the base level of the paragraph.
+ */
+ public sbyte GetBaseLevel() {
+ return paragraphEmbeddingLevel;
+ }
+
+ // --- internal utilities -------------------------------------------------
+
+ /**
+ * Return true if the type is considered a whitespace type for the line break rules.
+ */
+ private static bool IsWhitespace(sbyte biditype) {
+ switch (biditype) {
+ case LRE:
+ case RLE:
+ case LRO:
+ case RLO:
+ case PDF:
+ case BN:
+ case WS:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Return the strong type (L or R) corresponding to the level.
+ */
+ private static sbyte TypeForLevel(int level) {
+ return ((level & 0x1) == 0) ? L : R;
+ }
+
+ /**
+ * Return the limit of the run starting at index that includes only resultTypes in validSet.
+ * This checks the value at index, and will return index if that value is not in validSet.
+ */
+ private int FindRunLimit(int index, int limit, sbyte[] validSet) {
+ --index;
+ loop:
+ while (++index < limit) {
+ sbyte t = resultTypes[index];
+ for (int i = 0; i < validSet.Length; ++i) {
+ if (t == validSet[i]) {
+ goto loop;
+ }
+ }
+ // didn't find a match in validSet
+ return index;
+ }
+ return limit;
+ }
+
+ /**
+ * Return the start of the run including index that includes only resultTypes in validSet.
+ * This assumes the value at index is valid, and does not check it.
+ */
+ private int FindRunStart(int index, sbyte[] validSet) {
+ loop:
+ while (--index >= 0) {
+ sbyte t = resultTypes[index];
+ for (int i = 0; i < validSet.Length; ++i) {
+ if (t == validSet[i]) {
+ goto loop;
+ }
+ }
+ return index + 1;
+ }
+ return 0;
+ }
+
+ /**
+ * Set resultTypes from start up to (but not including) limit to newType.
+ */
+ private void SetTypes(int start, int limit, sbyte newType) {
+ for (int i = start; i < limit; ++i) {
+ resultTypes[i] = newType;
+ }
+ }
+
+ /**
+ * Set resultLevels from start up to (but not including) limit to newLevel.
+ */
+ private void SetLevels(int start, int limit, sbyte newLevel) {
+ for (int i = start; i < limit; ++i) {
+ resultLevels[i] = newLevel;
+ }
+ }
+
+ // --- input validation ---------------------------------------------------
+
+ /**
+ * Throw exception if type array is invalid.
+ */
+ private static void ValidateTypes(sbyte[] types) {
+ if (types == null) {
+ throw new ArgumentException("types is null");
+ }
+ for (int i = 0; i < types.Length; ++i) {
+ if (types[i] < TYPE_MIN || types[i] > TYPE_MAX) {
+ throw new ArgumentException("illegal type value at " + i + ": " + types[i]);
+ }
+ }
+ for (int i = 0; i < types.Length - 1; ++i) {
+ if (types[i] == B) {
+ throw new ArgumentException("B type before end of paragraph at index: " + i);
+ }
+ }
+ }
+
+ /**
+ * Throw exception if paragraph embedding level is invalid. Special allowance for -1 so that
+ * default processing can still be performed when using this API.
+ */
+ private static void ValidateParagraphEmbeddingLevel(sbyte paragraphEmbeddingLevel) {
+ if (paragraphEmbeddingLevel != -1 &&
+ paragraphEmbeddingLevel != 0 &&
+ paragraphEmbeddingLevel != 1) {
+ throw new ArgumentException("illegal paragraph embedding level: " + paragraphEmbeddingLevel);
+ }
+ }
+
+ /**
+ * Throw exception if line breaks array is invalid.
+ */
+ private static void ValidateLineBreaks(int[] linebreaks, int textLength) {
+ int prev = 0;
+ for (int i = 0; i < linebreaks.Length; ++i) {
+ int next = linebreaks[i];
+ if (next <= prev) {
+ throw new ArgumentException("bad linebreak: " + next + " at index: " + i);
+ }
+ prev = next;
+ }
+ if (prev != textLength) {
+ throw new ArgumentException("last linebreak must be at " + textLength);
+ }
+ }
+
+ private static sbyte[] rtypes = new sbyte[0x10000];
+
+ private static char[] baseTypes = {
+ (char)0, (char)8, (char)BN, (char)9, (char)9, (char)S, (char)10, (char)10, (char)B, (char)11, (char)11, (char)S, (char)12, (char)12, (char)WS, (char)13, (char)13, (char)B,
+ (char)14, (char)27, (char)BN, (char)28, (char)30, (char)B, (char)31, (char)31, (char)S, (char)32, (char)32, (char)WS, (char)33, (char)34, (char)ON, (char)35, (char)37, (char)ET,
+ (char)38, (char)42, (char)ON, (char)43, (char)43, (char)ET, (char)44, (char)44, (char)CS, (char)45, (char)45, (char)ET, (char)46, (char)46, (char)CS, (char)47, (char)47, (char)ES,
+ (char)48, (char)57, (char)EN, (char)58, (char)58, (char)CS, (char)59, (char)64, (char)ON, (char)65, (char)90, (char)L, (char)91, (char)96, (char)ON, (char)97, (char)122, (char)L,
+ (char)123, (char)126, (char)ON, (char)127, (char)132, (char)BN, (char)133, (char)133, (char)B, (char)134, (char)159, (char)BN, (char)160, (char)160, (char)CS,
+ (char)161, (char)161, (char)ON, (char)162, (char)165, (char)ET, (char)166, (char)169, (char)ON, (char)170, (char)170, (char)L, (char)171, (char)175, (char)ON,
+ (char)176, (char)177, (char)ET, (char)178, (char)179, (char)EN, (char)180, (char)180, (char)ON, (char)181, (char)181, (char)L, (char)182, (char)184, (char)ON,
+ (char)185, (char)185, (char)EN, (char)186, (char)186, (char)L, (char)187, (char)191, (char)ON, (char)192, (char)214, (char)L, (char)215, (char)215, (char)ON,
+ (char)216, (char)246, (char)L, (char)247, (char)247, (char)ON, (char)248, (char)696, (char)L, (char)697, (char)698, (char)ON, (char)699, (char)705, (char)L,
+ (char)706, (char)719, (char)ON, (char)720, (char)721, (char)L, (char)722, (char)735, (char)ON, (char)736, (char)740, (char)L, (char)741, (char)749, (char)ON,
+ (char)750, (char)750, (char)L, (char)751, (char)767, (char)ON, (char)768, (char)855, (char)NSM, (char)856, (char)860, (char)L, (char)861, (char)879, (char)NSM,
+ (char)880, (char)883, (char)L, (char)884, (char)885, (char)ON, (char)886, (char)893, (char)L, (char)894, (char)894, (char)ON, (char)895, (char)899, (char)L,
+ (char)900, (char)901, (char)ON, (char)902, (char)902, (char)L, (char)903, (char)903, (char)ON, (char)904, (char)1013, (char)L, (char)1014, (char)1014, (char)ON,
+ (char)1015, (char)1154, (char)L, (char)1155, (char)1158, (char)NSM, (char)1159, (char)1159, (char)L, (char)1160, (char)1161, (char)NSM,
+ (char)1162, (char)1417, (char)L, (char)1418, (char)1418, (char)ON, (char)1419, (char)1424, (char)L, (char)1425, (char)1441, (char)NSM,
+ (char)1442, (char)1442, (char)L, (char)1443, (char)1465, (char)NSM, (char)1466, (char)1466, (char)L, (char)1467, (char)1469, (char)NSM,
+ (char)1470, (char)1470, (char)R, (char)1471, (char)1471, (char)NSM, (char)1472, (char)1472, (char)R, (char)1473, (char)1474, (char)NSM,
+ (char)1475, (char)1475, (char)R, (char)1476, (char)1476, (char)NSM, (char)1477, (char)1487, (char)L, (char)1488, (char)1514, (char)R,
+ (char)1515, (char)1519, (char)L, (char)1520, (char)1524, (char)R, (char)1525, (char)1535, (char)L, (char)1536, (char)1539, (char)AL,
+ (char)1540, (char)1547, (char)L, (char)1548, (char)1548, (char)CS, (char)1549, (char)1549, (char)AL, (char)1550, (char)1551, (char)ON,
+ (char)1552, (char)1557, (char)NSM, (char)1558, (char)1562, (char)L, (char)1563, (char)1563, (char)AL, (char)1564, (char)1566, (char)L,
+ (char)1567, (char)1567, (char)AL, (char)1568, (char)1568, (char)L, (char)1569, (char)1594, (char)AL, (char)1595, (char)1599, (char)L,
+ (char)1600, (char)1610, (char)AL, (char)1611, (char)1624, (char)NSM, (char)1625, (char)1631, (char)L, (char)1632, (char)1641, (char)AN,
+ (char)1642, (char)1642, (char)ET, (char)1643, (char)1644, (char)AN, (char)1645, (char)1647, (char)AL, (char)1648, (char)1648, (char)NSM,
+ (char)1649, (char)1749, (char)AL, (char)1750, (char)1756, (char)NSM, (char)1757, (char)1757, (char)AL, (char)1758, (char)1764, (char)NSM,
+ (char)1765, (char)1766, (char)AL, (char)1767, (char)1768, (char)NSM, (char)1769, (char)1769, (char)ON, (char)1770, (char)1773, (char)NSM,
+ (char)1774, (char)1775, (char)AL, (char)1776, (char)1785, (char)EN, (char)1786, (char)1805, (char)AL, (char)1806, (char)1806, (char)L,
+ (char)1807, (char)1807, (char)BN, (char)1808, (char)1808, (char)AL, (char)1809, (char)1809, (char)NSM, (char)1810, (char)1839, (char)AL,
+ (char)1840, (char)1866, (char)NSM, (char)1867, (char)1868, (char)L, (char)1869, (char)1871, (char)AL, (char)1872, (char)1919, (char)L,
+ (char)1920, (char)1957, (char)AL, (char)1958, (char)1968, (char)NSM, (char)1969, (char)1969, (char)AL, (char)1970, (char)2304, (char)L,
+ (char)2305, (char)2306, (char)NSM, (char)2307, (char)2363, (char)L, (char)2364, (char)2364, (char)NSM, (char)2365, (char)2368, (char)L,
+ (char)2369, (char)2376, (char)NSM, (char)2377, (char)2380, (char)L, (char)2381, (char)2381, (char)NSM, (char)2382, (char)2384, (char)L,
+ (char)2385, (char)2388, (char)NSM, (char)2389, (char)2401, (char)L, (char)2402, (char)2403, (char)NSM, (char)2404, (char)2432, (char)L,
+ (char)2433, (char)2433, (char)NSM, (char)2434, (char)2491, (char)L, (char)2492, (char)2492, (char)NSM, (char)2493, (char)2496, (char)L,
+ (char)2497, (char)2500, (char)NSM, (char)2501, (char)2508, (char)L, (char)2509, (char)2509, (char)NSM, (char)2510, (char)2529, (char)L,
+ (char)2530, (char)2531, (char)NSM, (char)2532, (char)2545, (char)L, (char)2546, (char)2547, (char)ET, (char)2548, (char)2560, (char)L,
+ (char)2561, (char)2562, (char)NSM, (char)2563, (char)2619, (char)L, (char)2620, (char)2620, (char)NSM, (char)2621, (char)2624, (char)L,
+ (char)2625, (char)2626, (char)NSM, (char)2627, (char)2630, (char)L, (char)2631, (char)2632, (char)NSM, (char)2633, (char)2634, (char)L,
+ (char)2635, (char)2637, (char)NSM, (char)2638, (char)2671, (char)L, (char)2672, (char)2673, (char)NSM, (char)2674, (char)2688, (char)L,
+ (char)2689, (char)2690, (char)NSM, (char)2691, (char)2747, (char)L, (char)2748, (char)2748, (char)NSM, (char)2749, (char)2752, (char)L,
+ (char)2753, (char)2757, (char)NSM, (char)2758, (char)2758, (char)L, (char)2759, (char)2760, (char)NSM, (char)2761, (char)2764, (char)L,
+ (char)2765, (char)2765, (char)NSM, (char)2766, (char)2785, (char)L, (char)2786, (char)2787, (char)NSM, (char)2788, (char)2800, (char)L,
+ (char)2801, (char)2801, (char)ET, (char)2802, (char)2816, (char)L, (char)2817, (char)2817, (char)NSM, (char)2818, (char)2875, (char)L,
+ (char)2876, (char)2876, (char)NSM, (char)2877, (char)2878, (char)L, (char)2879, (char)2879, (char)NSM, (char)2880, (char)2880, (char)L,
+ (char)2881, (char)2883, (char)NSM, (char)2884, (char)2892, (char)L, (char)2893, (char)2893, (char)NSM, (char)2894, (char)2901, (char)L,
+ (char)2902, (char)2902, (char)NSM, (char)2903, (char)2945, (char)L, (char)2946, (char)2946, (char)NSM, (char)2947, (char)3007, (char)L,
+ (char)3008, (char)3008, (char)NSM, (char)3009, (char)3020, (char)L, (char)3021, (char)3021, (char)NSM, (char)3022, (char)3058, (char)L,
+ (char)3059, (char)3064, (char)ON, (char)3065, (char)3065, (char)ET, (char)3066, (char)3066, (char)ON, (char)3067, (char)3133, (char)L,
+ (char)3134, (char)3136, (char)NSM, (char)3137, (char)3141, (char)L, (char)3142, (char)3144, (char)NSM, (char)3145, (char)3145, (char)L,
+ (char)3146, (char)3149, (char)NSM, (char)3150, (char)3156, (char)L, (char)3157, (char)3158, (char)NSM, (char)3159, (char)3259, (char)L,
+ (char)3260, (char)3260, (char)NSM, (char)3261, (char)3275, (char)L, (char)3276, (char)3277, (char)NSM, (char)3278, (char)3392, (char)L,
+ (char)3393, (char)3395, (char)NSM, (char)3396, (char)3404, (char)L, (char)3405, (char)3405, (char)NSM, (char)3406, (char)3529, (char)L,
+ (char)3530, (char)3530, (char)NSM, (char)3531, (char)3537, (char)L, (char)3538, (char)3540, (char)NSM, (char)3541, (char)3541, (char)L,
+ (char)3542, (char)3542, (char)NSM, (char)3543, (char)3632, (char)L, (char)3633, (char)3633, (char)NSM, (char)3634, (char)3635, (char)L,
+ (char)3636, (char)3642, (char)NSM, (char)3643, (char)3646, (char)L, (char)3647, (char)3647, (char)ET, (char)3648, (char)3654, (char)L,
+ (char)3655, (char)3662, (char)NSM, (char)3663, (char)3760, (char)L, (char)3761, (char)3761, (char)NSM, (char)3762, (char)3763, (char)L,
+ (char)3764, (char)3769, (char)NSM, (char)3770, (char)3770, (char)L, (char)3771, (char)3772, (char)NSM, (char)3773, (char)3783, (char)L,
+ (char)3784, (char)3789, (char)NSM, (char)3790, (char)3863, (char)L, (char)3864, (char)3865, (char)NSM, (char)3866, (char)3892, (char)L,
+ (char)3893, (char)3893, (char)NSM, (char)3894, (char)3894, (char)L, (char)3895, (char)3895, (char)NSM, (char)3896, (char)3896, (char)L,
+ (char)3897, (char)3897, (char)NSM, (char)3898, (char)3901, (char)ON, (char)3902, (char)3952, (char)L, (char)3953, (char)3966, (char)NSM,
+ (char)3967, (char)3967, (char)L, (char)3968, (char)3972, (char)NSM, (char)3973, (char)3973, (char)L, (char)3974, (char)3975, (char)NSM,
+ (char)3976, (char)3983, (char)L, (char)3984, (char)3991, (char)NSM, (char)3992, (char)3992, (char)L, (char)3993, (char)4028, (char)NSM,
+ (char)4029, (char)4037, (char)L, (char)4038, (char)4038, (char)NSM, (char)4039, (char)4140, (char)L, (char)4141, (char)4144, (char)NSM,
+ (char)4145, (char)4145, (char)L, (char)4146, (char)4146, (char)NSM, (char)4147, (char)4149, (char)L, (char)4150, (char)4151, (char)NSM,
+ (char)4152, (char)4152, (char)L, (char)4153, (char)4153, (char)NSM, (char)4154, (char)4183, (char)L, (char)4184, (char)4185, (char)NSM,
+ (char)4186, (char)5759, (char)L, (char)5760, (char)5760, (char)WS, (char)5761, (char)5786, (char)L, (char)5787, (char)5788, (char)ON,
+ (char)5789, (char)5905, (char)L, (char)5906, (char)5908, (char)NSM, (char)5909, (char)5937, (char)L, (char)5938, (char)5940, (char)NSM,
+ (char)5941, (char)5969, (char)L, (char)5970, (char)5971, (char)NSM, (char)5972, (char)6001, (char)L, (char)6002, (char)6003, (char)NSM,
+ (char)6004, (char)6070, (char)L, (char)6071, (char)6077, (char)NSM, (char)6078, (char)6085, (char)L, (char)6086, (char)6086, (char)NSM,
+ (char)6087, (char)6088, (char)L, (char)6089, (char)6099, (char)NSM, (char)6100, (char)6106, (char)L, (char)6107, (char)6107, (char)ET,
+ (char)6108, (char)6108, (char)L, (char)6109, (char)6109, (char)NSM, (char)6110, (char)6127, (char)L, (char)6128, (char)6137, (char)ON,
+ (char)6138, (char)6143, (char)L, (char)6144, (char)6154, (char)ON, (char)6155, (char)6157, (char)NSM, (char)6158, (char)6158, (char)WS,
+ (char)6159, (char)6312, (char)L, (char)6313, (char)6313, (char)NSM, (char)6314, (char)6431, (char)L, (char)6432, (char)6434, (char)NSM,
+ (char)6435, (char)6438, (char)L, (char)6439, (char)6443, (char)NSM, (char)6444, (char)6449, (char)L, (char)6450, (char)6450, (char)NSM,
+ (char)6451, (char)6456, (char)L, (char)6457, (char)6459, (char)NSM, (char)6460, (char)6463, (char)L, (char)6464, (char)6464, (char)ON,
+ (char)6465, (char)6467, (char)L, (char)6468, (char)6469, (char)ON, (char)6470, (char)6623, (char)L, (char)6624, (char)6655, (char)ON,
+ (char)6656, (char)8124, (char)L, (char)8125, (char)8125, (char)ON, (char)8126, (char)8126, (char)L, (char)8127, (char)8129, (char)ON,
+ (char)8130, (char)8140, (char)L, (char)8141, (char)8143, (char)ON, (char)8144, (char)8156, (char)L, (char)8157, (char)8159, (char)ON,
+ (char)8160, (char)8172, (char)L, (char)8173, (char)8175, (char)ON, (char)8176, (char)8188, (char)L, (char)8189, (char)8190, (char)ON,
+ (char)8191, (char)8191, (char)L, (char)8192, (char)8202, (char)WS, (char)8203, (char)8205, (char)BN, (char)8206, (char)8206, (char)L,
+ (char)8207, (char)8207, (char)R, (char)8208, (char)8231, (char)ON, (char)8232, (char)8232, (char)WS, (char)8233, (char)8233, (char)B,
+ (char)8234, (char)8234, (char)LRE, (char)8235, (char)8235, (char)RLE, (char)8236, (char)8236, (char)PDF, (char)8237, (char)8237, (char)LRO,
+ (char)8238, (char)8238, (char)RLO, (char)8239, (char)8239, (char)WS, (char)8240, (char)8244, (char)ET, (char)8245, (char)8276, (char)ON,
+ (char)8277, (char)8278, (char)L, (char)8279, (char)8279, (char)ON, (char)8280, (char)8286, (char)L, (char)8287, (char)8287, (char)WS,
+ (char)8288, (char)8291, (char)BN, (char)8292, (char)8297, (char)L, (char)8298, (char)8303, (char)BN, (char)8304, (char)8304, (char)EN,
+ (char)8305, (char)8307, (char)L, (char)8308, (char)8313, (char)EN, (char)8314, (char)8315, (char)ET, (char)8316, (char)8318, (char)ON,
+ (char)8319, (char)8319, (char)L, (char)8320, (char)8329, (char)EN, (char)8330, (char)8331, (char)ET, (char)8332, (char)8334, (char)ON,
+ (char)8335, (char)8351, (char)L, (char)8352, (char)8369, (char)ET, (char)8370, (char)8399, (char)L, (char)8400, (char)8426, (char)NSM,
+ (char)8427, (char)8447, (char)L, (char)8448, (char)8449, (char)ON, (char)8450, (char)8450, (char)L, (char)8451, (char)8454, (char)ON,
+ (char)8455, (char)8455, (char)L, (char)8456, (char)8457, (char)ON, (char)8458, (char)8467, (char)L, (char)8468, (char)8468, (char)ON,
+ (char)8469, (char)8469, (char)L, (char)8470, (char)8472, (char)ON, (char)8473, (char)8477, (char)L, (char)8478, (char)8483, (char)ON,
+ (char)8484, (char)8484, (char)L, (char)8485, (char)8485, (char)ON, (char)8486, (char)8486, (char)L, (char)8487, (char)8487, (char)ON,
+ (char)8488, (char)8488, (char)L, (char)8489, (char)8489, (char)ON, (char)8490, (char)8493, (char)L, (char)8494, (char)8494, (char)ET,
+ (char)8495, (char)8497, (char)L, (char)8498, (char)8498, (char)ON, (char)8499, (char)8505, (char)L, (char)8506, (char)8507, (char)ON,
+ (char)8508, (char)8511, (char)L, (char)8512, (char)8516, (char)ON, (char)8517, (char)8521, (char)L, (char)8522, (char)8523, (char)ON,
+ (char)8524, (char)8530, (char)L, (char)8531, (char)8543, (char)ON, (char)8544, (char)8591, (char)L, (char)8592, (char)8721, (char)ON,
+ (char)8722, (char)8723, (char)ET, (char)8724, (char)9013, (char)ON, (char)9014, (char)9082, (char)L, (char)9083, (char)9108, (char)ON,
+ (char)9109, (char)9109, (char)L, (char)9110, (char)9168, (char)ON, (char)9169, (char)9215, (char)L, (char)9216, (char)9254, (char)ON,
+ (char)9255, (char)9279, (char)L, (char)9280, (char)9290, (char)ON, (char)9291, (char)9311, (char)L, (char)9312, (char)9371, (char)EN,
+ (char)9372, (char)9449, (char)L, (char)9450, (char)9450, (char)EN, (char)9451, (char)9751, (char)ON, (char)9752, (char)9752, (char)L,
+ (char)9753, (char)9853, (char)ON, (char)9854, (char)9855, (char)L, (char)9856, (char)9873, (char)ON, (char)9874, (char)9887, (char)L,
+ (char)9888, (char)9889, (char)ON, (char)9890, (char)9984, (char)L, (char)9985, (char)9988, (char)ON, (char)9989, (char)9989, (char)L,
+ (char)9990, (char)9993, (char)ON, (char)9994, (char)9995, (char)L, (char)9996, (char)10023, (char)ON, (char)10024, (char)10024, (char)L,
+ (char)10025, (char)10059, (char)ON, (char)10060, (char)10060, (char)L, (char)10061, (char)10061, (char)ON, (char)10062, (char)10062, (char)L,
+ (char)10063, (char)10066, (char)ON, (char)10067, (char)10069, (char)L, (char)10070, (char)10070, (char)ON, (char)10071, (char)10071, (char)L,
+ (char)10072, (char)10078, (char)ON, (char)10079, (char)10080, (char)L, (char)10081, (char)10132, (char)ON, (char)10133, (char)10135, (char)L,
+ (char)10136, (char)10159, (char)ON, (char)10160, (char)10160, (char)L, (char)10161, (char)10174, (char)ON, (char)10175, (char)10191, (char)L,
+ (char)10192, (char)10219, (char)ON, (char)10220, (char)10223, (char)L, (char)10224, (char)11021, (char)ON, (char)11022, (char)11903, (char)L,
+ (char)11904, (char)11929, (char)ON, (char)11930, (char)11930, (char)L, (char)11931, (char)12019, (char)ON, (char)12020, (char)12031, (char)L,
+ (char)12032, (char)12245, (char)ON, (char)12246, (char)12271, (char)L, (char)12272, (char)12283, (char)ON, (char)12284, (char)12287, (char)L,
+ (char)12288, (char)12288, (char)WS, (char)12289, (char)12292, (char)ON, (char)12293, (char)12295, (char)L, (char)12296, (char)12320, (char)ON,
+ (char)12321, (char)12329, (char)L, (char)12330, (char)12335, (char)NSM, (char)12336, (char)12336, (char)ON, (char)12337, (char)12341, (char)L,
+ (char)12342, (char)12343, (char)ON, (char)12344, (char)12348, (char)L, (char)12349, (char)12351, (char)ON, (char)12352, (char)12440, (char)L,
+ (char)12441, (char)12442, (char)NSM, (char)12443, (char)12444, (char)ON, (char)12445, (char)12447, (char)L, (char)12448, (char)12448, (char)ON,
+ (char)12449, (char)12538, (char)L, (char)12539, (char)12539, (char)ON, (char)12540, (char)12828, (char)L, (char)12829, (char)12830, (char)ON,
+ (char)12831, (char)12879, (char)L, (char)12880, (char)12895, (char)ON, (char)12896, (char)12923, (char)L, (char)12924, (char)12925, (char)ON,
+ (char)12926, (char)12976, (char)L, (char)12977, (char)12991, (char)ON, (char)12992, (char)13003, (char)L, (char)13004, (char)13007, (char)ON,
+ (char)13008, (char)13174, (char)L, (char)13175, (char)13178, (char)ON, (char)13179, (char)13277, (char)L, (char)13278, (char)13279, (char)ON,
+ (char)13280, (char)13310, (char)L, (char)13311, (char)13311, (char)ON, (char)13312, (char)19903, (char)L, (char)19904, (char)19967, (char)ON,
+ (char)19968, (char)42127, (char)L, (char)42128, (char)42182, (char)ON, (char)42183, (char)64284, (char)L, (char)64285, (char)64285, (char)R,
+ (char)64286, (char)64286, (char)NSM, (char)64287, (char)64296, (char)R, (char)64297, (char)64297, (char)ET, (char)64298, (char)64310, (char)R,
+ (char)64311, (char)64311, (char)L, (char)64312, (char)64316, (char)R, (char)64317, (char)64317, (char)L, (char)64318, (char)64318, (char)R,
+ (char)64319, (char)64319, (char)L, (char)64320, (char)64321, (char)R, (char)64322, (char)64322, (char)L, (char)64323, (char)64324, (char)R,
+ (char)64325, (char)64325, (char)L, (char)64326, (char)64335, (char)R, (char)64336, (char)64433, (char)AL, (char)64434, (char)64466, (char)L,
+ (char)64467, (char)64829, (char)AL, (char)64830, (char)64831, (char)ON, (char)64832, (char)64847, (char)L, (char)64848, (char)64911, (char)AL,
+ (char)64912, (char)64913, (char)L, (char)64914, (char)64967, (char)AL, (char)64968, (char)65007, (char)L, (char)65008, (char)65020, (char)AL,
+ (char)65021, (char)65021, (char)ON, (char)65022, (char)65023, (char)L, (char)65024, (char)65039, (char)NSM, (char)65040, (char)65055, (char)L,
+ (char)65056, (char)65059, (char)NSM, (char)65060, (char)65071, (char)L, (char)65072, (char)65103, (char)ON, (char)65104, (char)65104, (char)CS,
+ (char)65105, (char)65105, (char)ON, (char)65106, (char)65106, (char)CS, (char)65107, (char)65107, (char)L, (char)65108, (char)65108, (char)ON,
+ (char)65109, (char)65109, (char)CS, (char)65110, (char)65118, (char)ON, (char)65119, (char)65119, (char)ET, (char)65120, (char)65121, (char)ON,
+ (char)65122, (char)65123, (char)ET, (char)65124, (char)65126, (char)ON, (char)65127, (char)65127, (char)L, (char)65128, (char)65128, (char)ON,
+ (char)65129, (char)65130, (char)ET, (char)65131, (char)65131, (char)ON, (char)65132, (char)65135, (char)L, (char)65136, (char)65140, (char)AL,
+ (char)65141, (char)65141, (char)L, (char)65142, (char)65276, (char)AL, (char)65277, (char)65278, (char)L, (char)65279, (char)65279, (char)BN,
+ (char)65280, (char)65280, (char)L, (char)65281, (char)65282, (char)ON, (char)65283, (char)65285, (char)ET, (char)65286, (char)65290, (char)ON,
+ (char)65291, (char)65291, (char)ET, (char)65292, (char)65292, (char)CS, (char)65293, (char)65293, (char)ET, (char)65294, (char)65294, (char)CS,
+ (char)65295, (char)65295, (char)ES, (char)65296, (char)65305, (char)EN, (char)65306, (char)65306, (char)CS, (char)65307, (char)65312, (char)ON,
+ (char)65313, (char)65338, (char)L, (char)65339, (char)65344, (char)ON, (char)65345, (char)65370, (char)L, (char)65371, (char)65381, (char)ON,
+ (char)65382, (char)65503, (char)L, (char)65504, (char)65505, (char)ET, (char)65506, (char)65508, (char)ON, (char)65509, (char)65510, (char)ET,
+ (char)65511, (char)65511, (char)L, (char)65512, (char)65518, (char)ON, (char)65519, (char)65528, (char)L, (char)65529, (char)65531, (char)BN,
+ (char)65532, (char)65533, (char)ON, (char)65534, (char)65535, (char)L};
+
+ static BidiOrder() {
+ for (int k = 0; k < baseTypes.Length; ++k) {
+ int start = baseTypes[k];
+ int end = baseTypes[++k];
+ sbyte b = (sbyte)baseTypes[++k];
+ while (start <= end)
+ rtypes[start++] = b;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/ByteBuffer.cs b/iTechSharp/iTextSharp/text/pdf/ByteBuffer.cs
new file mode 100644
index 0000000..8c7d617
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/ByteBuffer.cs
@@ -0,0 +1,673 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Globalization;
+
+/*
+ * $Id: ByteBuffer.cs,v 1.7 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2000, 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Acts like a
+ * This can only be used to increment the size.
+ * If the size that is passed through is smaller than the current size, nothing happens.
+ *
+ * @param size the size of the cache
+ */
+
+ public static void SetCacheSize(int size) {
+ if (size > 3276700) size = 3276700;
+ if (size <= byteCacheSize) return;
+ byte[][] tmpCache = new byte[size][];
+ System.Array.Copy(byteCache, 0, tmpCache, 0, byteCacheSize);
+ byteCache = tmpCache;
+ byteCacheSize = size;
+ }
+
+ /**
+ * You can fill the cache in advance if you want to.
+ *
+ * @param decimals
+ */
+
+ public static void FillCache(int decimals) {
+ int step = 1;
+ switch (decimals) {
+ case 0:
+ step = 100;
+ break;
+ case 1:
+ step = 10;
+ break;
+ }
+ for (int i = 1; i < byteCacheSize; i += step) {
+ if (byteCache[i] != null) continue;
+ byteCache[i] = ConvertToBytes(i);
+ }
+ }
+
+ /**
+ * Converts an double (multiplied by 100 and cast to an int) into an array of bytes.
+ *
+ * @param i the int
+ * @return a bytearray
+ */
+
+ private static byte[] ConvertToBytes(int i) {
+ int size = (int)Math.Floor(Math.Log(i) / Math.Log(10));
+ if (i % 100 != 0) {
+ size += 2;
+ }
+ if (i % 10 != 0) {
+ size++;
+ }
+ if (i < 100) {
+ size++;
+ if (i < 10) {
+ size++;
+ }
+ }
+ size--;
+ byte[] cache = new byte[size];
+ size --;
+ if (i < 100) {
+ cache[0] = (byte)'0';
+ }
+ if (i % 10 != 0) {
+ cache[size--] = bytes[i % 10];
+ }
+ if (i % 100 != 0) {
+ cache[size--] = bytes[(i / 10) % 10];
+ cache[size--] = (byte)'.';
+ }
+ size = (int)Math.Floor(Math.Log(i) / Math.Log(10)) - 1;
+ int add = 0;
+ while (add < size) {
+ cache[add] = bytes[(i / (int)Math.Pow(10, size - add + 1)) % 10];
+ add++;
+ }
+ return cache;
+ }
+
+ /**
+ * Appends an
+ * Several parameters can be set like the first paragraph line indent and
+ * extra space between paragraphs.
+ *
+ * A call to the method
+ * I the column ended, a new column definition can be loaded with the method
+ *
+ * If the text ended, more text can be loaded with
+ * Full bidirectional reordering is supported. If the run direction is
+ *
+ * It removes all the text placed with
+ * Each array element will contain a
+ * for the moment every character less than or equal to SPACE, the character '-'
+ * and some specific unicode ranges are 'splitCharacters'.
+ *
+ * @param start start position in the array
+ * @param current current position in the array
+ * @param end end position in the array
+ * @param cc the character array that has to be checked
+ * @param ck chunk array
+ * @return
+ * The built in fonts "Symbol" and "ZapfDingbats", if used, have a special encoding
+ * to allow the characters to be referred by Unicode.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class FontSelector {
+
+ protected ArrayList fonts = new ArrayList();
+
+ /**
+ * Adds a
+ *
+ * @param cell the cell
+ * @param position the coordinates of the cell
+ * @param canvases an array of
+ *
+ * The
+ * Note that if even if a page is not written this method is still
+ * called. It is preferable to use
+ * Note that this method is called with the page number equal
+ * to the last page plus one.
+ *
+ * @param writer the
+ *
+ *
+ *
+ *
+ *
+ *
+ * It is usefull to pinpoint the
+ // Use just like java.util.Hashtable, except that the keys must be ints.
+ // This is much faster than creating a new int for each access.
+ //
+ // Fetch the software.
+ // @see java.util.Hashtable
+
+ public class IntHashtable {
+ /// The hash table data.
+ private IntHashtableEntry[] table;
+
+ /// The total number of entries in the hash table.
+ private int count;
+
+ /// Rehashes the table when count exceeds this threshold.
+ private int threshold;
+
+ /// The load factor for the hashtable.
+ private float loadFactor;
+
+ /// Constructs a new, empty hashtable with the specified initial
+ // capacity and the specified load factor.
+ // @param initialCapacity the initial number of buckets
+ // @param loadFactor a number between 0.0 and 1.0, it defines
+ // the threshold for rehashing the hashtable into
+ // a bigger one.
+ // @exception IllegalArgumentException If the initial capacity
+ // is less than or equal to zero.
+ // @exception IllegalArgumentException If the load factor is
+ // less than or equal to zero.
+ public IntHashtable( int initialCapacity, float loadFactor ) {
+ if ( initialCapacity <= 0 || loadFactor <= 0.0 )
+ throw new ArgumentException();
+ this.loadFactor = loadFactor;
+ table = new IntHashtableEntry[initialCapacity];
+ threshold = (int) ( initialCapacity * loadFactor );
+ }
+
+ /// Constructs a new, empty hashtable with the specified initial
+ // capacity.
+ // @param initialCapacity the initial number of buckets
+ public IntHashtable( int initialCapacity ) : this( initialCapacity, 0.75f ) {}
+
+ /// Constructs a new, empty hashtable. A default capacity and load factor
+ // is used. Note that the hashtable will automatically grow when it gets
+ // full.
+ public IntHashtable() : this( 101, 0.75f ) {}
+
+ /// Returns the number of elements contained in the hashtable.
+ public int Size {
+ get {
+ return count;
+ }
+ }
+
+ /// Returns true if the hashtable contains no elements.
+ public bool IsEmpty() {
+ return count == 0;
+ }
+
+ /// Returns true if the specified object is an element of the hashtable.
+ // This operation is more expensive than the ContainsKey() method.
+ // @param value the value that we are looking for
+ // @exception NullPointerException If the value being searched
+ // for is equal to null.
+ // @see IntHashtable#containsKey
+ public bool Contains( int value ) {
+ IntHashtableEntry[] tab = table;
+ for ( int i = tab.Length ; i-- > 0 ; ) {
+ for ( IntHashtableEntry e = tab[i] ; e != null ; e = e.next ) {
+ if ( e.value == value )
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// Returns true if the collection contains an element for the key.
+ // @param key the key that we are looking for
+ // @see IntHashtable#contains
+ public bool ContainsKey( int key ) {
+ IntHashtableEntry[] tab = table;
+ int hash = key;
+ int index = ( hash & 0x7FFFFFFF ) % tab.Length;
+ for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next ) {
+ if ( e.hash == hash && e.key == key )
+ return true;
+ }
+ return false;
+ }
+
+ /// Gets the object associated with the specified key in the
+ // hashtable.
+ // @param key the specified key
+ // @returns the element for the key or null if the key
+ // is not defined in the hash table.
+ // @see IntHashtable#put
+ public int this[int key] {
+ get {
+ IntHashtableEntry[] tab = table;
+ int hash = key;
+ int index = ( hash & 0x7FFFFFFF ) % tab.Length;
+ for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next ) {
+ if ( e.hash == hash && e.key == key )
+ return e.value;
+ }
+ return 0;
+ }
+
+ set {
+ // Makes sure the key is not already in the hashtable.
+ IntHashtableEntry[] tab = table;
+ int hash = key;
+ int index = ( hash & 0x7FFFFFFF ) % tab.Length;
+ for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next ) {
+ if ( e.hash == hash && e.key == key ) {
+ e.value = value;
+ return;
+ }
+ }
+
+ if ( count >= threshold ) {
+ // Rehash the table if the threshold is exceeded.
+ Rehash();
+ this[key] = value;
+ return;
+ }
+
+ // Creates the new entry.
+ IntHashtableEntry en = new IntHashtableEntry();
+ en.hash = hash;
+ en.key = key;
+ en.value = value;
+ en.next = tab[index];
+ tab[index] = en;
+ ++count;
+ }
+ }
+
+ /// Rehashes the content of the table into a bigger table.
+ // This method is called automatically when the hashtable's
+ // size exceeds the threshold.
+ protected void Rehash() {
+ int oldCapacity = table.Length;
+ IntHashtableEntry[] oldTable = table;
+
+ int newCapacity = oldCapacity * 2 + 1;
+ IntHashtableEntry[] newTable = new IntHashtableEntry[newCapacity];
+
+ threshold = (int) ( newCapacity * loadFactor );
+ table = newTable;
+
+ for ( int i = oldCapacity ; i-- > 0 ; ) {
+ for ( IntHashtableEntry old = oldTable[i] ; old != null ; ) {
+ IntHashtableEntry e = old;
+ old = old.next;
+
+ int index = ( e.hash & 0x7FFFFFFF ) % newCapacity;
+ e.next = newTable[index];
+ newTable[index] = e;
+ }
+ }
+ }
+
+ /// Removes the element corresponding to the key. Does nothing if the
+ // key is not present.
+ // @param key the key that needs to be removed
+ // @return the value of key, or null if the key was not found.
+ public int Remove( int key ) {
+ IntHashtableEntry[] tab = table;
+ int hash = key;
+ int index = ( hash & 0x7FFFFFFF ) % tab.Length;
+ for ( IntHashtableEntry e = tab[index], prev = null ; e != null ; prev = e, e = e.next ) {
+ if ( e.hash == hash && e.key == key ) {
+ if ( prev != null )
+ prev.next = e.next;
+ else
+ tab[index] = e.next;
+ --count;
+ return e.value;
+ }
+ }
+ return 0;
+ }
+
+ /// Clears the hash table so that it has no more elements in it.
+ public void Clear() {
+ IntHashtableEntry[] tab = table;
+ for ( int index = tab.Length; --index >= 0; )
+ tab[index] = null;
+ count = 0;
+ }
+
+ public IntHashtable Clone() {
+ IntHashtable t = new IntHashtable();
+ t.count = count;
+ t.loadFactor = loadFactor;
+ t.threshold = threshold;
+ t.table = new IntHashtableEntry[table.Length];
+ for (int i = table.Length ; i-- > 0 ; ) {
+ t.table[i] = (table[i] != null)
+ ? (IntHashtableEntry)table[i].Clone() : null;
+ }
+ return t;
+ }
+
+ public int[] ToOrderedKeys() {
+ int[] res = GetKeys();
+ Array.Sort(res);
+ return res;
+ }
+
+ public int[] GetKeys() {
+ int[] res = new int[count];
+ int ptr = 0;
+ int index = table.Length;
+ IntHashtableEntry entry = null;
+ while (true) {
+ if (entry == null)
+ while ((index-- > 0) && ((entry = table[index]) == null));
+ if (entry == null)
+ break;
+ IntHashtableEntry e = entry;
+ entry = e.next;
+ res[ptr++] = e.key;
+ }
+ return res;
+ }
+
+ public class IntHashtableEntry {
+ internal int hash;
+ internal int key;
+ internal int value;
+ internal IntHashtableEntry next;
+
+ public int Key {
+ get {
+ return key;
+ }
+ }
+
+ public int Value {
+ get {
+ return value;
+ }
+ }
+
+ protected internal IntHashtableEntry Clone() {
+ IntHashtableEntry entry = new IntHashtableEntry();
+ entry.hash = hash;
+ entry.key = key;
+ entry.value = value;
+ entry.next = (next != null) ? next.Clone() : null;
+ return entry;
+ }
+ }
+
+ public IntHashtableIterator GetEntryIterator() {
+ return new IntHashtableIterator(table);
+ }
+
+ public class IntHashtableIterator {
+ // boolean keys;
+ int index;
+ IntHashtableEntry[] table;
+ IntHashtableEntry entry;
+
+ internal IntHashtableIterator(IntHashtableEntry[] table) {
+ this.table = table;
+ this.index = table.Length;
+ }
+
+ public bool HasNext() {
+ if (entry != null) {
+ return true;
+ }
+ while (index-- > 0) {
+ if ((entry = table[index]) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public IntHashtableEntry Next() {
+ if (entry == null) {
+ while ((index-- > 0) && ((entry = table[index]) == null));
+ }
+ if (entry != null) {
+ IntHashtableEntry e = entry;
+ entry = e.next;
+ return e;
+ }
+ throw new InvalidOperationException("IntHashtableIterator");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/LZWDecoder.cs b/iTechSharp/iTextSharp/text/pdf/LZWDecoder.cs
new file mode 100644
index 0000000..cad5aff
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/LZWDecoder.cs
@@ -0,0 +1,240 @@
+using System;
+using System.IO;
+using System.Collections;
+
+/*
+ * Copyright 2002-2008 by Paulo Soares.
+ *
+ * This code was originally released in 2001 by SUN (see class
+ * com.sun.media.imageioimpl.plugins.tiff.TIFFLZWDecompressor.java)
+ * using the BSD license in a specific wording. In a mail dating from
+ * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission
+ * to use the code under the following version of the BSD license:
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for
+ * use in the design, construction, operation or maintenance of any
+ * nuclear facility.
+ */
+namespace iTextSharp.text.pdf {
+ /**
+ * A class for performing LZW decoding.
+ *
+ *
+ */
+ public class LZWDecoder {
+
+ byte[][] stringTable;
+ byte[] data = null;
+ Stream uncompData;
+ int tableIndex, bitsToGet = 9;
+ int bytePointer;
+ int nextData = 0;
+ int nextBits = 0;
+
+ internal int[] andTable = {
+ 511,
+ 1023,
+ 2047,
+ 4095
+ };
+
+ public LZWDecoder() {
+ }
+
+ /**
+ * Method to decode LZW compressed data.
+ *
+ * @param data The compressed data.
+ * @param uncompData Array to return the uncompressed data in.
+ */
+ public void Decode(byte[] data, Stream uncompData) {
+
+ if (data[0] == (byte)0x00 && data[1] == (byte)0x01) {
+ throw new Exception("LZW flavour not supported.");
+ }
+
+ InitializeStringTable();
+
+ this.data = data;
+ this.uncompData = uncompData;
+
+ // Initialize pointers
+ bytePointer = 0;
+
+ nextData = 0;
+ nextBits = 0;
+
+ int code, oldCode = 0;
+ byte[] str;
+
+ while ((code = this.NextCode) != 257) {
+
+ if (code == 256) {
+
+ InitializeStringTable();
+ code = NextCode;
+
+ if (code == 257) {
+ break;
+ }
+
+ WriteString(stringTable[code]);
+ oldCode = code;
+
+ } else {
+
+ if (code < tableIndex) {
+
+ str = stringTable[code];
+
+ WriteString(str);
+ AddStringToTable(stringTable[oldCode], str[0]);
+ oldCode = code;
+
+ } else {
+
+ str = stringTable[oldCode];
+ str = ComposeString(str, str[0]);
+ WriteString(str);
+ AddStringToTable(str);
+ oldCode = code;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Initialize the string table.
+ */
+ public void InitializeStringTable() {
+
+ stringTable = new byte[8192][];
+
+ for (int i=0; i<256; i++) {
+ stringTable[i] = new byte[1];
+ stringTable[i][0] = (byte)i;
+ }
+
+ tableIndex = 258;
+ bitsToGet = 9;
+ }
+
+ /**
+ * Write out the string just uncompressed.
+ */
+ public void WriteString(byte[] str) {
+ uncompData.Write(str, 0, str.Length);
+ }
+
+ /**
+ * Add a new string to the string table.
+ */
+ public void AddStringToTable(byte[] oldstring, byte newstring) {
+ int length = oldstring.Length;
+ byte[] str = new byte[length + 1];
+ Array.Copy(oldstring, 0, str, 0, length);
+ str[length] = newstring;
+
+ // Add this new string to the table
+ stringTable[tableIndex++] = str;
+
+ if (tableIndex == 511) {
+ bitsToGet = 10;
+ } else if (tableIndex == 1023) {
+ bitsToGet = 11;
+ } else if (tableIndex == 2047) {
+ bitsToGet = 12;
+ }
+ }
+
+ /**
+ * Add a new string to the string table.
+ */
+ public void AddStringToTable(byte[] str) {
+
+ // Add this new string to the table
+ stringTable[tableIndex++] = str;
+
+ if (tableIndex == 511) {
+ bitsToGet = 10;
+ } else if (tableIndex == 1023) {
+ bitsToGet = 11;
+ } else if (tableIndex == 2047) {
+ bitsToGet = 12;
+ }
+ }
+
+ /**
+ * Append
+ * An array is a sequence of PDF objects. An array may contain a mixture of object types.
+ * An array is written as a left square bracket ([), followed by a sequence of objects,
+ * followed by a right square bracket (]).
+ * The newly added object will be the first element in the
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.2 (page 37).
+ *
+ * @see PdfObject
+ * @see BadPdfFormatException
+ */
+
+ public class PdfBoolean : PdfObject {
+
+ // static membervariables (possible values of a bool object)
+ public static readonly PdfBoolean PDFTRUE = new PdfBoolean(true);
+ public static readonly PdfBoolean PDFFALSE = new PdfBoolean(false);
+ /** A possible value of
+ * A
+ * Remark: all the lines that can be drawn are removed from the object!
+ *
+ * @param top the top of the part of the table that can be drawn
+ * @param bottom the bottom of the part of the table that can be drawn
+ * @return an
+ * Remark: all the lines that can be drawn are removed from the object!
+ *
+ * @param top the top of the part of the table that can be drawn
+ * @param bottom the bottom of the part of the table that can be drawn
+ * @return an
+ * Headers may allways be removed, even if they are drawn only partially:
+ * they will be repeated on each following page anyway!
+ *
+ * @return
+ * A
+ * This attributes require the mesurement of characters widths when rendering
+ * such as underline.
+ */
+ protected Hashtable attributes = new Hashtable();
+
+ /**
+ * Non metric attributes.
+ *
+ * This attributes do not require the mesurement of characters widths when rendering
+ * such as Color.
+ */
+ protected Hashtable noStroke = new Hashtable();
+
+ /**
+ * Returns null if the
+ * Returns null if the
+ * @param string the
+ * Flatness sets the maximum permitted distance in device pixels between the
+ * mathematically correct path and an approximation constructed from straight line segments.
+ * The line cap style specifies the shape to be used at the end of open subpaths
+ * when they are stroked.
+ * The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
+ * It is specified by an array and a phase. The array specifies the length
+ * of the alternating dashes and gaps. The phase specifies the distance into the dash
+ * pattern to start the dash.
+ * The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
+ * It is specified by an array and a phase. The array specifies the length
+ * of the alternating dashes and gaps. The phase specifies the distance into the dash
+ * pattern to start the dash.
+ * The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
+ * It is specified by an array and a phase. The array specifies the length
+ * of the alternating dashes and gaps. The phase specifies the distance into the dash
+ * pattern to start the dash.
+ * The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
+ * It is specified by an array and a phase. The array specifies the length
+ * of the alternating dashes and gaps. The phase specifies the distance into the dash
+ * pattern to start the dash.
+ * The line join style specifies the shape to be used at the corners of paths
+ * that are stroked.
+ * The line width specifies the thickness of the line used to stroke a path and is measured
+ * in used space units.
+ * When two line segments meet at a sharp angle and mitered joins have been specified as the
+ * line join style, it is possible for the miter to extend far beyond the thickness of the line
+ * stroking path. The miter limit imposes a maximum on the ratio of the miter length to the line
+ * witdh. When the limit is exceeded, the join is converted from a miter to a bevel.
+ * Sets the color space to DeviceGray (or the DefaultGray color space),
+ * and sets the gray tint to use for filling paths.
+ * Sets the color space to DeviceGray (or the DefaultGray color space),
+ * and sets the gray tint to use for stroking paths.
+ * Sets the color space to DeviceRGB (or the DefaultRGB color space),
+ * and sets the color to use for filling paths.
+ * Following the PDF manual, each operand must be a number between 0 (minimum intensity) and
+ * 1 (maximum intensity).
+ * Sets the color space to DeviceRGB (or the DefaultRGB color space),
+ * and sets the color to use for stroking paths.
+ * Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and
+ * 1 (maximum intensity).
+ *
+ * @param red the intensity of red. A value between 0 and 1
+ * @param green the intensity of green. A value between 0 and 1
+ * @param blue the intensity of blue. A value between 0 and 1
+ */
+
+ public virtual void SetRGBColorStrokeF(float red, float green, float blue) {
+ HelperRGB(red, green, blue);
+ content.Append(" RG").Append_i(separator);
+ }
+
+ /**
+ * Changes the current color for stroking paths to black.
+ *
+ */
+
+ public virtual void ResetRGBColorStroke() {
+ content.Append("0 G").Append_i(separator);
+ }
+
+ /**
+ * Helper to validate and write the CMYK color components.
+ *
+ * @param cyan the intensity of cyan. A value between 0 and 1
+ * @param magenta the intensity of magenta. A value between 0 and 1
+ * @param yellow the intensity of yellow. A value between 0 and 1
+ * @param black the intensity of black. A value between 0 and 1
+ */
+ private void HelperCMYK(float cyan, float magenta, float yellow, float black) {
+ if (cyan < 0)
+ cyan = 0.0f;
+ else if (cyan > 1.0f)
+ cyan = 1.0f;
+ if (magenta < 0)
+ magenta = 0.0f;
+ else if (magenta > 1.0f)
+ magenta = 1.0f;
+ if (yellow < 0)
+ yellow = 0.0f;
+ else if (yellow > 1.0f)
+ yellow = 1.0f;
+ if (black < 0)
+ black = 0.0f;
+ else if (black > 1.0f)
+ black = 1.0f;
+ content.Append(cyan).Append(' ').Append(magenta).Append(' ').Append(yellow).Append(' ').Append(black);
+ }
+
+ /**
+ * Changes the current color for filling paths (device dependent colors!).
+ *
+ * Sets the color space to DeviceCMYK (or the DefaultCMYK color space),
+ * and sets the color to use for filling paths.
+ * Following the PDF manual, each operand must be a number between 0 (no ink) and
+ * 1 (maximum ink).
+ * Sets the color space to DeviceCMYK (or the DefaultCMYK color space),
+ * and sets the color to use for stroking paths.
+ * Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and
+ * 1 (maximum intensity).
+ *
+ * @param cyan the intensity of cyan. A value between 0 and 1
+ * @param magenta the intensity of magenta. A value between 0 and 1
+ * @param yellow the intensity of yellow. A value between 0 and 1
+ * @param black the intensity of black. A value between 0 and 1
+ */
+
+ public virtual void SetCMYKColorStrokeF(float cyan, float magenta, float yellow, float black) {
+ HelperCMYK(cyan, magenta, yellow, black);
+ content.Append(" K").Append_i(separator);
+ }
+
+ /**
+ * Changes the current color for stroking paths to black.
+ *
+ */
+
+ public virtual void ResetCMYKColorStroke() {
+ content.Append("0 0 0 1 K").Append_i(separator);
+ }
+
+ /**
+ * Move the current point (x, y), omitting any connecting line segment.
+ *
+ * @param x new x-coordinate
+ * @param y new y-coordinate
+ */
+
+ public void MoveTo(float x, float y) {
+ content.Append(x).Append(' ').Append(y).Append(" m").Append_i(separator);
+ }
+
+ /**
+ * Appends a straight line segment from the current point (x, y). The new current
+ * point is (x, y).
+ *
+ * @param x new x-coordinate
+ * @param y new y-coordinate
+ */
+
+ public void LineTo(float x, float y) {
+ content.Append(x).Append(' ').Append(y).Append(" l").Append_i(separator);
+ }
+
+ /**
+ * Appends a Bêzier curve to the path, starting from the current point.
+ *
+ * @param x1 x-coordinate of the first control point
+ * @param y1 y-coordinate of the first control point
+ * @param x2 x-coordinate of the second control point
+ * @param y2 y-coordinate of the second control point
+ * @param x3 x-coordinaat of the ending point (= new current point)
+ * @param y3 y-coordinaat of the ending point (= new current point)
+ */
+
+ public void CurveTo(float x1, float y1, float x2, float y2, float x3, float y3) {
+ content.Append(x1).Append(' ').Append(y1).Append(' ').Append(x2).Append(' ').Append(y2).Append(' ').Append(x3).Append(' ').Append(y3).Append(" c").Append_i(separator);
+ }
+
+ /**
+ * Appends a Bêzier curve to the path, starting from the current point.
+ *
+ * @param x2 x-coordinate of the second control point
+ * @param y2 y-coordinate of the second control point
+ * @param x3 x-coordinaat of the ending point (= new current point)
+ * @param y3 y-coordinaat of the ending point (= new current point)
+ */
+
+ public void CurveTo(float x2, float y2, float x3, float y3) {
+ content.Append(x2).Append(' ').Append(y2).Append(' ').Append(x3).Append(' ').Append(y3).Append(" v").Append_i(separator);
+ }
+
+ /**
+ * Appends a Bêzier curve to the path, starting from the current point.
+ *
+ * @param x1 x-coordinate of the first control point
+ * @param y1 y-coordinate of the first control point
+ * @param x3 x-coordinaat of the ending point (= new current point)
+ * @param y3 y-coordinaat of the ending point (= new current point)
+ */
+
+ public void CurveFromTo(float x1, float y1, float x3, float y3) {
+ content.Append(x1).Append(' ').Append(y1).Append(' ').Append(x3).Append(' ').Append(y3).Append(" y").Append_i(separator);
+ }
+
+ /** Draws a circle. The endpoint will (x+r, y).
+ *
+ * @param x x center of circle
+ * @param y y center of circle
+ * @param r radius of circle
+ */
+ public void Circle(float x, float y, float r) {
+ float b = 0.5523f;
+ MoveTo(x + r, y);
+ CurveTo(x + r, y + r * b, x + r * b, y + r, x, y + r);
+ CurveTo(x - r * b, y + r, x - r, y + r * b, x - r, y);
+ CurveTo(x - r, y - r * b, x - r * b, y - r, x, y - r);
+ CurveTo(x + r * b, y - r, x + r, y - r * b, x + r, y);
+ }
+
+
+
+ /**
+ * Adds a rectangle to the current path.
+ *
+ * @param x x-coordinate of the starting point
+ * @param y y-coordinate of the starting point
+ * @param w width
+ * @param h height
+ */
+
+ public void Rectangle(float x, float y, float w, float h) {
+ content.Append(x).Append(' ').Append(y).Append(' ').Append(w).Append(' ').Append(h).Append(" re").Append_i(separator);
+ }
+
+ private bool CompareColors(Color c1, Color c2) {
+ if (c1 == null && c2 == null)
+ return true;
+ if (c1 == null || c2 == null)
+ return false;
+ if (c1 is ExtendedColor)
+ return c1.Equals(c2);
+ return c2.Equals(c1);
+ }
+
+ /**
+ * Adds a variable width border to the current path.
+ * Only use if {@link com.lowagie.text.Rectangle#isUseVariableBorders() Rectangle.isUseVariableBorders}
+ * = true.
+ * @param rect a
+ * This allows to write text in subscript or basescript mode.
+ * Remark: this operation also initializes the current point position.
+ * Remark: this operation also initializes the current point position.
+ * As a side effect, this sets the leading parameter in the text state.
+ * (x1, y1) and (x2, y2) are the corners of the enclosing rectangle.
+ * Angles, measured in degrees, start with 0 to the right (the positive X
+ * axis) and increase counter-clockwise. The arc extends from startAng
+ * to startAng+extent. I.e. startAng=0 and extent=180 yields an openside-down
+ * semi-circle.
+ *
+ * The resulting coordinates are of the form float[]{x1,y1,x2,y2,x3,y3, x4,y4}
+ * such that the curve goes from (x1, y1) to (x4, y4) with (x2, y2) and
+ * (x3, y3) as their respective Bezier control points.
+ *
+ * Note: this code was taken from ReportLab (www.reportlab.com), an excelent
+ * PDF generator for Python.
+ *
+ * @param x1 a corner of the enclosing rectangle
+ * @param y1 a corner of the enclosing rectangle
+ * @param x2 a corner of the enclosing rectangle
+ * @param y2 a corner of the enclosing rectangle
+ * @param startAng starting angle in degrees
+ * @param extent angle extent in degrees
+ * @return a list of float[] with the bezier curves
+ */
+ public static ArrayList BezierArc(float x1, float y1, float x2, float y2, float startAng, float extent) {
+ float tmp;
+ if (x1 > x2) {
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+ if (y2 > y1) {
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
+
+ float fragAngle;
+ int Nfrag;
+ if (Math.Abs(extent) <= 90f) {
+ fragAngle = extent;
+ Nfrag = 1;
+ }
+ else {
+ Nfrag = (int)(Math.Ceiling(Math.Abs(extent)/90f));
+ fragAngle = extent / Nfrag;
+ }
+ float x_cen = (x1+x2)/2f;
+ float y_cen = (y1+y2)/2f;
+ float rx = (x2-x1)/2f;
+ float ry = (y2-y1)/2f;
+ float halfAng = (float)(fragAngle * Math.PI / 360.0);
+ float kappa = (float)(Math.Abs(4.0 / 3.0 * (1.0 - Math.Cos(halfAng)) / Math.Sin(halfAng)));
+ ArrayList pointList = new ArrayList();
+ for (int i = 0; i < Nfrag; ++i) {
+ float theta0 = (float)((startAng + i*fragAngle) * Math.PI / 180.0);
+ float theta1 = (float)((startAng + (i+1)*fragAngle) * Math.PI / 180.0);
+ float cos0 = (float)Math.Cos(theta0);
+ float cos1 = (float)Math.Cos(theta1);
+ float sin0 = (float)Math.Sin(theta0);
+ float sin1 = (float)Math.Sin(theta1);
+ if (fragAngle > 0f) {
+ pointList.Add(new float[]{x_cen + rx * cos0,
+ y_cen - ry * sin0,
+ x_cen + rx * (cos0 - kappa * sin0),
+ y_cen - ry * (sin0 + kappa * cos0),
+ x_cen + rx * (cos1 + kappa * sin1),
+ y_cen - ry * (sin1 - kappa * cos1),
+ x_cen + rx * cos1,
+ y_cen - ry * sin1});
+ }
+ else {
+ pointList.Add(new float[]{x_cen + rx * cos0,
+ y_cen - ry * sin0,
+ x_cen + rx * (cos0 + kappa * sin0),
+ y_cen - ry * (sin0 - kappa * cos0),
+ x_cen + rx * (cos1 - kappa * sin1),
+ y_cen - ry * (sin1 + kappa * cos1),
+ x_cen + rx * cos1,
+ y_cen - ry * sin1});
+ }
+ }
+ return pointList;
+ }
+
+ /**
+ * Draws a partial ellipse inscribed within the rectangle x1,y1,x2,y2,
+ * starting at startAng degrees and covering extent degrees. Angles
+ * start with 0 to the right (+x) and increase counter-clockwise.
+ *
+ * @param x1 a corner of the enclosing rectangle
+ * @param y1 a corner of the enclosing rectangle
+ * @param x2 a corner of the enclosing rectangle
+ * @param y2 a corner of the enclosing rectangle
+ * @param startAng starting angle in degrees
+ * @param extent angle extent in degrees
+ */
+ public void Arc(float x1, float y1, float x2, float y2, float startAng, float extent) {
+ ArrayList ar = BezierArc(x1, y1, x2, y2, startAng, extent);
+ if (ar.Count == 0)
+ return;
+ float[] pt = (float [])ar[0];
+ MoveTo(pt[0], pt[1]);
+ for (int k = 0; k < ar.Count; ++k) {
+ pt = (float [])ar[k];
+ CurveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]);
+ }
+ }
+
+ /**
+ * Draws an ellipse inscribed within the rectangle x1,y1,x2,y2.
+ *
+ * @param x1 a corner of the enclosing rectangle
+ * @param y1 a corner of the enclosing rectangle
+ * @param x2 a corner of the enclosing rectangle
+ * @param y2 a corner of the enclosing rectangle
+ */
+ public void Ellipse(float x1, float y1, float x2, float y2) {
+ Arc(x1, y1, x2, y2, 0f, 360f);
+ }
+
+ /**
+ * Create a new colored tiling pattern.
+ *
+ * @param width the width of the pattern
+ * @param height the height of the pattern
+ * @param xstep the desired horizontal spacing between pattern cells.
+ * May be either positive or negative, but not zero.
+ * @param ystep the desired vertical spacing between pattern cells.
+ * May be either positive or negative, but not zero.
+ * @return the
+ * Creates a new template that is nothing more than a form XObject. This template can be included
+ * in this
+ * Sets the color space to DeviceCMYK (or the DefaultCMYK color space),
+ * and sets the color to use for filling paths.
+ * This method is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 8.5.2.1 (page 331).
+ * Following the PDF manual, each operand must be a number between 0 (no ink) and
+ * 1 (maximum ink). This method however accepts only ints between 0x00 and 0xFF.
+ * Sets the color space to DeviceCMYK (or the DefaultCMYK color space),
+ * and sets the color to use for stroking paths.
+ * This method is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 8.5.2.1 (page 331).
+ * Sets the color space to DeviceRGB (or the DefaultRGB color space),
+ * and sets the color to use for filling paths.
+ * This method is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 8.5.2.1 (page 331).
+ * Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and
+ * 1 (maximum intensity). This method however accepts only ints between 0x00 and 0xFF.
+ * Sets the color space to DeviceRGB (or the DefaultRGB color space),
+ * and sets the color to use for stroking paths.
+ * This method is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 8.5.2.1 (page 331).
+ * Note that nested layers with {@link PdfLayer#addChild(PdfLayer)} only require a single
+ * call to this method and a single call to {@link #endLayer()}; all the nesting control
+ * is built in.
+ * @param layer the layer
+ */
+ public void BeginLayer(IPdfOCG layer) {
+ if ((layer is PdfLayer) && ((PdfLayer)layer).Title != null)
+ throw new ArgumentException("A title is not a layer");
+ if (layerDepth == null)
+ layerDepth = new ArrayList();
+ if (layer is PdfLayerMembership) {
+ layerDepth.Add(1);
+ BeginLayer2(layer);
+ return;
+ }
+ int n = 0;
+ PdfLayer la = (PdfLayer)layer;
+ while (la != null) {
+ if (la.Title == null) {
+ BeginLayer2(la);
+ ++n;
+ }
+ la = la.Parent;
+ }
+ layerDepth.Add(n);
+ }
+
+ private void BeginLayer2(IPdfOCG layer) {
+ PdfName name = (PdfName)writer.AddSimpleProperty(layer, layer.Ref)[0];
+ PageResources prs = PageResources;
+ name = prs.AddProperty(name, layer.Ref);
+ content.Append("/OC ").Append(name.GetBytes()).Append(" BDC").Append_i(separator);
+ }
+
+ /**
+ * Ends a layer controled graphic block. It will end the most recent open block.
+ */
+ public void EndLayer() {
+ int n = 1;
+ if (layerDepth != null && layerDepth.Count > 0) {
+ n = (int)layerDepth[layerDepth.Count - 1];
+ layerDepth.RemoveAt(layerDepth.Count - 1);
+ }
+ while (n-- > 0)
+ content.Append("EMC").Append_i(separator);
+ }
+
+ internal virtual void AddAnnotation(PdfAnnotation annot) {
+ writer.AddAnnotation(annot);
+ }
+
+ /**
+ * Sets the default colorspace.
+ * @param name the name of the colorspace. It can be
+ * The pages-tree is built and written to the outputstream.
+ * A Catalog is constructed, as well as an Info-object,
+ * the referencetable is composed and everything is written
+ * to the outputstream embedded in a Trailer.
+ */
+
+ public override void Close() {
+ if (open) {
+ PdfReaderInstance ri = currentPdfReaderInstance;
+ pdf.Close();
+ base.Close();
+ if (ri != null) {
+ try {
+ ri.Reader.Close();
+ ri.ReaderFile.Close();
+ }
+ catch (IOException) {
+ // empty on purpose
+ }
+ }
+ }
+ }
+
+ public override void AddAnnotation(PdfAnnotation annot) { }
+ internal override PdfIndirectReference Add(PdfPage page, PdfContents contents) { return null; }
+
+ public override void FreeReader(PdfReader reader) {
+ indirectMap.Remove(reader);
+ if (currentPdfReaderInstance != null) {
+ if (currentPdfReaderInstance.Reader == reader) {
+ try {
+ currentPdfReaderInstance.Reader.Close();
+ currentPdfReaderInstance.ReaderFile.Close();
+ }
+ catch (IOException) {
+ // empty on purpose
+ }
+ currentPdfReaderInstance = null;
+ }
+ }
+ }
+
+ /**
+ * Create a page stamp. New content and annotations, including new fields, are allowed.
+ * The fields added cannot have parents in another pages. This method modifies the PdfReader instance.
+ * The general usage to stamp something in a page is:
+ *
+ *
+ * If set before opening the document it will also set the pdf version to 1.5.
+ */
+ public void SetFullCompression() {
+ fc.SetFullCompression();
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(byte[], byte[], int, int)
+ */
+ public void SetEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType) {
+ fc.SetEncryption(userPassword, ownerPassword, permissions, encryptionType);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#addViewerPreference(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfObject)
+ */
+ public void AddViewerPreference(PdfName key, PdfObject value) {
+ fc.AddViewerPreference(key, value);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#setViewerPreferences(int)
+ */
+ public int ViewerPreferences {
+ set {
+ fc.ViewerPreferences = value;
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(java.security.cert.Certificate[], int[], int)
+ */
+ public void SetEncryption(X509Certificate[] certs, int[] permissions, int encryptionType) {
+ fc.SetEncryption(certs, permissions, encryptionType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfCopyFieldsImp.cs b/iTechSharp/iTextSharp/text/pdf/PdfCopyFieldsImp.cs
new file mode 100644
index 0000000..d404fc1
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfCopyFieldsImp.cs
@@ -0,0 +1,600 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.util;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ *
+ * @author psoares
+ */
+ internal class PdfCopyFieldsImp : PdfWriter {
+
+ private static readonly PdfName iTextTag = new PdfName("_iTextTag_");
+ private static object zero = 0;
+ internal ArrayList readers = new ArrayList();
+ internal Hashtable readers2intrefs = new Hashtable();
+ internal Hashtable pages2intrefs = new Hashtable();
+ internal Hashtable visited = new Hashtable();
+ internal ArrayList fields = new ArrayList();
+ internal RandomAccessFileOrArray file;
+ internal Hashtable fieldTree = new Hashtable();
+ internal ArrayList pageRefs = new ArrayList();
+ internal ArrayList pageDics = new ArrayList();
+ internal PdfDictionary resources = new PdfDictionary();
+ internal PdfDictionary form;
+ bool closing = false;
+ internal Document nd;
+ private Hashtable tabOrder;
+ private ArrayList calculationOrder = new ArrayList();
+ private ArrayList calculationOrderRefs;
+
+ internal PdfCopyFieldsImp(Stream os) : this(os, '\0') {
+ }
+
+ internal PdfCopyFieldsImp(Stream os, char pdfVersion) : base(new PdfDocument(), os) {
+ pdf.AddWriter(this);
+ if (pdfVersion != 0)
+ base.PdfVersion = pdfVersion;
+ nd = new Document();
+ nd.AddDocListener(pdf);
+ }
+
+ internal void AddDocument(PdfReader reader, ArrayList pagesToKeep) {
+ if (!readers2intrefs.ContainsKey(reader) && reader.Tampered)
+ throw new DocumentException("The document was reused.");
+ reader = new PdfReader(reader);
+ reader.SelectPages(pagesToKeep);
+ if (reader.NumberOfPages == 0)
+ return;
+ reader.Tampered = false;
+ AddDocument(reader);
+ }
+
+ internal void AddDocument(PdfReader reader) {
+ if (!reader.IsOpenedWithFullPermissions)
+ throw new ArgumentException("PdfReader not opened with owner password");
+ OpenDoc();
+ if (readers2intrefs.ContainsKey(reader)) {
+ reader = new PdfReader(reader);
+ }
+ else {
+ if (reader.Tampered)
+ throw new DocumentException("The document was reused.");
+ reader.ConsolidateNamedDestinations();
+ reader.Tampered = true;
+ }
+ reader.ShuffleSubsetNames();
+ readers2intrefs[reader] = new IntHashtable();
+ readers.Add(reader);
+ int len = reader.NumberOfPages;
+ IntHashtable refs = new IntHashtable();
+ for (int p = 1; p <= len; ++p) {
+ refs[reader.GetPageOrigRef(p).Number] = 1;
+ reader.ReleasePage(p);
+ }
+ pages2intrefs[reader] = refs;
+ visited[reader] = new IntHashtable();
+ fields.Add(reader.AcroFields);
+ UpdateCalculationOrder(reader);
+ }
+
+ private static String GetCOName(PdfReader reader, PRIndirectReference refi) {
+ String name = "";
+ while (refi != null) {
+ PdfObject obj = PdfReader.GetPdfObject(refi);
+ if (obj == null || obj.Type != PdfObject.DICTIONARY)
+ break;
+ PdfDictionary dic = (PdfDictionary)obj;
+ PdfString t = (PdfString)PdfReader.GetPdfObject(dic.Get(PdfName.T));
+ if (t != null) {
+ name = t.ToUnicodeString()+ "." + name;
+ }
+ refi = (PRIndirectReference)dic.Get(PdfName.PARENT);
+ }
+ if (name.EndsWith("."))
+ name = name.Substring(0, name.Length - 1);
+ return name;
+ }
+
+ private void UpdateCalculationOrder(PdfReader reader) {
+ PdfDictionary catalog = reader.Catalog;
+ PdfDictionary acro = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.ACROFORM));
+ if (acro == null)
+ return;
+ PdfArray co = (PdfArray)PdfReader.GetPdfObject(acro.Get(PdfName.CO));
+ if (co == null || co.Size == 0)
+ return;
+ AcroFields af = reader.AcroFields;
+ ArrayList coa = co.ArrayList;
+ for (int k = 0; k < coa.Count; ++k) {
+ PdfObject obj = (PdfObject)coa[k];
+ if (obj == null || !obj.IsIndirect())
+ continue;
+ String name = GetCOName(reader, (PRIndirectReference)obj) ;
+ if (af.GetFieldItem(name) == null)
+ continue;
+ name = "." + name;
+ if (calculationOrder.Contains(name))
+ continue;
+ calculationOrder.Add(name);
+ }
+ }
+
+ internal void Propagate(PdfObject obj, PdfIndirectReference refo, bool restricted) {
+ if (obj == null)
+ return;
+ // if (refo != null)
+ // AddToBody(obj, refo);
+ if (obj is PdfIndirectReference)
+ return;
+ switch (obj.Type) {
+ case PdfObject.DICTIONARY:
+ case PdfObject.STREAM: {
+ PdfDictionary dic = (PdfDictionary)obj;
+ foreach (PdfName key in dic.Keys) {
+ if (restricted && (key.Equals(PdfName.PARENT) || key.Equals(PdfName.KIDS)))
+ continue;
+ PdfObject ob = dic.Get(key);
+ if (ob != null && ob.IsIndirect()) {
+ PRIndirectReference ind = (PRIndirectReference)ob;
+ if (!SetVisited(ind) && !IsPage(ind)) {
+ PdfIndirectReference refi = GetNewReference(ind);
+ Propagate(PdfReader.GetPdfObjectRelease(ind), refi, restricted);
+ }
+ }
+ else
+ Propagate(ob, null, restricted);
+ }
+ break;
+ }
+ case PdfObject.ARRAY: {
+ ArrayList list = ((PdfArray)obj).ArrayList;
+ //PdfArray arr = new PdfArray();
+ foreach (PdfObject ob in list) {
+ if (ob != null && ob.IsIndirect()) {
+ PRIndirectReference ind = (PRIndirectReference)ob;
+ if (!IsVisited(ind) && !IsPage(ind)) {
+ PdfIndirectReference refi = GetNewReference(ind);
+ Propagate(PdfReader.GetPdfObjectRelease(ind), refi, restricted);
+ }
+ }
+ else
+ Propagate(ob, null, restricted);
+ }
+ break;
+ }
+ case PdfObject.INDIRECT: {
+ throw new Exception("Reference pointing to reference.");
+ }
+ }
+ }
+
+ private void AdjustTabOrder(PdfArray annots, PdfIndirectReference ind, PdfNumber nn) {
+ int v = nn.IntValue;
+ ArrayList t = (ArrayList)tabOrder[annots] ;
+ if (t == null) {
+ t = new ArrayList();
+ int size = annots.Size - 1;
+ for (int k = 0; k < size; ++k) {
+ t.Add(zero);
+ }
+ t.Add(v);
+ tabOrder[annots] = t;
+ annots.Add(ind);
+ }
+ else {
+ int size = t.Count - 1;
+ for (int k = size; k >= 0; --k) {
+ if ((int)t[k] <= v) {
+ t.Insert(k + 1, v);
+ annots.ArrayList.Insert(k + 1, ind);
+ size = -2;
+ break;
+ }
+ }
+ if (size != -2) {
+ t.Insert(0, v);
+ annots.ArrayList.Insert(0, ind);
+ }
+ }
+ }
+
+ protected PdfArray BranchForm(Hashtable level, PdfIndirectReference parent, String fname) {
+ PdfArray arr = new PdfArray();
+ foreach (DictionaryEntry entry in level) {
+ String name = (String)entry.Key;
+ Object obj = entry.Value;
+ PdfIndirectReference ind = PdfIndirectReference;
+ PdfDictionary dic = new PdfDictionary();
+ if (parent != null)
+ dic.Put(PdfName.PARENT, parent);
+ dic.Put(PdfName.T, new PdfString(name, PdfObject.TEXT_UNICODE));
+ String fname2 = fname + "." + name;
+ int coidx = calculationOrder.IndexOf(fname2);
+ if (coidx >= 0)
+ calculationOrderRefs[coidx] = ind;
+ if (obj is Hashtable) {
+ dic.Put(PdfName.KIDS, BranchForm((Hashtable)obj, ind, fname2));
+ arr.Add(ind);
+ AddToBody(dic, ind);
+ }
+ else {
+ ArrayList list = (ArrayList)obj;
+ dic.MergeDifferent((PdfDictionary)list[0]);
+ if (list.Count == 3) {
+ dic.MergeDifferent((PdfDictionary)list[2]);
+ int page = (int)list[1];
+ PdfDictionary pageDic = (PdfDictionary)pageDics[page - 1];
+ PdfArray annots = (PdfArray)PdfReader.GetPdfObject(pageDic.Get(PdfName.ANNOTS));
+ if (annots == null) {
+ annots = new PdfArray();
+ pageDic.Put(PdfName.ANNOTS, annots);
+ }
+ PdfNumber nn = (PdfNumber)dic.Get(iTextTag);
+ dic.Remove(iTextTag);
+ AdjustTabOrder(annots, ind, nn);
+ }
+ else {
+ PdfArray kids = new PdfArray();
+ for (int k = 1; k < list.Count; k += 2) {
+ int page = (int)list[k];
+ PdfDictionary pageDic = (PdfDictionary)pageDics[page - 1];
+ PdfArray annots = (PdfArray)PdfReader.GetPdfObject(pageDic.Get(PdfName.ANNOTS));
+ if (annots == null) {
+ annots = new PdfArray();
+ pageDic.Put(PdfName.ANNOTS, annots);
+ }
+ PdfDictionary widget = new PdfDictionary();
+ widget.Merge((PdfDictionary)list[k + 1]);
+ widget.Put(PdfName.PARENT, ind);
+ PdfNumber nn = (PdfNumber)widget.Get(iTextTag);
+ widget.Remove(iTextTag);
+ PdfIndirectReference wref = AddToBody(widget).IndirectReference;
+ AdjustTabOrder(annots, wref, nn);
+ kids.Add(wref);
+ Propagate(widget, null, false);
+ }
+ dic.Put(PdfName.KIDS, kids);
+ }
+ arr.Add(ind);
+ AddToBody(dic, ind);
+ Propagate(dic, null, false);
+ }
+ }
+ return arr;
+ }
+
+ protected void CreateAcroForms() {
+ if (fieldTree.Count == 0)
+ return;
+ form = new PdfDictionary();
+ form.Put(PdfName.DR, resources);
+ Propagate(resources, null, false);
+ form.Put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
+ tabOrder = new Hashtable();
+ calculationOrderRefs = new ArrayList(calculationOrder);
+ form.Put(PdfName.FIELDS, BranchForm(fieldTree, null, ""));
+ PdfArray co = new PdfArray();
+ for (int k = 0; k < calculationOrderRefs.Count; ++k) {
+ Object obj = calculationOrderRefs[k];
+ if (obj is PdfIndirectReference)
+ co.Add((PdfIndirectReference)obj);
+ }
+ if (co.Size > 0)
+ form.Put(PdfName.CO, co);
+ }
+
+ public override void Close() {
+ if (closing) {
+ base.Close();
+ return;
+ }
+ closing = true;
+ CloseIt();
+ }
+
+ protected void CloseIt() {
+ for (int k = 0; k < readers.Count; ++k) {
+ ((PdfReader)readers[k]).RemoveFields();
+ }
+ for (int r = 0; r < readers.Count; ++r) {
+ PdfReader reader = (PdfReader)readers[r];
+ for (int page = 1; page <= reader.NumberOfPages; ++page) {
+ pageRefs.Add(GetNewReference(reader.GetPageOrigRef(page)));
+ pageDics.Add(reader.GetPageN(page));
+ }
+ }
+ MergeFields();
+ CreateAcroForms();
+ for (int r = 0; r < readers.Count; ++r) {
+ PdfReader reader = (PdfReader)readers[r];
+ for (int page = 1; page <= reader.NumberOfPages; ++page) {
+ PdfDictionary dic = reader.GetPageN(page);
+ PdfIndirectReference pageRef = GetNewReference(reader.GetPageOrigRef(page));
+ PdfIndirectReference parent = root.AddPageRef(pageRef);
+ dic.Put(PdfName.PARENT, parent);
+ Propagate(dic, pageRef, false);
+ }
+ }
+ foreach (DictionaryEntry entry in readers2intrefs) {
+ PdfReader reader = (PdfReader)entry.Key;
+ try {
+ file = reader.SafeFile;
+ file.ReOpen();
+ IntHashtable t = (IntHashtable)entry.Value;
+ int[] keys = t.ToOrderedKeys();
+ for (int k = 0; k < keys.Length; ++k) {
+ PRIndirectReference refi = new PRIndirectReference(reader, keys[k]);
+ AddToBody(PdfReader.GetPdfObjectRelease(refi), t[keys[k]]);
+ }
+ }
+ finally {
+ try {
+ file.Close();
+ reader.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+ pdf.Close();
+ }
+
+ internal void AddPageOffsetToField(Hashtable fd, int pageOffset) {
+ if (pageOffset == 0)
+ return;
+ foreach (AcroFields.Item item in fd.Values) {
+ ArrayList page = item.page;
+ for (int k = 0; k < page.Count; ++k)
+ page[k] = (int)page[k] + pageOffset;
+ }
+ }
+
+ internal void CreateWidgets(ArrayList list, AcroFields.Item item) {
+ for (int k = 0; k < item.merged.Count; ++k) {
+ list.Add(item.page[k]);
+ PdfDictionary merged = (PdfDictionary)item.merged[k];
+ PdfObject dr = merged.Get(PdfName.DR);
+ if (dr != null)
+ PdfFormField.MergeResources(resources, (PdfDictionary)PdfReader.GetPdfObject(dr));
+ PdfDictionary widget = new PdfDictionary();
+ foreach (PdfName key in merged.Keys) {
+ if (widgetKeys.ContainsKey(key))
+ widget.Put(key, merged.Get(key));
+ }
+ widget.Put(iTextTag, new PdfNumber((int)item.tabOrder[k] + 1));
+ list.Add(widget);
+ }
+ }
+
+ internal void MergeField(String name, AcroFields.Item item) {
+ Hashtable map = fieldTree;
+ StringTokenizer tk = new StringTokenizer(name, ".");
+ if (!tk.HasMoreTokens())
+ return;
+ while (true) {
+ String s = tk.NextToken();
+ Object obj = map[s];
+ if (tk.HasMoreTokens()) {
+ if (obj == null) {
+ obj = new Hashtable();
+ map[s] = obj;
+ map = (Hashtable)obj;
+ continue;
+ }
+ else if (obj is Hashtable)
+ map = (Hashtable)obj;
+ else
+ return;
+ }
+ else {
+ if (obj is Hashtable)
+ return;
+ PdfDictionary merged = (PdfDictionary)item.merged[0];
+ if (obj == null) {
+ PdfDictionary field = new PdfDictionary();
+ foreach (PdfName key in merged.Keys) {
+ if (fieldKeys.ContainsKey(key))
+ field.Put(key, merged.Get(key));
+ }
+ ArrayList list = new ArrayList();
+ list.Add(field);
+ CreateWidgets(list, item);
+ map[s] = list;
+ }
+ else {
+ ArrayList list = (ArrayList)obj;
+ PdfDictionary field = (PdfDictionary)list[0];
+ PdfName type1 = (PdfName)field.Get(PdfName.FT);
+ PdfName type2 = (PdfName)merged.Get(PdfName.FT);
+ if (type1 == null || !type1.Equals(type2))
+ return;
+ int flag1 = 0;
+ PdfObject f1 = field.Get(PdfName.FF);
+ if (f1 != null && f1.IsNumber())
+ flag1 = ((PdfNumber)f1).IntValue;
+ int flag2 = 0;
+ PdfObject f2 = merged.Get(PdfName.FF);
+ if (f2 != null && f2.IsNumber())
+ flag2 = ((PdfNumber)f2).IntValue;
+ if (type1.Equals(PdfName.BTN)) {
+ if (((flag1 ^ flag2) & PdfFormField.FF_PUSHBUTTON) != 0)
+ return;
+ if ((flag1 & PdfFormField.FF_PUSHBUTTON) == 0 && ((flag1 ^ flag2) & PdfFormField.FF_RADIO) != 0)
+ return;
+ }
+ else if (type1.Equals(PdfName.CH)) {
+ if (((flag1 ^ flag2) & PdfFormField.FF_COMBO) != 0)
+ return;
+ }
+ CreateWidgets(list, item);
+ }
+ return;
+ }
+ }
+ }
+
+ internal void MergeWithMaster(Hashtable fd) {
+ foreach (DictionaryEntry entry in fd) {
+ String name = (String)entry.Key;
+ MergeField(name, (AcroFields.Item)entry.Value);
+ }
+ }
+
+ internal void MergeFields() {
+ int pageOffset = 0;
+ for (int k = 0; k < fields.Count; ++k) {
+ Hashtable fd = ((AcroFields)fields[k]).Fields;
+ AddPageOffsetToField(fd, pageOffset);
+ MergeWithMaster(fd);
+ pageOffset += ((PdfReader)readers[k]).NumberOfPages;
+ }
+ }
+
+ public override PdfIndirectReference GetPageReference(int page) {
+ return (PdfIndirectReference)pageRefs[page - 1];
+ }
+
+ protected override PdfDictionary GetCatalog(PdfIndirectReference rootObj) {
+ PdfDictionary cat = pdf.GetCatalog(rootObj);
+ if (form != null) {
+ PdfIndirectReference refi = AddToBody(form).IndirectReference;
+ cat.Put(PdfName.ACROFORM, refi);
+ }
+ WriteOutlines(cat, false);
+ return cat;
+ }
+
+ protected PdfIndirectReference GetNewReference(PRIndirectReference refi) {
+ return new PdfIndirectReference(0, GetNewObjectNumber(refi.Reader, refi.Number, 0));
+ }
+
+ protected internal override int GetNewObjectNumber(PdfReader reader, int number, int generation) {
+ IntHashtable refs = (IntHashtable)readers2intrefs[reader];
+ int n = refs[number];
+ if (n == 0) {
+ n = IndirectReferenceNumber;
+ refs[number] = n;
+ }
+ return n;
+ }
+
+ protected bool IsVisited(PdfReader reader, int number, int generation) {
+ IntHashtable refs = (IntHashtable)readers2intrefs[reader];
+ return refs.ContainsKey(number);
+ }
+
+ protected bool IsVisited(PRIndirectReference refi) {
+ IntHashtable refs = (IntHashtable)visited[refi.Reader];
+ return refs.ContainsKey(refi.Number);
+ }
+
+ protected bool SetVisited(PRIndirectReference refi) {
+ IntHashtable refs = (IntHashtable)visited[refi.Reader];
+ int old = refs[refi.Number];
+ refs[refi.Number] = 1;
+ return (old != 0);
+ }
+
+ protected bool IsPage(PRIndirectReference refi) {
+ IntHashtable refs = (IntHashtable)pages2intrefs[refi.Reader] ;
+ return refs.ContainsKey(refi.Number);
+ }
+
+ internal override RandomAccessFileOrArray GetReaderFile(PdfReader reader) {
+ return file;
+ }
+
+ public void OpenDoc() {
+ if (!nd.IsOpen())
+ nd.Open();
+ }
+
+ protected internal static Hashtable widgetKeys = new Hashtable();
+ protected internal static Hashtable fieldKeys = new Hashtable();
+ static PdfCopyFieldsImp() {
+ object one = 1;
+ widgetKeys[PdfName.SUBTYPE] = one;
+ widgetKeys[PdfName.CONTENTS] = one;
+ widgetKeys[PdfName.RECT] = one;
+ widgetKeys[PdfName.NM] = one;
+ widgetKeys[PdfName.M] = one;
+ widgetKeys[PdfName.F] = one;
+ widgetKeys[PdfName.BS] = one;
+ widgetKeys[PdfName.BORDER] = one;
+ widgetKeys[PdfName.AP] = one;
+ widgetKeys[PdfName.AS] = one;
+ widgetKeys[PdfName.C] = one;
+ widgetKeys[PdfName.A] = one;
+ widgetKeys[PdfName.STRUCTPARENT] = one;
+ widgetKeys[PdfName.OC] = one;
+ widgetKeys[PdfName.H] = one;
+ widgetKeys[PdfName.MK] = one;
+ widgetKeys[PdfName.DA] = one;
+ widgetKeys[PdfName.Q] = one;
+ fieldKeys[PdfName.AA] = one;
+ fieldKeys[PdfName.FT] = one;
+ fieldKeys[PdfName.TU] = one;
+ fieldKeys[PdfName.TM] = one;
+ fieldKeys[PdfName.FF] = one;
+ fieldKeys[PdfName.V] = one;
+ fieldKeys[PdfName.DV] = one;
+ fieldKeys[PdfName.DS] = one;
+ fieldKeys[PdfName.RV] = one;
+ fieldKeys[PdfName.OPT] = one;
+ fieldKeys[PdfName.MAXLEN] = one;
+ fieldKeys[PdfName.TI] = one;
+ fieldKeys[PdfName.I] = one;
+ fieldKeys[PdfName.LOCK] = one;
+ fieldKeys[PdfName.SV] = one;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfDashPattern.cs b/iTechSharp/iTextSharp/text/pdf/PdfDashPattern.cs
new file mode 100644
index 0000000..386b3d6
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfDashPattern.cs
@@ -0,0 +1,142 @@
+using System;
+using System.IO;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfDashPattern.cs,v 1.3 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A
+ * PDF defines a standard date format. The PDF date format closely follows the format
+ * defined by the international standard ASN.1 (Abstract Syntax Notation One, defined
+ * in CCITT X.208 or ISO/IEC 8824). A date is a
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 7.2 (page 183-184)
+ *
+ * @see PdfString
+ * @see java.util.GregorianCalendar
+ */
+
+ public class PdfDate : PdfString {
+
+ // constructors
+
+ /**
+ * Constructs a
+ * If type equals FITB, the bounding box of a page
+ * will fit the window of the Reader. Otherwise the type will be set to
+ * FIT so that the entire page will fit to the window.
+ *
+ * @param type The destination type
+ */
+
+ public PdfDestination(int type) : base() {
+ if (type == FITB) {
+ Add(PdfName.FITB);
+ }
+ else {
+ Add(PdfName.FIT);
+ }
+ }
+
+ /**
+ * Constructs a new
+ * If type equals FITBH / FITBV,
+ * the width / height of the bounding box of a page will fit the window
+ * of the Reader. The parameter will specify the y / x coordinate of the
+ * top / left edge of the window. If the type equals FITH
+ * or FITV the width / height of the entire page will fit
+ * the window and the parameter will specify the y / x coordinate of the
+ * top / left edge. In all other cases the type will be set to FITH.
+ *
+ * @param type the destination type
+ * @param parameter a parameter to combined with the destination type
+ */
+
+ public PdfDestination(int type, float parameter) : base(new PdfNumber(parameter)) {
+ switch (type) {
+ default:
+ AddFirst(PdfName.FITH);
+ break;
+ case FITV:
+ AddFirst(PdfName.FITV);
+ break;
+ case FITBH:
+ AddFirst(PdfName.FITBH);
+ break;
+ case FITBV:
+ AddFirst(PdfName.FITBV);
+ break;
+ }
+ }
+
+ /** Constructs a new
+ * Display the page, with the coordinates (left, top) positioned
+ * at the top-left corner of the window and the contents of the page magnified
+ * by the factor zoom. A negative value for any of the parameters left or top, or a
+ * zoom value of 0 specifies that the current value of that parameter is to be retained unchanged.
+ * @param type must be a PdfDestination.XYZ
+ * @param left the left value. Negative to place a null
+ * @param top the top value. Negative to place a null
+ * @param zoom The zoom factor. A value of 0 keeps the current value
+ */
+
+ public PdfDestination(int type, float left, float top, float zoom) : base(PdfName.XYZ) {
+ if (left < 0)
+ Add(PdfNull.PDFNULL);
+ else
+ Add(new PdfNumber(left));
+ if (top < 0)
+ Add(PdfNull.PDFNULL);
+ else
+ Add(new PdfNumber(top));
+ Add(new PdfNumber(zoom));
+ }
+
+ /** Constructs a new
+ * Display the page, with its contents magnified just enough
+ * to fit the rectangle specified by the coordinates left, bottom, right, and top
+ * entirely within the window both horizontally and vertically. If the required
+ * horizontal and vertical magnification factors are different, use the smaller of
+ * the two, centering the rectangle within the window in the other dimension.
+ *
+ * @param type must be PdfDestination.FITR
+ * @param left a parameter
+ * @param bottom a parameter
+ * @param right a parameter
+ * @param top a parameter
+ * @since iText0.38
+ */
+
+ public PdfDestination(int type, float left, float bottom, float right, float top) : base(PdfName.FITR) {
+ Add(new PdfNumber(left));
+ Add(new PdfNumber(bottom));
+ Add(new PdfNumber(right));
+ Add(new PdfNumber(top));
+ }
+
+ // methods
+
+ /**
+ * Checks if an indirect reference to a page has been added.
+ *
+ * @return
+ * A dictionary is an associative table containing pairs of objects. The first element
+ * of each pair is called the key and the second element is called the value.
+ * Unlike dictionaries in the PostScript language, a key must be a
+ *
+ * @see PdfObject
+ * @see PdfName
+ * @see BadPdfFormatException
+ */
+
+ public class PdfDictionary : PdfObject {
+
+ // static membervariables (types of dictionary's)
+
+ /** This is a possible type of dictionary */
+ public static PdfName FONT = PdfName.FONT;
+
+ /** This is a possible type of dictionary */
+ public static PdfName OUTLINES = PdfName.OUTLINES;
+
+ /** This is a possible type of dictionary */
+ public static PdfName PAGE = PdfName.PAGE;
+
+ /** This is a possible type of dictionary */
+ public static PdfName PAGES = PdfName.PAGES;
+
+ /** This is a possible type of dictionary */
+ public static PdfName CATALOG = PdfName.CATALOG;
+
+ // membervariables
+
+ /** This is the type of this dictionary */
+ private PdfName dictionaryType = null;
+
+ /** This is the hashmap that contains all the values and keys of the dictionary */
+ protected internal Hashtable hashMap;
+
+ // constructors
+
+ /**
+ * Constructs an empty
+ * A
+ * A document's trailer may contain a reference to an Info dictionary that provides information
+ * about the document. This optional dictionary may contain one or more keys, whose values
+ * should be strings.
+ * The Catalog is a dictionary that is the root node of the document. It contains a reference
+ * to the tree of pages contained in the document, a reference to the tree of objects representing
+ * the document's outline, a reference to the document's article threads, and the list of named
+ * destinations. In addition, the Catalog indicates whether the document's outline or thumbnail
+ * page images should be displayed automatically when the document is viewed and wether some location
+ * other than the first page should be shown when the document is opened.
+ * You have to open the document before you can begin to add content
+ * to the body of the document.
+ */
+ public override void Open() {
+ if (!open) {
+ base.Open();
+ writer.Open();
+ rootOutline = new PdfOutline(writer);
+ currentOutline = rootOutline;
+ }
+ InitPage();
+ }
+
+ // [L2] DocListener interface
+
+ /**
+ * Closes the document.
+ *
+ * Once all the content has been written in the body, you have to close
+ * the body. After that nothing can be written to the body anymore.
+ */
+ public override void Close() {
+ if (close) {
+ return;
+ }
+ bool wasImage = (imageWait != null);
+ NewPage();
+ if (imageWait != null || wasImage) NewPage();
+ if (annotationsImp.HasUnusedAnnotations())
+ throw new Exception("Not all annotations could be added to the document (the document doesn't have enough pages).");
+ IPdfPageEvent pageEvent = writer.PageEvent;
+ if (pageEvent != null)
+ pageEvent.OnCloseDocument(writer, this);
+ base.Close();
+
+ writer.AddLocalDestinations(localDestinations);
+ CalculateOutlineCount();
+ WriteOutlines();
+
+ writer.Close();
+ }
+
+ // [L3] DocListener interface
+
+ protected internal int textEmptySize;
+
+ // [C9] Metadata for the page
+ /** XMP Metadata for the page. */
+ protected byte[] xmpMetadata = null;
+ /**
+ * Use this method to set the XMP Metadata.
+ * @param xmpMetadata The xmpMetadata to set.
+ */
+ public byte[] XmpMetadata {
+ set {
+ xmpMetadata = value;
+ }
+ }
+
+ /**
+ * Makes a new page and sends it to the
+ * If the footer/header is set, it is printed.
+ * @throws DocumentException on error
+ */
+
+ protected internal void InitPage() {
+ // the pagenumber is incremented
+ pageN++;
+
+ // initialisation of some page objects
+ annotationsImp.ResetAnnotations();
+ pageResources = new PageResources();
+
+ writer.ResetContent();
+ graphics = new PdfContentByte(writer);
+ text = new PdfContentByte(writer);
+ text.Reset();
+ text.BeginText();
+ textEmptySize = text.Size;
+
+ markPoint = 0;
+ SetNewPageSizeAndMargins();
+ imageEnd = -1;
+ indentation.imageIndentRight = 0;
+ indentation.imageIndentLeft = 0;
+ indentation.indentBottom = 0;
+ indentation.indentTop = 0;
+ currentHeight = 0;
+
+ // backgroundcolors, etc...
+ thisBoxSize = new Hashtable(boxSize);
+ if (pageSize.BackgroundColor != null
+ || pageSize.HasBorders()
+ || pageSize.BorderColor != null) {
+ Add(pageSize);
+ }
+
+ float oldleading = leading;
+ int oldAlignment = alignment;
+ // if there is a footer, the footer is added
+ DoFooter();
+ // we move to the left/top position of the page
+ text.MoveText(Left, Top);
+ DoHeader();
+ pageEmpty = true;
+ // if there is an image waiting to be drawn, draw it
+ if (imageWait != null) {
+ Add(imageWait);
+ imageWait = null;
+ }
+ leading = oldleading;
+ alignment = oldAlignment;
+ CarriageReturn();
+
+ IPdfPageEvent pageEvent = writer.PageEvent;
+ if (pageEvent != null) {
+ if (firstPageEvent) {
+ pageEvent.OnOpenDocument(writer, this);
+ }
+ pageEvent.OnStartPage(writer, this);
+ }
+ firstPageEvent = false;
+ }
+
+ /** The line that is currently being written. */
+ protected internal PdfLine line = null;
+
+ /** The lines that are written until now. */
+ protected internal ArrayList lines = new ArrayList();
+
+ /**
+ * Adds the current line to the list of lines and also adds an empty line.
+ * @throws DocumentException on error
+ */
+
+ protected internal void NewLine() {
+ lastElementType = -1;
+ CarriageReturn();
+ if (lines != null && lines.Count > 0) {
+ lines.Add(line);
+ currentHeight += line.Height;
+ }
+ line = new PdfLine(IndentLeft, IndentRight, alignment, leading);
+ }
+
+ /**
+ * If the current line is not empty or null, it is added to the arraylist
+ * of lines and a new empty line is added.
+ * @throws DocumentException on error
+ */
+
+ protected internal void CarriageReturn() {
+ // the arraylist with lines may not be null
+ if (lines == null) {
+ lines = new ArrayList();
+ }
+ // If the current line is not null
+ if (line != null) {
+ // we check if the end of the page is reached (bugfix by Francois Gravel)
+ if (currentHeight + line.Height + leading < IndentTop - IndentBottom) {
+ // if so nonempty lines are added and the heigt is augmented
+ if (line.Size > 0) {
+ currentHeight += line.Height;
+ lines.Add(line);
+ pageEmpty = false;
+ }
+ }
+ // if the end of the line is reached, we start a new page
+ else {
+ NewPage();
+ }
+ }
+ if (imageEnd > -1 && currentHeight > imageEnd) {
+ imageEnd = -1;
+ indentation.imageIndentRight = 0;
+ indentation.imageIndentLeft = 0;
+ }
+ // a new current line is constructed
+ line = new PdfLine(IndentLeft, IndentRight, alignment, leading);
+ }
+
+ /**
+ * Gets the current vertical page position.
+ * @param ensureNewLine Tells whether a new line shall be enforced. This may cause side effects
+ * for elements that do not terminate the lines they've started because those lines will get
+ * terminated.
+ * @return The current vertical page position.
+ */
+ public float GetVerticalPosition(bool ensureNewLine) {
+ // ensuring that a new line has been started.
+ if (ensureNewLine) {
+ EnsureNewLine();
+ }
+ return Top - currentHeight - indentation.indentTop;
+ }
+
+ /** Holds the type of the last element, that has been added to the document. */
+ protected internal int lastElementType = -1;
+
+ /**
+ * Ensures that a new line has been started.
+ */
+ protected internal void EnsureNewLine() {
+ if ((lastElementType == Element.PHRASE) ||
+ (lastElementType == Element.CHUNK)) {
+ NewLine();
+ FlushLines();
+ }
+ }
+
+ /**
+ * Writes all the lines to the text-object.
+ *
+ * @return the displacement that was caused
+ * @throws DocumentException on error
+ */
+ protected internal float FlushLines() {
+ // checks if the ArrayList with the lines is not null
+ if (lines == null) {
+ return 0;
+ }
+ // checks if a new Line has to be made.
+ if (line != null && line.Size > 0) {
+ lines.Add(line);
+ line = new PdfLine(IndentLeft, IndentRight, alignment, leading);
+ }
+
+ // checks if the ArrayList with the lines is empty
+ if (lines.Count == 0) {
+ return 0;
+ }
+
+ // initialisation of some parameters
+ Object[] currentValues = new Object[2];
+ PdfFont currentFont = null;
+ float displacement = 0;
+
+ currentValues[1] = (float)0;
+ // looping over all the lines
+ foreach (PdfLine l in lines) {
+
+ // this is a line in the loop
+
+ float moveTextX = l.IndentLeft - IndentLeft + indentation.indentLeft + indentation.listIndentLeft + indentation.sectionIndentLeft;
+ text.MoveText(moveTextX, -l.Height);
+ // is the line preceeded by a symbol?
+ if (l.ListSymbol != null) {
+ ColumnText.ShowTextAligned(graphics, Element.ALIGN_LEFT, new Phrase(l.ListSymbol), text.XTLM - l.ListIndent, text.YTLM, 0);
+ }
+
+ currentValues[0] = currentFont;
+
+ WriteLineToContent(l, text, graphics, currentValues, writer.SpaceCharRatio);
+
+ currentFont = (PdfFont)currentValues[0];
+
+ displacement += l.Height;
+ text.MoveText(-moveTextX, 0);
+ }
+ lines = new ArrayList();
+ return displacement;
+ }
+
+ /** The characters to be applied the hanging punctuation. */
+ internal const String hangingPunctuation = ".,;:'";
+
+ /**
+ * Writes a text line to the document. It takes care of all the attributes.
+ *
+ * Before entering the line position must have been established and the
+ *
+ * Limitation: in this class only base 14 Type 1 fonts (courier, courier bold, courier oblique,
+ * courier boldoblique, helvetica, helvetica bold, helvetica oblique, helvetica boldoblique,
+ * symbol, times roman, times bold, times italic, times bolditalic, zapfdingbats) and their
+ * standard encoding (standard, MacRoman, (MacExpert,) WinAnsi) are supported.
+ * An indirect object is an object that has been labeled so that it can be referenced by
+ * other objects. Any type of
+ * Any object used as an element of an array or as a value in a dictionary may be specified
+ * by either a direct object of an indirect reference. An indirect reference is a reference
+ * to an indirect object, and consists of the indirect object's object number, generation number
+ * and the R keyword.
+ * The alignment of the last line of for instance a
+ * This is only necessary for the first line of a
+ * A name, like a string, is a sequence of characters. It must begin with a slash
+ * followed by a sequence of ASCII characters in the range 32 through 136 except
+ * %, (, ), [, ], <, >, {, }, / and #. Any character except 0x00 may be included
+ * in a name by writing its twocharacter hex code, preceded by #. The maximum number
+ * of characters in a name is 127.
+ *
+ * @see PdfObject
+ * @see PdfDictionary
+ * @see BadPdfFormatException
+ */
+
+ public class PdfName : PdfObject, IComparable {
+
+ // static membervariables (a variety of standard names used in PDF)
+
+ /** A name */
+ public static readonly PdfName A = new PdfName("A");
+ /** A name */
+ public static readonly PdfName AA = new PdfName("AA");
+ /** A name */
+ public static readonly PdfName ABSOLUTECALORIMETRIC = new PdfName("AbsoluteColorimetric");
+ /** A name */
+ public static readonly PdfName AC = new PdfName("AC");
+ /** A name */
+ public static readonly PdfName ACROFORM = new PdfName("AcroForm");
+ /** A name */
+ public static readonly PdfName ACTION = new PdfName("Action");
+ /** A name */
+ public static readonly PdfName ADBE_PKCS7_DETACHED = new PdfName("adbe.pkcs7.detached");
+ /** A name */
+ public static readonly PdfName ADBE_PKCS7_S4 =new PdfName("adbe.pkcs7.s4");
+ /** A name */
+ public static readonly PdfName ADBE_PKCS7_S5 =new PdfName("adbe.pkcs7.s5");
+ /** A name */
+ public static readonly PdfName ADBE_PKCS7_SHA1 = new PdfName("adbe.pkcs7.sha1");
+ /** A name */
+ public static readonly PdfName ADBE_X509_RSA_SHA1 = new PdfName("adbe.x509.rsa_sha1");
+ /** A name */
+ public static readonly PdfName ADOBE_PPKLITE = new PdfName("Adobe.PPKLite");
+ /** A name */
+ public static readonly PdfName ADOBE_PPKMS = new PdfName("Adobe.PPKMS");
+ /** A name */
+ public static readonly PdfName AESV2 = new PdfName("AESV2");
+ /** A name */
+ public static readonly PdfName AIS = new PdfName("AIS");
+ /** A name */
+ public static readonly PdfName ALLPAGES = new PdfName("AllPages");
+ /** A name */
+ public static readonly PdfName ALT = new PdfName("Alt");
+ /** A name */
+ public static readonly PdfName ALTERNATE = new PdfName("Alternate");
+ /** A name */
+ public static readonly PdfName ANNOT = new PdfName("Annot");
+ /** A name */
+ public static readonly PdfName ANTIALIAS = new PdfName("AntiAlias");
+ /** A name */
+ public static readonly PdfName ANNOTS = new PdfName("Annots");
+ /** A name */
+ public static readonly PdfName AP = new PdfName("AP");
+ /** A name */
+ public static readonly PdfName APPDEFAULT = new PdfName("AppDefault");
+ /** A name */
+ public static readonly PdfName ARTBOX = new PdfName("ArtBox");
+ /** A name */
+ public static readonly PdfName ASCENT = new PdfName("Ascent");
+ /** A name */
+ public static readonly PdfName AS = new PdfName("AS");
+ /** A name */
+ public static readonly PdfName ASCII85DECODE = new PdfName("ASCII85Decode");
+ /** A name */
+ public static readonly PdfName ASCIIHEXDECODE = new PdfName("ASCIIHexDecode");
+ /** A name */
+ public static readonly PdfName AUTHEVENT = new PdfName("AuthEvent");
+ /** A name */
+ public static readonly PdfName AUTHOR = new PdfName("Author");
+ /** A name */
+ public static readonly PdfName B = new PdfName("B");
+ /** A name */
+ public static readonly PdfName BASEENCODING = new PdfName("BaseEncoding");
+ /** A name */
+ public static readonly PdfName BASEFONT = new PdfName("BaseFont");
+ /** A name */
+ public static readonly PdfName BBOX = new PdfName("BBox");
+ /** A name */
+ public static readonly PdfName BC = new PdfName("BC");
+ /** A name */
+ public static readonly PdfName BG = new PdfName("BG");
+ /** A name */
+ public static readonly PdfName BIGFIVE = new PdfName("BigFive");
+ /** A name */
+ public static readonly PdfName BITSPERCOMPONENT = new PdfName("BitsPerComponent");
+ /** A name */
+ public static readonly PdfName BITSPERSAMPLE = new PdfName("BitsPerSample");
+ /** A name */
+ public static readonly PdfName BL = new PdfName("Bl");
+ /** A name */
+ public static readonly PdfName BLACKIS1 = new PdfName("BlackIs1");
+ /** A name */
+ public static readonly PdfName BLACKPOINT = new PdfName("BlackPoint");
+ /** A name */
+ public static readonly PdfName BLEEDBOX = new PdfName("BleedBox");
+ /** A name */
+ public static readonly PdfName BLINDS = new PdfName("Blinds");
+ /** A name */
+ public static readonly PdfName BM = new PdfName("BM");
+ /** A name */
+ public static readonly PdfName BORDER = new PdfName("Border");
+ /** A name */
+ public static readonly PdfName BOUNDS = new PdfName("Bounds");
+ /** A name */
+ public static readonly PdfName BOX = new PdfName("Box");
+ /** A name */
+ public static readonly PdfName BS = new PdfName("BS");
+ /** A name */
+ public static readonly PdfName BTN = new PdfName("Btn");
+ /** A name */
+ public static readonly PdfName BYTERANGE = new PdfName("ByteRange");
+ /** A name */
+ public static readonly PdfName C = new PdfName("C");
+ /** A name */
+ public static readonly PdfName C0 = new PdfName("C0");
+ /** A name */
+ public static readonly PdfName C1 = new PdfName("C1");
+ /** A name */
+ public static readonly PdfName CA = new PdfName("CA");
+ /** A name */
+ public static readonly PdfName ca_ = new PdfName("ca");
+ /** A name */
+ public static readonly PdfName CALGRAY = new PdfName("CalGray");
+ /** A name */
+ public static readonly PdfName CALRGB = new PdfName("CalRGB");
+ /** A name */
+ public static readonly PdfName CAPHEIGHT = new PdfName("CapHeight");
+ /** A name */
+ public static readonly PdfName CATALOG = new PdfName("Catalog");
+ /** A name */
+ public static readonly PdfName CATEGORY = new PdfName("Category");
+ /** A name */
+ public static readonly PdfName CCITTFAXDECODE = new PdfName("CCITTFaxDecode");
+ /** A name */
+ public static readonly PdfName CENTERWINDOW = new PdfName("CenterWindow");
+ /** A name */
+ public static readonly PdfName CERT = new PdfName("Cert");
+ /** A name */
+ public static readonly PdfName CF = new PdfName("CF");
+ /** A name */
+ public static readonly PdfName CFM = new PdfName("CFM");
+ /** A name */
+ public static readonly PdfName CH = new PdfName("Ch");
+ /** A name */
+ public static readonly PdfName CHARPROCS = new PdfName("CharProcs");
+ /** A name */
+ public static readonly PdfName CI = new PdfName("CI");
+ /** A name */
+ public static readonly PdfName CIDFONTTYPE0 = new PdfName("CIDFontType0");
+ /** A name */
+ public static readonly PdfName CIDFONTTYPE2 = new PdfName("CIDFontType2");
+ /** A name */
+ public static readonly PdfName CIDSET = new PdfName("CIDSet");
+ /** A name */
+ public static readonly PdfName CIDSYSTEMINFO = new PdfName("CIDSystemInfo");
+ /** A name */
+ public static readonly PdfName CIDTOGIDMAP = new PdfName("CIDToGIDMap");
+ /** A name */
+ public static readonly PdfName CIRCLE = new PdfName("Circle");
+ /** A name */
+ public static readonly PdfName CO = new PdfName("CO");
+ /** A name */
+ public static readonly PdfName COLORS = new PdfName("Colors");
+ /** A name */
+ public static readonly PdfName COLORSPACE = new PdfName("ColorSpace");
+ /** A name */
+ public static readonly PdfName COLLECTION = new PdfName("Collection");
+ /** A name */
+ public static readonly PdfName COLLECTIONFIELD = new PdfName("CollectionField");
+ /** A name */
+ public static readonly PdfName COLLECTIONITEM = new PdfName("CollectionItem");
+ /** A name */
+ public static readonly PdfName COLLECTIONSCHEMA = new PdfName("CollectionSchema");
+ /** A name */
+ public static readonly PdfName COLLECTIONSORT = new PdfName("CollectionSort");
+ /** A name */
+ public static readonly PdfName COLLECTIONSUBITEM = new PdfName("CollectionSubitem");
+ /** A name */
+ public static readonly PdfName COLUMNS = new PdfName("Columns");
+ /** A name */
+ public static readonly PdfName CONTACTINFO = new PdfName("ContactInfo");
+ /** A name */
+ public static readonly PdfName CONTENT = new PdfName("Content");
+ /** A name */
+ public static readonly PdfName CONTENTS = new PdfName("Contents");
+ /** A name */
+ public static readonly PdfName COORDS = new PdfName("Coords");
+ /** A name */
+ public static readonly PdfName COUNT = new PdfName("Count");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName COURIER = new PdfName("Courier");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName COURIER_BOLD = new PdfName("Courier-Bold");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName COURIER_OBLIQUE = new PdfName("Courier-Oblique");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName COURIER_BOLDOBLIQUE = new PdfName("Courier-BoldOblique");
+ /** A name */
+ public static readonly PdfName CREATIONDATE = new PdfName("CreationDate");
+ /** A name */
+ public static readonly PdfName CREATOR = new PdfName("Creator");
+ /** A name */
+ public static readonly PdfName CREATORINFO = new PdfName("CreatorInfo");
+ /** A name */
+ public static readonly PdfName CROPBOX = new PdfName("CropBox");
+ /** A name */
+ public static readonly PdfName CRYPT = new PdfName("Crypt");
+ /** A name */
+ public static readonly PdfName CS = new PdfName("CS");
+ /** A name */
+ public static readonly PdfName D = new PdfName("D");
+ /** A name */
+ public static readonly PdfName DA = new PdfName("DA");
+ /** A name */
+ public static readonly PdfName DATA = new PdfName("Data");
+ /** A name */
+ public static readonly PdfName DC = new PdfName("DC");
+ /** A name */
+ public static readonly PdfName DCTDECODE = new PdfName("DCTDecode");
+ /** A name */
+ public static readonly PdfName DECODE = new PdfName("Decode");
+ /** A name */
+ public static readonly PdfName DECODEPARMS = new PdfName("DecodeParms");
+ /** A name */
+ public static readonly PdfName DEFAULTCRYPTFILER = new PdfName("DefaultCryptFilter");
+ /** A name */
+ public static readonly PdfName DEFAULTCMYK = new PdfName("DefaultCMYK");
+ /** A name */
+ public static readonly PdfName DEFAULTGRAY = new PdfName("DefaultGray");
+ /** A name */
+ public static readonly PdfName DEFAULTRGB = new PdfName("DefaultRGB");
+ /** A name */
+ public static readonly PdfName DESC = new PdfName("Desc");
+ /** A name */
+ public static readonly PdfName DESCENDANTFONTS = new PdfName("DescendantFonts");
+ /** A name */
+ public static readonly PdfName DESCENT = new PdfName("Descent");
+ /** A name */
+ public static readonly PdfName DEST = new PdfName("Dest");
+ /** A name */
+ public static readonly PdfName DESTOUTPUTPROFILE = new PdfName("DestOutputProfile");
+ /** A name */
+ public static readonly PdfName DESTS = new PdfName("Dests");
+ /** A name */
+ public static readonly PdfName DEVICEGRAY = new PdfName("DeviceGray");
+ /** A name */
+ public static readonly PdfName DEVICERGB = new PdfName("DeviceRGB");
+ /** A name */
+ public static readonly PdfName DEVICECMYK = new PdfName("DeviceCMYK");
+ /** A name */
+ public static readonly PdfName DI = new PdfName("Di");
+ /** A name */
+ public static readonly PdfName DIFFERENCES = new PdfName("Differences");
+ /** A name */
+ public static readonly PdfName DISSOLVE = new PdfName("Dissolve");
+ /** A name */
+ public static readonly PdfName DIRECTION = new PdfName("Direction");
+ /** A name */
+ public static readonly PdfName DISPLAYDOCTITLE = new PdfName("DisplayDocTitle");
+ /** A name */
+ public static readonly PdfName DIV = new PdfName("Div");
+ /** A name */
+ public static readonly PdfName DM = new PdfName("Dm");
+ /** A name */
+ public static readonly PdfName DOCMDP = new PdfName("DocMDP");
+ /** A name */
+ public static readonly PdfName DOCOPEN = new PdfName("DocOpen");
+ /** A name */
+ public static readonly PdfName DOMAIN = new PdfName("Domain");
+ /** A name */
+ public static readonly PdfName DP = new PdfName("DP");
+ /** A name */
+ public static readonly PdfName DR = new PdfName("DR");
+ /** A name */
+ public static readonly PdfName DS = new PdfName("DS");
+ /** A name */
+ public static readonly PdfName DUR = new PdfName("Dur");
+ /** A name */
+ public static readonly PdfName DUPLEX = new PdfName("Duplex");
+ /** A name */
+ public static readonly PdfName DUPLEXFLIPSHORTEDGE = new PdfName("DuplexFlipShortEdge");
+ /** A name */
+ public static readonly PdfName DUPLEXFLIPLONGEDGE = new PdfName("DuplexFlipLongEdge");
+ /** A name */
+ public static readonly PdfName DV = new PdfName("DV");
+ /** A name */
+ public static readonly PdfName DW = new PdfName("DW");
+ /** A name */
+ public static readonly PdfName E = new PdfName("E");
+ /** A name */
+ public static readonly PdfName EARLYCHANGE = new PdfName("EarlyChange");
+ /** A name */
+ public static readonly PdfName EF = new PdfName("EF");
+ /** A name */
+ public static readonly PdfName EMBEDDEDFILE = new PdfName("EmbeddedFile");
+ /** A name */
+ public static readonly PdfName EMBEDDEDFILES = new PdfName("EmbeddedFiles");
+ /** A name */
+ public static readonly PdfName ENCODE = new PdfName("Encode");
+ /** A name */
+ public static readonly PdfName ENCODEDBYTEALIGN = new PdfName("EncodedByteAlign");
+ /** A name */
+ public static readonly PdfName ENCODING = new PdfName("Encoding");
+ /** A name */
+ public static readonly PdfName ENCRYPT = new PdfName("Encrypt");
+ /** A name */
+ public static readonly PdfName ENCRYPTMETADATA = new PdfName("EncryptMetadata");
+ /** A name */
+ public static readonly PdfName ENDOFBLOCK = new PdfName("EndOfBlock");
+ /** A name */
+ public static readonly PdfName ENDOFLINE = new PdfName("EndOfLine");
+ /** A name */
+ public static readonly PdfName EXTEND = new PdfName("Extend");
+ /** A name */
+ public static readonly PdfName EXTGSTATE = new PdfName("ExtGState");
+ /** A name */
+ public static readonly PdfName EXPORT = new PdfName("Export");
+ /** A name */
+ public static readonly PdfName EXPORTSTATE = new PdfName("ExportState");
+ /** A name */
+ public static readonly PdfName EVENT = new PdfName("Event");
+ /** A name */
+ public static readonly PdfName F = new PdfName("F");
+ /** A name */
+ public static readonly PdfName FB = new PdfName("FB");
+ /** A name */
+ public static readonly PdfName FDECODEPARMS = new PdfName("FDecodeParms");
+ /** A name */
+ public static readonly PdfName FDF = new PdfName("FDF");
+ /** A name */
+ public static readonly PdfName FF = new PdfName("Ff");
+ /** A name */
+ public static readonly PdfName FFILTER = new PdfName("FFilter");
+ /** A name */
+ public static readonly PdfName FIELDS = new PdfName("Fields");
+ /** A name */
+ public static readonly PdfName FILEATTACHMENT = new PdfName("FileAttachment");
+ /** A name */
+ public static readonly PdfName FILESPEC = new PdfName("Filespec");
+ /** A name */
+ public static readonly PdfName FILTER = new PdfName("Filter");
+ /** A name */
+ public static readonly PdfName FIRST = new PdfName("First");
+ /** A name */
+ public static readonly PdfName FIRSTCHAR = new PdfName("FirstChar");
+ /** A name */
+ public static readonly PdfName FIRSTPAGE = new PdfName("FirstPage");
+ /** A name */
+ public static readonly PdfName FIT = new PdfName("Fit");
+ /** A name */
+ public static readonly PdfName FITH = new PdfName("FitH");
+ /** A name */
+ public static readonly PdfName FITV = new PdfName("FitV");
+ /** A name */
+ public static readonly PdfName FITR = new PdfName("FitR");
+ /** A name */
+ public static readonly PdfName FITB = new PdfName("FitB");
+ /** A name */
+ public static readonly PdfName FITBH = new PdfName("FitBH");
+ /** A name */
+ public static readonly PdfName FITBV = new PdfName("FitBV");
+ /** A name */
+ public static readonly PdfName FITWINDOW = new PdfName("FitWindow");
+ /** A name */
+ public static readonly PdfName FLAGS = new PdfName("Flags");
+ /** A name */
+ public static readonly PdfName FLATEDECODE = new PdfName("FlateDecode");
+ /** A name */
+ public static readonly PdfName FO = new PdfName("Fo");
+ /** A name */
+ public static readonly PdfName FONT = new PdfName("Font");
+ /** A name */
+ public static readonly PdfName FONTBBOX = new PdfName("FontBBox");
+ /** A name */
+ public static readonly PdfName FONTDESCRIPTOR = new PdfName("FontDescriptor");
+ /** A name */
+ public static readonly PdfName FONTFILE = new PdfName("FontFile");
+ /** A name */
+ public static readonly PdfName FONTFILE2 = new PdfName("FontFile2");
+ /** A name */
+ public static readonly PdfName FONTFILE3 = new PdfName("FontFile3");
+ /** A name */
+ public static readonly PdfName FONTMATRIX = new PdfName("FontMatrix");
+ /** A name */
+ public static readonly PdfName FONTNAME = new PdfName("FontName");
+ /** A name */
+ public static readonly PdfName FORM = new PdfName("Form");
+ /** A name */
+ public static readonly PdfName FORMTYPE = new PdfName("FormType");
+ /** A name */
+ public static readonly PdfName FREETEXT = new PdfName("FreeText");
+ /** A name */
+ public static readonly PdfName FRM = new PdfName("FRM");
+ /** A name */
+ public static readonly PdfName FS = new PdfName("FS");
+ /** A name */
+ public static readonly PdfName FT = new PdfName("FT");
+ /** A name */
+ public static readonly PdfName FULLSCREEN = new PdfName("FullScreen");
+ /** A name */
+ public static readonly PdfName FUNCTION = new PdfName("Function");
+ /** A name */
+ public static readonly PdfName FUNCTIONS = new PdfName("Functions");
+ /** A name */
+ public static readonly PdfName FUNCTIONTYPE = new PdfName("FunctionType");
+ /** A name of an attribute. */
+ public static readonly PdfName GAMMA = new PdfName("Gamma");
+ /** A name of an attribute. */
+ public static readonly PdfName GBK = new PdfName("GBK");
+ /** A name of an attribute. */
+ public static readonly PdfName GLITTER = new PdfName("Glitter");
+ /** A name of an attribute. */
+ public static readonly PdfName GOTO = new PdfName("GoTo");
+ /** A name of an attribute. */
+ public static readonly PdfName GOTOE = new PdfName("GoToE");
+ /** A name of an attribute. */
+ public static readonly PdfName GOTOR = new PdfName("GoToR");
+ /** A name of an attribute. */
+ public static readonly PdfName GROUP = new PdfName("Group");
+ /** A name of an attribute. */
+ public static readonly PdfName GTS_PDFA1 = new PdfName("GTS_PDFA1");
+ /** A name of an attribute. */
+ public static readonly PdfName GTS_PDFX = new PdfName("GTS_PDFX");
+ /** A name of an attribute. */
+ public static readonly PdfName GTS_PDFXVERSION = new PdfName("GTS_PDFXVersion");
+ /** A name of an attribute. */
+ public static readonly PdfName H = new PdfName("H");
+ /** A name of an attribute. */
+ public static readonly PdfName HEIGHT = new PdfName("Height");
+ /** A name */
+ public static readonly PdfName HELV = new PdfName("Helv");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName HELVETICA = new PdfName("Helvetica");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName HELVETICA_BOLD = new PdfName("Helvetica-Bold");
+ /** This is a static PdfName PdfName of a base 14 type 1 font */
+ public static readonly PdfName HELVETICA_OBLIQUE = new PdfName("Helvetica-Oblique");
+ /** This is a static PdfName PdfName of a base 14 type 1 font */
+ public static readonly PdfName HELVETICA_BOLDOBLIQUE = new PdfName("Helvetica-BoldOblique");
+ /** A name */
+ public static readonly PdfName HID = new PdfName("Hid");
+ /** A name */
+ public static readonly PdfName HIDE = new PdfName("Hide");
+ /** A name */
+ public static readonly PdfName HIDEMENUBAR = new PdfName("HideMenubar");
+ /** A name */
+ public static readonly PdfName HIDETOOLBAR = new PdfName("HideToolbar");
+ /** A name */
+ public static readonly PdfName HIDEWINDOWUI = new PdfName("HideWindowUI");
+ /** A name */
+ public static readonly PdfName HIGHLIGHT = new PdfName("Highlight");
+ /** A name */
+ public static readonly PdfName I = new PdfName("I");
+ /** A name */
+ public static readonly PdfName ICCBASED = new PdfName("ICCBased");
+ /** A name */
+ public static readonly PdfName ID = new PdfName("ID");
+ /** A name */
+ public static readonly PdfName IDENTITY = new PdfName("Identity");
+ /** A name */
+ public static readonly PdfName IF = new PdfName("IF");
+ /** A name */
+ public static readonly PdfName IMAGE = new PdfName("Image");
+ /** A name */
+ public static readonly PdfName IMAGEB = new PdfName("ImageB");
+ /** A name */
+ public static readonly PdfName IMAGEC = new PdfName("ImageC");
+ /** A name */
+ public static readonly PdfName IMAGEI = new PdfName("ImageI");
+ /** A name */
+ public static readonly PdfName IMAGEMASK = new PdfName("ImageMask");
+ /** A name */
+ public static readonly PdfName INDEX = new PdfName("Index");
+ /** A name */
+ public static readonly PdfName INDEXED = new PdfName("Indexed");
+ /** A name */
+ public static readonly PdfName INFO = new PdfName("Info");
+ /** A name */
+ public static readonly PdfName INK = new PdfName("Ink");
+ /** A name */
+ public static readonly PdfName INKLIST = new PdfName("InkList");
+ /** A name */
+ public static readonly PdfName IMPORTDATA = new PdfName("ImportData");
+ /** A name */
+ public static readonly PdfName INTENT = new PdfName("Intent");
+ /** A name */
+ public static readonly PdfName INTERPOLATE = new PdfName("Interpolate");
+ /** A name */
+ public static readonly PdfName ISMAP = new PdfName("IsMap");
+ /** A name */
+ public static readonly PdfName IRT = new PdfName("IRT");
+ /** A name */
+ public static readonly PdfName ITALICANGLE = new PdfName("ItalicAngle");
+ /** A name */
+ public static readonly PdfName IX = new PdfName("IX");
+ /** A name */
+ public static readonly PdfName JAVASCRIPT = new PdfName("JavaScript");
+ /** A name */
+ public static readonly PdfName JPXDECODE = new PdfName("JPXDecode");
+ /** A name */
+ public static readonly PdfName JS = new PdfName("JS");
+ /** A name */
+ public static readonly PdfName K = new PdfName("K");
+ /** A name */
+ public static readonly PdfName KEYWORDS = new PdfName("Keywords");
+ /** A name */
+ public static readonly PdfName KIDS = new PdfName("Kids");
+ /** A name */
+ public static readonly PdfName L = new PdfName("L");
+ /** A name */
+ public static readonly PdfName L2R = new PdfName("L2R");
+ /** A name */
+ public static readonly PdfName LANG = new PdfName("Lang");
+ /** A name */
+ public static readonly PdfName LANGUAGE = new PdfName("Language");
+ /** A name */
+ public static readonly PdfName LAST = new PdfName("Last");
+ /** A name */
+ public static readonly PdfName LASTCHAR = new PdfName("LastChar");
+ /** A name */
+ public static readonly PdfName LASTPAGE = new PdfName("LastPage");
+ /** A name */
+ public static readonly PdfName LAUNCH = new PdfName("Launch");
+ /** A name */
+ public static readonly PdfName LENGTH = new PdfName("Length");
+ /** A name */
+ public static readonly PdfName LENGTH1 = new PdfName("Length1");
+ /** A name */
+ public static readonly PdfName LIMITS = new PdfName("Limits");
+ /** A name */
+ public static readonly PdfName LINE = new PdfName("Line");
+ /** A name */
+ public static readonly PdfName LINK = new PdfName("Link");
+ /** A name */
+ public static readonly PdfName LISTMODE = new PdfName("ListMode");
+ /** A name */
+ public static readonly PdfName LOCATION = new PdfName("Location");
+ /** A name */
+ public static readonly PdfName LOCK = new PdfName("Lock");
+ /** A name */
+ public static readonly PdfName LOCKED = new PdfName("Locked");
+ /** A name */
+ public static readonly PdfName LZWDECODE = new PdfName("LZWDecode");
+ /** A name */
+ public static readonly PdfName M = new PdfName("M");
+ /** A name */
+ public static readonly PdfName MATRIX = new PdfName("Matrix");
+ /** A name of an encoding */
+ public static readonly PdfName MAC_EXPERT_ENCODING = new PdfName("MacExpertEncoding");
+ /** A name of an encoding */
+ public static readonly PdfName MAC_ROMAN_ENCODING = new PdfName("MacRomanEncoding");
+ /** A name */
+ public static readonly PdfName MARKED = new PdfName("Marked");
+ /** A name */
+ public static readonly PdfName MARKINFO = new PdfName("MarkInfo");
+ /** A name */
+ public static readonly PdfName MASK = new PdfName("Mask");
+ /** A name */
+ public static readonly PdfName MAX = new PdfName("max");
+ /** A name */
+ public static readonly PdfName MAXLEN = new PdfName("MaxLen");
+ /** A name */
+ public static readonly PdfName MEDIABOX = new PdfName("MediaBox");
+ /** A name */
+ public static readonly PdfName MCID = new PdfName("MCID");
+ /** A name */
+ public static readonly PdfName MCR = new PdfName("MCR");
+ /** A name */
+ public static readonly PdfName METADATA = new PdfName("Metadata");
+ /** A name */
+ public static readonly PdfName MIN = new PdfName("min");
+ /** A name */
+ public static readonly PdfName MK = new PdfName("MK");
+ /** A name */
+ public static readonly PdfName MMTYPE1 = new PdfName("MMType1");
+ /** A name */
+ public static readonly PdfName MODDATE = new PdfName("ModDate");
+ /** A name */
+ public static readonly PdfName N = new PdfName("N");
+ /** A name */
+ public static readonly PdfName N0 = new PdfName("n0");
+ /** A name */
+ public static readonly PdfName N1 = new PdfName("n1");
+ /** A name */
+ public static readonly PdfName N2 = new PdfName("n2");
+ /** A name */
+ public static readonly PdfName N3 = new PdfName("n3");
+ /** A name */
+ public static readonly PdfName N4 = new PdfName("n4");
+ /** A name */
+ public new static readonly PdfName NAME = new PdfName("Name");
+ /** A name */
+ public static readonly PdfName NAMED = new PdfName("Named");
+ /** A name */
+ public static readonly PdfName NAMES = new PdfName("Names");
+ /** A name */
+ public static readonly PdfName NEEDAPPEARANCES = new PdfName("NeedAppearances");
+ /** A name */
+ public static readonly PdfName NEWWINDOW = new PdfName("NewWindow");
+ /** A name */
+ public static readonly PdfName NEXT = new PdfName("Next");
+ /** A name */
+ public static readonly PdfName NEXTPAGE = new PdfName("NextPage");
+ /** A name */
+ public static readonly PdfName NM = new PdfName("NM");
+ /** A name */
+ public static readonly PdfName NONE = new PdfName("None");
+ /** A name */
+ public static readonly PdfName NONFULLSCREENPAGEMODE = new PdfName("NonFullScreenPageMode");
+ /** A name */
+ public static readonly PdfName NUMCOPIES = new PdfName("NumCopies");
+ /** A name */
+ public static readonly PdfName NUMS = new PdfName("Nums");
+ /** A name */
+ public static readonly PdfName O = new PdfName("O");
+ /** A name */
+ public static readonly PdfName OBJSTM = new PdfName("ObjStm");
+ /** A name */
+ public static readonly PdfName OC = new PdfName("OC");
+ /** A name */
+ public static readonly PdfName OCG = new PdfName("OCG");
+ /** A name */
+ public static readonly PdfName OCGS = new PdfName("OCGs");
+ /** A name */
+ public static readonly PdfName OCMD = new PdfName("OCMD");
+ /** A name */
+ public static readonly PdfName OCPROPERTIES = new PdfName("OCProperties");
+ /** A name */
+ public static readonly PdfName Off_ = new PdfName("Off");
+ /** A name */
+ public static readonly PdfName OFF = new PdfName("OFF");
+ /** A name */
+ public static readonly PdfName ON = new PdfName("ON");
+ /** A name */
+ public static readonly PdfName ONECOLUMN = new PdfName("OneColumn");
+ /** A name */
+ public static readonly PdfName OPEN = new PdfName("Open");
+ /** A name */
+ public static readonly PdfName OPENACTION = new PdfName("OpenAction");
+ /** A name */
+ public static readonly PdfName OP = new PdfName("OP");
+ /** A name */
+ public static readonly PdfName op_ = new PdfName("op");
+ /** A name */
+ public static readonly PdfName OPM = new PdfName("OPM");
+ /** A name */
+ public static readonly PdfName OPT = new PdfName("Opt");
+ /** A name */
+ public static readonly PdfName ORDER = new PdfName("Order");
+ /** A name */
+ public static readonly PdfName ORDERING = new PdfName("Ordering");
+ /** A name */
+ public static readonly PdfName OUTLINES = new PdfName("Outlines");
+ /** A name */
+ public static readonly PdfName OUTPUTCONDITION = new PdfName("OutputCondition");
+ /** A name */
+ public static readonly PdfName OUTPUTCONDITIONIDENTIFIER = new PdfName("OutputConditionIdentifier");
+ /** A name */
+ public static readonly PdfName OUTPUTINTENT = new PdfName("OutputIntent");
+ /** A name */
+ public static readonly PdfName OUTPUTINTENTS = new PdfName("OutputIntents");
+ /** A name */
+ public static readonly PdfName P = new PdfName("P");
+ /** A name */
+ public static readonly PdfName PAGE = new PdfName("Page");
+ /** A name */
+ public static readonly PdfName PAGELABELS = new PdfName("PageLabels");
+ /** A name */
+ public static readonly PdfName PAGELAYOUT = new PdfName("PageLayout");
+ /** A name */
+ public static readonly PdfName PAGEMODE = new PdfName("PageMode");
+ /** A name */
+ public static readonly PdfName PAGES = new PdfName("Pages");
+ /** A name */
+ public static readonly PdfName PAINTTYPE = new PdfName("PaintType");
+ /** A name */
+ public static readonly PdfName PANOSE = new PdfName("Panose");
+ /** A name */
+ public static readonly PdfName PARAMS = new PdfName("Params");
+ /** A name */
+ public static readonly PdfName PARENT = new PdfName("Parent");
+ /** A name */
+ public static readonly PdfName PARENTTREE = new PdfName("ParentTree");
+ /** A name */
+ public static readonly PdfName PATTERN = new PdfName("Pattern");
+ /** A name */
+ public static readonly PdfName PATTERNTYPE = new PdfName("PatternType");
+ /** A name */
+ public static readonly PdfName PDF = new PdfName("PDF");
+ /** A name */
+ public static readonly PdfName PDFDOCENCODING = new PdfName("PDFDocEncoding");
+ /** A name */
+ public static readonly PdfName PERCEPTUAL = new PdfName("Perceptual");
+ /** A name */
+ public static readonly PdfName PERMS = new PdfName("Perms");
+ /** A name */
+ public static readonly PdfName PG = new PdfName("Pg");
+ /** A name */
+ public static readonly PdfName PICKTRAYBYPDFSIZE = new PdfName("PickTrayByPDFSize");
+ /** A name */
+ public static readonly PdfName POPUP = new PdfName("Popup");
+ /** A name */
+ public static readonly PdfName PREDICTOR = new PdfName("Predictor");
+ /** A name */
+ public static readonly PdfName PREFERRED = new PdfName("Preferred");
+ /** A name */
+ public static readonly PdfName PRESERVERB = new PdfName("PreserveRB");
+ /** A name */
+ public static readonly PdfName PREV = new PdfName("Prev");
+ /** A name */
+ public static readonly PdfName PREVPAGE = new PdfName("PrevPage");
+ /** A name */
+ public static readonly PdfName PRINT = new PdfName("Print");
+ /** A name */
+ public static readonly PdfName PRINTAREA = new PdfName("PrintArea");
+ /** A name */
+ public static readonly PdfName PRINTCLIP = new PdfName("PrintClip");
+ /** A name */
+ public static readonly PdfName PRINTPAGERANGE = new PdfName("PrintPageRange");
+ /** A name */
+ public static readonly PdfName PRINTSCALING = new PdfName("PrintScaling");
+ /** A name */
+ public static readonly PdfName PRINTSTATE = new PdfName("PrintState");
+ /** A name */
+ public static readonly PdfName PROCSET = new PdfName("ProcSet");
+ /** A name */
+ public static readonly PdfName PRODUCER = new PdfName("Producer");
+ /** A name */
+ public static readonly PdfName PROPERTIES = new PdfName("Properties");
+ /** A name */
+ public static readonly PdfName PS = new PdfName("PS");
+ /** A name */
+ public static readonly PdfName PUBSEC = new PdfName("Adobe.PubSec");
+ /** A name */
+ public static readonly PdfName Q = new PdfName("Q");
+ /** A name */
+ public static readonly PdfName QUADPOINTS = new PdfName("QuadPoints");
+ /** A name */
+ public static readonly PdfName R = new PdfName("R");
+ /** A name */
+ public static readonly PdfName R2L = new PdfName("R2L");
+ /** A name */
+ public static readonly PdfName RANGE = new PdfName("Range");
+ /** A name */
+ public static readonly PdfName RC = new PdfName("RC");
+ /** A name */
+ public static readonly PdfName RBGROUPS = new PdfName("RBGroups");
+ /** A name */
+ public static readonly PdfName REASON = new PdfName("Reason");
+ /** A name */
+ public static readonly PdfName RECIPIENTS = new PdfName("Recipients");
+ /** A name */
+ public static readonly PdfName RECT = new PdfName("Rect");
+ /** A name */
+ public static readonly PdfName REFERENCE = new PdfName("Reference");
+ /** A name */
+ public static readonly PdfName REGISTRY = new PdfName("Registry");
+ /** A name */
+ public static readonly PdfName REGISTRYNAME = new PdfName("RegistryName");
+ /** A name */
+ public static readonly PdfName RELATIVECALORIMETRIC = new PdfName("RelativeColorimetric");
+ /** A name */
+ public static readonly PdfName RENDITION = new PdfName("Rendition");
+ /** A name */
+ public static readonly PdfName RESETFORM = new PdfName("ResetForm");
+ /** A name */
+ public static readonly PdfName RESOURCES = new PdfName("Resources");
+ /** A name */
+ public static readonly PdfName RI = new PdfName("RI");
+ /** A name */
+ public static readonly PdfName ROLEMAP = new PdfName("RoleMap");
+ /** A name */
+ public static readonly PdfName ROOT = new PdfName("Root");
+ /** A name */
+ public static readonly PdfName ROTATE = new PdfName("Rotate");
+ /** A name */
+ public static readonly PdfName ROWS = new PdfName("Rows");
+ /** A name */
+ public static readonly PdfName RUNLENGTHDECODE = new PdfName("RunLengthDecode");
+ /** A name */
+ public static readonly PdfName RV = new PdfName("RV");
+ /** A name */
+ public static readonly PdfName S = new PdfName("S");
+ /** A name */
+ public static readonly PdfName SATURATION = new PdfName("Saturation");
+ /** A name */
+ public static readonly PdfName SCHEMA = new PdfName("Schema");
+ /** A name */
+ public static readonly PdfName SCREEN = new PdfName("Screen");
+ /** A name */
+ public static readonly PdfName SECT = new PdfName("Sect");
+ /** A name */
+ public static readonly PdfName SEPARATION = new PdfName("Separation");
+ /** A name */
+ public static readonly PdfName SETOCGSTATE = new PdfName("SetOCGState");
+ /** A name */
+ public static readonly PdfName SHADING = new PdfName("Shading");
+ /** A name */
+ public static readonly PdfName SHADINGTYPE = new PdfName("ShadingType");
+ /** A name */
+ public static readonly PdfName SHIFT_JIS = new PdfName("Shift-JIS");
+ /** A name */
+ public static readonly PdfName SIG = new PdfName("Sig");
+ /** A name */
+ public static readonly PdfName SIGFLAGS = new PdfName("SigFlags");
+ /** A name */
+ public static readonly PdfName SIGREF = new PdfName("SigRef");
+ /** A name */
+ public static readonly PdfName SIMPLEX = new PdfName("Simplex");
+ /** A name */
+ public static readonly PdfName SINGLEPAGE = new PdfName("SinglePage");
+ /** A name */
+ public static readonly PdfName SIZE = new PdfName("Size");
+ /** A name */
+ public static readonly PdfName SMASK = new PdfName("SMask");
+ /** A name */
+ public static readonly PdfName SORT = new PdfName("Sort");
+ /** A name */
+ public static readonly PdfName SPAN = new PdfName("Span");
+ /** A name */
+ public static readonly PdfName SPLIT = new PdfName("Split");
+ /** A name */
+ public static readonly PdfName SQUARE = new PdfName("Square");
+ /** A name */
+ public static readonly PdfName SQUIGGLY = new PdfName("Squiggly");
+ /** A name */
+ public static readonly PdfName ST = new PdfName("St");
+ /** A name */
+ public static readonly PdfName STAMP = new PdfName("Stamp");
+ /** A name */
+ public static readonly PdfName STANDARD = new PdfName("Standard");
+ /** A name */
+ public static readonly PdfName STATE = new PdfName("State");
+ /** A name */
+ public static readonly PdfName STDCF = new PdfName("StdCF");
+ /** A name */
+ public static readonly PdfName STEMV = new PdfName("StemV");
+ /** A name */
+ public static readonly PdfName STMF = new PdfName("StmF");
+ /** A name */
+ public static readonly PdfName STRF = new PdfName("StrF");
+ /** A name */
+ public static readonly PdfName STRIKEOUT = new PdfName("StrikeOut");
+ /** A name */
+ public static readonly PdfName STRUCTPARENT = new PdfName("StructParent");
+ /** A name */
+ public static readonly PdfName STRUCTPARENTS = new PdfName("StructParents");
+ /** A name */
+ public static readonly PdfName STRUCTTREEROOT = new PdfName("StructTreeRoot");
+ /** A name */
+ public static readonly PdfName STYLE = new PdfName("Style");
+ /** A name */
+ public static readonly PdfName SUBFILTER = new PdfName("SubFilter");
+ /** A name */
+ public static readonly PdfName SUBJECT = new PdfName("Subject");
+ /** A name */
+ public static readonly PdfName SUBMITFORM = new PdfName("SubmitForm");
+ /** A name */
+ public static readonly PdfName SUBTYPE = new PdfName("Subtype");
+ /** A name */
+ public static readonly PdfName SUPPLEMENT = new PdfName("Supplement");
+ /** A name */
+ public static readonly PdfName SV = new PdfName("SV");
+ /** A name */
+ public static readonly PdfName SW = new PdfName("SW");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName SYMBOL = new PdfName("Symbol");
+ /** A name */
+ public static readonly PdfName T = new PdfName("T");
+ /** A name */
+ public static readonly PdfName TEXT = new PdfName("Text");
+ /** A name */
+ public static readonly PdfName THUMB = new PdfName("Thumb");
+ /** A name */
+ public static readonly PdfName THREADS = new PdfName("Threads");
+ /** A name */
+ public static readonly PdfName TI = new PdfName("TI");
+ /** A name */
+ public static readonly PdfName TILINGTYPE = new PdfName("TilingType");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName TIMES_ROMAN = new PdfName("Times-Roman");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName TIMES_BOLD = new PdfName("Times-Bold");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName TIMES_ITALIC = new PdfName("Times-Italic");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName TIMES_BOLDITALIC = new PdfName("Times-BoldItalic");
+ /** A name */
+ public static readonly PdfName TITLE = new PdfName("Title");
+ /** A name */
+ public static readonly PdfName TK = new PdfName("TK");
+ /** A name */
+ public static readonly PdfName TM = new PdfName("TM");
+ /** A name */
+ public static readonly PdfName TOGGLE = new PdfName("Toggle");
+ /** A name */
+ public static readonly PdfName TOUNICODE = new PdfName("ToUnicode");
+ /** A name */
+ public static readonly PdfName TP = new PdfName("TP");
+ /** A name */
+ public static readonly PdfName TRANS = new PdfName("Trans");
+ /** A name */
+ public static readonly PdfName TRANSFORMPARAMS = new PdfName("TransformParams");
+ /** A name */
+ public static readonly PdfName TRANSFORMMETHOD = new PdfName("TransformMethod");
+ /** A name */
+ public static readonly PdfName TRANSPARENCY = new PdfName("Transparency");
+ /** A name */
+ public static readonly PdfName TRAPPED = new PdfName("Trapped");
+ /** A name */
+ public static readonly PdfName TRIMBOX = new PdfName("TrimBox");
+ /** A name */
+ public static readonly PdfName TRUETYPE = new PdfName("TrueType");
+ /** A name */
+ public static readonly PdfName TU = new PdfName("TU");
+ /** A name */
+ public static readonly PdfName TWOCOLUMNLEFT = new PdfName("TwoColumnLeft");
+ /** A name */
+ public static readonly PdfName TWOCOLUMNRIGHT = new PdfName("TwoColumnRight");
+ /** A name */
+ public static readonly PdfName TWOPAGELEFT = new PdfName("TwoPageLeft");
+ /** A name */
+ public static readonly PdfName TWOPAGERIGHT = new PdfName("TwoPageRight");
+ /** A name */
+ public static readonly PdfName TX = new PdfName("Tx");
+ /** A name */
+ public static readonly PdfName TYPE = new PdfName("Type");
+ /** A name */
+ public static readonly PdfName TYPE0 = new PdfName("Type0");
+ /** A name */
+ public static readonly PdfName TYPE1 = new PdfName("Type1");
+ /** A name of an attribute. */
+ public static readonly PdfName TYPE3 = new PdfName("Type3");
+ /** A name of an attribute. */
+ public static readonly PdfName U = new PdfName("U");
+ /** A name of an attribute. */
+ public static readonly PdfName UF = new PdfName("UF");
+ /** A name of an attribute. */
+ public static readonly PdfName UHC = new PdfName("UHC");
+ /** A name of an attribute. */
+ public static readonly PdfName UNDERLINE = new PdfName("Underline");
+ /** A name */
+ public static readonly PdfName UR = new PdfName("UR");
+ /** A name */
+ public static readonly PdfName UR3 = new PdfName("UR3");
+ /** A name */
+ public static readonly PdfName URI = new PdfName("URI");
+ /** A name */
+ public static readonly PdfName URL = new PdfName("URL");
+ /** A name */
+ public static readonly PdfName USAGE = new PdfName("Usage");
+ /** A name */
+ public static readonly PdfName USEATTACHMENTS = new PdfName("UseAttachments");
+ /** A name */
+ public static readonly PdfName USENONE = new PdfName("UseNone");
+ /** A name */
+ public static readonly PdfName USEOC = new PdfName("UseOC");
+ /** A name */
+ public static readonly PdfName USEOUTLINES = new PdfName("UseOutlines");
+ /** A name */
+ public static readonly PdfName USER = new PdfName("User");
+ /** A name */
+ public static readonly PdfName USERPROPERTIES = new PdfName("UserProperties");
+ /** A name */
+ public static readonly PdfName USERUNIT = new PdfName("UserUnit");
+ /** A name */
+ public static readonly PdfName USETHUMBS = new PdfName("UseThumbs");
+ /** A name */
+ public static readonly PdfName V = new PdfName("V");
+ /** A name */
+ public static readonly PdfName V2 = new PdfName("V2");
+ /** A name */
+ public static readonly PdfName VERISIGN_PPKVS = new PdfName("VeriSign.PPKVS");
+ /** A name */
+ public static readonly PdfName VERSION = new PdfName("Version");
+ /** A name */
+ public static readonly PdfName VIEW = new PdfName("View");
+ /** A name */
+ public static readonly PdfName VIEWAREA = new PdfName("ViewArea");
+ /** A name */
+ public static readonly PdfName VIEWCLIP = new PdfName("ViewClip");
+ /** A name */
+ public static readonly PdfName VIEWERPREFERENCES = new PdfName("ViewerPreferences");
+ /** A name */
+ public static readonly PdfName VIEWSTATE = new PdfName("ViewState");
+ /** A name */
+ public static readonly PdfName VISIBLEPAGES = new PdfName("VisiblePages");
+ /** A name of an attribute. */
+ public static readonly PdfName W = new PdfName("W");
+ /** A name of an attribute. */
+ public static readonly PdfName W2 = new PdfName("W2");
+ /** A name of an attribute. */
+ public static readonly PdfName WC = new PdfName("WC");
+ /** A name of an attribute. */
+ public static readonly PdfName WIDGET = new PdfName("Widget");
+ /** A name of an attribute. */
+ public static readonly PdfName WIDTH = new PdfName("Width");
+ /** A name */
+ public static readonly PdfName WIDTHS = new PdfName("Widths");
+ /** A name of an encoding */
+ public static readonly PdfName WIN = new PdfName("Win");
+ /** A name of an encoding */
+ public static readonly PdfName WIN_ANSI_ENCODING = new PdfName("WinAnsiEncoding");
+ /** A name of an encoding */
+ public static readonly PdfName WIPE = new PdfName("Wipe");
+ /** A name */
+ public static readonly PdfName WHITEPOINT = new PdfName("WhitePoint");
+ /** A name */
+ public static readonly PdfName WP = new PdfName("WP");
+ /** A name of an encoding */
+ public static readonly PdfName WS = new PdfName("WS");
+ /** A name */
+ public static readonly PdfName X = new PdfName("X");
+ /** A name */
+ public static readonly PdfName XFA = new PdfName("XFA");
+ /** A name */
+ public static readonly PdfName XML = new PdfName("XML");
+ /** A name */
+ public static readonly PdfName XOBJECT = new PdfName("XObject");
+ /** A name */
+ public static readonly PdfName XSTEP = new PdfName("XStep");
+ /** A name */
+ public static readonly PdfName XREF = new PdfName("XRef");
+ /** A name */
+ public static readonly PdfName XREFSTM = new PdfName("XRefStm");
+ /** A name */
+ public static readonly PdfName XYZ = new PdfName("XYZ");
+ /** A name */
+ public static readonly PdfName YSTEP = new PdfName("YStep");
+ /** A name */
+ public static readonly PdfName ZADB = new PdfName("ZaDb");
+ /** A name of a base 14 type 1 font */
+ public static readonly PdfName ZAPFDINGBATS = new PdfName("ZapfDingbats");
+ /** A name */
+ public static readonly PdfName ZOOM = new PdfName("Zoom");
+
+ private int hash = 0;
+
+ // constructors
+
+ /**
+ * Constructs a new
+ *
+ *
+ * @param object the Object to be compared.
+ * @return a negative int, zero, or a positive int as this object
+ * is less than, equal to, or greater than the specified object.
+ *
+ * @throws Exception if the specified object's type prevents it
+ * from being compared to this Object.
+ */
+ public int CompareTo(Object obj) {
+ PdfName name = (PdfName) obj;
+
+ byte[] myBytes = bytes;
+ byte[] objBytes = name.bytes;
+ int len = Math.Min(myBytes.Length, objBytes.Length);
+ for (int i=0; i
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.9 (page 53).
+ *
+ * @see PdfObject
+ */
+
+ public class PdfNull : PdfObject {
+
+ // static membervariables
+
+ /** This is an instance of the
+ * You never need to do this yourself, you can always use the static object PDFNULL.
+ */
+
+ public PdfNull() : base(NULL, "null") {}
+
+ public override String ToString() {
+ return "null";
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfNumber.cs b/iTechSharp/iTextSharp/text/pdf/PdfNumber.cs
new file mode 100644
index 0000000..421c437
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfNumber.cs
@@ -0,0 +1,163 @@
+using System;
+
+/*
+ * $Id: PdfNumber.cs,v 1.4 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ *
+ * ints may be specified by signed or unsigned constants. Reals may only be
+ * in decimal format.
+ * PDF supports seven basic types of objects: bools, numbers, strings, names,
+ * arrays, dictionaries and streams. In addition, PDF provides a null object.
+ * Objects may be labeled so that they can be referred to by other objects.
+ * In some cases, namely for
+ * Remark: the actual content of an object is in most cases identical to its representation.
+ * The following statement is always true: Length() >= PdfLength().
+ * In some cases, namely for
+ * Remark: the actual content of an object is in some cases identical to its representation.
+ * The following statement is always true: Length() >= PdfLength().
+ * An outline allows a user to access views of a document by name.
+ * This is the constructor for the
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * This is the constructor for an
+ * It's based in code found at org.bouncycastle.
+ */
+ public class PdfPKCS7 {
+
+ private byte[] sigAttr;
+ private byte[] digestAttr;
+ private int version, signerversion;
+ private Hashtable digestalgos;
+ private ArrayList certs, crls;
+ private X509Certificate signCert;
+ private byte[] digest;
+ private IDigest messageDigest;
+ private String digestAlgorithm, digestEncryptionAlgorithm;
+ private ISigner sig;
+ private ICipherParameters privKey;
+ private byte[] RSAdata;
+ private bool verified;
+ private bool verifyResult;
+ private byte[] externalDigest;
+ private byte[] externalRSAdata;
+
+ private const String ID_PKCS7_DATA = "1.2.840.113549.1.7.1";
+ private const String ID_PKCS7_SIGNED_DATA = "1.2.840.113549.1.7.2";
+ private const String ID_MD5 = "1.2.840.113549.2.5";
+ private const String ID_MD2 = "1.2.840.113549.2.2";
+ private const String ID_SHA1 = "1.3.14.3.2.26";
+ private const String ID_RSA = "1.2.840.113549.1.1.1";
+ private const String ID_DSA = "1.2.840.10040.4.1";
+ private const String ID_CONTENT_TYPE = "1.2.840.113549.1.9.3";
+ private const String ID_MESSAGE_DIGEST = "1.2.840.113549.1.9.4";
+ private const String ID_SIGNING_TIME = "1.2.840.113549.1.9.5";
+ private const String ID_MD2RSA = "1.2.840.113549.1.1.2";
+ private const String ID_MD5RSA = "1.2.840.113549.1.1.4";
+ private const String ID_SHA1RSA = "1.2.840.113549.1.1.5";
+ /**
+ * Holds value of property reason.
+ */
+ private String reason;
+
+ /**
+ * Holds value of property location.
+ */
+ private String location;
+
+ /**
+ * Holds value of property signDate.
+ */
+ private DateTime signDate;
+
+ /**
+ * Holds value of property signName.
+ */
+ private String signName;
+
+ /**
+ * Verifies a signature using the sub-filter adbe.x509.rsa_sha1.
+ * @param contentsKey the /Contents key
+ * @param certsKey the /Cert key
+ * @param provider the provider or
+ * A simple example:
+ *
+ * Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
+ */
+ public static DerObjectIdentifier EmailAddress = new DerObjectIdentifier("1.2.840.113549.1.9.1");
+
+ /**
+ * email address in Verisign certificates
+ */
+ public static DerObjectIdentifier E = EmailAddress;
+
+ /** object identifier */
+ public static DerObjectIdentifier DC = new DerObjectIdentifier("0.9.2342.19200300.100.1.25");
+
+ /** LDAP User id. */
+ public static DerObjectIdentifier UID = new DerObjectIdentifier("0.9.2342.19200300.100.1.1");
+
+ /** A Hashtable with default symbols */
+ public static Hashtable DefaultSymbols = new Hashtable();
+
+ static X509Name(){
+ DefaultSymbols[C] = "C";
+ DefaultSymbols[O] = "O";
+ DefaultSymbols[T] = "T";
+ DefaultSymbols[OU] = "OU";
+ DefaultSymbols[CN] = "CN";
+ DefaultSymbols[L] = "L";
+ DefaultSymbols[ST] = "ST";
+ DefaultSymbols[SN] = "SN";
+ DefaultSymbols[EmailAddress] = "E";
+ DefaultSymbols[DC] = "DC";
+ DefaultSymbols[UID] = "UID";
+ DefaultSymbols[SURNAME] = "SURNAME";
+ DefaultSymbols[GIVENNAME] = "GIVENNAME";
+ DefaultSymbols[INITIALS] = "INITIALS";
+ DefaultSymbols[GENERATION] = "GENERATION";
+ }
+ /** A Hashtable with values */
+ public Hashtable values = new Hashtable();
+
+ /**
+ * Constructs an X509 name
+ * @param seq an Asn1 Sequence
+ */
+ public X509Name(Asn1Sequence seq) {
+ IEnumerator e = seq.GetEnumerator();
+
+ while (e.MoveNext()) {
+ Asn1Set sett = (Asn1Set)e.Current;
+
+ for (int i = 0; i < sett.Count; i++) {
+ Asn1Sequence s = (Asn1Sequence)sett[i];
+ String id = (String)DefaultSymbols[s[0]];
+ if (id == null)
+ continue;
+ ArrayList vs = (ArrayList)values[id];
+ if (vs == null) {
+ vs = new ArrayList();
+ values[id] = vs;
+ }
+ vs.Add(((DerStringBase)s[1]).GetString());
+ }
+ }
+ }
+ /**
+ * Constructs an X509 name
+ * @param dirName a directory name
+ */
+ public X509Name(String dirName) {
+ X509NameTokenizer nTok = new X509NameTokenizer(dirName);
+
+ while (nTok.HasMoreTokens()) {
+ String token = nTok.NextToken();
+ int index = token.IndexOf('=');
+
+ if (index == -1) {
+ throw new ArgumentException("badly formated directory string");
+ }
+
+ String id = token.Substring(0, index).ToUpper(System.Globalization.CultureInfo.InvariantCulture);
+ String value = token.Substring(index + 1);
+ ArrayList vs = (ArrayList)values[id];
+ if (vs == null) {
+ vs = new ArrayList();
+ values[id] = vs;
+ }
+ vs.Add(value);
+ }
+
+ }
+
+ public String GetField(String name) {
+ ArrayList vs = (ArrayList)values[name];
+ return vs == null ? null : (String)vs[0];
+ }
+
+ /**
+ * gets a field array from the values Hashmap
+ * @param name
+ * @return an ArrayList
+ */
+ public ArrayList GetFieldArray(String name) {
+ ArrayList vs = (ArrayList)values[name];
+ return vs == null ? null : vs;
+ }
+
+ /**
+ * getter for values
+ * @return a Hashtable with the fields of the X509 name
+ */
+ public Hashtable GetFields() {
+ return values;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public override String ToString() {
+ return values.ToString();
+ }
+ }
+
+ /**
+ * class for breaking up an X500 Name into it's component tokens, ala
+ * java.util.StringTokenizer. We need this class as some of the
+ * lightweight Java environment don't support classes like
+ * StringTokenizer.
+ */
+ public class X509NameTokenizer {
+ private String oid;
+ private int index;
+ private StringBuilder buf = new StringBuilder();
+
+ public X509NameTokenizer(
+ String oid) {
+ this.oid = oid;
+ this.index = -1;
+ }
+
+ public bool HasMoreTokens() {
+ return (index != oid.Length);
+ }
+
+ public String NextToken() {
+ if (index == oid.Length) {
+ return null;
+ }
+
+ int end = index + 1;
+ bool quoted = false;
+ bool escaped = false;
+
+ buf.Length = 0;
+
+ while (end != oid.Length) {
+ char c = oid[end];
+
+ if (c == '"') {
+ if (!escaped) {
+ quoted = !quoted;
+ }
+ else {
+ buf.Append(c);
+ }
+ escaped = false;
+ }
+ else {
+ if (escaped || quoted) {
+ buf.Append(c);
+ escaped = false;
+ }
+ else if (c == '\\') {
+ escaped = true;
+ }
+ else if (c == ',') {
+ break;
+ }
+ else {
+ buf.Append(c);
+ }
+ }
+ end++;
+ }
+
+ index = end;
+ return buf.ToString().Trim();
+ }
+ }
+ }
+}
+
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPRow.cs b/iTechSharp/iTextSharp/text/pdf/PdfPRow.cs
new file mode 100644
index 0000000..ecb339d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPRow.cs
@@ -0,0 +1,649 @@
+using System;
+
+using iTextSharp.text;
+
+/*
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A row in a PdfPTable.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+
+ public class PdfPRow {
+
+ /** the bottom limit (bottom right y) */
+ public const float BOTTOM_LIMIT = -(1 << 30);
+
+ protected PdfPCell[] cells;
+
+ protected float[] widths;
+
+ protected float maxHeight = 0;
+
+ protected bool calculated = false;
+
+ private int[] canvasesPos;
+
+ /**
+ * Constructs a new PdfPRow with the cells in the array that was passed as a parameter.
+ * @param cells
+ */
+ public PdfPRow(PdfPCell[] cells) {
+ this.cells = cells;
+ widths = new float[cells.Length];
+ }
+
+ /**
+ * Makes a copy of an existing row.
+ * @param row
+ */
+ public PdfPRow(PdfPRow row) {
+ maxHeight = row.maxHeight;
+ calculated = row.calculated;
+ cells = new PdfPCell[row.cells.Length];
+ for (int k = 0; k < cells.Length; ++k) {
+ if (row.cells[k] != null)
+ cells[k] = new PdfPCell(row.cells[k]);
+ }
+ widths = new float[cells.Length];
+ Array.Copy(row.widths, 0, widths, 0, cells.Length);
+ }
+
+ /**
+ * Sets the widths of the columns in the row.
+ * @param widths
+ * @return true if everything went right
+ */
+ public bool SetWidths(float[] widths) {
+ if (widths.Length != cells.Length)
+ return false;
+ Array.Copy(widths, 0, this.widths, 0, cells.Length);
+ float total = 0;
+ calculated = false;
+ for (int k = 0; k < widths.Length; ++k) {
+ PdfPCell cell = cells[k];
+ cell.Left = total;
+ int last = k + cell.Colspan;
+ for (; k < last; ++k)
+ total += widths[k];
+ --k;
+ cell.Right = total;
+ cell.Top = 0;
+ }
+ return true;
+ }
+
+ /**
+ * Calculates the heights of each cell in the row.
+ * @return the maximum height of the row.
+ */
+ public float CalculateHeights() {
+ maxHeight = 0;
+ for (int k = 0; k < cells.Length; ++k) {
+ PdfPCell cell = cells[k];
+ if (cell == null)
+ continue;
+ Image img = cell.Image;
+ if (img != null) {
+ img.ScalePercent(100);
+ float refWidth = img.ScaledWidth;
+ if (cell.Rotation == 90 || cell.Rotation == 270) {
+ refWidth = img.ScaledHeight;
+ }
+ float scale = (cell.Right - cell.EffectivePaddingRight
+ - cell.EffectivePaddingLeft - cell.Left)
+ / refWidth;
+ img.ScalePercent(scale * 100);
+ float refHeight = img.ScaledHeight;
+ if (cell.Rotation == 90 || cell.Rotation == 270) {
+ refHeight = img.ScaledWidth;
+ }
+ cell.Bottom = cell.Top - cell.EffectivePaddingTop
+ - cell.EffectivePaddingBottom
+ - refHeight;
+ } else {
+ if (cell.Rotation == 0 || cell.Rotation == 180) {
+ float rightLimit = cell.NoWrap ? 20000 : cell.Right
+ - cell.EffectivePaddingRight;
+ float bry = (cell.FixedHeight > 0) ? cell.Top
+ - cell.EffectivePaddingTop
+ + cell.EffectivePaddingBottom
+ - cell.FixedHeight : BOTTOM_LIMIT;
+ ColumnText ct = ColumnText.Duplicate(cell.Column);
+ SetColumn(ct,
+ cell.Left + cell.EffectivePaddingLeft, bry,
+ rightLimit, cell.Top - cell.EffectivePaddingTop);
+ ct.Go(true);
+ float yLine = ct.YLine;
+ if (cell.UseDescender)
+ yLine += ct.Descender;
+ cell.Bottom = yLine - cell.EffectivePaddingBottom;
+ }
+ else {
+ if (cell.FixedHeight > 0) {
+ cell.Bottom = cell.Top - cell.FixedHeight;
+ }
+ else {
+ ColumnText ct = ColumnText.Duplicate(cell.Column);
+ SetColumn(ct, 0, cell.Left + cell.EffectivePaddingLeft,
+ 20000, cell.Right - cell.EffectivePaddingRight);
+ ct.Go(true);
+ cell.Bottom = cell.Top - cell.EffectivePaddingTop
+ - cell.EffectivePaddingBottom - ct.FilledWidth;
+ }
+ }
+ }
+ float height = cell.FixedHeight;
+ if (height <= 0)
+ height = cell.Height;
+ if (height < cell.FixedHeight)
+ height = cell.FixedHeight;
+ else if (height < cell.MinimumHeight)
+ height = cell.MinimumHeight;
+ if (height > maxHeight)
+ maxHeight = height;
+ }
+ calculated = true;
+ return maxHeight;
+ }
+
+ /**
+ * Writes the border and background of one cell in the row.
+ * @param xPos
+ * @param yPos
+ * @param cell
+ * @param canvases
+ */
+ public void WriteBorderAndBackground(float xPos, float yPos, PdfPCell cell,
+ PdfContentByte[] canvases) {
+ PdfContentByte lines = canvases[PdfPTable.LINECANVAS];
+ PdfContentByte backgr = canvases[PdfPTable.BACKGROUNDCANVAS];
+ // the coordinates of the border are retrieved
+ float x1 = cell.Left + xPos;
+ float y2 = cell.Top + yPos;
+ float x2 = cell.Right + xPos;
+ float y1 = y2 - maxHeight;
+
+ // the backgroundcolor is set
+ Color background = cell.BackgroundColor;
+ if (background != null) {
+ backgr.SetColorFill(background);
+ backgr.Rectangle(x1, y1, x2 - x1, y2 - y1);
+ backgr.Fill();
+ }
+ // if the element hasn't got any borders, nothing is added
+ if (cell.HasBorders()) {
+ if (cell.UseVariableBorders) {
+ Rectangle borderRect = new Rectangle(cell.Left + xPos, cell.Top
+ - maxHeight + yPos, cell.Right + xPos, cell.Top
+ + yPos);
+ borderRect.CloneNonPositionParameters(cell);
+ borderRect.BackgroundColor = null;
+ lines.Rectangle(borderRect);
+ } else {
+ // the width is set to the width of the element
+ if (cell.BorderWidth != Rectangle.UNDEFINED) {
+ lines.SetLineWidth(cell.BorderWidth);
+ }
+ // the color is set to the color of the element
+ Color color = cell.BorderColor;
+ if (color != null) {
+ lines.SetColorStroke(color);
+ }
+
+ // if the box is a rectangle, it is added as a rectangle
+ if (cell.HasBorder(Rectangle.BOX)) {
+ lines.Rectangle(x1, y1, x2 - x1, y2 - y1);
+ }
+ // if the border isn't a rectangle, the different sides are
+ // added apart
+ else {
+ if (cell.HasBorder(Rectangle.RIGHT_BORDER)) {
+ lines.MoveTo(x2, y1);
+ lines.LineTo(x2, y2);
+ }
+ if (cell.HasBorder(Rectangle.LEFT_BORDER)) {
+ lines.MoveTo(x1, y1);
+ lines.LineTo(x1, y2);
+ }
+ if (cell.HasBorder(Rectangle.BOTTOM_BORDER)) {
+ lines.MoveTo(x1, y1);
+ lines.LineTo(x2, y1);
+ }
+ if (cell.HasBorder(Rectangle.TOP_BORDER)) {
+ lines.MoveTo(x1, y2);
+ lines.LineTo(x2, y2);
+ }
+ }
+ lines.Stroke();
+ if (color != null) {
+ lines.ResetRGBColorStroke();
+ }
+ }
+ }
+ }
+
+ private void SaveAndRotateCanvases(PdfContentByte[] canvases, float a, float b, float c, float d, float e, float f) {
+ int last = PdfPTable.TEXTCANVAS + 1;
+ if (canvasesPos == null) {
+ canvasesPos = new int[last * 2];
+ }
+ for (int k = 0; k < last; ++k) {
+ ByteBuffer bb = canvases[k].InternalBuffer;
+ canvasesPos[k * 2] = bb.Size;
+ canvases[k].SaveState();
+ canvases[k].ConcatCTM(a, b, c, d, e, f);
+ canvasesPos[k * 2 + 1] = bb.Size;
+ }
+ }
+
+ private void RestoreCanvases(PdfContentByte[] canvases) {
+ int last = PdfPTable.TEXTCANVAS + 1;
+ for (int k = 0; k < last; ++k) {
+ ByteBuffer bb = canvases[k].InternalBuffer;
+ int p1 = bb.Size;
+ canvases[k].RestoreState();
+ if (p1 == canvasesPos[k * 2 + 1])
+ bb.Size = canvasesPos[k * 2];
+ }
+ }
+
+ private float SetColumn(ColumnText ct, float llx, float lly, float urx, float ury) {
+ if (llx > urx)
+ urx = llx;
+ if (lly > ury)
+ ury = lly;
+ ct.SetSimpleColumn(llx, lly, urx, ury);
+ return ury;
+ }
+
+ /**
+ * Writes a number of cells (not necessarily all cells).
+ * @param colStart
+ * @param colEnd
+ * @param xPos
+ * @param yPos
+ * @param canvases
+ */
+ public void WriteCells(int colStart, int colEnd, float xPos, float yPos,
+ PdfContentByte[] canvases) {
+ if (!calculated)
+ CalculateHeights();
+ if (colEnd < 0)
+ colEnd = cells.Length;
+ colEnd = Math.Min(colEnd, cells.Length);
+ if (colStart < 0)
+ colStart = 0;
+ if (colStart >= colEnd)
+ return;
+ int newStart;
+ for (newStart = colStart; newStart >= 0; --newStart) {
+ if (cells[newStart] != null)
+ break;
+ xPos -= widths[newStart - 1];
+ }
+ xPos -= cells[newStart].Left;
+ for (int k = newStart; k < colEnd; ++k) {
+ PdfPCell cell = cells[k];
+ if (cell == null)
+ continue;
+ WriteBorderAndBackground(xPos, yPos, cell, canvases);
+ Image img = cell.Image;
+ float tly = 0;
+ switch (cell.VerticalAlignment) {
+ case Element.ALIGN_BOTTOM:
+ tly = cell.Top + yPos - maxHeight + cell.Height
+ - cell.EffectivePaddingTop;
+ break;
+ case Element.ALIGN_MIDDLE:
+ tly = cell.Top + yPos + (cell.Height - maxHeight) / 2
+ - cell.EffectivePaddingTop;
+ break;
+ default:
+ tly = cell.Top + yPos - cell.EffectivePaddingTop;
+ break;
+ }
+ if (img != null) {
+ if (cell.Rotation != 0) {
+ img = Image.GetInstance(img);
+ img.Rotation = img.GetImageRotation() + (float)(cell.Rotation * Math.PI / 180.0);
+ }
+ bool vf = false;
+ if (cell.Height > maxHeight) {
+ img.ScalePercent(100);
+ float scale = (maxHeight - cell.EffectivePaddingTop - cell
+ .EffectivePaddingBottom)
+ / img.ScaledHeight;
+ img.ScalePercent(scale * 100);
+ vf = true;
+ }
+ float left = cell.Left + xPos
+ + cell.EffectivePaddingLeft;
+ if (vf) {
+ switch (cell.HorizontalAlignment) {
+ case Element.ALIGN_CENTER:
+ left = xPos
+ + (cell.Left + cell.EffectivePaddingLeft
+ + cell.Right
+ - cell.EffectivePaddingRight - img
+ .ScaledWidth) / 2;
+ break;
+ case Element.ALIGN_RIGHT:
+ left = xPos + cell.Right
+ - cell.EffectivePaddingRight
+ - img.ScaledWidth;
+ break;
+ default:
+ break;
+ }
+ tly = cell.Top + yPos - cell.EffectivePaddingTop;
+ }
+ img.SetAbsolutePosition(left, tly - img.ScaledHeight);
+ canvases[PdfPTable.TEXTCANVAS].AddImage(img);
+ } else {
+ if (cell.Rotation == 90 || cell.Rotation == 270) {
+ float netWidth = maxHeight - cell.EffectivePaddingTop - cell.EffectivePaddingBottom;
+ float netHeight = cell.Width - cell.EffectivePaddingLeft - cell.EffectivePaddingRight;
+ ColumnText ct = ColumnText.Duplicate(cell.Column);
+ ct.Canvases = canvases;
+ ct.SetSimpleColumn(0, 0, netWidth + 0.001f, -netHeight);
+ ct.Go(true);
+ float calcHeight = -ct.YLine;
+ if (netWidth <= 0 || netHeight <= 0)
+ calcHeight = 0;
+ if (calcHeight > 0) {
+ if (cell.UseDescender)
+ calcHeight -= ct.Descender;
+ ct = ColumnText.Duplicate(cell.Column);
+ ct.Canvases = canvases;
+ ct.SetSimpleColumn(0, -0.001f, netWidth + 0.001f, calcHeight);
+ float pivotX;
+ float pivotY;
+ if (cell.Rotation == 90) {
+ pivotY = cell.Top + yPos - maxHeight + cell.EffectivePaddingBottom;
+ switch (cell.VerticalAlignment) {
+ case Element.ALIGN_BOTTOM:
+ pivotX = cell.Left + xPos + cell.Width - cell.EffectivePaddingRight;
+ break;
+ case Element.ALIGN_MIDDLE:
+ pivotX = cell.Left + xPos + (cell.Width + cell.EffectivePaddingLeft - cell.EffectivePaddingRight + calcHeight) / 2;
+ break;
+ default: //top
+ pivotX = cell.Left + xPos + cell.EffectivePaddingLeft + calcHeight;
+ break;
+ }
+ SaveAndRotateCanvases(canvases, 0,1,-1,0,pivotX,pivotY);
+ }
+ else {
+ pivotY = cell.Top + yPos - cell.EffectivePaddingTop;
+ switch (cell.VerticalAlignment) {
+ case Element.ALIGN_BOTTOM:
+ pivotX = cell.Left + xPos + cell.EffectivePaddingLeft;
+ break;
+ case Element.ALIGN_MIDDLE:
+ pivotX = cell.Left + xPos + (cell.Width + cell.EffectivePaddingLeft - cell.EffectivePaddingRight - calcHeight) / 2;
+ break;
+ default: //top
+ pivotX = cell.Left + xPos + cell.Width - cell.EffectivePaddingRight - calcHeight;
+ break;
+ }
+ SaveAndRotateCanvases(canvases, 0,-1,1,0,pivotX,pivotY);
+ }
+ try {
+ ct.Go();
+ } finally {
+ RestoreCanvases(canvases);
+ }
+ }
+ }
+ else {
+ float fixedHeight = cell.FixedHeight;
+ float rightLimit = cell.Right + xPos
+ - cell.EffectivePaddingRight;
+ float leftLimit = cell.Left + xPos
+ + cell.EffectivePaddingLeft;
+ if (cell.NoWrap) {
+ switch (cell.HorizontalAlignment) {
+ case Element.ALIGN_CENTER:
+ rightLimit += 10000;
+ leftLimit -= 10000;
+ break;
+ case Element.ALIGN_RIGHT:
+ leftLimit -= 20000;
+ break;
+ default:
+ rightLimit += 20000;
+ break;
+ }
+ }
+ ColumnText ct = ColumnText.Duplicate(cell.Column);
+ ct.Canvases = canvases;
+ float bry = tly
+ - (maxHeight /* cell.Height */
+ - cell.EffectivePaddingTop - cell
+ .EffectivePaddingBottom);
+ if (fixedHeight > 0) {
+ if (cell.Height > maxHeight) {
+ tly = cell.Top + yPos - cell.EffectivePaddingTop;
+ bry = cell.Top + yPos - maxHeight
+ + cell.EffectivePaddingBottom;
+ }
+ }
+ if ((tly > bry || ct.ZeroHeightElement()) && leftLimit < rightLimit) {
+ ct.SetSimpleColumn(leftLimit, bry - 0.001f, rightLimit, tly);
+ if (cell.Rotation == 180) {
+ float shx = leftLimit + rightLimit;
+ float shy = yPos + yPos - maxHeight + cell.EffectivePaddingBottom - cell.EffectivePaddingTop;
+ SaveAndRotateCanvases(canvases, -1,0,0,-1,shx,shy);
+ }
+ try {
+ ct.Go();
+ } finally {
+ if (cell.Rotation == 180) {
+ RestoreCanvases(canvases);
+ }
+ }
+ }
+ }
+ }
+ IPdfPCellEvent evt = cell.CellEvent;
+ if (evt != null) {
+ Rectangle rect = new Rectangle(cell.Left + xPos, cell.Top
+ + yPos - maxHeight, cell.Right + xPos, cell.Top
+ + yPos);
+ evt.CellLayout(cell, rect, canvases);
+ }
+ }
+ }
+
+ /**
+ * Checks if the dimensions of the columns were calculated.
+ * @return true if the dimensions of the columns were calculated
+ */
+ public bool IsCalculated() {
+ return calculated;
+ }
+
+ /**
+ * Gets the maximum height of the row (i.e. of the 'highest' cell).
+ * @return the maximum height of the row
+ */
+ public float MaxHeights {
+ get {
+ if (calculated)
+ return maxHeight;
+ else
+ return CalculateHeights();
+ }
+ set {
+ this.maxHeight = value;
+ }
+ }
+
+
+ internal float[] GetEventWidth(float xPos) {
+ int n = 0;
+ for (int k = 0; k < cells.Length; ++k) {
+ if (cells[k] != null)
+ ++n;
+ }
+ float[] width = new float[n + 1];
+ n = 0;
+ width[n++] = xPos;
+ for (int k = 0; k < cells.Length; ++k) {
+ if (cells[k] != null) {
+ width[n] = width[n - 1] + cells[k].Width;
+ ++n;
+ }
+ }
+ return width;
+ }
+
+ /**
+ * Splits a row to newHeight. The returned row is the remainder. It will
+ * return null if the newHeight was so small that only an empty row would
+ * result.
+ *
+ * @param newHeight
+ * the new height
+ * @return the remainder row or null if the newHeight was so small that only
+ * an empty row would result
+ */
+ public PdfPRow SplitRow(float newHeight) {
+ PdfPCell[] newCells = new PdfPCell[cells.Length];
+ float[] fh = new float[cells.Length * 2];
+ bool allEmpty = true;
+ for (int k = 0; k < cells.Length; ++k) {
+ PdfPCell cell = cells[k];
+ if (cell == null)
+ continue;
+ fh[k * 2] = cell.FixedHeight;
+ fh[k * 2 + 1] = cell.MinimumHeight;
+ Image img = cell.Image;
+ PdfPCell c2 = new PdfPCell(cell);
+ if (img != null) {
+ if (newHeight > cell.EffectivePaddingBottom
+ + cell.EffectivePaddingTop + 2) {
+ c2.Phrase = null;
+ allEmpty = false;
+ }
+ } else {
+ int status;
+ float y;
+ ColumnText ct = ColumnText.Duplicate(cell.Column);
+ if (cell.Rotation == 90 || cell.Rotation == 270) {
+ y = SetColumn(ct,
+ cell.Top - newHeight + cell.EffectivePaddingBottom,
+ cell.Left + cell.EffectivePaddingLeft,
+ cell.Top - cell.EffectivePaddingTop,
+ cell.Right - cell.EffectivePaddingRight);
+ }
+ else {
+ float rightLimit = cell.NoWrap ? 20000 : cell.Right
+ - cell.EffectivePaddingRight;
+ float y1 = cell.Top - newHeight
+ + cell.EffectivePaddingBottom;
+ float y2 = cell.Top - cell.EffectivePaddingTop;
+ y = Math.Max(y1, y2);
+ y = SetColumn(ct,
+ cell.Left + cell.EffectivePaddingLeft, y1,
+ rightLimit, y2);
+ }
+ status = ct.Go(true);
+ bool thisEmpty = (ct.YLine == y);
+ if (thisEmpty)
+ ct = ColumnText.Duplicate(cell.Column);
+ allEmpty = (allEmpty && thisEmpty);
+ if ((status & ColumnText.NO_MORE_TEXT) == 0 || thisEmpty) {
+ c2.Column = ct;
+ ct.FilledWidth = 0;
+ } else {
+ c2.Phrase = null;
+ }
+ }
+ newCells[k] = c2;
+ cell.FixedHeight = newHeight;
+ }
+ if (allEmpty) {
+ for (int k = 0; k < cells.Length; ++k) {
+ PdfPCell cell = cells[k];
+ if (cell == null)
+ continue;
+ float f = fh[k * 2];
+ float m = fh[k * 2 + 1];
+ if (f <= 0)
+ cell.MinimumHeight = m;
+ else
+ cell.FixedHeight = f;
+ }
+ return null;
+ }
+ CalculateHeights();
+ PdfPRow split = new PdfPRow(newCells);
+ split.widths = (float[]) widths.Clone();
+ split.CalculateHeights();
+ return split;
+ }
+
+ /**
+ * Returns the array of cells in the row.
+ * Please be extremely careful with this method.
+ * Use the cells as read only objects.
+ * @return an array of cells
+ * @since 2.1.1
+ */
+ public PdfPCell[] Cells {
+ get {
+ return cells;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPSXObject.cs b/iTechSharp/iTextSharp/text/pdf/PdfPSXObject.cs
new file mode 100644
index 0000000..78f0a4f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPSXObject.cs
@@ -0,0 +1,101 @@
+using System;
+/*
+ * Copyright 2005 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Implements the PostScript XObject.
+ */
+ public class PdfPSXObject : PdfTemplate {
+
+ /** Creates a new instance of PdfPSXObject */
+ protected PdfPSXObject() {
+ }
+
+ /**
+ * Constructs a PSXObject
+ * @param wr
+ */
+ public PdfPSXObject(PdfWriter wr) : base(wr) {
+ }
+
+ /**
+ * Gets the stream representing this object.
+ *
+ * @return the stream representing this object
+ * @throws IOException
+ */
+
+ internal override PdfStream FormXObject {
+ get {
+ PdfStream s = new PdfStream(content.ToByteArray());
+ s.Put(PdfName.TYPE, PdfName.XOBJECT);
+ s.Put(PdfName.SUBTYPE, PdfName.PS);
+ s.FlateCompress();
+ return s;
+ }
+ }
+
+ /**
+ * Gets a duplicate of this
+ * A PdfPTableEvent can be associated to the table to do custom drawing
+ * when the table is rendered.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+
+ public class PdfPTable : ILargeElement{
+
+ /** The index of the original
+ *
+ *
+ * The table event is only fired for complete rows.
+ * @param colStart the first column to be written, zero index
+ * @param colEnd the last column to be written + 1. If it is -1 all the
+ * columns to the end are written
+ * @param rowStart the first row to be written, zero index
+ * @param rowEnd the last row to be written + 1. If it is -1 all the
+ * rows to the end are written
+ * @param xPos the x write coodinate
+ * @param yPos the y write coodinate
+ * @param canvases an array of 4
+ * The table event is only fired for complete rows.
+ *
+ * @param colStart the first column to be written, zero index
+ * @param colEnd the last column to be written + 1. If it is -1 all the
+ * @param rowStart the first row to be written, zero index
+ * @param rowEnd the last row to be written + 1. If it is -1 all the
+ * rows to the end are written
+ * @param xPos the x write coodinate
+ * @param yPos the y write coodinate
+ * @param canvas the
+ *
+ * The layers are placed in sequence on top of each other.
+ * @param canvas the
+ * A Page object is a dictionary whose keys describe a single page containing text,
+ * graphics, and images. A Page onjects is a leaf of the Pages tree.
+ * This method allways returns
+ * Note that if even if a page is not written this method is still
+ * called. It is preferable to use
+ * Note that this method is called with the page number equal
+ * to the last page plus one.
+ *
+ * @param writer the
+ *
+ *
+ *
+ *
+ *
+ *
+ * It is usefull to pinpoint the
+ * The Pages of a document are accessible through a tree of nodes known as the Pages tree.
+ * This tree defines the ordering of the pages in the document.
+ * No signature validation is made, use the methods availabe for that in
+ * Rectangles are used to describe locations on the page and bounding boxes for several
+ * objects in PDF, such as fonts. A rectangle is represented as an
+ * The marking operations for drawing a page are stored in a stream that is the value of the
+ * Contents key in the Page object's dictionary. Each marking context includes a list
+ * of the named resources it uses. This resource list is stored as a dictionary that is the
+ * value of the context's Resources key, and it serves two functions: it enumerates
+ * the named resources in the contents stream, and it established the mapping from the names
+ * to the objects used by the marking operations.
+ * Consult PPKAppearances.pdf
+ * for further details.
+ * @param layer the layer
+ * @return a template
+ */
+ public PdfTemplate GetLayer(int layer) {
+ if (layer < 0 || layer >= app.Length)
+ return null;
+ PdfTemplate t = app[layer];
+ if (t == null) {
+ t = app[layer] = new PdfTemplate(writer);
+ t.BoundingBox = rect;
+ writer.AddDirectTemplateSimple(t, new PdfName("n" + layer));
+ }
+ return t;
+ }
+
+ /**
+ * Gets the template that aggregates all appearance layers. This corresponds to the /FRM resource.
+ *
+ * Consult PPKAppearances.pdf
+ * for further details.
+ * @return the template that aggregates all appearance layers
+ */
+ public PdfTemplate GetTopLayer() {
+ if (frm == null) {
+ frm = new PdfTemplate(writer);
+ frm.BoundingBox = rect;
+ writer.AddDirectTemplateSimple(frm, new PdfName("FRM"));
+ }
+ return frm;
+ }
+
+ /**
+ * Gets the main appearance layer.
+ *
+ * Consult PPKAppearances.pdf
+ * for further details.
+ * @return the main appearance layer
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public PdfTemplate GetAppearance() {
+ if (IsInvisible()) {
+ PdfTemplate t = new PdfTemplate(writer);
+ t.BoundingBox = new Rectangle(0, 0);
+ writer.AddDirectTemplateSimple(t, null);
+ return t;
+ }
+ if (app[0] == null) {
+ PdfTemplate t = app[0] = new PdfTemplate(writer);
+ t.BoundingBox = new Rectangle(100, 100);
+ writer.AddDirectTemplateSimple(t, new PdfName("n0"));
+ t.SetLiteral("% DSBlank\n");
+ }
+ if (app[1] == null && !acro6Layers) {
+ PdfTemplate t = app[1] = new PdfTemplate(writer);
+ t.BoundingBox = new Rectangle(100, 100);
+ writer.AddDirectTemplateSimple(t, new PdfName("n1"));
+ t.SetLiteral(questionMark);
+ }
+ if (app[2] == null) {
+ String text;
+ if (layer2Text == null) {
+ StringBuilder buf = new StringBuilder();
+ buf.Append("Digitally signed by ").Append(PdfPKCS7.GetSubjectFields((X509Certificate)certChain[0]).GetField("CN")).Append('\n');
+ buf.Append("Date: ").Append(signDate.ToString("yyyy.MM.dd HH:mm:ss zzz"));
+ if (reason != null)
+ buf.Append('\n').Append("Reason: ").Append(reason);
+ if (location != null)
+ buf.Append('\n').Append("Location: ").Append(location);
+ text = buf.ToString();
+ }
+ else
+ text = layer2Text;
+ PdfTemplate t = app[2] = new PdfTemplate(writer);
+ t.BoundingBox = rect;
+ writer.AddDirectTemplateSimple(t, new PdfName("n2"));
+ if (image != null) {
+ if (imageScale == 0) {
+ t.AddImage(image, rect.Width, 0, 0, rect.Height, 0, 0);
+ }
+ else {
+ float usableScale = imageScale;
+ if (imageScale < 0)
+ usableScale = Math.Min(rect.Width / image.Width, rect.Height / image.Height);
+ float w = image.Width * usableScale;
+ float h = image.Height * usableScale;
+ float x = (rect.Width - w) / 2;
+ float y = (rect.Height - h) / 2;
+ t.AddImage(image, w, 0, 0, h, x, y);
+ }
+ }
+ Font font;
+ if (layer2Font == null)
+ font = new Font();
+ else
+ font = new Font(layer2Font);
+ float size = font.Size;
+
+ Rectangle dataRect = null;
+ Rectangle signatureRect = null;
+
+ if (Render == SignatureRender.NameAndDescription ||
+ (Render == SignatureRender.GraphicAndDescription && this.SignatureGraphic != null)) {
+ // origin is the bottom-left
+ signatureRect = new Rectangle(
+ MARGIN,
+ MARGIN,
+ rect.Width / 2 - MARGIN,
+ rect.Height - MARGIN);
+ dataRect = new Rectangle(
+ rect.Width / 2 + MARGIN / 2,
+ MARGIN,
+ rect.Width - MARGIN / 2,
+ rect.Height - MARGIN);
+
+ if (rect.Height > rect.Width) {
+ signatureRect = new Rectangle(
+ MARGIN,
+ rect.Height / 2,
+ rect.Width - MARGIN,
+ rect.Height);
+ dataRect = new Rectangle(
+ MARGIN,
+ MARGIN,
+ rect.Width - MARGIN,
+ rect.Height / 2 - MARGIN);
+ }
+ }
+ else {
+ dataRect = new Rectangle(
+ MARGIN,
+ MARGIN,
+ rect.Width - MARGIN,
+ rect.Height * (1 - TOP_SECTION) - MARGIN);
+ }
+
+ if (Render == SignatureRender.NameAndDescription) {
+ string signedBy = iTextSharp.text.pdf.PdfPKCS7.GetSubjectFields(this.certChain[0]).GetField("CN");
+ Rectangle sr2 = new Rectangle(signatureRect.Width - MARGIN, signatureRect.Height - MARGIN );
+ float signedSize = FitText(font, signedBy, sr2, -1, runDirection);
+
+ ColumnText ct2 = new ColumnText(t);
+ ct2.RunDirection = runDirection;
+ ct2.SetSimpleColumn(new Phrase(signedBy, font), signatureRect.Left, signatureRect.Bottom, signatureRect.Right, signatureRect.Top, signedSize, Element.ALIGN_LEFT);
+
+ ct2.Go();
+ }
+ else if (Render == SignatureRender.GraphicAndDescription) {
+ ColumnText ct2 = new ColumnText(t);
+ ct2.RunDirection = runDirection;
+ ct2.SetSimpleColumn(signatureRect.Left, signatureRect.Bottom, signatureRect.Right, signatureRect.Top, 0, Element.ALIGN_RIGHT);
+
+ Image im = Image.GetInstance(SignatureGraphic);
+ im.ScaleToFit(signatureRect.Width, signatureRect.Height);
+
+ Paragraph p = new Paragraph();
+ // must calculate the point to draw from to make image appear in middle of column
+ float x = 0;
+ // experimentation found this magic number to counteract Adobe's signature graphic, which
+ // offsets the y co-ordinate by 15 units
+ float y = -im.ScaledHeight + 15;
+
+ x = x + (signatureRect.Width - im.ScaledWidth) / 2;
+ y = y - (signatureRect.Height - im.ScaledHeight) / 2;
+ p.Add(new Chunk(im, x + (signatureRect.Width - im.ScaledWidth) / 2, y, false));
+ ct2.AddElement(p);
+ ct2.Go();
+ }
+
+ if (size <= 0) {
+ Rectangle sr = new Rectangle(dataRect.Width, dataRect.Height);
+ size = FitText(font, text, sr, 12, runDirection);
+ }
+ ColumnText ct = new ColumnText(t);
+ ct.RunDirection = runDirection;
+ ct.SetSimpleColumn(new Phrase(text, font), dataRect.Left, dataRect.Bottom, dataRect.Right, dataRect.Top, size, Element.ALIGN_LEFT);
+ ct.Go();
+
+ }
+ if (app[3] == null && !acro6Layers) {
+ PdfTemplate t = app[3] = new PdfTemplate(writer);
+ t.BoundingBox = new Rectangle(100, 100);
+ writer.AddDirectTemplateSimple(t, new PdfName("n3"));
+ t.SetLiteral("% DSBlank\n");
+ }
+ if (app[4] == null && !acro6Layers) {
+ PdfTemplate t = app[4] = new PdfTemplate(writer);
+ t.BoundingBox = new Rectangle(0, rect.Height * (1 - TOP_SECTION), rect.Right, rect.Top);
+ writer.AddDirectTemplateSimple(t, new PdfName("n4"));
+ Font font;
+ if (layer2Font == null)
+ font = new Font();
+ else
+ font = new Font(layer2Font);
+ float size = font.Size;
+ String text = "Signature Not Verified";
+ if (layer4Text != null)
+ text = layer4Text;
+ Rectangle sr = new Rectangle(rect.Width - 2 * MARGIN, rect.Height * TOP_SECTION - 2 * MARGIN);
+ size = FitText(font, text, sr, 15, runDirection);
+ ColumnText ct = new ColumnText(t);
+ ct.RunDirection = runDirection;
+ ct.SetSimpleColumn(new Phrase(text, font), MARGIN, 0, rect.Width - MARGIN, rect.Height - MARGIN, size, Element.ALIGN_LEFT);
+ ct.Go();
+ }
+ int rotation = writer.reader.GetPageRotation(page);
+ Rectangle rotated = new Rectangle(rect);
+ int n = rotation;
+ while (n > 0) {
+ rotated = rotated.Rotate();
+ n -= 90;
+ }
+ if (frm == null) {
+ frm = new PdfTemplate(writer);
+ frm.BoundingBox = rotated;
+ writer.AddDirectTemplateSimple(frm, new PdfName("FRM"));
+ float scale = Math.Min(rect.Width, rect.Height) * 0.9f;
+ float x = (rect.Width - scale) / 2;
+ float y = (rect.Height - scale) / 2;
+ scale /= 100;
+ if (rotation == 90)
+ frm.ConcatCTM(0, 1, -1, 0, rect.Height, 0);
+ else if (rotation == 180)
+ frm.ConcatCTM(-1, 0, 0, -1, rect.Width, rect.Height);
+ else if (rotation == 270)
+ frm.ConcatCTM(0, -1, 1, 0, 0, rect.Width);
+ frm.AddTemplate(app[0], 0, 0);
+ if (!acro6Layers)
+ frm.AddTemplate(app[1], scale, 0, 0, scale, x, y);
+ frm.AddTemplate(app[2], 0, 0);
+ if (!acro6Layers) {
+ frm.AddTemplate(app[3], scale, 0, 0, scale, x, y);
+ frm.AddTemplate(app[4], 0, 0);
+ }
+ }
+ PdfTemplate napp = new PdfTemplate(writer);
+ napp.BoundingBox = rotated;
+ writer.AddDirectTemplateSimple(napp, null);
+ napp.AddTemplate(frm, 0, 0);
+ return napp;
+ }
+
+ /**
+ * Fits the text to some rectangle adjusting the font size as needed.
+ * @param font the font to use
+ * @param text the text
+ * @param rect the rectangle where the text must fit
+ * @param maxFontSize the maximum font size
+ * @param runDirection the run direction
+ * @return the calculated font size that makes the text fit
+ */
+ public static float FitText(Font font, String text, Rectangle rect, float maxFontSize, int runDirection) {
+ ColumnText ct = null;
+ int status = 0;
+ if (maxFontSize <= 0) {
+ int cr = 0;
+ int lf = 0;
+ char[] t = text.ToCharArray();
+ for (int k = 0; k < t.Length; ++k) {
+ if (t[k] == '\n')
+ ++lf;
+ else if (t[k] == '\r')
+ ++cr;
+ }
+ int minLines = Math.Max(cr, lf) + 1;
+ maxFontSize = Math.Abs(rect.Height) / minLines - 0.001f;
+ }
+ font.Size = maxFontSize;
+ Phrase ph = new Phrase(text, font);
+ ct = new ColumnText(null);
+ ct.SetSimpleColumn(ph, rect.Left, rect.Bottom, rect.Right, rect.Top, maxFontSize, Element.ALIGN_LEFT);
+ ct.RunDirection = runDirection;
+ status = ct.Go(true);
+ if ((status & ColumnText.NO_MORE_TEXT) != 0)
+ return maxFontSize;
+ float precision = 0.1f;
+ float min = 0;
+ float max = maxFontSize;
+ float size = maxFontSize;
+ for (int k = 0; k < 50; ++k) { //just in case it doesn't converge
+ size = (min + max) / 2;
+ ct = new ColumnText(null);
+ font.Size = size;
+ ct.SetSimpleColumn(new Phrase(text, font), rect.Left, rect.Bottom, rect.Right, rect.Top, size, Element.ALIGN_LEFT);
+ ct.RunDirection = runDirection;
+ status = ct.Go(true);
+ if ((status & ColumnText.NO_MORE_TEXT) != 0) {
+ if (max - min < size * precision)
+ return size;
+ min = size;
+ }
+ else
+ max = size;
+ }
+ return size;
+ }
+
+ /**
+ * Sets the digest/signature to an external calculated value.
+ * @param digest the digest. This is the actual signature
+ * @param RSAdata the extra data that goes into the data tag in PKCS#7
+ * @param digestEncryptionAlgorithm the encryption algorithm. It may must be
+ * If calling PreClose() dont't call PdfStamper.Close().
+ *
+ * No external signatures are allowed if this methos is called.
+ * @throws IOException on error
+ * @throws DocumentException on error
+ */
+ public void PreClose() {
+ PreClose(null);
+ }
+ /**
+ * This is the first method to be called when using external signatures. The general sequence is:
+ * PreClose(), GetDocumentBytes() and Close().
+ *
+ * If calling PreClose() dont't call PdfStamper.Close().
+ *
+ * If using an external signature
+ *
+ * @return the document bytes that are hashable
+ */
+ public Stream RangeStream {
+ get {
+ return new PdfSignatureAppearance.FRangeStream(raf, bout, range);
+ }
+ }
+
+ /**
+ * Gets the user made signature dictionary. This is the dictionary at the /V key.
+ * @return the user made signature dictionary
+ */
+ public PdfDictionary CryptoDictionary {
+ get {
+ return cryptoDictionary;
+ }
+ set {
+ cryptoDictionary = value;
+ }
+ }
+
+ /**
+ * Gets the
+ * The main use is to insert external signatures.
+ * @return the instance of the standard signature dictionary
+ */
+ public PdfSigGenericPKCS SigStandard {
+ get {
+ return sigStandard;
+ }
+ }
+
+ /**
+ * Sets the signing contact.
+ * @param contact the signing contact
+ */
+ public string Contact {
+ get {
+ return contact;
+ }
+ set {
+ contact = value;
+ }
+ }
+
+ /**
+ * Sets the n2 and n4 layer font. If the font size is zero, auto-fit will be used.
+ * @param layer2Font the n2 and n4 font
+ */
+ public Font Layer2Font {
+ get {
+ return layer2Font;
+ }
+ set {
+ layer2Font = value;
+ }
+ }
+
+ /**
+ * Acrobat 6.0 and higher recomends that only layer n2 and n4 be present. This method sets that mode.
+ * @param acro6Layers if
+ * It is also possible to change the field values and to
+ * flatten them. New fields can be added but not flattened.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfStamper : IPdfViewerPreferences, IPdfEncryptionSettings {
+ /**
+ * The writer
+ */
+ protected PdfStamperImp stamper;
+ private Hashtable moreInfo;
+ private bool hasSignature;
+ private PdfSignatureAppearance sigApp;
+
+ /** Starts the process of adding extra content to an existing PDF
+ * document.
+ * @param reader the original document. It cannot be reused
+ * @param os the output stream
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public PdfStamper(PdfReader reader, Stream os) {
+ stamper = new PdfStamperImp(reader, os, '\0', false);
+ }
+
+ /**
+ * Starts the process of adding extra content to an existing PDF
+ * document.
+ * @param reader the original document. It cannot be reused
+ * @param os the output stream
+ * @param pdfVersion the new pdf version or '\0' to keep the same version as the original
+ * document
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public PdfStamper(PdfReader reader, Stream os, char pdfVersion) {
+ stamper = new PdfStamperImp(reader, os, pdfVersion, false);
+ }
+
+ /**
+ * Starts the process of adding extra content to an existing PDF
+ * document, possibly as a new revision.
+ * @param reader the original document. It cannot be reused
+ * @param os the output stream
+ * @param pdfVersion the new pdf version or '\0' to keep the same version as the original
+ * document
+ * @param append if
+ * If closing a signed document with an external signature the closing must be done
+ * in the
+ * Calling
+ * A possible use for adding a signature without invalidating an existing one is:
+ *
+ *
+ * Note that the pdf is created in memory.
+ *
+ * A possible use is:
+ *
+ *
+ * A possible use is:
+ *
+ *
+ * A stream, like a string, is a sequence of characters. However, an application can
+ * read a small portion of a stream at a time, while a string must be read in its entirety.
+ * For this reason, objects with potentially large amounts of data, such as images and
+ * page descriptions, are represented as streams.
+ *
+ * This method must be called and can only be called if the contructor {@link #PdfStream(InputStream,PdfWriter)}
+ * is used to create the stream.
+ * @throws IOException on error
+ * @see #PdfStream(InputStream,PdfWriter)
+ */
+ public void WriteLength() {
+ if (inputStream == null)
+ throw new PdfException("WriteLength() can only be called in a contructed PdfStream(InputStream,PdfWriter).");
+ if (inputStreamLength == -1)
+ throw new PdfException("WriteLength() can only be called after output of the stream body.");
+ writer.AddToBody(new PdfNumber(inputStreamLength), iref, false);
+ }
+
+ public int RawLength {
+ get {
+ return rawLength;
+ }
+ }
+
+ // methods
+
+ /**
+ * Compresses the stream.
+ *
+ * @throws PdfException if a filter is allready defined
+ */
+
+ public void FlateCompress() {
+ if (!Document.Compress)
+ return;
+ // check if the flateCompress-method has allready been
+ if (compressed) {
+ return;
+ }
+ if (inputStream != null) {
+ compressed = true;
+ return;
+ }
+ // check if a filter allready exists
+ PdfObject filter = PdfReader.GetPdfObject(Get(PdfName.FILTER));
+ if (filter != null) {
+ if (filter.IsName()) {
+ if (PdfName.FLATEDECODE.Equals(filter))
+ return;
+ }
+ else if (filter.IsArray()) {
+ if (((PdfArray) filter).Contains(PdfName.FLATEDECODE))
+ return;
+ }
+ else {
+ throw new PdfException("Stream could not be compressed: filter is not a name or array.");
+ }
+ }
+ // compress
+ MemoryStream stream = new MemoryStream();
+ ZDeflaterOutputStream zip = new ZDeflaterOutputStream(stream);
+ if (streamBytes != null)
+ streamBytes.WriteTo(zip);
+ else
+ zip.Write(bytes, 0, bytes.Length);
+ //zip.Close();
+ zip.Finish();
+ // update the object
+ streamBytes = stream;
+ bytes = null;
+ Put(PdfName.LENGTH, new PdfNumber(streamBytes.Length));
+ if (filter == null) {
+ Put(PdfName.FILTER, PdfName.FLATEDECODE);
+ }
+ else {
+ PdfArray filters = new PdfArray(filter);
+ filters.Add(PdfName.FLATEDECODE);
+ Put(PdfName.FILTER, filters);
+ }
+ compressed = true;
+ }
+
+ protected virtual void SuperToPdf(PdfWriter writer, Stream os) {
+ base.ToPdf(writer, os);
+ }
+
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ if (inputStream != null && compressed)
+ Put(PdfName.FILTER, PdfName.FLATEDECODE);
+ PdfEncryption crypto = null;
+ if (writer != null)
+ crypto = writer.Encryption;
+ if (crypto != null) {
+ PdfObject filter = Get(PdfName.FILTER);
+ if (filter != null) {
+ if (PdfName.CRYPT.Equals(filter))
+ crypto = null;
+ else if (filter.IsArray()) {
+ ArrayList af = ((PdfArray)filter).ArrayList;
+ if (af.Count > 0 && PdfName.CRYPT.Equals(af[0]))
+ crypto = null;
+ }
+ }
+ }
+ PdfObject nn = Get(PdfName.LENGTH);
+ if (crypto != null && nn != null && nn.IsNumber()) {
+ int sz = ((PdfNumber)nn).IntValue;
+ Put(PdfName.LENGTH, new PdfNumber(crypto.CalculateStreamSize(sz)));
+ SuperToPdf(writer, os);
+ Put(PdfName.LENGTH, nn);
+ }
+ else
+ SuperToPdf(writer, os);
+ os.Write(STARTSTREAM, 0, STARTSTREAM.Length);
+ if (inputStream != null) {
+ rawLength = 0;
+ ZDeflaterOutputStream def = null;
+ OutputStreamCounter osc = new OutputStreamCounter(os);
+ OutputStreamEncryption ose = null;
+ Stream fout = osc;
+ if (crypto != null)
+ fout = ose = crypto.GetEncryptionStream(fout);
+ if (compressed)
+ fout = def = new ZDeflaterOutputStream(fout);
+
+ byte[] buf = new byte[4192];
+ while (true) {
+ int n = inputStream.Read(buf, 0, buf.Length);
+ if (n <= 0)
+ break;
+ fout.Write(buf, 0, n);
+ rawLength += n;
+ }
+ if (def != null)
+ def.Finish();
+ if (ose != null)
+ ose.Finish();
+ inputStreamLength = osc.Counter;
+ }
+ else {
+ if (crypto == null) {
+ if (streamBytes != null)
+ streamBytes.WriteTo(os);
+ else
+ os.Write(bytes, 0, bytes.Length);
+ }
+ else {
+ byte[] b;
+ if (streamBytes != null) {
+ b = crypto.EncryptByteArray(streamBytes.ToArray());
+ }
+ else {
+ b = crypto.EncryptByteArray(bytes);
+ }
+ os.Write(b, 0, b.Length);
+ }
+ }
+ os.Write(ENDSTREAM, 0, ENDSTREAM.Length);
+ }
+
+ /**
+ * Writes the data content to an
+ * A string is a sequence of characters delimited by parenthesis. If a string is too long
+ * to be conveniently placed on a single line, it may be split across multiple lines by using
+ * the backslash character (\) at the end of a line to indicate that the string continues
+ * on the following line. Within a string, the backslash character is used as an escape to
+ * specify unbalanced parenthesis, non-printing ASCII characters, and the backslash character
+ * itself. Use of the \ddd escape sequence is the preferred way to represent characters
+ * outside the printable ASCII character set. Pre-requisite: the object must have been built with the parameter
+ * Creates a new template that is nothing more than a form XObject. This template can be included
+ * in this
+ * A
+ * When this
+ * This class covers the third section of Chapter 5 in the 'Portable Document Format
+ * Reference Manual version 1.3' (page 55-60). It contains the body of a PDF document
+ * (section 5.14) and it can also generate a Cross-reference Table (section 5.15).
+ *
+ * @see PdfWriter
+ * @see PdfObject
+ * @see PdfIndirectObject
+ */
+
+ public class PdfBody {
+
+ // inner classes
+
+ /**
+ *
+ * This methods creates a
+ * This methods creates a
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 5.16 (page 59-60).
+ */
+
+ internal class PdfTrailer : PdfDictionary {
+
+ // membervariables
+
+ internal int offset;
+
+ // constructors
+
+ /**
+ * Constructs a PDF-Trailer.
+ *
+ * @param size the number of entries in the
+ * Remark: a PdfWriter can only be constructed by calling the method
+ *
+ * The document has to be open before you can begin to add content
+ * to the body of the document.
+ *
+ * @return a
+ * When this method is called, the PDF-document header is
+ * written to the outputstream.
+ */
+ public override void Open() {
+ base.Open();
+ pdf_version.WriteHeader(os);
+ body = new PdfBody(this);
+ if (pdfxConformance.IsPdfX32002()) {
+ PdfDictionary sec = new PdfDictionary();
+ sec.Put(PdfName.GAMMA, new PdfArray(new float[]{2.2f,2.2f,2.2f}));
+ sec.Put(PdfName.MATRIX, new PdfArray(new float[]{0.4124f,0.2126f,0.0193f,0.3576f,0.7152f,0.1192f,0.1805f,0.0722f,0.9505f}));
+ sec.Put(PdfName.WHITEPOINT, new PdfArray(new float[]{0.9505f,1f,1.089f}));
+ PdfArray arr = new PdfArray(PdfName.CALRGB);
+ arr.Add(sec);
+ SetDefaultColorspace(PdfName.DEFAULTRGB, AddToBody(arr).IndirectReference);
+ }
+ }
+
+ /**
+ * Signals that the
+ * The pages-tree is built and written to the outputstream.
+ * A Catalog is constructed, as well as an Info-object,
+ * the referencetable is composed and everything is written
+ * to the outputstream embedded in a Trailer.
+ */
+ public override void Close() {
+ if (open) {
+ if ((currentPageNumber - 1) != pageReferences.Count)
+ throw new Exception("The page " + pageReferences.Count +
+ " was requested but the document has only " + (currentPageNumber - 1) + " pages.");
+ pdf.Close();
+ AddSharedObjectsToBody();
+ // add the root to the body
+ PdfIndirectReference rootRef = root.WritePageTree();
+ // make the catalog-object and add it to the body
+ PdfDictionary catalog = GetCatalog(rootRef);
+ // [C9] if there is XMP data to add: add it
+ if (xmpMetadata != null) {
+ PdfStream xmp = new PdfStream(xmpMetadata);
+ xmp.Put(PdfName.TYPE, PdfName.METADATA);
+ xmp.Put(PdfName.SUBTYPE, PdfName.XML);
+ if (crypto != null && !crypto.IsMetadataEncrypted()) {
+ PdfArray ar = new PdfArray();
+ ar.Add(PdfName.CRYPT);
+ xmp.Put(PdfName.FILTER, ar);
+ }
+ catalog.Put(PdfName.METADATA, body.Add(xmp).IndirectReference);
+ }
+ // [C10] make pdfx conformant
+ if (IsPdfX()) {
+ pdfxConformance.CompleteInfoDictionary(Info);
+ pdfxConformance.CompleteExtraCatalog(ExtraCatalog);
+ }
+ // [C11] Output Intents
+ if (extraCatalog != null) {
+ catalog.MergeDifferent(extraCatalog);
+ }
+
+ WriteOutlines(catalog, false);
+
+ // add the Catalog to the body
+ PdfIndirectObject indirectCatalog = AddToBody(catalog, false);
+ // add the info-object to the body
+ PdfIndirectObject infoObj = AddToBody(Info, false);
+
+ // [F1] encryption
+ PdfIndirectReference encryption = null;
+ PdfObject fileID = null;
+ body.FlushObjStm();
+ if (crypto != null) {
+ PdfIndirectObject encryptionObject = AddToBody(crypto.GetEncryptionDictionary(), false);
+ encryption = encryptionObject.IndirectReference;
+ fileID = crypto.FileID;
+ }
+ else
+ fileID = PdfEncryption.CreateInfoId(PdfEncryption.CreateDocumentId());
+
+ // write the cross-reference table of the body
+ body.WriteCrossReferenceTable(os, indirectCatalog.IndirectReference,
+ infoObj.IndirectReference, encryption, fileID, prevxref);
+
+ // make the trailer
+ // [F2] full compression
+ if (fullCompression) {
+ byte[] tmp = GetISOBytes("startxref\n");
+ os.Write(tmp, 0, tmp.Length);
+ tmp = GetISOBytes(body.Offset.ToString());
+ os.Write(tmp, 0, tmp.Length);
+ tmp = GetISOBytes("\n%%EOF\n");
+ os.Write(tmp, 0, tmp.Length);
+ }
+ else {
+ PdfTrailer trailer = new PdfTrailer(body.Size,
+ body.Offset,
+ indirectCatalog.IndirectReference,
+ infoObj.IndirectReference,
+ encryption,
+ fileID, prevxref);
+ trailer.ToPdf(this, os);
+ }
+ base.Close();
+ }
+ }
+
+ protected void AddSharedObjectsToBody() {
+ // add the fonts
+ foreach (FontDetails details in documentFonts.Values) {
+ details.WriteFont(this);
+ }
+ // add the form XObjects
+ foreach (Object[] objs in formXObjects.Values) {
+ PdfTemplate template = (PdfTemplate)objs[1];
+ if (template != null && template.IndirectReference is PRIndirectReference)
+ continue;
+ if (template != null && template.Type == PdfTemplate.TYPE_TEMPLATE) {
+ AddToBody(template.FormXObject, template.IndirectReference);
+ }
+ }
+ // add all the dependencies in the imported pages
+ foreach (PdfReaderInstance rd in importedPages.Values) {
+ currentPdfReaderInstance = rd;
+ currentPdfReaderInstance.WriteAllPages();
+ }
+ currentPdfReaderInstance = null;
+ // add the color
+ foreach (ColorDetails color in documentColors.Values) {
+ AddToBody(color.GetSpotColor(this), color.IndirectReference);
+ }
+ // add the pattern
+ foreach (PdfPatternPainter pat in documentPatterns.Keys) {
+ AddToBody(pat.Pattern, pat.IndirectReference);
+ }
+ // add the shading patterns
+ foreach (PdfShadingPattern shadingPattern in documentShadingPatterns.Keys) {
+ shadingPattern.AddToBody();
+ }
+ // add the shadings
+ foreach (PdfShading shading in documentShadings.Keys) {
+ shading.AddToBody();
+ }
+ // add the extgstate
+ foreach (DictionaryEntry entry in documentExtGState) {
+ PdfDictionary gstate = (PdfDictionary)entry.Key;
+ PdfObject[] obj = (PdfObject[])entry.Value;
+ AddToBody(gstate, (PdfIndirectReference)obj[1]);
+ }
+
+ // add the properties
+ foreach (DictionaryEntry entry in documentProperties) {
+ Object prop = entry.Key;
+ PdfObject[] obj = (PdfObject[])entry.Value;
+ if (prop is PdfLayerMembership){
+ PdfLayerMembership layer = (PdfLayerMembership)prop;
+ AddToBody(layer.PdfObject, layer.Ref);
+ }
+ else if ((prop is PdfDictionary) && !(prop is PdfLayer)){
+ AddToBody((PdfDictionary)prop, (PdfIndirectReference)obj[1]);
+ }
+ }
+ foreach (IPdfOCG layer in documentOCG.Keys) {
+ AddToBody(layer.PdfObject, layer.Ref);
+ }
+ }
+
+ // Root data for the PDF document (used when composing the Catalog)
+
+ // [C1] Outlines (bookmarks)
+
+ /**
+ * Use this method to get the root outline
+ * and construct bookmarks.
+ * @return the root outline
+ */
+ public PdfOutline RootOutline {
+ get {
+ return directContent.RootOutline;
+ }
+ }
+
+ protected ArrayList newBookmarks;
+
+ /**
+ * Sets the bookmarks. The list structure is defined in
+ * {@link SimpleBookmark}.
+ * @param outlines the bookmarks or
+ * If set before opening the document it will also set the pdf version to 1.5.
+ */
+ public void SetFullCompression() {
+ this.fullCompression = true;
+ SetAtLeastPdfVersion(VERSION_1_5);
+ }
+
+ // [F3] adding fonts
+
+ /** The fonts of this document */
+ protected Hashtable documentFonts = new Hashtable();
+
+ /** The font number counter for the fonts in the document. */
+ protected int fontNumber = 1;
+
+ /**
+ * Adds a
+ * The colorspace is applied immediately when creating templates and at the page
+ * end for the main document content.
+ * @param key the name of the colorspace. It can be
+ * Example usage:
+ *
+ *
+ * Example usage:
+ *
+ *
+ * This method blocks until the two bytes are read, the end of the
+ * stream is detected, or an exception is thrown.
+ *
+ * @return the next two bytes of this stream, interpreted as a signed
+ * 16-bit number.
+ * @exception EOFException if this stream reaches the end before reading
+ * two bytes.
+ * @exception IOException if an I/O error occurs.
+ */
+ public short ReadShortLE() {
+ int ch1 = this.Read();
+ int ch2 = this.Read();
+ if ((ch1 | ch2) < 0)
+ throw new EndOfStreamException();
+ return (short)((ch2 << 8) + (ch1 << 0));
+ }
+
+ public int ReadUnsignedShort() {
+ int ch1 = this.Read();
+ int ch2 = this.Read();
+ if ((ch1 | ch2) < 0)
+ throw new EndOfStreamException();
+ return (ch1 << 8) + ch2;
+ }
+
+ /**
+ * Reads an unsigned 16-bit number from this stream in little-endian order.
+ * This method reads
+ * two bytes from the stream, starting at the current stream pointer.
+ * If the bytes read, in order, are
+ *
+ * This method blocks until the two bytes are read, the end of the
+ * stream is detected, or an exception is thrown.
+ *
+ * @return the next two bytes of this stream, interpreted as an
+ * unsigned 16-bit integer.
+ * @exception EOFException if this stream reaches the end before reading
+ * two bytes.
+ * @exception IOException if an I/O error occurs.
+ */
+ public int ReadUnsignedShortLE() {
+ int ch1 = this.Read();
+ int ch2 = this.Read();
+ if ((ch1 | ch2) < 0)
+ throw new EndOfStreamException();
+ return (ch2 << 8) + (ch1 << 0);
+ }
+
+ public char ReadChar() {
+ int ch1 = this.Read();
+ int ch2 = this.Read();
+ if ((ch1 | ch2) < 0)
+ throw new EndOfStreamException();
+ return (char)((ch1 << 8) + ch2);
+ }
+
+ /**
+ * Reads a Unicode character from this stream in little-endian order.
+ * This method reads two
+ * bytes from the stream, starting at the current stream pointer.
+ * If the bytes read, in order, are
+ *
+ * This method blocks until the two bytes are read, the end of the
+ * stream is detected, or an exception is thrown.
+ *
+ * @return the next two bytes of this stream as a Unicode character.
+ * @exception EOFException if this stream reaches the end before reading
+ * two bytes.
+ * @exception IOException if an I/O error occurs.
+ */
+ public char ReadCharLE() {
+ int ch1 = this.Read();
+ int ch2 = this.Read();
+ if ((ch1 | ch2) < 0)
+ throw new EndOfStreamException();
+ return (char)((ch2 << 8) + (ch1 << 0));
+ }
+
+ public int ReadInt() {
+ int ch1 = this.Read();
+ int ch2 = this.Read();
+ int ch3 = this.Read();
+ int ch4 = this.Read();
+ if ((ch1 | ch2 | ch3 | ch4) < 0)
+ throw new EndOfStreamException();
+ return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
+ }
+
+ /**
+ * Reads a signed 32-bit integer from this stream in little-endian order.
+ * This method reads 4
+ * bytes from the stream, starting at the current stream pointer.
+ * If the bytes read, in order, are
+ * This method blocks until the four bytes are read, the end of the
+ * stream is detected, or an exception is thrown.
+ *
+ * @return the next four bytes of this stream, interpreted as an
+ *
+ * This method blocks until the four bytes are read, the end of the
+ * stream is detected, or an exception is thrown.
+ *
+ * @return the next four bytes of this stream, interpreted as a
+ *
+ * The general systax is:
+ * You can have multiple ranges separated by commas ','. The '!' modifier removes the
+ * range from what is already selected. The range changes are incremental, that is,
+ * numbers are added or deleted as the range appears. The start or the end, but not both, can be ommited.
+ */
+ public class SequenceList {
+ protected const int COMMA = 1;
+ protected const int MINUS = 2;
+ protected const int NOT = 3;
+ protected const int TEXT = 4;
+ protected const int NUMBER = 5;
+ protected const int END = 6;
+ protected const char EOT = '\uffff';
+
+ private const int FIRST = 0;
+ private const int DIGIT = 1;
+ private const int OTHER = 2;
+ private const int DIGIT2 = 3;
+ private const String NOT_OTHER = "-,!0123456789";
+
+ protected char[] text;
+ protected int ptr;
+ protected int number;
+ protected String other;
+
+ protected int low;
+ protected int high;
+ protected bool odd;
+ protected bool even;
+ protected bool inverse;
+
+ protected SequenceList(String range) {
+ ptr = 0;
+ text = range.ToCharArray();
+ }
+
+ protected char NextChar() {
+ while (true) {
+ if (ptr >= text.Length)
+ return EOT;
+ char c = text[ptr++];
+ if (c > ' ')
+ return c;
+ }
+ }
+
+ protected void PutBack() {
+ --ptr;
+ if (ptr < 0)
+ ptr = 0;
+ }
+
+ protected int Type {
+ get {
+ StringBuilder buf = new StringBuilder();
+ int state = FIRST;
+ while (true) {
+ char c = NextChar();
+ if (c == EOT) {
+ if (state == DIGIT) {
+ number = int.Parse(other = buf.ToString());
+ return NUMBER;
+ }
+ else if (state == OTHER) {
+ other = buf.ToString().ToLower(System.Globalization.CultureInfo.InvariantCulture);
+ return TEXT;
+ }
+ return END;
+ }
+ switch (state) {
+ case FIRST:
+ switch (c) {
+ case '!':
+ return NOT;
+ case '-':
+ return MINUS;
+ case ',':
+ return COMMA;
+ }
+ buf.Append(c);
+ if (c >= '0' && c <= '9')
+ state = DIGIT;
+ else
+ state = OTHER;
+ break;
+ case DIGIT:
+ if (c >= '0' && c <= '9')
+ buf.Append(c);
+ else {
+ PutBack();
+ number = int.Parse(other = buf.ToString());
+ return NUMBER;
+ }
+ break;
+ case OTHER:
+ if (NOT_OTHER.IndexOf(c) < 0)
+ buf.Append(c);
+ else {
+ PutBack();
+ other = buf.ToString().ToLower(System.Globalization.CultureInfo.InvariantCulture);
+ return TEXT;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ private void OtherProc() {
+ if (other.Equals("odd") || other.Equals("o")) {
+ odd = true;
+ even = false;
+ }
+ else if (other.Equals("even") || other.Equals("e")) {
+ odd = false;
+ even = true;
+ }
+ }
+
+ protected bool GetAttributes() {
+ low = -1;
+ high = -1;
+ odd = even = inverse = false;
+ int state = OTHER;
+ while (true) {
+ int type = Type;
+ if (type == END || type == COMMA) {
+ if (state == DIGIT)
+ high = low;
+ return (type == END);
+ }
+ switch (state) {
+ case OTHER:
+ switch (type) {
+ case NOT:
+ inverse = true;
+ break;
+ case MINUS:
+ state = DIGIT2;
+ break;
+ default:
+ if (type == NUMBER) {
+ low = number;
+ state = DIGIT;
+ }
+ else
+ OtherProc();
+ break;
+ }
+ break;
+ case DIGIT:
+ switch (type) {
+ case NOT:
+ inverse = true;
+ state = OTHER;
+ high = low;
+ break;
+ case MINUS:
+ state = DIGIT2;
+ break;
+ default:
+ high = low;
+ state = OTHER;
+ OtherProc();
+ break;
+ }
+ break;
+ case DIGIT2:
+ switch (type) {
+ case NOT:
+ inverse = true;
+ state = OTHER;
+ break;
+ case MINUS:
+ break;
+ case NUMBER:
+ high = number;
+ state = OTHER;
+ break;
+ default:
+ state = OTHER;
+ OtherProc();
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * Generates a list of numbers from a string.
+ * @param ranges the comma separated ranges
+ * @param maxNumber the maximum number in the range
+ * @return a list with the numbers as
+ * The list structure is composed by a number of Hashtable, keyed by strings, one Hashtable
+ * for each bookmark.
+ * The element values are all strings with the exception of the key "Kids" that has
+ * another list for the child bookmarks.
+ *
+ * All the bookmarks have a "Title" with the
+ * bookmark title and optionally a "Style" that can be "bold", "italic" or a
+ * combination of both. They can also have a "Color" key with a value of three
+ * floats separated by spaces. The key "Open" can have the values "true" or "false" and
+ * signals the open status of the children. It's "true" by default.
+ *
+ * The actions and the parameters can be:
+ *
+ *
+ *
+ * The key is the code and the value is an
+ *
+ * An example:
+ *
+ *
+ * It is based in the JAI codec.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class BmpImage {
+
+ // BMP variables
+ private Stream inputStream;
+ private long bitmapFileSize;
+ private long bitmapOffset;
+ private long compression;
+ private long imageSize;
+ private byte[] palette;
+ private int imageType;
+ private int numBands;
+ private bool isBottomUp;
+ private int bitsPerPixel;
+ private int redMask, greenMask, blueMask, alphaMask;
+ public Hashtable properties = new Hashtable();
+ private long xPelsPerMeter;
+ private long yPelsPerMeter;
+ // BMP Image types
+ private const int VERSION_2_1_BIT = 0;
+ private const int VERSION_2_4_BIT = 1;
+ private const int VERSION_2_8_BIT = 2;
+ private const int VERSION_2_24_BIT = 3;
+
+ private const int VERSION_3_1_BIT = 4;
+ private const int VERSION_3_4_BIT = 5;
+ private const int VERSION_3_8_BIT = 6;
+ private const int VERSION_3_24_BIT = 7;
+
+ private const int VERSION_3_NT_16_BIT = 8;
+ private const int VERSION_3_NT_32_BIT = 9;
+
+ private const int VERSION_4_1_BIT = 10;
+ private const int VERSION_4_4_BIT = 11;
+ private const int VERSION_4_8_BIT = 12;
+ private const int VERSION_4_16_BIT = 13;
+ private const int VERSION_4_24_BIT = 14;
+ private const int VERSION_4_32_BIT = 15;
+
+ // Color space types
+ private const int LCS_CALIBRATED_RGB = 0;
+ private const int LCS_sRGB = 1;
+ private const int LCS_CMYK = 2;
+
+ // Compression Types
+ private const int BI_RGB = 0;
+ private const int BI_RLE8 = 1;
+ private const int BI_RLE4 = 2;
+ private const int BI_BITFIELDS = 3;
+
+ int width;
+ int height;
+
+ internal BmpImage(Stream isp, bool noHeader, int size) {
+ bitmapFileSize = size;
+ bitmapOffset = 0;
+ Process(isp, noHeader);
+ }
+
+ /** Reads a BMP from an url.
+ * @param url the url
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(Uri url) {
+ Stream isp = null;
+ try {
+ isp = WebRequest.Create(url).GetResponse().GetResponseStream();
+ Image img = GetImage(isp);
+ img.Url = url;
+ return img;
+ }
+ finally {
+ if (isp != null) {
+ isp.Close();
+ }
+ }
+ }
+
+ /** Reads a BMP from a stream. The stream is not closed.
+ * @param is the stream
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(Stream isp) {
+ return GetImage(isp, false, 0);
+ }
+
+ /** Reads a BMP from a stream. The stream is not closed.
+ * The BMP may not have a header and be considered as a plain DIB.
+ * @param is the stream
+ * @param noHeader true to process a plain DIB
+ * @param size the size of the DIB. Not used for a BMP
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(Stream isp, bool noHeader, int size) {
+ BmpImage bmp = new BmpImage(isp, noHeader, size);
+ Image img = bmp.GetImage();
+ img.SetDpi((int)((double)bmp.xPelsPerMeter * 0.0254 + 0.5), (int)((double)bmp.yPelsPerMeter * 0.0254 + 0.5));
+ img.OriginalType = Image.ORIGINAL_BMP;
+ return img;
+ }
+
+ /** Reads a BMP from a file.
+ * @param file the file
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(String file) {
+ return GetImage(Utilities.ToURL(file));
+ }
+
+ /** Reads a BMP from a byte array.
+ * @param data the byte array
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(byte[] data) {
+ Stream isp = new MemoryStream(data);
+ Image img = GetImage(isp);
+ img.OriginalData = data;
+ return img;
+ }
+
+
+ protected void Process(Stream stream, bool noHeader) {
+ if (noHeader || stream is BufferedStream) {
+ inputStream = stream;
+ } else {
+ inputStream = new BufferedStream(stream);
+ }
+ if (!noHeader) {
+ // Start File Header
+ if (!(ReadUnsignedByte(inputStream) == 'B' &&
+ ReadUnsignedByte(inputStream) == 'M')) {
+ throw new Exception("Invalid magic value for BMP file.");
+ }
+
+ // Read file size
+ bitmapFileSize = ReadDWord(inputStream);
+
+ // Read the two reserved fields
+ ReadWord(inputStream);
+ ReadWord(inputStream);
+
+ // Offset to the bitmap from the beginning
+ bitmapOffset = ReadDWord(inputStream);
+
+ // End File Header
+ }
+ // Start BitmapCoreHeader
+ long size = ReadDWord(inputStream);
+
+ if (size == 12) {
+ width = ReadWord(inputStream);
+ height = ReadWord(inputStream);
+ } else {
+ width = ReadLong(inputStream);
+ height = ReadLong(inputStream);
+ }
+
+ int planes = ReadWord(inputStream);
+ bitsPerPixel = ReadWord(inputStream);
+
+ properties["color_planes"] = planes;
+ properties["bits_per_pixel"] = bitsPerPixel;
+
+ // As BMP always has 3 rgb bands, except for Version 5,
+ // which is bgra
+ numBands = 3;
+ if (bitmapOffset == 0)
+ bitmapOffset = size;
+ if (size == 12) {
+ // Windows 2.x and OS/2 1.x
+ properties["bmp_version"] = "BMP v. 2.x";
+
+ // Classify the image type
+ if (bitsPerPixel == 1) {
+ imageType = VERSION_2_1_BIT;
+ } else if (bitsPerPixel == 4) {
+ imageType = VERSION_2_4_BIT;
+ } else if (bitsPerPixel == 8) {
+ imageType = VERSION_2_8_BIT;
+ } else if (bitsPerPixel == 24) {
+ imageType = VERSION_2_24_BIT;
+ }
+
+ // Read in the palette
+ int numberOfEntries = (int)((bitmapOffset-14-size) / 3);
+ int sizeOfPalette = numberOfEntries*3;
+ if (bitmapOffset == size) {
+ switch (imageType) {
+ case VERSION_2_1_BIT:
+ sizeOfPalette = 2 * 3;
+ break;
+ case VERSION_2_4_BIT:
+ sizeOfPalette = 16 * 3;
+ break;
+ case VERSION_2_8_BIT:
+ sizeOfPalette = 256 * 3;
+ break;
+ case VERSION_2_24_BIT:
+ sizeOfPalette = 0;
+ break;
+ }
+ bitmapOffset = size + sizeOfPalette;
+ }
+ ReadPalette(sizeOfPalette);
+ } else {
+
+ compression = ReadDWord(inputStream);
+ imageSize = ReadDWord(inputStream);
+ xPelsPerMeter = ReadLong(inputStream);
+ yPelsPerMeter = ReadLong(inputStream);
+ long colorsUsed = ReadDWord(inputStream);
+ long colorsImportant = ReadDWord(inputStream);
+
+ switch ((int)compression) {
+ case BI_RGB:
+ properties["compression"] = "BI_RGB";
+ break;
+
+ case BI_RLE8:
+ properties["compression"] = "BI_RLE8";
+ break;
+
+ case BI_RLE4:
+ properties["compression"] = "BI_RLE4";
+ break;
+
+ case BI_BITFIELDS:
+ properties["compression"] = "BI_BITFIELDS";
+ break;
+ }
+
+ properties["x_pixels_per_meter"] = xPelsPerMeter;
+ properties["y_pixels_per_meter"] = yPelsPerMeter;
+ properties["colors_used"] = colorsUsed;
+ properties["colors_important"] = colorsImportant;
+
+ if (size == 40) {
+ // Windows 3.x and Windows NT
+ switch ((int)compression) {
+
+ case BI_RGB: // No compression
+ case BI_RLE8: // 8-bit RLE compression
+ case BI_RLE4: // 4-bit RLE compression
+
+ if (bitsPerPixel == 1) {
+ imageType = VERSION_3_1_BIT;
+ } else if (bitsPerPixel == 4) {
+ imageType = VERSION_3_4_BIT;
+ } else if (bitsPerPixel == 8) {
+ imageType = VERSION_3_8_BIT;
+ } else if (bitsPerPixel == 24) {
+ imageType = VERSION_3_24_BIT;
+ } else if (bitsPerPixel == 16) {
+ imageType = VERSION_3_NT_16_BIT;
+ redMask = 0x7C00;
+ greenMask = 0x3E0;
+ blueMask = 0x1F;
+ properties["red_mask"] = redMask;
+ properties["green_mask"] = greenMask;
+ properties["blue_mask"] = blueMask;
+ } else if (bitsPerPixel == 32) {
+ imageType = VERSION_3_NT_32_BIT;
+ redMask = 0x00FF0000;
+ greenMask = 0x0000FF00;
+ blueMask = 0x000000FF;
+ properties["red_mask"] = redMask;
+ properties["green_mask"] = greenMask;
+ properties["blue_mask"] = blueMask;
+ }
+
+ // Read in the palette
+ int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
+ int sizeOfPalette = numberOfEntries*4;
+ if (bitmapOffset == size) {
+ switch (imageType) {
+ case VERSION_3_1_BIT:
+ sizeOfPalette = (int)(colorsUsed == 0 ? 2 : colorsUsed) * 4;
+ break;
+ case VERSION_3_4_BIT:
+ sizeOfPalette = (int)(colorsUsed == 0 ? 16 : colorsUsed) * 4;
+ break;
+ case VERSION_3_8_BIT:
+ sizeOfPalette = (int)(colorsUsed == 0 ? 256 : colorsUsed) * 4;
+ break;
+ default:
+ sizeOfPalette = 0;
+ break;
+ }
+ bitmapOffset = size + sizeOfPalette;
+ }
+ ReadPalette(sizeOfPalette);
+ properties["bmp_version"] = "BMP v. 3.x";
+ break;
+
+ case BI_BITFIELDS:
+
+ if (bitsPerPixel == 16) {
+ imageType = VERSION_3_NT_16_BIT;
+ } else if (bitsPerPixel == 32) {
+ imageType = VERSION_3_NT_32_BIT;
+ }
+
+ // BitsField encoding
+ redMask = (int)ReadDWord(inputStream);
+ greenMask = (int)ReadDWord(inputStream);
+ blueMask = (int)ReadDWord(inputStream);
+
+ properties["red_mask"] = redMask;
+ properties["green_mask"] = greenMask;
+ properties["blue_mask"] = blueMask;
+
+ if (colorsUsed != 0) {
+ // there is a palette
+ sizeOfPalette = (int)colorsUsed*4;
+ ReadPalette(sizeOfPalette);
+ }
+
+ properties["bmp_version"] = "BMP v. 3.x NT";
+ break;
+
+ default:
+ throw new
+ Exception("Invalid compression specified in BMP file.");
+ }
+ } else if (size == 108) {
+ // Windows 4.x BMP
+
+ properties["bmp_version"] = "BMP v. 4.x";
+
+ // rgb masks, valid only if comp is BI_BITFIELDS
+ redMask = (int)ReadDWord(inputStream);
+ greenMask = (int)ReadDWord(inputStream);
+ blueMask = (int)ReadDWord(inputStream);
+ // Only supported for 32bpp BI_RGB argb
+ alphaMask = (int)ReadDWord(inputStream);
+ long csType = ReadDWord(inputStream);
+ int redX = ReadLong(inputStream);
+ int redY = ReadLong(inputStream);
+ int redZ = ReadLong(inputStream);
+ int greenX = ReadLong(inputStream);
+ int greenY = ReadLong(inputStream);
+ int greenZ = ReadLong(inputStream);
+ int blueX = ReadLong(inputStream);
+ int blueY = ReadLong(inputStream);
+ int blueZ = ReadLong(inputStream);
+ long gammaRed = ReadDWord(inputStream);
+ long gammaGreen = ReadDWord(inputStream);
+ long gammaBlue = ReadDWord(inputStream);
+
+ if (bitsPerPixel == 1) {
+ imageType = VERSION_4_1_BIT;
+ } else if (bitsPerPixel == 4) {
+ imageType = VERSION_4_4_BIT;
+ } else if (bitsPerPixel == 8) {
+ imageType = VERSION_4_8_BIT;
+ } else if (bitsPerPixel == 16) {
+ imageType = VERSION_4_16_BIT;
+ if ((int)compression == BI_RGB) {
+ redMask = 0x7C00;
+ greenMask = 0x3E0;
+ blueMask = 0x1F;
+ }
+ } else if (bitsPerPixel == 24) {
+ imageType = VERSION_4_24_BIT;
+ } else if (bitsPerPixel == 32) {
+ imageType = VERSION_4_32_BIT;
+ if ((int)compression == BI_RGB) {
+ redMask = 0x00FF0000;
+ greenMask = 0x0000FF00;
+ blueMask = 0x000000FF;
+ }
+ }
+
+ properties["red_mask"] = redMask;
+ properties["green_mask"] = greenMask;
+ properties["blue_mask"] = blueMask;
+ properties["alpha_mask"] = alphaMask;
+
+ // Read in the palette
+ int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
+ int sizeOfPalette = numberOfEntries*4;
+ if (bitmapOffset == size) {
+ switch (imageType) {
+ case VERSION_4_1_BIT:
+ sizeOfPalette = (int)(colorsUsed == 0 ? 2 : colorsUsed) * 4;
+ break;
+ case VERSION_4_4_BIT:
+ sizeOfPalette = (int)(colorsUsed == 0 ? 16 : colorsUsed) * 4;
+ break;
+ case VERSION_4_8_BIT:
+ sizeOfPalette = (int)(colorsUsed == 0 ? 256 : colorsUsed) * 4;
+ break;
+ default:
+ sizeOfPalette = 0;
+ break;
+ }
+ bitmapOffset = size + sizeOfPalette;
+ }
+ ReadPalette(sizeOfPalette);
+
+ switch ((int)csType) {
+ case LCS_CALIBRATED_RGB:
+ // All the new fields are valid only for this case
+ properties["color_space"] = "LCS_CALIBRATED_RGB";
+ properties["redX"] = redX;
+ properties["redY"] = redY;
+ properties["redZ"] = redZ;
+ properties["greenX"] = greenX;
+ properties["greenY"] = greenY;
+ properties["greenZ"] = greenZ;
+ properties["blueX"] = blueX;
+ properties["blueY"] = blueY;
+ properties["blueZ"] = blueZ;
+ properties["gamma_red"] = gammaRed;
+ properties["gamma_green"] = gammaGreen;
+ properties["gamma_blue"] = gammaBlue;
+
+ // break;
+ throw new
+ Exception("Not implemented yet.");
+
+ case LCS_sRGB:
+ // Default Windows color space
+ properties["color_space"] = "LCS_sRGB";
+ break;
+
+ case LCS_CMYK:
+ properties["color_space"] = "LCS_CMYK";
+ // break;
+ throw new
+ Exception("Not implemented yet.");
+ }
+
+ } else {
+ properties["bmp_version"] = "BMP v. 5.x";
+ throw new
+ Exception("BMP version 5 not implemented yet.");
+ }
+ }
+
+ if (height > 0) {
+ // bottom up image
+ isBottomUp = true;
+ } else {
+ // top down image
+ isBottomUp = false;
+ height = Math.Abs(height);
+ }
+ // When number of bitsPerPixel is <= 8, we use IndexColorModel.
+ if (bitsPerPixel == 1 || bitsPerPixel == 4 || bitsPerPixel == 8) {
+
+ numBands = 1;
+
+
+ // Create IndexColorModel from the palette.
+ byte[] r;
+ byte[] g;
+ byte[] b;
+ int sizep;
+ if (imageType == VERSION_2_1_BIT ||
+ imageType == VERSION_2_4_BIT ||
+ imageType == VERSION_2_8_BIT) {
+
+ sizep = palette.Length/3;
+
+ if (sizep > 256) {
+ sizep = 256;
+ }
+
+ int off;
+ r = new byte[sizep];
+ g = new byte[sizep];
+ b = new byte[sizep];
+ for (int i=0; i
+ * It is based in part in the JAI codec.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PngImage {
+ /** Some PNG specific values. */
+ public static int[] PNGID = {137, 80, 78, 71, 13, 10, 26, 10};
+
+ /** A PNG marker. */
+ public const String IHDR = "IHDR";
+
+ /** A PNG marker. */
+ public const String PLTE = "PLTE";
+
+ /** A PNG marker. */
+ public const String IDAT = "IDAT";
+
+ /** A PNG marker. */
+ public const String IEND = "IEND";
+
+ /** A PNG marker. */
+ public const String tRNS = "tRNS";
+
+ /** A PNG marker. */
+ public const String pHYs = "pHYs";
+
+ /** A PNG marker. */
+ public const String gAMA = "gAMA";
+
+ /** A PNG marker. */
+ public const String cHRM = "cHRM";
+
+ /** A PNG marker. */
+ public const String sRGB = "sRGB";
+
+ /** A PNG marker. */
+ public const String iCCP = "iCCP";
+
+ private const int TRANSFERSIZE = 4096;
+ private const int PNG_FILTER_NONE = 0;
+ private const int PNG_FILTER_SUB = 1;
+ private const int PNG_FILTER_UP = 2;
+ private const int PNG_FILTER_AVERAGE = 3;
+ private const int PNG_FILTER_PAETH = 4;
+ private static PdfName[] intents = {PdfName.PERCEPTUAL,
+ PdfName.RELATIVECALORIMETRIC,PdfName.SATURATION,PdfName.ABSOLUTECALORIMETRIC};
+
+ Stream isp;
+ Stream dataStream;
+ int width;
+ int height;
+ int bitDepth;
+ int colorType;
+ int compressionMethod;
+ int filterMethod;
+ int interlaceMethod;
+ PdfDictionary additional = new PdfDictionary();
+ byte[] image;
+ byte[] smask;
+ byte[] trans;
+ MemoryStream idat = new MemoryStream();
+ int dpiX;
+ int dpiY;
+ float XYRatio;
+ bool genBWMask;
+ bool palShades;
+ int transRedGray = -1;
+ int transGreen = -1;
+ int transBlue = -1;
+ int inputBands;
+ int bytesPerPixel; // number of bytes per input pixel
+ byte[] colorTable;
+ float gamma = 1f;
+ bool hasCHRM = false;
+ float xW, yW, xR, yR, xG, yG, xB, yB;
+ PdfName intent;
+ ICC_Profile icc_profile;
+
+
+
+ /** Creates a new instance of PngImage */
+ PngImage(Stream isp) {
+ this.isp = isp;
+ }
+
+ /** Reads a PNG from an url.
+ * @param url the url
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(Uri url) {
+ Stream isp = null;
+ try {
+ isp = WebRequest.Create(url).GetResponse().GetResponseStream();
+ Image img = GetImage(isp);
+ img.Url = url;
+ return img;
+ }
+ finally {
+ if (isp != null) {
+ isp.Close();
+ }
+ }
+ }
+
+ /** Reads a PNG from a stream.
+ * @param is the stream
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(Stream isp) {
+ PngImage png = new PngImage(isp);
+ return png.GetImage();
+ }
+
+ /** Reads a PNG from a file.
+ * @param file the file
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(String file) {
+ return GetImage(Utilities.ToURL(file));
+ }
+
+ /** Reads a PNG from a byte array.
+ * @param data the byte array
+ * @throws IOException on error
+ * @return the image
+ */
+ public static Image GetImage(byte[] data) {
+ Stream isp = new MemoryStream(data);
+ Image img = GetImage(isp);
+ img.OriginalData = data;
+ return img;
+ }
+
+ static bool CheckMarker(String s) {
+ if (s.Length != 4)
+ return false;
+ for (int k = 0; k < 4; ++k) {
+ char c = s[k];
+ if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
+ return false;
+ }
+ return true;
+ }
+
+ void ReadPng() {
+ for (int i = 0; i < PNGID.Length; i++) {
+ if (PNGID[i] != isp.ReadByte()) {
+ throw new IOException("File is not a valid PNG.");
+ }
+ }
+ byte[] buffer = new byte[TRANSFERSIZE];
+ while (true) {
+ int len = GetInt(isp);
+ String marker = GetString(isp);
+ if (len < 0 || !CheckMarker(marker))
+ throw new IOException("Corrupted PNG file.");
+ if (IDAT.Equals(marker)) {
+ int size;
+ while (len != 0) {
+ size = isp.Read(buffer, 0, Math.Min(len, TRANSFERSIZE));
+ if (size <= 0)
+ return;
+ idat.Write(buffer, 0, size);
+ len -= size;
+ }
+ }
+ else if (tRNS.Equals(marker)) {
+ switch (colorType) {
+ case 0:
+ if (len >= 2) {
+ len -= 2;
+ int gray = GetWord(isp);
+ if (bitDepth == 16)
+ transRedGray = gray;
+ else
+ additional.Put(PdfName.MASK, new PdfLiteral("["+gray+" "+gray+"]"));
+ }
+ break;
+ case 2:
+ if (len >= 6) {
+ len -= 6;
+ int red = GetWord(isp);
+ int green = GetWord(isp);
+ int blue = GetWord(isp);
+ if (bitDepth == 16) {
+ transRedGray = red;
+ transGreen = green;
+ transBlue = blue;
+ }
+ else
+ additional.Put(PdfName.MASK, new PdfLiteral("["+red+" "+red+" "+green+" "+green+" "+blue+" "+blue+"]"));
+ }
+ break;
+ case 3:
+ if (len > 0) {
+ trans = new byte[len];
+ for (int k = 0; k < len; ++k)
+ trans[k] = (byte)isp.ReadByte();
+ len = 0;
+ }
+ break;
+ }
+ Utilities.Skip(isp, len);
+ }
+ else if (IHDR.Equals(marker)) {
+ width = GetInt(isp);
+ height = GetInt(isp);
+
+ bitDepth = isp.ReadByte();
+ colorType = isp.ReadByte();
+ compressionMethod = isp.ReadByte();
+ filterMethod = isp.ReadByte();
+ interlaceMethod = isp.ReadByte();
+ }
+ else if (PLTE.Equals(marker)) {
+ if (colorType == 3) {
+ PdfArray colorspace = new PdfArray();
+ colorspace.Add(PdfName.INDEXED);
+ colorspace.Add(GetColorspace());
+ colorspace.Add(new PdfNumber(len / 3 - 1));
+ ByteBuffer colortable = new ByteBuffer();
+ while ((len--) > 0) {
+ colortable.Append_i(isp.ReadByte());
+ }
+ colorspace.Add(new PdfString(colorTable = colortable.ToByteArray()));
+ additional.Put(PdfName.COLORSPACE, colorspace);
+ }
+ else {
+ Utilities.Skip(isp, len);
+ }
+ }
+ else if (pHYs.Equals(marker)) {
+ int dx = GetInt(isp);
+ int dy = GetInt(isp);
+ int unit = isp.ReadByte();
+ if (unit == 1) {
+ dpiX = (int)((float)dx * 0.0254f + 0.5f);
+ dpiY = (int)((float)dy * 0.0254f + 0.5f);
+ }
+ else {
+ if (dy != 0)
+ XYRatio = (float)dx / (float)dy;
+ }
+ }
+ else if (cHRM.Equals(marker)) {
+ xW = (float)GetInt(isp) / 100000f;
+ yW = (float)GetInt(isp) / 100000f;
+ xR = (float)GetInt(isp) / 100000f;
+ yR = (float)GetInt(isp) / 100000f;
+ xG = (float)GetInt(isp) / 100000f;
+ yG = (float)GetInt(isp) / 100000f;
+ xB = (float)GetInt(isp) / 100000f;
+ yB = (float)GetInt(isp) / 100000f;
+ hasCHRM = !(Math.Abs(xW)<0.0001f||Math.Abs(yW)<0.0001f||Math.Abs(xR)<0.0001f||Math.Abs(yR)<0.0001f||Math.Abs(xG)<0.0001f||Math.Abs(yG)<0.0001f||Math.Abs(xB)<0.0001f||Math.Abs(yB)<0.0001f);
+ }
+ else if (sRGB.Equals(marker)) {
+ int ri = isp.ReadByte();
+ intent = intents[ri];
+ gamma = 2.2f;
+ xW = 0.3127f;
+ yW = 0.329f;
+ xR = 0.64f;
+ yR = 0.33f;
+ xG = 0.3f;
+ yG = 0.6f;
+ xB = 0.15f;
+ yB = 0.06f;
+ hasCHRM = true;
+ }
+ else if (gAMA.Equals(marker)) {
+ int gm = GetInt(isp);
+ if (gm != 0) {
+ gamma = 100000f / (float)gm;
+ if (!hasCHRM) {
+ xW = 0.3127f;
+ yW = 0.329f;
+ xR = 0.64f;
+ yR = 0.33f;
+ xG = 0.3f;
+ yG = 0.6f;
+ xB = 0.15f;
+ yB = 0.06f;
+ hasCHRM = true;
+ }
+ }
+ }
+ else if (iCCP.Equals(marker)) {
+ do {
+ --len;
+ } while (isp.ReadByte() != 0);
+ isp.ReadByte();
+ --len;
+ byte[] icccom = new byte[len];
+ int p = 0;
+ while (len > 0) {
+ int r = isp.Read(icccom, p, len);
+ if (r < 0)
+ throw new IOException("Premature end of file.");
+ p += r;
+ len -= r;
+ }
+ byte[] iccp = PdfReader.FlateDecode(icccom, true);
+ icccom = null;
+ try {
+ icc_profile = ICC_Profile.GetInstance(iccp);
+ }
+ catch {
+ icc_profile = null;
+ }
+ }
+ else if (IEND.Equals(marker)) {
+ break;
+ }
+ else {
+ Utilities.Skip(isp, len);
+ }
+ Utilities.Skip(isp, 4);
+ }
+ }
+
+ PdfObject GetColorspace() {
+ if (icc_profile != null) {
+ if ((colorType & 2) == 0)
+ return PdfName.DEVICEGRAY;
+ else
+ return PdfName.DEVICERGB;
+ }
+ if (gamma == 1f && !hasCHRM) {
+ if ((colorType & 2) == 0)
+ return PdfName.DEVICEGRAY;
+ else
+ return PdfName.DEVICERGB;
+ }
+ else {
+ PdfArray array = new PdfArray();
+ PdfDictionary dic = new PdfDictionary();
+ if ((colorType & 2) == 0) {
+ if (gamma == 1f)
+ return PdfName.DEVICEGRAY;
+ array.Add(PdfName.CALGRAY);
+ dic.Put(PdfName.GAMMA, new PdfNumber(gamma));
+ dic.Put(PdfName.WHITEPOINT, new PdfLiteral("[1 1 1]"));
+ array.Add(dic);
+ }
+ else {
+ PdfObject wp = new PdfLiteral("[1 1 1]");
+ array.Add(PdfName.CALRGB);
+ if (gamma != 1f) {
+ PdfArray gm = new PdfArray();
+ PdfNumber n = new PdfNumber(gamma);
+ gm.Add(n);
+ gm.Add(n);
+ gm.Add(n);
+ dic.Put(PdfName.GAMMA, gm);
+ }
+ if (hasCHRM) {
+ float z = yW*((xG-xB)*yR-(xR-xB)*yG+(xR-xG)*yB);
+ float YA = yR*((xG-xB)*yW-(xW-xB)*yG+(xW-xG)*yB)/z;
+ float XA = YA*xR/yR;
+ float ZA = YA*((1-xR)/yR-1);
+ float YB = -yG*((xR-xB)*yW-(xW-xB)*yR+(xW-xR)*yB)/z;
+ float XB = YB*xG/yG;
+ float ZB = YB*((1-xG)/yG-1);
+ float YC = yB*((xR-xG)*yW-(xW-xG)*yW+(xW-xR)*yG)/z;
+ float XC = YC*xB/yB;
+ float ZC = YC*((1-xB)/yB-1);
+ float XW = XA+XB+XC;
+ float YW = 1;//YA+YB+YC;
+ float ZW = ZA+ZB+ZC;
+ PdfArray wpa = new PdfArray();
+ wpa.Add(new PdfNumber(XW));
+ wpa.Add(new PdfNumber(YW));
+ wpa.Add(new PdfNumber(ZW));
+ wp = wpa;
+ PdfArray matrix = new PdfArray();
+ matrix.Add(new PdfNumber(XA));
+ matrix.Add(new PdfNumber(YA));
+ matrix.Add(new PdfNumber(ZA));
+ matrix.Add(new PdfNumber(XB));
+ matrix.Add(new PdfNumber(YB));
+ matrix.Add(new PdfNumber(ZB));
+ matrix.Add(new PdfNumber(XC));
+ matrix.Add(new PdfNumber(YC));
+ matrix.Add(new PdfNumber(ZC));
+ dic.Put(PdfName.MATRIX, matrix);
+ }
+ dic.Put(PdfName.WHITEPOINT, wp);
+ array.Add(dic);
+ }
+ return array;
+ }
+ }
+
+ Image GetImage() {
+ ReadPng();
+ int pal0 = 0;
+ int palIdx = 0;
+ palShades = false;
+ if (trans != null) {
+ for (int k = 0; k < trans.Length; ++k) {
+ int n = trans[k] & 0xff;
+ if (n == 0) {
+ ++pal0;
+ palIdx = k;
+ }
+ if (n != 0 && n != 255) {
+ palShades = true;
+ break;
+ }
+ }
+ }
+ if ((colorType & 4) != 0)
+ palShades = true;
+ genBWMask = (!palShades && (pal0 > 1 || transRedGray >= 0));
+ if (!palShades && !genBWMask && pal0 == 1) {
+ additional.Put(PdfName.MASK, new PdfLiteral("["+palIdx+" "+palIdx+"]"));
+ }
+ bool needDecode = (interlaceMethod == 1) || (bitDepth == 16) || ((colorType & 4) != 0) || palShades || genBWMask;
+ switch (colorType) {
+ case 0:
+ inputBands = 1;
+ break;
+ case 2:
+ inputBands = 3;
+ break;
+ case 3:
+ inputBands = 1;
+ break;
+ case 4:
+ inputBands = 2;
+ break;
+ case 6:
+ inputBands = 4;
+ break;
+ }
+ if (needDecode)
+ DecodeIdat();
+ int components = inputBands;
+ if ((colorType & 4) != 0)
+ --components;
+ int bpc = bitDepth;
+ if (bpc == 16)
+ bpc = 8;
+ Image img;
+ if (image != null)
+ img = Image.GetInstance(width, height, components, bpc, image);
+ else {
+ img = new ImgRaw(width, height, components, bpc, idat.ToArray());
+ img.Deflated = true;
+ PdfDictionary decodeparms = new PdfDictionary();
+ decodeparms.Put(PdfName.BITSPERCOMPONENT, new PdfNumber(bitDepth));
+ decodeparms.Put(PdfName.PREDICTOR, new PdfNumber(15));
+ decodeparms.Put(PdfName.COLUMNS, new PdfNumber(width));
+ decodeparms.Put(PdfName.COLORS, new PdfNumber((colorType == 3 || (colorType & 2) == 0) ? 1 : 3));
+ additional.Put(PdfName.DECODEPARMS, decodeparms);
+ }
+ if (additional.Get(PdfName.COLORSPACE) == null)
+ additional.Put(PdfName.COLORSPACE, GetColorspace());
+ if (intent != null)
+ additional.Put(PdfName.INTENT, intent);
+ if (additional.Size > 0)
+ img.Additional = additional;
+ if (icc_profile != null)
+ img.TagICC = icc_profile;
+ if (palShades) {
+ Image im2 = Image.GetInstance(width, height, 1, 8, smask);
+ im2.MakeMask();
+ img.ImageMask = im2;
+ }
+ if (genBWMask) {
+ Image im2 = Image.GetInstance(width, height, 1, 1, smask);
+ im2.MakeMask();
+ img.ImageMask = im2;
+ }
+ img.SetDpi(dpiX, dpiY);
+ img.XYRatio = XYRatio;
+ img.OriginalType = Image.ORIGINAL_PNG;
+ return img;
+ }
+
+ void DecodeIdat() {
+ int nbitDepth = bitDepth;
+ if (nbitDepth == 16)
+ nbitDepth = 8;
+ int size = -1;
+ bytesPerPixel = (bitDepth == 16) ? 2 : 1;
+ switch (colorType) {
+ case 0:
+ size = (nbitDepth * width + 7) / 8 * height;
+ break;
+ case 2:
+ size = width * 3 * height;
+ bytesPerPixel *= 3;
+ break;
+ case 3:
+ if (interlaceMethod == 1)
+ size = (nbitDepth * width + 7) / 8 * height;
+ bytesPerPixel = 1;
+ break;
+ case 4:
+ size = width * height;
+ bytesPerPixel *= 2;
+ break;
+ case 6:
+ size = width * 3 * height;
+ bytesPerPixel *= 4;
+ break;
+ }
+ if (size >= 0)
+ image = new byte[size];
+ if (palShades)
+ smask = new byte[width * height];
+ else if (genBWMask)
+ smask = new byte[(width + 7) / 8 * height];
+ idat.Position = 0;
+ dataStream = new ZInflaterInputStream(idat);
+
+ if (interlaceMethod != 1) {
+ DecodePass(0, 0, 1, 1, width, height);
+ }
+ else {
+ DecodePass(0, 0, 8, 8, (width + 7)/8, (height + 7)/8);
+ DecodePass(4, 0, 8, 8, (width + 3)/8, (height + 7)/8);
+ DecodePass(0, 4, 4, 8, (width + 3)/4, (height + 3)/8);
+ DecodePass(2, 0, 4, 4, (width + 1)/4, (height + 3)/4);
+ DecodePass(0, 2, 2, 4, (width + 1)/2, (height + 1)/4);
+ DecodePass(1, 0, 2, 2, width/2, (height + 1)/2);
+ DecodePass(0, 1, 1, 2, width, height/2);
+ }
+
+ }
+
+ void DecodePass( int xOffset, int yOffset,
+ int xStep, int yStep,
+ int passWidth, int passHeight) {
+ if ((passWidth == 0) || (passHeight == 0)) {
+ return;
+ }
+
+ int bytesPerRow = (inputBands*passWidth*bitDepth + 7)/8;
+ byte[] curr = new byte[bytesPerRow];
+ byte[] prior = new byte[bytesPerRow];
+
+ // Decode the (sub)image row-by-row
+ int srcY, dstY;
+ for (srcY = 0, dstY = yOffset;
+ srcY < passHeight;
+ srcY++, dstY += yStep) {
+ // Read the filter type byte and a row of data
+ int filter = 0;
+ try {
+ filter = dataStream.ReadByte();
+ ReadFully(dataStream,curr, 0, bytesPerRow);
+ } catch {
+ // empty on purpose
+ }
+
+ switch (filter) {
+ case PNG_FILTER_NONE:
+ break;
+ case PNG_FILTER_SUB:
+ DecodeSubFilter(curr, bytesPerRow, bytesPerPixel);
+ break;
+ case PNG_FILTER_UP:
+ DecodeUpFilter(curr, prior, bytesPerRow);
+ break;
+ case PNG_FILTER_AVERAGE:
+ DecodeAverageFilter(curr, prior, bytesPerRow, bytesPerPixel);
+ break;
+ case PNG_FILTER_PAETH:
+ DecodePaethFilter(curr, prior, bytesPerRow, bytesPerPixel);
+ break;
+ default:
+ // Error -- uknown filter type
+ throw new Exception("PNG filter unknown.");
+ }
+
+ ProcessPixels(curr, xOffset, xStep, dstY, passWidth);
+
+ // Swap curr and prior
+ byte[] tmp = prior;
+ prior = curr;
+ curr = tmp;
+ }
+ }
+
+ void ProcessPixels(byte[] curr, int xOffset, int step, int y, int width) {
+ int srcX, dstX;
+
+ int[] outp = GetPixel(curr);
+ int sizes = 0;
+ switch (colorType) {
+ case 0:
+ case 3:
+ case 4:
+ sizes = 1;
+ break;
+ case 2:
+ case 6:
+ sizes = 3;
+ break;
+ }
+ if (image != null) {
+ dstX = xOffset;
+ int yStride = (sizes*this.width*(bitDepth == 16 ? 8 : bitDepth)+ 7)/8;
+ for (srcX = 0; srcX < width; srcX++) {
+ SetPixel(image, outp, inputBands * srcX, sizes, dstX, y, bitDepth, yStride);
+ dstX += step;
+ }
+ }
+ if (palShades) {
+ if ((colorType & 4) != 0) {
+ if (bitDepth == 16) {
+ for (int k = 0; k < width; ++k) {
+ int t = k * inputBands + sizes;
+ outp[t] = Util.USR(outp[t], 8);
+ }
+ }
+ int yStride = this.width;
+ dstX = xOffset;
+ for (srcX = 0; srcX < width; srcX++) {
+ SetPixel(smask, outp, inputBands * srcX + sizes, 1, dstX, y, 8, yStride);
+ dstX += step;
+ }
+ }
+ else { //colorType 3
+ int yStride = this.width;
+ int[] v = new int[1];
+ dstX = xOffset;
+ for (srcX = 0; srcX < width; srcX++) {
+ int idx = outp[srcX];
+ if (idx < trans.Length)
+ v[0] = trans[idx];
+ SetPixel(smask, v, 0, 1, dstX, y, 8, yStride);
+ dstX += step;
+ }
+ }
+ }
+ else if (genBWMask) {
+ switch (colorType) {
+ case 3: {
+ int yStride = (this.width + 7) / 8;
+ int[] v = new int[1];
+ dstX = xOffset;
+ for (srcX = 0; srcX < width; srcX++) {
+ int idx = outp[srcX];
+ if (idx < trans.Length)
+ v[0] = (trans[idx] == 0 ? 1 : 0);
+ SetPixel(smask, v, 0, 1, dstX, y, 1, yStride);
+ dstX += step;
+ }
+ break;
+ }
+ case 0: {
+ int yStride = (this.width + 7) / 8;
+ int[] v = new int[1];
+ dstX = xOffset;
+ for (srcX = 0; srcX < width; srcX++) {
+ int g = outp[srcX];
+ v[0] = (g == transRedGray ? 1 : 0);
+ SetPixel(smask, v, 0, 1, dstX, y, 1, yStride);
+ dstX += step;
+ }
+ break;
+ }
+ case 2: {
+ int yStride = (this.width + 7) / 8;
+ int[] v = new int[1];
+ dstX = xOffset;
+ for (srcX = 0; srcX < width; srcX++) {
+ int markRed = inputBands * srcX;
+ v[0] = (outp[markRed] == transRedGray && outp[markRed + 1] == transGreen
+ && outp[markRed + 2] == transBlue ? 1 : 0);
+ SetPixel(smask, v, 0, 1, dstX, y, 1, yStride);
+ dstX += step;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ static int GetPixel(byte[] image, int x, int y, int bitDepth, int bytesPerRow) {
+ if (bitDepth == 8) {
+ int pos = bytesPerRow * y + x;
+ return image[pos] & 0xff;
+ }
+ else {
+ int pos = bytesPerRow * y + x / (8 / bitDepth);
+ int v = image[pos] >> (8 - bitDepth * (x % (8 / bitDepth))- bitDepth);
+ return v & ((1 << bitDepth) - 1);
+ }
+ }
+
+ static void SetPixel(byte[] image, int[] data, int offset, int size, int x, int y, int bitDepth, int bytesPerRow) {
+ if (bitDepth == 8) {
+ int pos = bytesPerRow * y + size * x;
+ for (int k = 0; k < size; ++k)
+ image[pos + k] = (byte)data[k + offset];
+ }
+ else if (bitDepth == 16) {
+ int pos = bytesPerRow * y + size * x;
+ for (int k = 0; k < size; ++k)
+ image[pos + k] = (byte)(data[k + offset] >> 8);
+ }
+ else {
+ int pos = bytesPerRow * y + x / (8 / bitDepth);
+ int v = data[offset] << (8 - bitDepth * (x % (8 / bitDepth))- bitDepth);
+ image[pos] |= (byte)v;
+ }
+ }
+
+ int[] GetPixel(byte[] curr) {
+ switch (bitDepth) {
+ case 8: {
+ int[] outp = new int[curr.Length];
+ for (int k = 0; k < outp.Length; ++k)
+ outp[k] = curr[k] & 0xff;
+ return outp;
+ }
+ case 16: {
+ int[] outp = new int[curr.Length / 2];
+ for (int k = 0; k < outp.Length; ++k)
+ outp[k] = ((curr[k * 2] & 0xff) << 8) + (curr[k * 2 + 1] & 0xff);
+ return outp;
+ }
+ default: {
+ int[] outp = new int[curr.Length * 8 / bitDepth];
+ int idx = 0;
+ int passes = 8 / bitDepth;
+ int mask = (1 << bitDepth) - 1;
+ for (int k = 0; k < curr.Length; ++k) {
+ for (int j = passes - 1; j >= 0; --j) {
+ outp[idx++] = Util.USR(curr[k], bitDepth * j) & mask;
+ }
+ }
+ return outp;
+ }
+ }
+ }
+
+ private static void DecodeSubFilter(byte[] curr, int count, int bpp) {
+ for (int i = bpp; i < count; i++) {
+ int val;
+
+ val = curr[i] & 0xff;
+ val += curr[i - bpp] & 0xff;
+
+ curr[i] = (byte)val;
+ }
+ }
+
+ private static void DecodeUpFilter(byte[] curr, byte[] prev,
+ int count) {
+ for (int i = 0; i < count; i++) {
+ int raw = curr[i] & 0xff;
+ int prior = prev[i] & 0xff;
+
+ curr[i] = (byte)(raw + prior);
+ }
+ }
+
+ private static void DecodeAverageFilter(byte[] curr, byte[] prev,
+ int count, int bpp) {
+ int raw, priorPixel, priorRow;
+
+ for (int i = 0; i < bpp; i++) {
+ raw = curr[i] & 0xff;
+ priorRow = prev[i] & 0xff;
+
+ curr[i] = (byte)(raw + priorRow/2);
+ }
+
+ for (int i = bpp; i < count; i++) {
+ raw = curr[i] & 0xff;
+ priorPixel = curr[i - bpp] & 0xff;
+ priorRow = prev[i] & 0xff;
+
+ curr[i] = (byte)(raw + (priorPixel + priorRow)/2);
+ }
+ }
+
+ private static int PaethPredictor(int a, int b, int c) {
+ int p = a + b - c;
+ int pa = Math.Abs(p - a);
+ int pb = Math.Abs(p - b);
+ int pc = Math.Abs(p - c);
+
+ if ((pa <= pb) && (pa <= pc)) {
+ return a;
+ } else if (pb <= pc) {
+ return b;
+ } else {
+ return c;
+ }
+ }
+
+ private static void DecodePaethFilter(byte[] curr, byte[] prev,
+ int count, int bpp) {
+ int raw, priorPixel, priorRow, priorRowPixel;
+
+ for (int i = 0; i < bpp; i++) {
+ raw = curr[i] & 0xff;
+ priorRow = prev[i] & 0xff;
+
+ curr[i] = (byte)(raw + priorRow);
+ }
+
+ for (int i = bpp; i < count; i++) {
+ raw = curr[i] & 0xff;
+ priorPixel = curr[i - bpp] & 0xff;
+ priorRow = prev[i] & 0xff;
+ priorRowPixel = prev[i - bpp] & 0xff;
+
+ curr[i] = (byte)(raw + PaethPredictor(priorPixel,
+ priorRow,
+ priorRowPixel));
+ }
+ }
+
+ /**
+ * Gets an A TIFF IFD consists of a set of TIFFField tags. Methods are
+ * provided to query the set of tags and to obtain the raw field
+ * array. In addition, convenience methods are provided for acquiring
+ * the values of tags that contain a single value that fits into a
+ * byte, int, long, float, or double.
+ *
+ * Every TIFF file is made up of one or more public IFDs that are
+ * joined in a linked list, rooted in the file header. A file may
+ * also contain so-called private IFDs that are referenced from
+ * tag data and do not appear in the main list.
+ *
+ * This class is not a committed part of the JAI API. It may
+ * be removed or changed in future releases of JAI.
+ *
+ * @see TIFFField
+ */
+ public class TIFFDirectory {
+
+ /** A bool storing the endianness of the stream. */
+ bool isBigEndian;
+
+ /** The number of entries in the IFD. */
+ int numEntries;
+
+ /** An array of TIFFFields. */
+ TIFFField[] fields;
+
+ /** A Hashtable indexing the fields by tag number. */
+ Hashtable fieldIndex = new Hashtable();
+
+ /** The offset of this IFD. */
+ long IFDOffset = 8;
+
+ /** The offset of the next IFD. */
+ long nextIFDOffset = 0;
+
+ /** The default constructor. */
+ TIFFDirectory() {}
+
+ private static bool IsValidEndianTag(int endian) {
+ return ((endian == 0x4949) || (endian == 0x4d4d));
+ }
+
+ /**
+ * Constructs a TIFFDirectory from a SeekableStream.
+ * The directory parameter specifies which directory to read from
+ * the linked list present in the stream; directory 0 is normally
+ * read but it is possible to store multiple images in a single
+ * TIFF file by maintaing multiple directories.
+ *
+ * @param stream a SeekableStream to read from.
+ * @param directory the index of the directory to read.
+ */
+ public TIFFDirectory(RandomAccessFileOrArray stream, int directory)
+ {
+
+ long global_save_offset = stream.FilePointer;
+ long ifd_offset;
+
+ // Read the TIFF header
+ stream.Seek(0L);
+ int endian = stream.ReadUnsignedShort();
+ if (!IsValidEndianTag(endian)) {
+ throw new
+ ArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
+ }
+ isBigEndian = (endian == 0x4d4d);
+
+ int magic = ReadUnsignedShort(stream);
+ if (magic != 42) {
+ throw new
+ ArgumentException("Bad magic number, should be 42.");
+ }
+
+ // Get the initial ifd offset as an unsigned int (using a long)
+ ifd_offset = ReadUnsignedInt(stream);
+
+ for (int i = 0; i < directory; i++) {
+ if (ifd_offset == 0L) {
+ throw new
+ ArgumentException("Directory number too large.");
+ }
+
+ stream.Seek(ifd_offset);
+ int entries = ReadUnsignedShort(stream);
+ stream.Skip(12*entries);
+
+ ifd_offset = ReadUnsignedInt(stream);
+ }
+
+ stream.Seek(ifd_offset);
+ Initialize(stream);
+ stream.Seek(global_save_offset);
+ }
+
+ /**
+ * Constructs a TIFFDirectory by reading a SeekableStream.
+ * The ifd_offset parameter specifies the stream offset from which
+ * to begin reading; this mechanism is sometimes used to store
+ * private IFDs within a TIFF file that are not part of the normal
+ * sequence of IFDs.
+ *
+ * @param stream a SeekableStream to read from.
+ * @param ifd_offset the long byte offset of the directory.
+ * @param directory the index of the directory to read beyond the
+ * one at the current stream offset; zero indicates the IFD
+ * at the current offset.
+ */
+ public TIFFDirectory(RandomAccessFileOrArray stream, long ifd_offset, int directory)
+ {
+
+ long global_save_offset = stream.FilePointer;
+ stream.Seek(0L);
+ int endian = stream.ReadUnsignedShort();
+ if (!IsValidEndianTag(endian)) {
+ throw new
+ ArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
+ }
+ isBigEndian = (endian == 0x4d4d);
+
+ // Seek to the first IFD.
+ stream.Seek(ifd_offset);
+
+ // Seek to desired IFD if necessary.
+ int dirNum = 0;
+ while (dirNum < directory) {
+ // Get the number of fields in the current IFD.
+ int numEntries = ReadUnsignedShort(stream);
+
+ // Skip to the next IFD offset value field.
+ stream.Seek(ifd_offset + 12*numEntries);
+
+ // Read the offset to the next IFD beyond this one.
+ ifd_offset = ReadUnsignedInt(stream);
+
+ // Seek to the next IFD.
+ stream.Seek(ifd_offset);
+
+ // Increment the directory.
+ dirNum++;
+ }
+
+ Initialize(stream);
+ stream.Seek(global_save_offset);
+ }
+
+ private static int[] sizeOfType = {
+ 0, // 0 = n/a
+ 1, // 1 = byte
+ 1, // 2 = ascii
+ 2, // 3 = short
+ 4, // 4 = long
+ 8, // 5 = rational
+ 1, // 6 = sbyte
+ 1, // 7 = undefined
+ 2, // 8 = sshort
+ 4, // 9 = slong
+ 8, // 10 = srational
+ 4, // 11 = float
+ 8 // 12 = double
+ };
+
+ private void Initialize(RandomAccessFileOrArray stream) {
+ long nextTagOffset = 0L;
+ long maxOffset = (long) stream.Length;
+ int i, j;
+
+ IFDOffset = stream.FilePointer;
+
+ numEntries = ReadUnsignedShort(stream);
+ fields = new TIFFField[numEntries];
+
+ for (i = 0; (i < numEntries) && (nextTagOffset < maxOffset); i++) {
+ int tag = ReadUnsignedShort(stream);
+ int type = ReadUnsignedShort(stream);
+ int count = (int)(ReadUnsignedInt(stream));
+ bool processTag = true;
+
+ // The place to return to to read the next tag
+ nextTagOffset = stream.FilePointer + 4;
+
+ try {
+ // If the tag data can't fit in 4 bytes, the next 4 bytes
+ // contain the starting offset of the data
+ if (count*sizeOfType[type] > 4) {
+ long valueOffset = ReadUnsignedInt(stream);
+
+ // bounds check offset for EOF
+ if (valueOffset < maxOffset) {
+ stream.Seek(valueOffset);
+ }
+ else {
+ // bad offset pointer .. skip tag
+ processTag = false;
+ }
+ }
+ } catch (ArgumentOutOfRangeException) {
+ // if the data type is unknown we should skip this TIFF Field
+ processTag = false;
+ }
+
+ if (processTag) {
+ fieldIndex[tag] = i;
+ Object obj = null;
+
+ switch (type) {
+ case TIFFField.TIFF_BYTE:
+ case TIFFField.TIFF_SBYTE:
+ case TIFFField.TIFF_UNDEFINED:
+ case TIFFField.TIFF_ASCII:
+ byte[] bvalues = new byte[count];
+ stream.ReadFully(bvalues, 0, count);
+
+ if (type == TIFFField.TIFF_ASCII) {
+
+ // Can be multiple strings
+ int index = 0, prevIndex = 0;
+ ArrayList v = new ArrayList();
+
+ while (index < count) {
+
+ while ((index < count) && (bvalues[index++] != 0));
+
+ // When we encountered zero, means one string has ended
+ char[] cht = new char[index - prevIndex];
+ Array.Copy(bvalues, prevIndex, cht, 0, index - prevIndex);
+ v.Add(new String(cht));
+ prevIndex = index;
+ }
+
+ count = v.Count;
+ String[] strings = new String[count];
+ for (int c = 0 ; c < count; c++) {
+ strings[c] = (String)v[c];
+ }
+
+ obj = strings;
+ } else {
+ obj = bvalues;
+ }
+
+ break;
+
+ case TIFFField.TIFF_SHORT:
+ char[] cvalues = new char[count];
+ for (j = 0; j < count; j++) {
+ cvalues[j] = (char)(ReadUnsignedShort(stream));
+ }
+ obj = cvalues;
+ break;
+
+ case TIFFField.TIFF_LONG:
+ long[] lvalues = new long[count];
+ for (j = 0; j < count; j++) {
+ lvalues[j] = ReadUnsignedInt(stream);
+ }
+ obj = lvalues;
+ break;
+
+ case TIFFField.TIFF_RATIONAL:
+ long[][] llvalues = new long[count][];
+ for (j = 0; j < count; j++) {
+ long v0 = ReadUnsignedInt(stream);
+ long v1 = ReadUnsignedInt(stream);
+ llvalues[j] = new long[]{v0, v1};
+ }
+ obj = llvalues;
+ break;
+
+ case TIFFField.TIFF_SSHORT:
+ short[] svalues = new short[count];
+ for (j = 0; j < count; j++) {
+ svalues[j] = ReadShort(stream);
+ }
+ obj = svalues;
+ break;
+
+ case TIFFField.TIFF_SLONG:
+ int[] ivalues = new int[count];
+ for (j = 0; j < count; j++) {
+ ivalues[j] = ReadInt(stream);
+ }
+ obj = ivalues;
+ break;
+
+ case TIFFField.TIFF_SRATIONAL:
+ int[,] iivalues = new int[count,2];
+ for (j = 0; j < count; j++) {
+ iivalues[j,0] = ReadInt(stream);
+ iivalues[j,1] = ReadInt(stream);
+ }
+ obj = iivalues;
+ break;
+
+ case TIFFField.TIFF_FLOAT:
+ float[] fvalues = new float[count];
+ for (j = 0; j < count; j++) {
+ fvalues[j] = ReadFloat(stream);
+ }
+ obj = fvalues;
+ break;
+
+ case TIFFField.TIFF_DOUBLE:
+ double[] dvalues = new double[count];
+ for (j = 0; j < count; j++) {
+ dvalues[j] = ReadDouble(stream);
+ }
+ obj = dvalues;
+ break;
+
+ default:
+ break;
+ }
+
+ fields[i] = new TIFFField(tag, type, count, obj);
+ }
+
+ stream.Seek(nextTagOffset);
+ }
+
+ // Read the offset of the next IFD.
+ try {
+ nextIFDOffset = ReadUnsignedInt(stream);
+ }
+ catch {
+ // broken tiffs may not have this pointer
+ nextIFDOffset = 0;
+ }
+ }
+
+ /** Returns the number of directory entries. */
+ public int GetNumEntries() {
+ return numEntries;
+ }
+
+ /**
+ * Returns the value of a given tag as a TIFFField,
+ * or null if the tag is not present.
+ */
+ public TIFFField GetField(int tag) {
+ object i = fieldIndex[tag];
+ if (i == null) {
+ return null;
+ } else {
+ return fields[(int)i];
+ }
+ }
+
+ /**
+ * Returns true if a tag appears in the directory.
+ */
+ public bool IsTagPresent(int tag) {
+ return fieldIndex.ContainsKey(tag);
+ }
+
+ /**
+ * Returns an ordered array of ints indicating the tag
+ * values.
+ */
+ public int[] GetTags() {
+ int[] tags = new int[fieldIndex.Count];
+ fieldIndex.Keys.CopyTo(tags, 0);
+ return tags;
+ }
+
+ /**
+ * Returns an array of TIFFFields containing all the fields
+ * in this directory.
+ */
+ public TIFFField[] GetFields() {
+ return fields;
+ }
+
+ /**
+ * Returns the value of a particular index of a given tag as a
+ * byte. The caller is responsible for ensuring that the tag is
+ * present and has type TIFFField.TIFF_SBYTE, TIFF_BYTE, or
+ * TIFF_UNDEFINED.
+ */
+ public byte GetFieldAsByte(int tag, int index) {
+ int i = (int)fieldIndex[tag];
+ byte [] b = (fields[(int)i]).GetAsBytes();
+ return b[index];
+ }
+
+ /**
+ * Returns the value of index 0 of a given tag as a
+ * byte. The caller is responsible for ensuring that the tag is
+ * present and has type TIFFField.TIFF_SBYTE, TIFF_BYTE, or
+ * TIFF_UNDEFINED.
+ */
+ public byte GetFieldAsByte(int tag) {
+ return GetFieldAsByte(tag, 0);
+ }
+
+ /**
+ * Returns the value of a particular index of a given tag as a
+ * long. The caller is responsible for ensuring that the tag is
+ * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED,
+ * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG.
+ */
+ public long GetFieldAsLong(int tag, int index) {
+ int i = (int)fieldIndex[tag];
+ return (fields[i]).GetAsLong(index);
+ }
+
+ /**
+ * Returns the value of index 0 of a given tag as a
+ * long. The caller is responsible for ensuring that the tag is
+ * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED,
+ * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG.
+ */
+ public long GetFieldAsLong(int tag) {
+ return GetFieldAsLong(tag, 0);
+ }
+
+ /**
+ * Returns the value of a particular index of a given tag as a
+ * float. The caller is responsible for ensuring that the tag is
+ * present and has numeric type (all but TIFF_UNDEFINED and
+ * TIFF_ASCII).
+ */
+ public float GetFieldAsFloat(int tag, int index) {
+ int i = (int)fieldIndex[tag];
+ return fields[i].GetAsFloat(index);
+ }
+
+ /**
+ * Returns the value of index 0 of a given tag as a float. The
+ * caller is responsible for ensuring that the tag is present and
+ * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII).
+ */
+ public float GetFieldAsFloat(int tag) {
+ return GetFieldAsFloat(tag, 0);
+ }
+
+ /**
+ * Returns the value of a particular index of a given tag as a
+ * double. The caller is responsible for ensuring that the tag is
+ * present and has numeric type (all but TIFF_UNDEFINED and
+ * TIFF_ASCII).
+ */
+ public double GetFieldAsDouble(int tag, int index) {
+ int i = (int)fieldIndex[tag];
+ return fields[i].GetAsDouble(index);
+ }
+
+ /**
+ * Returns the value of index 0 of a given tag as a double. The
+ * caller is responsible for ensuring that the tag is present and
+ * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII).
+ */
+ public double GetFieldAsDouble(int tag) {
+ return GetFieldAsDouble(tag, 0);
+ }
+
+ // Methods to read primitive data types from the stream
+
+ private short ReadShort(RandomAccessFileOrArray stream)
+ {
+ if (isBigEndian) {
+ return stream.ReadShort();
+ } else {
+ return stream.ReadShortLE();
+ }
+ }
+
+ private int ReadUnsignedShort(RandomAccessFileOrArray stream)
+ {
+ if (isBigEndian) {
+ return stream.ReadUnsignedShort();
+ } else {
+ return stream.ReadUnsignedShortLE();
+ }
+ }
+
+ private int ReadInt(RandomAccessFileOrArray stream)
+ {
+ if (isBigEndian) {
+ return stream.ReadInt();
+ } else {
+ return stream.ReadIntLE();
+ }
+ }
+
+ private long ReadUnsignedInt(RandomAccessFileOrArray stream)
+ {
+ if (isBigEndian) {
+ return stream.ReadUnsignedInt();
+ } else {
+ return stream.ReadUnsignedIntLE();
+ }
+ }
+
+ private long ReadLong(RandomAccessFileOrArray stream)
+ {
+ if (isBigEndian) {
+ return stream.ReadLong();
+ } else {
+ return stream.ReadLongLE();
+ }
+ }
+
+ private float ReadFloat(RandomAccessFileOrArray stream)
+ {
+ if (isBigEndian) {
+ return stream.ReadFloat();
+ } else {
+ return stream.ReadFloatLE();
+ }
+ }
+
+ private double ReadDouble(RandomAccessFileOrArray stream)
+ {
+ if (isBigEndian) {
+ return stream.ReadDouble();
+ } else {
+ return stream.ReadDoubleLE();
+ }
+ }
+
+ private static int ReadUnsignedShort(RandomAccessFileOrArray stream,
+ bool isBigEndian)
+ {
+ if (isBigEndian) {
+ return stream.ReadUnsignedShort();
+ } else {
+ return stream.ReadUnsignedShortLE();
+ }
+ }
+
+ private static long ReadUnsignedInt(RandomAccessFileOrArray stream,
+ bool isBigEndian)
+ {
+ if (isBigEndian) {
+ return stream.ReadUnsignedInt();
+ } else {
+ return stream.ReadUnsignedIntLE();
+ }
+ }
+
+ // Utilities
+
+ /**
+ * Returns the number of image directories (subimages) stored in a
+ * given TIFF file, represented by a The TIFF file format is described in more detail in the
+ * comments for the TIFFDescriptor class.
+ *
+ * A field in a TIFF Image File Directory (IFD). A field is defined
+ * as a sequence of values of identical data type. TIFF 6.0 defines
+ * 12 data types, which are mapped internally onto the Java datatypes
+ * byte, int, long, float, and double.
+ *
+ * This class is not a committed part of the JAI API. It may
+ * be removed or changed in future releases of JAI.
+ *
+ * @see TIFFDirectory
+ */
+ public class TIFFField : IComparable {
+
+ /** Flag for 8 bit unsigned integers. */
+ public const int TIFF_BYTE = 1;
+
+ /** Flag for null-terminated ASCII strings. */
+ public const int TIFF_ASCII = 2;
+
+ /** Flag for 16 bit unsigned integers. */
+ public const int TIFF_SHORT = 3;
+
+ /** Flag for 32 bit unsigned integers. */
+ public const int TIFF_LONG = 4;
+
+ /** Flag for pairs of 32 bit unsigned integers. */
+ public const int TIFF_RATIONAL = 5;
+
+ /** Flag for 8 bit signed integers. */
+ public const int TIFF_SBYTE = 6;
+
+ /** Flag for 8 bit uninterpreted bytes. */
+ public const int TIFF_UNDEFINED = 7;
+
+ /** Flag for 16 bit signed integers. */
+ public const int TIFF_SSHORT = 8;
+
+ /** Flag for 32 bit signed integers. */
+ public const int TIFF_SLONG = 9;
+
+ /** Flag for pairs of 32 bit signed integers. */
+ public const int TIFF_SRATIONAL = 10;
+
+ /** Flag for 32 bit IEEE floats. */
+ public const int TIFF_FLOAT = 11;
+
+ /** Flag for 64 bit IEEE doubles. */
+ public const int TIFF_DOUBLE = 12;
+
+ /** The tag number. */
+ int tag;
+
+ /** The tag type. */
+ int type;
+
+ /** The number of data items present in the field. */
+ int count;
+
+ /** The field data. */
+ Object data;
+
+ /** The default constructor. */
+ internal TIFFField() {}
+
+ /**
+ * Constructs a TIFFField with arbitrary data. The data
+ * parameter must be an array of a Java type appropriate for the
+ * type of the TIFF field. Since there is no available 32-bit
+ * unsigned datatype, long is used. The mapping between types is
+ * as follows:
+ *
+ * For data in TIFF_BYTE format, the application must take
+ * care when promoting the data to longer integral types
+ * to avoid sign extension.
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_BYTE, TIFF_SBYTE, or TIFF_UNDEFINED.
+ */
+ public byte[] GetAsBytes() {
+ return (byte[])data;
+ }
+
+ /**
+ * Returns TIFF_SHORT data as an array of chars (unsigned 16-bit
+ * integers).
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_SHORT.
+ */
+ public char[] GetAsChars() {
+ return (char[])data;
+ }
+
+ /**
+ * Returns TIFF_SSHORT data as an array of shorts (signed 16-bit
+ * integers).
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_SSHORT.
+ */
+ public short[] GetAsShorts() {
+ return (short[])data;
+ }
+
+ /**
+ * Returns TIFF_SLONG data as an array of ints (signed 32-bit
+ * integers).
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_SLONG.
+ */
+ public int[] GetAsInts() {
+ return (int[])data;
+ }
+
+ /**
+ * Returns TIFF_LONG data as an array of longs (signed 64-bit
+ * integers).
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_LONG.
+ */
+ public long[] GetAsLongs() {
+ return (long[])data;
+ }
+
+ /**
+ * Returns TIFF_FLOAT data as an array of floats.
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_FLOAT.
+ */
+ public float[] GetAsFloats() {
+ return (float[])data;
+ }
+
+ /**
+ * Returns TIFF_DOUBLE data as an array of doubles.
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_DOUBLE.
+ */
+ public double[] GetAsDoubles() {
+ return (double[])data;
+ }
+
+ /**
+ * Returns TIFF_SRATIONAL data as an array of 2-element arrays of ints.
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_SRATIONAL.
+ */
+ public int[][] GetAsSRationals() {
+ return (int[][])data;
+ }
+
+ /**
+ * Returns TIFF_RATIONAL data as an array of 2-element arrays of longs.
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_RATTIONAL.
+ */
+ public long[][] GetAsRationals() {
+ return (long[][])data;
+ }
+
+ /**
+ * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
+ * TIFF_SSHORT, or TIFF_SLONG format as an int.
+ *
+ * TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned;
+ * that is, no sign extension will take place and the returned
+ * value will be in the range [0, 255]. TIFF_SBYTE data will
+ * be returned in the range [-128, 127].
+ *
+ * A ClassCastException will be thrown if the field is not of
+ * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
+ * TIFF_SSHORT, or TIFF_SLONG.
+ */
+ public int GetAsInt(int index) {
+ switch (type) {
+ case TIFF_BYTE: case TIFF_UNDEFINED:
+ return ((byte[])data)[index] & 0xff;
+ case TIFF_SBYTE:
+ return ((byte[])data)[index];
+ case TIFF_SHORT:
+ return ((char[])data)[index] & 0xffff;
+ case TIFF_SSHORT:
+ return ((short[])data)[index];
+ case TIFF_SLONG:
+ return ((int[])data)[index];
+ default:
+ throw new InvalidCastException();
+ }
+ }
+
+ /**
+ * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
+ * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG format as a long.
+ *
+ * TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned;
+ * that is, no sign extension will take place and the returned
+ * value will be in the range [0, 255]. TIFF_SBYTE data will
+ * be returned in the range [-128, 127].
+ *
+ * A ClassCastException will be thrown if the field is not of
+ * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
+ * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG.
+ */
+ public long GetAsLong(int index) {
+ switch (type) {
+ case TIFF_BYTE: case TIFF_UNDEFINED:
+ return ((byte[])data)[index] & 0xff;
+ case TIFF_SBYTE:
+ return ((byte[])data)[index];
+ case TIFF_SHORT:
+ return ((char[])data)[index] & 0xffff;
+ case TIFF_SSHORT:
+ return ((short[])data)[index];
+ case TIFF_SLONG:
+ return ((int[])data)[index];
+ case TIFF_LONG:
+ return ((long[])data)[index];
+ default:
+ throw new InvalidCastException();
+ }
+ }
+
+ /**
+ * Returns data in any numerical format as a float. Data in
+ * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by
+ * dividing the numerator into the denominator using
+ * double-precision arithmetic and then truncating to single
+ * precision. Data in TIFF_SLONG, TIFF_LONG, or TIFF_DOUBLE
+ * format may suffer from truncation.
+ *
+ * A ClassCastException will be thrown if the field is
+ * of type TIFF_UNDEFINED or TIFF_ASCII.
+ */
+ public float GetAsFloat(int index) {
+ switch (type) {
+ case TIFF_BYTE:
+ return ((byte[])data)[index] & 0xff;
+ case TIFF_SBYTE:
+ return ((byte[])data)[index];
+ case TIFF_SHORT:
+ return ((char[])data)[index] & 0xffff;
+ case TIFF_SSHORT:
+ return ((short[])data)[index];
+ case TIFF_SLONG:
+ return ((int[])data)[index];
+ case TIFF_LONG:
+ return ((long[])data)[index];
+ case TIFF_FLOAT:
+ return ((float[])data)[index];
+ case TIFF_DOUBLE:
+ return (float)((double[])data)[index];
+ case TIFF_SRATIONAL:
+ int[] ivalue = GetAsSRational(index);
+ return (float)((double)ivalue[0]/ivalue[1]);
+ case TIFF_RATIONAL:
+ long[] lvalue = GetAsRational(index);
+ return (float)((double)lvalue[0]/lvalue[1]);
+ default:
+ throw new InvalidCastException();
+ }
+ }
+
+ /**
+ * Returns data in any numerical format as a float. Data in
+ * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by
+ * dividing the numerator into the denominator using
+ * double-precision arithmetic.
+ *
+ * A ClassCastException will be thrown if the field is of
+ * type TIFF_UNDEFINED or TIFF_ASCII.
+ */
+ public double GetAsDouble(int index) {
+ switch (type) {
+ case TIFF_BYTE:
+ return ((byte[])data)[index] & 0xff;
+ case TIFF_SBYTE:
+ return ((byte[])data)[index];
+ case TIFF_SHORT:
+ return ((char[])data)[index] & 0xffff;
+ case TIFF_SSHORT:
+ return ((short[])data)[index];
+ case TIFF_SLONG:
+ return ((int[])data)[index];
+ case TIFF_LONG:
+ return ((long[])data)[index];
+ case TIFF_FLOAT:
+ return ((float[])data)[index];
+ case TIFF_DOUBLE:
+ return ((double[])data)[index];
+ case TIFF_SRATIONAL:
+ int[] ivalue = GetAsSRational(index);
+ return (double)ivalue[0]/ivalue[1];
+ case TIFF_RATIONAL:
+ long[] lvalue = GetAsRational(index);
+ return (double)lvalue[0]/lvalue[1];
+ default:
+ throw new InvalidCastException();
+ }
+ }
+
+ /**
+ * Returns a TIFF_ASCII data item as a String.
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_ASCII.
+ */
+ public String GetAsString(int index) {
+ return ((String[])data)[index];
+ }
+
+ /**
+ * Returns a TIFF_SRATIONAL data item as a two-element array
+ * of ints.
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_SRATIONAL.
+ */
+ public int[] GetAsSRational(int index) {
+ return ((int[][])data)[index];
+ }
+
+ /**
+ * Returns a TIFF_RATIONAL data item as a two-element array
+ * of ints.
+ *
+ * A ClassCastException will be thrown if the field is not
+ * of type TIFF_RATIONAL.
+ */
+ public long[] GetAsRational(int index) {
+ if (type == TIFF_LONG)
+ return GetAsLongs();
+ return ((long[][])data)[index];
+ }
+
+ /**
+ * Compares this Note: this class has a natural ordering that is inconsistent
+ * with
+ * In the first step, only in1, in2,in3 and tag are used.
+ * After the collections of the index entries, pagenumbers are used.
+ *
+ * Note that if even if a page is not written this method is still called.
+ * It is preferable to use
+ * Note that this method is called with the page number equal to the last
+ * page plus one.
+ *
+ * @param writer
+ * the
+ *
+ *
+ *
+ *
+ *
+ *
+ * It is usefull to pinpoint the Search for all possible partial matches of word starting
+ * at index an update interletter values. In other words, it
+ * does something like: But it is done in an efficient way since the patterns are
+ * stored in a ternary tree. In fact, this is the whole purpose
+ * of having the tree: doing this search without having to test
+ * every single pattern. The number of patterns for languages
+ * such as English range from 4000 to 10000. Thus, doing thousands
+ * of string comparisons for each word to hyphenate would be
+ * really slow without the tree. The tradeoff is memory, but
+ * using a ternary tree instead of a trie, almost halves the
+ * the memory used by Lout or TeX. It's also faster than using
+ * a hash table A ternary search tree is a hibrid between a binary tree and
+ * a digital search tree (trie). Keys are limited to strings.
+ * A data value of type char is stored in each leaf node.
+ * It can be used as an index (or pointer) to the data.
+ * Branches that only contain one key are compressed to one node
+ * by storing a pointer to the trailer substring of the key.
+ * This class is intended to serve as base class or helper class
+ * to implement Dictionary collections or the like. Ternary trees
+ * have some nice properties as the following: the tree can be
+ * traversed in sorted order, partial matches (wildcard) can be
+ * implemented, retrieval of all keys within a given distance
+ * from the target, etc. The storage requirements are higher than
+ * a binary tree but a lot less than a trie. Performance is
+ * comparable with a hash table, sometimes it outperforms a hash
+ * function (most of the time can determine a miss faster than a hash). The main purpose of this java port is to serve as a base for
+ * implementing TeX's hyphenation algorithm (see The TeXBook,
+ * appendix H). Each language requires from 5000 to 15000 hyphenation
+ * patterns which will be keys in this tree. The strings patterns
+ * are usually small (from 2 to 5 characters), but each char in the
+ * tree is stored in a node. Thus memory usage is the main concern.
+ * We will sacrify 'elegance' to keep memory requirenments to the
+ * minimum. Using java's char type as pointer (yes, I know pointer
+ * it is a forbidden word in java) we can keep the size of the node
+ * to be just 8 bytes (3 pointers and the data char). This gives
+ * room for about 65000 nodes. In my tests the english patterns
+ * took 7694 nodes and the german patterns 10055 nodes,
+ * so I think we are safe. All said, this is a map with strings as keys and char as value.
+ * Pretty limited!. It can be extended to a general map by
+ * using the string representation of an object and using the
+ * char value as an index to an array that contains the object
+ * values. The character stored in this node: splitchar
+ * Two special values are reserved: This shouldn't be a problem if we give the usual semantics to
+ * strings since 0xFFFF is garanteed not to be an Unicode character.
+ *
+ * The parser can:
+ *
+ *
+ * The code is based on
+ * http://www.javaworld.com/javaworld/javatips/javatip128/ with some extra
+ * code from XERCES to recognize the encoding.
+ */
+ public sealed class SimpleXMLParser {
+ /** possible states */
+ private const int UNKNOWN = 0;
+ private const int TEXT = 1;
+ private const int TAG_ENCOUNTERED = 2;
+ private const int EXAMIN_TAG = 3;
+ private const int TAG_EXAMINED = 4;
+ private const int IN_CLOSETAG = 5;
+ private const int SINGLE_TAG = 6;
+ private const int CDATA = 7;
+ private const int COMMENT = 8;
+ private const int PI = 9;
+ private const int ENTITY = 10;
+ private const int QUOTE = 11;
+ private const int ATTRIBUTE_KEY = 12;
+ private const int ATTRIBUTE_EQUAL = 13;
+ private const int ATTRIBUTE_VALUE = 14;
+
+ /** the state stack */
+ internal Stack stack;
+ /** The current character. */
+ internal int character = 0;
+ /** The previous character. */
+ internal int previousCharacter = -1;
+ /** the line we are currently reading */
+ internal int lines = 1;
+ /** the column where the current character occurs */
+ internal int columns = 0;
+ /** was the last character equivalent to a newline? */
+ internal bool eol = false;
+ /** the current state */
+ internal int state;
+ /** Are we parsing HTML? */
+ internal bool html;
+ /** current text (whatever is encountered between tags) */
+ internal StringBuilder text = new StringBuilder();
+ /** current entity (whatever is encountered between & and ;) */
+ internal StringBuilder entity = new StringBuilder();
+ /** current tagname */
+ internal String tag = null;
+ /** current attributes */
+ internal Hashtable attributes = null;
+ /** The handler to which we are going to forward document content */
+ internal ISimpleXMLDocHandler doc;
+ /** The handler to which we are going to forward comments. */
+ internal ISimpleXMLDocHandlerComment comment;
+ /** Keeps track of the number of tags that are open. */
+ internal int nested = 0;
+ /** the quote character that was used to open the quote. */
+ internal int quoteCharacter = '"';
+ /** the attribute key. */
+ internal String attributekey = null;
+ /** the attribute value. */
+ internal String attributevalue = null;
+
+ /**
+ * Creates a Simple XML parser object.
+ * Call Go(BufferedReader) immediately after creation.
+ */
+ private SimpleXMLParser(ISimpleXMLDocHandler doc, ISimpleXMLDocHandlerComment comment, bool html) {
+ this.doc = doc;
+ this.comment = comment;
+ this.html = html;
+ stack = new Stack();
+ state = html ? TEXT : UNKNOWN;
+ }
+
+ /**
+ * Does the actual parsing. Perform this immediately
+ * after creating the parser object.
+ */
+ private void Go(TextReader reader) {
+ doc.StartDocument();
+ while (true) {
+ // read a new character
+ if (previousCharacter == -1) {
+ character = reader.Read();
+ }
+ // or re-examin the previous character
+ else {
+ character = previousCharacter;
+ previousCharacter = -1;
+ }
+
+ // the end of the file was reached
+ if (character == -1) {
+ if (html) {
+ if (html && state == TEXT)
+ Flush();
+ doc.EndDocument();
+ } else {
+ ThrowException("Missing end tag");
+ }
+ return;
+ }
+
+ // dealing with \n and \r
+ if (character == '\n' && eol) {
+ eol = false;
+ continue;
+ } else if (eol) {
+ eol = false;
+ } else if (character == '\n') {
+ lines++;
+ columns = 0;
+ } else if (character == '\r') {
+ eol = true;
+ character = '\n';
+ lines++;
+ columns = 0;
+ } else {
+ columns++;
+ }
+
+ switch (state) {
+ // we are in an unknown state before there's actual content
+ case UNKNOWN:
+ if (character == '<') {
+ SaveState(TEXT);
+ state = TAG_ENCOUNTERED;
+ }
+ break;
+ // we can encounter any content
+ case TEXT:
+ if (character == '<') {
+ Flush();
+ SaveState(state);
+ state = TAG_ENCOUNTERED;
+ } else if (character == '&') {
+ SaveState(state);
+ entity.Length = 0;
+ state = ENTITY;
+ } else
+ text.Append((char)character);
+ break;
+ // we have just seen a < and are wondering what we are looking at
+ //
+ * Note: if the object has been read from an input stream, the only
+ * time you can be sure if isExplicit is returning the true state of
+ * affairs is if it returns false. An implicitly tagged object may appear
+ * to be explicitly tagged, so you need to understand the context under
+ * which the reading was done as well, see GetObject below.
+ * Note: tagged objects are generally context dependent if you're
+ * trying to extract a tagged object you should be going via the
+ * appropriate GetInstance method.
+ * Normally in a certificate we would expect "Z" rather than "GMT",
+ * however adding the "GMT" means we can just use:
+ *
+ * As Der requires the constructed, definite-length model to
+ * be used for structured types, this varies slightly from the
+ * ASN.1 descriptions given. Rather than just outputing Sequence,
+ * we also have to specify Constructed, and the objects length.
+ */
+ internal override void Encode(
+ DerOutputStream derOut)
+ {
+ // TODO Intermediate buffer could be avoided if we could calculate expected length
+ MemoryStream bOut = new MemoryStream();
+ DerOutputStream dOut = new DerOutputStream(bOut);
+
+ foreach (Asn1Encodable obj in this)
+ {
+ dOut.WriteObject(obj);
+ }
+
+ dOut.Close();
+
+ byte[] bytes = bOut.ToArray();
+
+ derOut.WriteEncoded(Asn1Tags.Sequence | Asn1Tags.Constructed, bytes);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/DerSet.cs b/iTechSharp/srcbc/asn1/DerSet.cs
new file mode 100644
index 0000000..c66dde8
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/DerSet.cs
@@ -0,0 +1,108 @@
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1
+{
+ /**
+ * A Der encoded set object
+ */
+ public class DerSet
+ : Asn1Set
+ {
+ public static readonly DerSet Empty = new DerSet();
+
+ public static DerSet FromVector(
+ Asn1EncodableVector v)
+ {
+ return v.Count < 1 ? Empty : new DerSet(v);
+ }
+
+ internal static DerSet FromVector(
+ Asn1EncodableVector v,
+ bool needsSorting)
+ {
+ return v.Count < 1 ? Empty : new DerSet(v, needsSorting);
+ }
+
+ /**
+ * create an empty set
+ */
+ public DerSet()
+ : base(0)
+ {
+ }
+
+ /**
+ * @param obj - a single object that makes up the set.
+ */
+ public DerSet(
+ Asn1Encodable obj)
+ : base(1)
+ {
+ AddObject(obj);
+ }
+
+ public DerSet(
+ params Asn1Encodable[] v)
+ : base(v.Length)
+ {
+ foreach (Asn1Encodable o in v)
+ {
+ AddObject(o);
+ }
+
+ Sort();
+ }
+
+ /**
+ * @param v - a vector of objects making up the set.
+ */
+ public DerSet(
+ Asn1EncodableVector v)
+ : this(v, true)
+ {
+ }
+
+ internal DerSet(
+ Asn1EncodableVector v,
+ bool needsSorting)
+ : base(v.Count)
+ {
+ foreach (Asn1Encodable o in v)
+ {
+ AddObject(o);
+ }
+
+ if (needsSorting)
+ {
+ Sort();
+ }
+ }
+
+ /*
+ * A note on the implementation:
+ *
+ * As Der requires the constructed, definite-length model to
+ * be used for structured types, this varies slightly from the
+ * ASN.1 descriptions given. Rather than just outputing Set,
+ * we also have to specify Constructed, and the objects length.
+ */
+ internal override void Encode(
+ DerOutputStream derOut)
+ {
+ // TODO Intermediate buffer could be avoided if we could calculate expected length
+ MemoryStream bOut = new MemoryStream();
+ DerOutputStream dOut = new DerOutputStream(bOut);
+
+ foreach (Asn1Encodable obj in this)
+ {
+ dOut.WriteObject(obj);
+ }
+
+ dOut.Close();
+
+ byte[] bytes = bOut.ToArray();
+
+ derOut.WriteEncoded(Asn1Tags.Set | Asn1Tags.Constructed, bytes);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/DerStringBase.cs b/iTechSharp/srcbc/asn1/DerStringBase.cs
new file mode 100644
index 0000000..2a5fb04
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/DerStringBase.cs
@@ -0,0 +1,22 @@
+namespace Org.BouncyCastle.Asn1
+{
+ public abstract class DerStringBase
+ : Asn1Object, IAsn1String
+ {
+ protected DerStringBase()
+ {
+ }
+
+ public abstract string GetString();
+
+ public override string ToString()
+ {
+ return GetString();
+ }
+
+ protected override int Asn1GetHashCode()
+ {
+ return GetString().GetHashCode();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/DerT61String.cs b/iTechSharp/srcbc/asn1/DerT61String.cs
new file mode 100644
index 0000000..3d20518
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/DerT61String.cs
@@ -0,0 +1,105 @@
+using System;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1
+{
+ /**
+ * Der T61String (also the teletex string) - 8-bit characters
+ */
+ public class DerT61String
+ : DerStringBase
+ {
+ private readonly string str;
+
+ /**
+ * return a T61 string from the passed in object.
+ *
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static DerT61String GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is DerT61String)
+ {
+ return (DerT61String)obj;
+ }
+
+ if (obj is Asn1OctetString)
+ {
+ return new DerT61String(((Asn1OctetString)obj).GetOctets());
+ }
+
+ if (obj is Asn1TaggedObject)
+ {
+ return GetInstance(((Asn1TaggedObject)obj).GetObject());
+ }
+
+ throw new ArgumentException("illegal object in GetInstance: " + obj.GetType().Name);
+ }
+
+ /**
+ * return an T61 string from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DerT61String GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(obj.GetObject());
+ }
+
+ /**
+ * basic constructor - with bytes.
+ */
+ public DerT61String(
+ byte[] str)
+ : this(Strings.FromByteArray(str))
+ {
+ }
+
+ /**
+ * basic constructor - with string.
+ */
+ public DerT61String(
+ string str)
+ {
+ if (str == null)
+ throw new ArgumentNullException("str");
+
+ this.str = str;
+ }
+
+ public override string GetString()
+ {
+ return str;
+ }
+
+ internal override void Encode(
+ DerOutputStream derOut)
+ {
+ derOut.WriteEncoded(Asn1Tags.T61String, GetOctets());
+ }
+
+ public byte[] GetOctets()
+ {
+ return Strings.ToByteArray(str);
+ }
+
+ protected override bool Asn1Equals(
+ Asn1Object asn1Object)
+ {
+ DerT61String other = asn1Object as DerT61String;
+
+ if (other == null)
+ return false;
+
+ return this.str.Equals(other.str);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/DerTaggedObject.cs b/iTechSharp/srcbc/asn1/DerTaggedObject.cs
new file mode 100644
index 0000000..717d724
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/DerTaggedObject.cs
@@ -0,0 +1,72 @@
+namespace Org.BouncyCastle.Asn1
+{
+ /**
+ * DER TaggedObject - in ASN.1 notation this is any object preceded by
+ * a [n] where n is some number - these are assumed to follow the construction
+ * rules (as with sequences).
+ */
+ public class DerTaggedObject
+ : Asn1TaggedObject
+ {
+ /**
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public DerTaggedObject(
+ int tagNo,
+ Asn1Encodable obj)
+ : base(tagNo, obj)
+ {
+ }
+
+ /**
+ * @param explicitly true if an explicitly tagged object.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public DerTaggedObject(
+ bool explicitly,
+ int tagNo,
+ Asn1Encodable obj)
+ : base(explicitly, tagNo, obj)
+ {
+ }
+
+ /**
+ * create an implicitly tagged object that contains a zero
+ * length sequence.
+ */
+ public DerTaggedObject(
+ int tagNo)
+ : base(false, tagNo, DerSequence.Empty)
+ {
+ }
+
+ internal override void Encode(
+ DerOutputStream derOut)
+ {
+ if (!IsEmpty())
+ {
+ byte[] bytes = obj.GetDerEncoded();
+
+ if (explicitly)
+ {
+ derOut.WriteEncoded(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, bytes);
+ }
+ else
+ {
+ //
+ // need to mark constructed types... (preserve Constructed tag)
+ //
+ int flags = (bytes[0] & Asn1Tags.Constructed) | Asn1Tags.Tagged;
+ derOut.WriteTag(flags, tagNo);
+ derOut.Write(bytes, 1, bytes.Length - 1);
+ }
+ }
+ else
+ {
+ derOut.WriteEncoded(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, new byte[0]);
+ }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/DerUTCTime.cs b/iTechSharp/srcbc/asn1/DerUTCTime.cs
new file mode 100644
index 0000000..4141856
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/DerUTCTime.cs
@@ -0,0 +1,259 @@
+using System;
+using System.Globalization;
+using System.Text;
+
+namespace Org.BouncyCastle.Asn1
+{
+ /**
+ * UTC time object.
+ */
+ public class DerUtcTime
+ : Asn1Object
+ {
+ private readonly string time;
+
+ /**
+ * return an UTC Time from the passed in object.
+ *
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static DerUtcTime GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is DerUtcTime)
+ {
+ return (DerUtcTime)obj;
+ }
+
+ if (obj is Asn1OctetString)
+ {
+ return new DerUtcTime(((Asn1OctetString)obj).GetOctets());
+ }
+
+ throw new ArgumentException("illegal object in GetInstance: " + obj.GetType().Name);
+ }
+
+ /**
+ * return an UTC Time from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DerUtcTime GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(obj.GetObject());
+ }
+
+ /**
+ * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
+ * never encoded. When you're creating one of these objects from scratch, that's
+ * what you want to use, otherwise we'll try to deal with whatever Gets read from
+ * the input stream... (this is why the input format is different from the GetTime()
+ * method output).
+ *
+ * @param time the time string.
+ * Normally in a certificate we would expect "Z" rather than "GMT",
+ * however adding the "GMT" means we can just use:
+ *
+ * Note: In some cases, due to the local date processing, this
+ * may lead to unexpected results. If you want to stick the normal
+ * convention of 1950 to 2049 use the GetAdjustedTime() method.
+ * ISIS-MTT PROFILE: The corresponding ProcurationSyntax contains either the
+ * name of the person who is represented (subcomponent thirdPerson) or a
+ * reference to his/her base certificate (in the component signingFor,
+ * subcomponent certRef), furthermore the optional components country and
+ * typeSubstitution to indicate the country whose laws apply, and respectively
+ * the type of procuration (e.g. manager, procuration, custody).
+ *
+ * ISIS-MTT PROFILE: The GeneralName MUST be of type directoryName and MAY only
+ * contain: - RFC3039 attributes, except pseudonym (countryName, commonName,
+ * surname, givenName, serialNumber, organizationName, organizationalUnitName,
+ * stateOrProvincename, localityName, postalAddress) and - SubjectDirectoryName
+ * attributes (title, dateOfBirth, placeOfBirth, gender, countryOfCitizenship,
+ * countryOfResidence and NameAtBirth).
+ * This routine is written to output Pkcs1 version 0, private keys. It stores a string in a chosen encoding.
+ * Useful when reading back a
+ * This constructor can handle:
+ *
+ * Note: A directory name can be encoded in different ways into a byte
+ * representation. Be aware of this if the byte representation is used for
+ * comparing results.
+ *
+ * If minimum is
+ * For an v2 attribute certificate this is:
+ *
+ *
+ * For an v1 attribute certificate this is:
+ *
+ * permitted and excluded are Vectors of GeneralSubtree objects. Useful for reconstructing a
+ * If
+ * The GetEncoded() method in the public keys in the JCE produces a DER
+ * encoded one of these.
+ * Note: issuerUniqueID and subjectUniqueID are both deprecated by the IETF. This class
+ * will parse them, but you really shouldn't be creating new ones.
+ * The targetCert field is currently not supported and must not be used
+ * according to RFC 3281.
+ *
+ * Exactly one of the parameters must be not
+ *
+ * The ArrayList is cloned before it is returned.
+ * According to RFC 3281 only one targets element must be produced. If
+ * multiple targets are given in the constructor they are merged into one
+ * targets element. If this was produced from a
+ * {@link Org.BouncyCastle.Asn1.Asn1Sequence} the encoding is kept.
+ *
+ * The ArrayList is copied.
+ * The ArrayList is cloned before it is returned. Useful from reconstructing a
+ * it's is assumed the table contains Oid/string pairs.
+ * It's is assumed the table contains Oid/string pairs. Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
+ * it's is assumed the table contains OID/string pairs, and the contents
+ * of the table are copied into an internal table as part of the
+ * construction process. The ordering ArrayList should contain the OIDs
+ * in the order they are meant to be encoded or printed in ToString.
+ * it's is assumed the table contains OID/string pairs, and the contents
+ * of the table are copied into an internal table as part of the
+ * construction process. The ordering ArrayList should contain the OIDs
+ * in the order they are meant to be encoded or printed in ToString.
+ * The passed in converter will be used to convert the strings into their
+ * ASN.1 counterparts.
+ * The passed in converter will be used to convert the strings into their
+ * ASN.1 counterparts.
+ * An example of an encoder look like below:
+ *
+
+
+
+ private void Zipup()
+ {
+ if (filesToZip.Count == 0)
+ {
+ System.Console.WriteLine("Nothing to do.");
+ return;
+ }
+
+ using (var raw = File.Open(_outputFileName, FileMode.Create, FileAccess.ReadWrite ))
+ {
+ using (var output= new ZipOutputStream(raw))
+ {
+ output.Password = "VerySecret!";
+ output.Encryption = EncryptionAlgorithm.WinZipAes256;
+
+ foreach (string inputFileName in filesToZip)
+ {
+ System.Console.WriteLine("file: {0}", inputFileName);
+
+ output.PutNextEntry(inputFileName);
+ using (var input = File.Open(inputFileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Write ))
+ {
+ byte[] buffer= new byte[2048];
+ int n;
+ while ((n= input.Read(buffer,0,buffer.Length)) > 0)
+ {
+ output.Write(buffer,0,n);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+ Private Sub Zipup()
+ Dim outputFileName As String = "XmlData.zip"
+ Dim filesToZip As String() = Directory.GetFiles(".", "*.xml")
+ If (filesToZip.Length = 0) Then
+ Console.WriteLine("Nothing to do.")
+ Else
+ Using raw As FileStream = File.Open(outputFileName, FileMode.Create, FileAccess.ReadWrite)
+ Using output As ZipOutputStream = New ZipOutputStream(raw)
+ output.Password = "VerySecret!"
+ output.Encryption = EncryptionAlgorithm.WinZipAes256
+ Dim inputFileName As String
+ For Each inputFileName In filesToZip
+ Console.WriteLine("file: {0}", inputFileName)
+ output.PutNextEntry(inputFileName)
+ Using input As FileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
+ Dim n As Integer
+ Dim buffer As Byte() = New Byte(2048) {}
+ Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
+ output.Write(buffer, 0, n)
+ Loop
+ End Using
+ Next
+ End Using
+ End Using
+ End If
+ End Sub
+
+
+ private void Zipup()
+ {
+ if (filesToZip.Count == 0)
+ {
+ System.Console.WriteLine("Nothing to do.");
+ return;
+ }
+
+ using (var output= new ZipOutputStream(outputFileName))
+ {
+ output.Password = "VerySecret!";
+ output.Encryption = EncryptionAlgorithm.WinZipAes256;
+
+ foreach (string inputFileName in filesToZip)
+ {
+ System.Console.WriteLine("file: {0}", inputFileName);
+
+ output.PutNextEntry(inputFileName);
+ using (var input = File.Open(inputFileName, FileMode.Open, FileAccess.Read,
+ FileShare.Read | FileShare.Write ))
+ {
+ byte[] buffer= new byte[2048];
+ int n;
+ while ((n= input.Read(buffer,0,buffer.Length)) > 0)
+ {
+ output.Write(buffer,0,n);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ Private Sub Zipup()
+ Dim outputFileName As String = "XmlData.zip"
+ Dim filesToZip As String() = Directory.GetFiles(".", "*.xml")
+ If (filesToZip.Length = 0) Then
+ Console.WriteLine("Nothing to do.")
+ Else
+ Using output As ZipOutputStream = New ZipOutputStream(outputFileName)
+ output.Password = "VerySecret!"
+ output.Encryption = EncryptionAlgorithm.WinZipAes256
+ Dim inputFileName As String
+ For Each inputFileName In filesToZip
+ Console.WriteLine("file: {0}", inputFileName)
+ output.PutNextEntry(inputFileName)
+ Using input As FileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
+ Dim n As Integer
+ Dim buffer As Byte() = New Byte(2048) {}
+ Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
+ output.Write(buffer, 0, n)
+ Loop
+ End Using
+ Next
+ End Using
+ End If
+ End Sub
+
+
+ private void Zipup()
+ {
+ using (FileStream fs raw = File.Open(_outputFileName, FileMode.Create, FileAccess.ReadWrite ))
+ {
+ using (var output= new ZipOutputStream(fs))
+ {
+ output.Password = "VerySecret!";
+ output.Encryption = EncryptionAlgorithm.WinZipAes256;
+ output.PutNextEntry("entry1.txt");
+ byte[] buffer= System.Text.Encoding.ASCII.GetBytes("This is the content for entry #1.");
+ output.Write(buffer,0,buffer.Length);
+ output.PutNextEntry("entry2.txt"); // this will be zero length
+ output.PutNextEntry("entry3.txt");
+ buffer= System.Text.Encoding.ASCII.GetBytes("This is the content for entry #3.");
+ output.Write(buffer,0,buffer.Length);
+ }
+ }
+ }
+
+
+
+
+
+
+
+
+ private void Unzip()
+ {
+ byte[] buffer= new byte[2048];
+ int n;
+ using (var raw = File.Open(inputFileName, FileMode.Open, FileAccess.Read))
+ {
+ using (var input= new ZipInputStream(raw))
+ {
+ ZipEntry e;
+ while (( e = input.GetNextEntry()) != null)
+ {
+ if (e.IsDirectory) continue;
+ string outputPath = Path.Combine(extractDir, e.FileName);
+ using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
+ {
+ while ((n= input.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ output.Write(buffer,0,n);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+ Private Sub UnZip()
+ Dim inputFileName As String = "MyArchive.zip"
+ Dim extractDir As String = "extract"
+ Dim buffer As Byte() = New Byte(2048) {}
+ Using raw As FileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read)
+ Using input As ZipInputStream = New ZipInputStream(raw)
+ Dim e As ZipEntry
+ Do While (Not e = input.GetNextEntry Is Nothing)
+ If Not e.IsDirectory Then
+ Using output As FileStream = File.Open(Path.Combine(extractDir, e.FileName), _
+ FileMode.Create, FileAccess.ReadWrite)
+ Dim n As Integer
+ Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
+ output.Write(buffer, 0, n)
+ Loop
+ End Using
+ End If
+ Loop
+ End Using
+ End Using
+ End Sub
+
+
+ private void Unzip()
+ {
+ byte[] buffer= new byte[2048];
+ int n;
+ using (var input= new ZipInputStream(inputFileName))
+ {
+ ZipEntry e;
+ while (( e = input.GetNextEntry()) != null)
+ {
+ if (e.IsDirectory) continue;
+ string outputPath = Path.Combine(extractDir, e.FileName);
+ using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
+ {
+ while ((n= input.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ output.Write(buffer,0,n);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ Private Sub UnZip()
+ Dim inputFileName As String = "MyArchive.zip"
+ Dim extractDir As String = "extract"
+ Dim buffer As Byte() = New Byte(2048) {}
+ Using input As ZipInputStream = New ZipInputStream(inputFileName)
+ Dim e As ZipEntry
+ Do While (Not e = input.GetNextEntry Is Nothing)
+ If Not e.IsDirectory Then
+ Using output As FileStream = File.Open(Path.Combine(extractDir, e.FileName), _
+ FileMode.Create, FileAccess.ReadWrite)
+ Dim n As Integer
+ Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
+ output.Write(buffer, 0, n)
+ Loop
+ End Using
+ End If
+ Loop
+ End Using
+ End Sub
+
+
+ byte[] buffer= new byte[2048];
+ int n;
+ using (var raw = File.Open(_inputFileName, FileMode.Open, FileAccess.Read ))
+ {
+ using (var input= new ZipInputStream(raw))
+ {
+ ZipEntry e;
+ while (( e = input.GetNextEntry()) != null)
+ {
+ input.Password = PasswordForEntry(e.FileName);
+ if (e.IsDirectory) continue;
+ string outputPath = Path.Combine(_extractDir, e.FileName);
+ using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
+ {
+ while ((n= input.Read(buffer,0,buffer.Length)) > 0)
+ {
+ output.Write(buffer,0,n);
+ }
+ }
+ }
+ }
+ }
+
+
+
+
+
+
+ var cipher = new ZipCrypto();
+ cipher.InitCipher(Password);
+ // Decrypt the header. This has a side effect of "further initializing the
+ // encryption keys" in the traditional zip encryption.
+ byte[] DecryptedMessage = cipher.DecryptMessage(EncryptedMessage);
+
+
+ Step 1 - Initializing the encryption keys
+ -----------------------------------------
+ Start with these keys:
+ Key(0) := 305419896 (0x12345678)
+ Key(1) := 591751049 (0x23456789)
+ Key(2) := 878082192 (0x34567890)
+
+ Then, initialize the keys with a password:
+
+ loop for i from 0 to length(password)-1
+ update_keys(password(i))
+ end loop
+
+ Where update_keys() is defined as:
+
+ update_keys(char):
+ Key(0) := crc32(key(0),char)
+ Key(1) := Key(1) + (Key(0) bitwiseAND 000000ffH)
+ Key(1) := Key(1) * 134775813 + 1
+ Key(2) := crc32(key(2),key(1) rightshift 24)
+ end update_keys
+
+ Where crc32(old_crc,char) is a routine that given a CRC value and a
+ character, returns an updated CRC value after applying the CRC-32
+ algorithm described elsewhere in this document.
+
+
+
+
+ private void WriteEntry (String filename, Stream output)
+ {
+ DataSet ds1 = ObtainDataSet();
+ ds1.WriteXml(output);
+ }
+
+ private void Run()
+ {
+ using (var zip = new ZipFile())
+ {
+ zip.AddEntry(zipEntryName, WriteEntry);
+ zip.Save(zipFileName);
+ }
+ }
+
+
+
+ Private Sub WriteEntry (ByVal filename As String, ByVal output As Stream)
+ DataSet ds1 = ObtainDataSet()
+ ds1.WriteXml(stream)
+ End Sub
+
+ Public Sub Run()
+ Using zip = New ZipFile
+ zip.AddEntry(zipEntryName, New WriteDelegate(AddressOf WriteEntry))
+ zip.Save(zipFileName)
+ End Using
+ End Sub
+
+
+ using (ZipFile zip = ZipFile.Read("PackedDocuments.zip"))
+ {
+ foreach (string s1 in zip.EntryFilenames)
+ {
+ if (s1.EndsWith(".txt"))
+ {
+ zip[s1].Extract("textfiles");
+ }
+ }
+ }
+
+
+ Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip")
+ Dim s1 As String
+ For Each s1 In zip.EntryFilenames
+ If s1.EndsWith(".txt") Then
+ zip(s1).Extract("textfiles")
+ End If
+ Next
+ End Using
+
+
+ String sZipPath = "Airborne.zip";
+ String sFilePath = "Readme.txt";
+ String sRootFolder = "Digado";
+ using (ZipFile zip = ZipFile.Read(sZipPath))
+ {
+ if (zip.EntryFileNames.Contains(sFilePath))
+ {
+ // use the string indexer on the zip file
+ zip[sFileName].Extract(sRootFolder,
+ ExtractExistingFileAction.OverwriteSilently);
+ }
+ }
+
+
+
+ Dim sZipPath as String = "Airborne.zip"
+ Dim sFilePath As String = "Readme.txt"
+ Dim sRootFolder As String = "Digado"
+ Using zip As ZipFile = ZipFile.Read(sZipPath)
+ If zip.EntryFileNames.Contains(sFilePath)
+ ' use the string indexer on the zip file
+ zip(sFilePath).Extract(sRootFolder, _
+ ExtractExistingFileAction.OverwriteSilently)
+ End If
+ End Using
+
+
+ using (var zip = ZipFile.Read(FilePath))
+ {
+ foreach (ZipEntry e in zip)
+ {
+ if (e.UsesEncryption)
+ e.ExtractWithPassword("Secret!");
+ else
+ e.Extract();
+ }
+ }
+
+
+ Using zip As ZipFile = ZipFile.Read(FilePath)
+ Dim e As ZipEntry
+ For Each e In zip
+ If (e.UsesEncryption)
+ e.ExtractWithPassword("Secret!")
+ Else
+ e.Extract
+ End If
+ Next
+ End Using
+
+
+ using (ZipFile zip = new ZipFile(ZipFileToRead))
+ {
+ ZipEntry e1= zip["Elevation.mp3"];
+ using (Ionic.Zlib.CrcCalculatorStream s = e1.OpenReader())
+ {
+ byte[] buffer = new byte[4096];
+ int n, totalBytesRead= 0;
+ do {
+ n = s.Read(buffer,0, buffer.Length);
+ totalBytesRead+=n;
+ } while (n>0);
+ if (s.Crc32 != e1.Crc32)
+ throw new Exception(string.Format("The Zip Entry failed the CRC Check. (0x{0:X8}!=0x{1:X8})", s.Crc32, e1.Crc32));
+ if (totalBytesRead != e1.UncompressedSize)
+ throw new Exception(string.Format("We read an unexpected number of bytes. ({0}!={1})", totalBytesRead, e1.UncompressedSize));
+ }
+ }
+
+
+ Using zip As New ZipFile(ZipFileToRead)
+ Dim e1 As ZipEntry = zip.Item("Elevation.mp3")
+ Using s As Ionic.Zlib.CrcCalculatorStream = e1.OpenReader
+ Dim n As Integer
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim totalBytesRead As Integer = 0
+ Do
+ n = s.Read(buffer, 0, buffer.Length)
+ totalBytesRead = (totalBytesRead + n)
+ Loop While (n > 0)
+ If (s.Crc32 <> e1.Crc32) Then
+ Throw New Exception(String.Format("The Zip Entry failed the CRC Check. (0x{0:X8}!=0x{1:X8})", s.Crc32, e1.Crc32))
+ End If
+ If (totalBytesRead <> e1.UncompressedSize) Then
+ Throw New Exception(String.Format("We read an unexpected number of bytes. ({0}!={1})", totalBytesRead, e1.UncompressedSize))
+ End If
+ End Using
+ End Using
+
+
+
+
+
+
+
+
+
+
+
+ using (ZipFile zip = new ZipFile(ZipFileToCreate))
+ {
+ ZipEntry e1= zip.AddFile(@"notes\Readme.txt");
+ ZipEntry e2= zip.AddFile(@"music\StopThisTrain.mp3");
+ e2.CompressionMethod = CompressionMethod.None;
+ zip.Save();
+ }
+
+
+
+ Using zip As New ZipFile(ZipFileToCreate)
+ zip.AddFile("notes\Readme.txt")
+ Dim e2 as ZipEntry = zip.AddFile("music\StopThisTrain.mp3")
+ e2.CompressionMethod = CompressionMethod.None
+ zip.Save
+ End Using
+
+
+ // Create a zip archive with AES Encryption.
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddFile("ReadMe.txt")
+ ZipEntry e1= zip.AddFile("2008-Regional-Sales-Report.pdf");
+ e1.Encryption= EncryptionAlgorithm.WinZipAes256;
+ e1.Password= "Top.Secret.No.Peeking!";
+ zip.Save("EncryptedArchive.zip");
+ }
+
+ // Extract a zip archive that uses AES Encryption.
+ // You do not need to specify the algorithm during extraction.
+ using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
+ {
+ // Specify the password that is used during extraction, for
+ // all entries that require a password:
+ zip.Password= "Top.Secret.No.Peeking!";
+ zip.ExtractAll("extractDirectory");
+ }
+
+
+
+ ' Create a zip that uses Encryption.
+ Using zip As New ZipFile()
+ zip.AddFile("ReadMe.txt")
+ Dim e1 as ZipEntry
+ e1= zip.AddFile("2008-Regional-Sales-Report.pdf")
+ e1.Encryption= EncryptionAlgorithm.WinZipAes256
+ e1.Password= "Top.Secret.No.Peeking!"
+ zip.Save("EncryptedArchive.zip")
+ End Using
+
+ ' Extract a zip archive that uses AES Encryption.
+ ' You do not need to specify the algorithm during extraction.
+ Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
+ ' Specify the password that is used during extraction, for
+ ' all entries that require a password:
+ zip.Password= "Top.Secret.No.Peeking!"
+ zip.ExtractAll("extractDirectory")
+ End Using
+
+
+
+ // create a file with encryption
+ using (ZipFile zip = new ZipFile())
+ {
+ ZipEntry entry;
+ entry= zip.AddFile("Declaration.txt");
+ entry.Password= "123456!";
+ entry = zip.AddFile("Report.xls");
+ entry.Password= "1Secret!";
+ zip.Save("EncryptedArchive.zip");
+ }
+
+ // extract entries that use encryption
+ using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
+ {
+ ZipEntry entry;
+ entry = zip["Declaration.txt"];
+ entry.Password = "123456!";
+ entry.Extract("extractDir");
+ entry = zip["Report.xls"];
+ entry.Password = "1Secret!";
+ entry.Extract("extractDir");
+ }
+
+
+
+
+ Using zip As New ZipFile
+ Dim entry as ZipEntry
+ entry= zip.AddFile("Declaration.txt")
+ entry.Password= "123456!"
+ entry = zip.AddFile("Report.xls")
+ entry.Password= "1Secret!"
+ zip.Save("EncryptedArchive.zip")
+ End Using
+
+
+ ' extract entries that use encryption
+ Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
+ Dim entry as ZipEntry
+ entry = zip("Declaration.txt")
+ entry.Password = "123456!"
+ entry.Extract("extractDir")
+ entry = zip("Report.xls")
+ entry.Password = "1Secret!"
+ entry.Extract("extractDir")
+ End Using
+
+
+
+
+ public static void ExtractProgress(object sender, ExtractProgressEventArgs e)
+ {
+ if (e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
+ Console.WriteLine("extract {0} ", e.CurrentEntry.FileName);
+
+ else if (e.EventType == ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite)
+ {
+ ZipEntry entry = e.CurrentEntry;
+ string response = null;
+ // Ask the user if he wants overwrite the file
+ do
+ {
+ Console.Write("Overwrite {0} in {1} ? (y/n/C) ", entry.FileName, e.ExtractLocation);
+ response = Console.ReadLine();
+ Console.WriteLine();
+
+ } while (response != null && response[0]!='Y' &&
+ response[0]!='N' && response[0]!='C');
+
+ if (response[0]=='C')
+ e.Cancel = true;
+ else if (response[0]=='Y')
+ entry.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
+ else
+ entry.ExtractExistingFile= ExtractExistingFileAction.DoNotOverwrite;
+ }
+ }
+
+
+ using (var zip = new ZipFile())
+ {
+ zip.AlternateEnoding = System.Text.Encoding.GetEncoding("ibm861");
+ zip.AlternateEnodingUsage = ZipOption.Always;
+ zip.AddFileS(arrayOfFiles);
+ zip.Save("Myarchive-Encoded-in-IBM861.zip");
+ }
+
+
+ using (var zip = new ZipFile())
+ {
+ var e = zip.UpdateFile("Descriptions.mme", "");
+ e.IsText = true;
+ zip.Save(zipPath);
+ }
+
+
+
+ Using zip As New ZipFile
+ Dim e2 as ZipEntry = zip.AddFile("Descriptions.mme", "")
+ e.IsText= True
+ zip.Save(zipPath)
+ End Using
+
+
+
+
+
+
+
+
+ String[] itemnames= {
+ "c:\\fixedContent\\Readme.txt",
+ "MyProposal.docx",
+ "c:\\SupportFiles", // a directory
+ "images\\Image1.jpg"
+ };
+
+ try
+ {
+ using (ZipFile zip = new ZipFile())
+ {
+ for (int i = 1; i < itemnames.Length; i++)
+ {
+ // will add Files or Dirs, recurses and flattens subdirectories
+ zip.AddItem(itemnames[i],"flat");
+ }
+ zip.Save(ZipToCreate);
+ }
+ }
+ catch (System.Exception ex1)
+ {
+ System.Console.Error.WriteLine("exception: {0}", ex1);
+ }
+
+
+
+ Dim itemnames As String() = _
+ New String() { "c:\fixedContent\Readme.txt", _
+ "MyProposal.docx", _
+ "SupportFiles", _
+ "images\Image1.jpg" }
+ Try
+ Using zip As New ZipFile
+ Dim i As Integer
+ For i = 1 To itemnames.Length - 1
+ ' will add Files or Dirs, recursing and flattening subdirectories.
+ zip.AddItem(itemnames(i), "flat")
+ Next i
+ zip.Save(ZipToCreate)
+ End Using
+ Catch ex1 As Exception
+ Console.Error.WriteLine("exception: {0}", ex1.ToString())
+ End Try
+
+
+ try
+ {
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddFile("c:\\photos\\personal\\7440-N49th.png");
+ zip.AddFile("c:\\Desktop\\2008-Regional-Sales-Report.pdf");
+ zip.AddFile("ReadMe.txt");
+
+ zip.Save("Package.zip");
+ }
+ }
+ catch (System.Exception ex1)
+ {
+ System.Console.Error.WriteLine("exception: " + ex1);
+ }
+
+
+
+ Try
+ Using zip As ZipFile = New ZipFile
+ zip.AddFile("c:\photos\personal\7440-N49th.png")
+ zip.AddFile("c:\Desktop\2008-Regional-Sales-Report.pdf")
+ zip.AddFile("ReadMe.txt")
+ zip.Save("Package.zip")
+ End Using
+ Catch ex1 As Exception
+ Console.Error.WriteLine("exception: {0}", ex1.ToString)
+ End Try
+
+
+ try
+ {
+ using (ZipFile zip = new ZipFile())
+ {
+ // the following entry will be inserted at the root in the archive.
+ zip.AddFile("c:\\datafiles\\ReadMe.txt", "");
+ // this image file will be inserted into the "images" directory in the archive.
+ zip.AddFile("c:\\photos\\personal\\7440-N49th.png", "images");
+ // the following will result in a password-protected file called
+ // files\\docs\\2008-Regional-Sales-Report.pdf in the archive.
+ zip.Password = "EncryptMe!";
+ zip.AddFile("c:\\Desktop\\2008-Regional-Sales-Report.pdf", "files\\docs");
+ zip.Save("Archive.zip");
+ }
+ }
+ catch (System.Exception ex1)
+ {
+ System.Console.Error.WriteLine("exception: {0}", ex1);
+ }
+
+
+
+ Try
+ Using zip As ZipFile = New ZipFile
+ ' the following entry will be inserted at the root in the archive.
+ zip.AddFile("c:\datafiles\ReadMe.txt", "")
+ ' this image file will be inserted into the "images" directory in the archive.
+ zip.AddFile("c:\photos\personal\7440-N49th.png", "images")
+ ' the following will result in a password-protected file called
+ ' files\\docs\\2008-Regional-Sales-Report.pdf in the archive.
+ zip.Password = "EncryptMe!"
+ zip.AddFile("c:\Desktop\2008-Regional-Sales-Report.pdf", "files\documents")
+ zip.Save("Archive.zip")
+ End Using
+ Catch ex1 As Exception
+ Console.Error.WriteLine("exception: {0}", ex1)
+ End Try
+
+
+ String ZipFileToCreate = "archive1.zip";
+ String DirectoryToZip = "c:\\reports";
+ using (ZipFile zip = new ZipFile())
+ {
+ // Store all files found in the top level directory, into the zip archive.
+ String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
+ zip.AddFiles(filenames);
+ zip.Save(ZipFileToCreate);
+ }
+
+
+
+ Dim ZipFileToCreate As String = "archive1.zip"
+ Dim DirectoryToZip As String = "c:\reports"
+ Using zip As ZipFile = New ZipFile
+ ' Store all files found in the top level directory, into the zip archive.
+ Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
+ zip.AddFiles(filenames)
+ zip.Save(ZipFileToCreate)
+ End Using
+
+
+ using (ZipFile zip1 = new ZipFile())
+ {
+ // UpdateFile might more accurately be called "AddOrUpdateFile"
+ zip1.UpdateFile("MyDocuments\\Readme.txt");
+ zip1.UpdateFile("CustomerList.csv");
+ zip1.Comment = "This zip archive has been created.";
+ zip1.Save("Content.zip");
+ }
+
+ using (ZipFile zip2 = ZipFile.Read("Content.zip"))
+ {
+ zip2.UpdateFile("Updates\\Readme.txt");
+ zip2.Comment = "This zip archive has been updated: The Readme.txt file has been changed.";
+ zip2.Save();
+ }
+
+
+
+ Using zip1 As New ZipFile
+ ' UpdateFile might more accurately be called "AddOrUpdateFile"
+ zip1.UpdateFile("MyDocuments\Readme.txt")
+ zip1.UpdateFile("CustomerList.csv")
+ zip1.Comment = "This zip archive has been created."
+ zip1.Save("Content.zip")
+ End Using
+
+ Using zip2 As ZipFile = ZipFile.Read("Content.zip")
+ zip2.UpdateFile("Updates\Readme.txt")
+ zip2.Comment = "This zip archive has been updated: The Readme.txt file has been changed."
+ zip2.Save
+ End Using
+
+
+ string Content = "This string will be the content of the Readme.txt file in the zip archive.";
+ using (ZipFile zip1 = new ZipFile())
+ {
+ zip1.AddFile("MyDocuments\\Resume.doc", "files");
+ zip1.AddEntry("Readme.txt", Content);
+ zip1.Comment = "This zip file was created at " + System.DateTime.Now.ToString("G");
+ zip1.Save("Content.zip");
+ }
+
+
+
+ Public Sub Run()
+ Dim Content As String = "This string will be the content of the Readme.txt file in the zip archive."
+ Using zip1 As ZipFile = New ZipFile
+ zip1.AddEntry("Readme.txt", Content)
+ zip1.AddFile("MyDocuments\Resume.doc", "files")
+ zip1.Comment = ("This zip file was created at " & DateTime.Now.ToString("G"))
+ zip1.Save("Content.zip")
+ End Using
+ End Sub
+
+
+ String zipToCreate = "Content.zip";
+ String fileNameInArchive = "Content-From-Stream.bin";
+ using (System.IO.Stream streamToRead = MyStreamOpener())
+ {
+ using (ZipFile zip = new ZipFile())
+ {
+ ZipEntry entry= zip.AddEntry(fileNameInArchive, streamToRead);
+ zip.AddFile("Readme.txt");
+ zip.Save(zipToCreate); // the stream is read implicitly here
+ }
+ }
+
+
+
+ Dim zipToCreate As String = "Content.zip"
+ Dim fileNameInArchive As String = "Content-From-Stream.bin"
+ Using streamToRead as System.IO.Stream = MyStreamOpener()
+ Using zip As ZipFile = New ZipFile()
+ Dim entry as ZipEntry = zip.AddEntry(fileNameInArchive, streamToRead)
+ zip.AddFile("Readme.txt")
+ zip.Save(zipToCreate) '' the stream is read implicitly, here
+ End Using
+ End Using
+
+
+ var c1= new System.Data.SqlClient.SqlConnection(connstring1);
+ var da = new System.Data.SqlClient.SqlDataAdapter()
+ {
+ SelectCommand= new System.Data.SqlClient.SqlCommand(strSelect, c1)
+ };
+
+ DataSet ds1 = new DataSet();
+ da.Fill(ds1, "Invoices");
+
+ using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
+ {
+ zip.AddEntry(zipEntryName, (name,stream) => ds1.WriteXml(stream) );
+ zip.Save(zipFileName);
+ }
+
+
+ using (var input = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ))
+ {
+ using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
+ {
+ zip.AddEntry(zipEntryName, (name,output) =>
+ {
+ byte[] buffer = new byte[BufferSize];
+ int n;
+ while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ // could transform the data here...
+ output.Write(buffer, 0, n);
+ // could update a progress bar here
+ }
+ });
+
+ zip.Save(zipFileName);
+ }
+ }
+
+
+ Private Sub WriteEntry (ByVal name As String, ByVal output As Stream)
+ Using input As FileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
+ Dim n As Integer = -1
+ Dim buffer As Byte() = New Byte(BufferSize){}
+ Do While n <> 0
+ n = input.Read(buffer, 0, buffer.Length)
+ output.Write(buffer, 0, n)
+ Loop
+ End Using
+ End Sub
+
+ Public Sub Run()
+ Using zip = New ZipFile
+ zip.AddEntry(zipEntryName, New WriteDelegate(AddressOf WriteEntry))
+ zip.Save(zipFileName)
+ End Using
+ End Sub
+
+
+ using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
+ {
+ zip.AddEntry(zipEntryName,
+ (name) => File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ),
+ (name, stream) => stream.Close()
+ );
+
+ zip.Save(zipFileName);
+ }
+
+
+
+
+ Function MyStreamOpener(ByVal entryName As String) As Stream
+ '' This simply opens a file. You probably want to do somethinig
+ '' more involved here: open a stream to read from a database,
+ '' open a stream on an HTTP connection, and so on.
+ Return File.OpenRead(entryName)
+ End Function
+
+ Sub MyStreamCloser(entryName As String, stream As Stream)
+ stream.Close()
+ End Sub
+
+ Public Sub Run()
+ Dim dirToZip As String = "fodder"
+ Dim zipFileToCreate As String = "Archive.zip"
+ Dim opener As OpenDelegate = AddressOf MyStreamOpener
+ Dim closer As CloseDelegate = AddressOf MyStreamCloser
+ Dim numFilestoAdd As Int32 = 4
+ Using zip As ZipFile = New ZipFile
+ Dim i As Integer
+ For i = 0 To numFilesToAdd - 1
+ zip.AddEntry(String.Format("content-{0:000}.txt"), opener, closer)
+ Next i
+ zip.Save(zipFileToCreate)
+ End Using
+ End Sub
+
+
+
+ public void ZipUp(string targetZip, string directory)
+ {
+ using (var zip = new ZipFile())
+ {
+ zip.AddDirectory(directory, System.IO.Path.GetFileName(directory));
+ zip.Save(targetZip);
+ }
+ }
+
+
+ String ZipFileToCreate = "archive1.zip";
+ String DirectoryToZip = "c:\\reports";
+ using (ZipFile zip = new ZipFile())
+ {
+ // Store all files found in the top level directory, into the zip archive.
+ String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
+ zip.AddFiles(filenames, "files");
+ zip.Save(ZipFileToCreate);
+ }
+
+
+
+ Dim ZipFileToCreate As String = "archive1.zip"
+ Dim DirectoryToZip As String = "c:\reports"
+ Using zip As ZipFile = New ZipFile()
+ Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
+ zip.AddFiles(filenames, "files")
+ zip.Save(ZipFileToCreate)
+ End Using
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ // Store all files found in the top level directory, into the zip archive.
+ // note: this code does not recurse subdirectories!
+ String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
+ zip.AddFiles(filenames, "files");
+ zip.Save("Backup.zip");
+ }
+
+
+
+ Using zip As New ZipFile
+ ' Store all files found in the top level directory, into the zip archive.
+ ' note: this code does not recurse subdirectories!
+ Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
+ zip.AddFiles(filenames, "files")
+ zip.Save("Backup.zip")
+ End Using
+
+
+ using (ZipFile zip = new ZipFile("Backup.zip", Console.Out))
+ {
+ // Store all files found in the top level directory, into the zip archive.
+ // note: this code does not recurse subdirectories!
+ // Status messages will be written to Console.Out
+ String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
+ zip.AddFiles(filenames);
+ zip.Save();
+ }
+
+
+
+ Using zip As New ZipFile("Backup.zip", Console.Out)
+ ' Store all files found in the top level directory, into the zip archive.
+ ' note: this code does not recurse subdirectories!
+ ' Status messages will be written to Console.Out
+ Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
+ zip.AddFiles(filenames)
+ zip.Save()
+ End Using
+
+
+ String ZipFileToRead = "ArchiveToModify.zip";
+ System.DateTime Threshold = new System.DateTime(2007,12,31);
+ using (ZipFile zip = ZipFile.Read(ZipFileToRead))
+ {
+ var EntriesToRemove = new System.Collections.Generic.List<ZipEntry>();
+ foreach (ZipEntry e in zip)
+ {
+ if (e.LastModified < Threshold)
+ {
+ // We cannot remove the entry from the list, within the context of
+ // an enumeration of said list.
+ // So we add the doomed entry to a list to be removed later.
+ EntriesToRemove.Add(e);
+ }
+ }
+
+ // actually remove the doomed entries.
+ foreach (ZipEntry zombie in EntriesToRemove)
+ zip.RemoveEntry(zombie);
+
+ zip.Comment= String.Format("This zip archive was updated at {0}.",
+ System.DateTime.Now.ToString("G"));
+
+ // save with a different name
+ zip.Save("Archive-Updated.zip");
+ }
+
+
+
+ Dim ZipFileToRead As String = "ArchiveToModify.zip"
+ Dim Threshold As New DateTime(2007, 12, 31)
+ Using zip As ZipFile = ZipFile.Read(ZipFileToRead)
+ Dim EntriesToRemove As New System.Collections.Generic.List(Of ZipEntry)
+ Dim e As ZipEntry
+ For Each e In zip
+ If (e.LastModified < Threshold) Then
+ ' We cannot remove the entry from the list, within the context of
+ ' an enumeration of said list.
+ ' So we add the doomed entry to a list to be removed later.
+ EntriesToRemove.Add(e)
+ End If
+ Next
+
+ ' actually remove the doomed entries.
+ Dim zombie As ZipEntry
+ For Each zombie In EntriesToRemove
+ zip.RemoveEntry(zombie)
+ Next
+ zip.Comment = String.Format("This zip archive was updated at {0}.", DateTime.Now.ToString("G"))
+ 'save as a different name
+ zip.Save("Archive-Updated.zip")
+ End Using
+
+
+ String zipFileToRead= "PackedDocuments.zip";
+ string candidate = "DatedMaterial.xps";
+ using (ZipFile zip = ZipFile.Read(zipFileToRead))
+ {
+ if (zip.EntryFilenames.Contains(candidate))
+ {
+ zip.RemoveEntry(candidate);
+ zip.Comment= String.Format("The file '{0}' has been removed from this archive.",
+ Candidate);
+ zip.Save();
+ }
+ }
+
+
+ Dim zipFileToRead As String = "PackedDocuments.zip"
+ Dim candidate As String = "DatedMaterial.xps"
+ Using zip As ZipFile = ZipFile.Read(zipFileToRead)
+ If zip.EntryFilenames.Contains(candidate) Then
+ zip.RemoveEntry(candidate)
+ zip.Comment = String.Format("The file '{0}' has been removed from this archive.", Candidate)
+ zip.Save
+ End If
+ End Using
+
+
+ using (ZipFile zip = ZipFile.Read(zipfile))
+ {
+ foreach (ZipEntry e in zip)
+ {
+ if (WantThisEntry(e.FileName))
+ zip.Extract(e.FileName, Console.OpenStandardOutput());
+ }
+ } // Dispose() is called implicitly here.
+
+
+
+ Using zip As ZipFile = ZipFile.Read(zipfile)
+ Dim e As ZipEntry
+ For Each e In zip
+ If WantThisEntry(e.FileName) Then
+ zip.Extract(e.FileName, Console.OpenStandardOutput())
+ End If
+ Next
+ End Using ' Dispose is implicity called here
+
+
+ String TargetDirectory= "unpack";
+ using(ZipFile zip= ZipFile.Read(ZipFileToExtract))
+ {
+ zip.ExtractExistingFile= ExtractExistingFileAction.OverwriteSilently;
+ zip.ExtractAll(TargetDirectory);
+ }
+
+
+
+ Dim TargetDirectory As String = "unpack"
+ Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
+ zip.ExtractExistingFile= ExtractExistingFileAction.OverwriteSilently
+ zip.ExtractAll(TargetDirectory)
+ End Using
+
+
+ String TargetDirectory= "c:\\unpack";
+ using(ZipFile zip= ZipFile.Read(ZipFileToExtract))
+ {
+ zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.DontOverwrite);
+ }
+
+
+
+ Dim TargetDirectory As String = "c:\unpack"
+ Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
+ zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.DontOverwrite)
+ End Using
+
+
+ string zipToExtract = "MyArchive.zip";
+ string extractDirectory = "extract";
+ var options = new ReadOptions
+ {
+ StatusMessageWriter = System.Console.Out,
+ Encoding = System.Text.Encoding.GetEncoding(950)
+ };
+ using (ZipFile zip = ZipFile.Read(zipToExtract, options))
+ {
+ foreach (ZipEntry e in zip)
+ {
+ e.Extract(extractDirectory);
+ }
+ }
+
+
+
+
+ Dim zipToExtract as String = "MyArchive.zip"
+ Dim extractDirectory as String = "extract"
+ Dim options as New ReadOptions
+ options.Encoding = System.Text.Encoding.GetEncoding(950)
+ options.StatusMessageWriter = System.Console.Out
+ Using zip As ZipFile = ZipFile.Read(zipToExtract, options)
+ Dim e As ZipEntry
+ For Each e In zip
+ e.Extract(extractDirectory)
+ Next
+ End Using
+
+
+ var options = new ReadOptions
+ {
+ StatusMessageWriter = new System.IO.StringWriter()
+ };
+ using (ZipFile zip = ZipFile.Read("PackedDocuments.zip", options))
+ {
+ var Threshold = new DateTime(2007,7,4);
+ // We cannot remove the entry from the list, within the context of
+ // an enumeration of said list.
+ // So we add the doomed entry to a list to be removed later.
+ // pass 1: mark the entries for removal
+ var MarkedEntries = new System.Collections.Generic.List<ZipEntry>();
+ foreach (ZipEntry e in zip)
+ {
+ if (e.LastModified < Threshold)
+ MarkedEntries.Add(e);
+ }
+ // pass 2: actually remove the entry.
+ foreach (ZipEntry zombie in MarkedEntries)
+ zip.RemoveEntry(zombie);
+ zip.Comment = "This archive has been updated.";
+ zip.Save();
+ }
+ // can now use contents of sw, eg store in an audit log
+
+
+
+ Dim options as New ReadOptions
+ options.StatusMessageWriter = New System.IO.StringWriter
+ Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip", options)
+ Dim Threshold As New DateTime(2007, 7, 4)
+ ' We cannot remove the entry from the list, within the context of
+ ' an enumeration of said list.
+ ' So we add the doomed entry to a list to be removed later.
+ ' pass 1: mark the entries for removal
+ Dim MarkedEntries As New System.Collections.Generic.List(Of ZipEntry)
+ Dim e As ZipEntry
+ For Each e In zip
+ If (e.LastModified < Threshold) Then
+ MarkedEntries.Add(e)
+ End If
+ Next
+ ' pass 2: actually remove the entry.
+ Dim zombie As ZipEntry
+ For Each zombie In MarkedEntries
+ zip.RemoveEntry(zombie)
+ Next
+ zip.Comment = "This archive has been updated."
+ zip.Save
+ End Using
+ ' can now use contents of sw, eg store in an audit log
+
+
+ using (ZipFile zip = ZipFile.Read(InputStream))
+ {
+ zip.Extract("NameOfEntryInArchive.doc", OutputStream);
+ }
+
+
+
+ Using zip as ZipFile = ZipFile.Read(InputStream)
+ zip.Extract("NameOfEntryInArchive.doc", OutputStream)
+ End Using
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddDirectory(@"c:\reports\January");
+ zip.Save("January.zip");
+ }
+
+
+
+ Using zip As New ZipFile()
+ zip.AddDirectory("c:\reports\January")
+ zip.Save("January.zip")
+ End Using
+
+
+
+ using (ZipFile zip = ZipFile.Read("ExistingArchive.zip"))
+ {
+ zip.AddFile("NewData.csv");
+ zip.Save("UpdatedArchive.zip");
+ }
+
+
+
+ Using zip As ZipFile = ZipFile.Read("ExistingArchive.zip")
+ zip.AddFile("NewData.csv")
+ zip.Save("UpdatedArchive.zip")
+ End Using
+
+
+
+ using (var zip = new Ionic.Zip.ZipFile())
+ {
+ zip.CompressionLevel= Ionic.Zlib.CompressionLevel.BestCompression;
+ zip.Password = "VerySecret.";
+ zip.Encryption = EncryptionAlgorithm.WinZipAes128;
+ zip.AddFile(sourceFileName);
+ MemoryStream output = new MemoryStream();
+ zip.Save(output);
+
+ byte[] zipbytes = output.ToArray();
+ }
+
+
+ using (var fs = new FileSteeam(filename, FileMode.Open))
+ {
+ using (var zip = Ionic.Zip.ZipFile.Read(inputStream))
+ {
+ zip.AddEntry("Name1.txt", "this is the content");
+ zip.Save(inputStream); // NO NO NO!!
+ }
+ }
+
+
+
+ using (var zip = Ionic.Zip.ZipFile.Read(filename))
+ {
+ zip.AddEntry("Name1.txt", "this is the content");
+ zip.Save(); // YES!
+ }
+
+
+
+
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ // To just match on filename wildcards,
+ // use the shorthand form of the selectionCriteria string.
+ zip.AddSelectedFiles("*.csv");
+ zip.Save(PathToZipArchive);
+ }
+
+
+ Using zip As ZipFile = New ZipFile()
+ zip.AddSelectedFiles("*.csv")
+ zip.Save(PathToZipArchive)
+ End Using
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ // Use a compound expression in the selectionCriteria string.
+ zip.AddSelectedFiles("name = *.xml and size > 1024kb", true);
+ zip.Save(PathToZipArchive);
+ }
+
+
+ Using zip As ZipFile = New ZipFile()
+ ' Use a compound expression in the selectionCriteria string.
+ zip.AddSelectedFiles("name = *.xml and size > 1024kb", true)
+ zip.Save(PathToZipArchive)
+ End Using
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ // Use a compound expression in the selectionCriteria string.
+ zip.AddSelectedFiles("name = *.xml and size > 1024kb", "d:\\rawdata");
+ zip.Save(PathToZipArchive);
+ }
+
+
+
+ Using zip As ZipFile = New ZipFile()
+ ' Use a compound expression in the selectionCriteria string.
+ zip.AddSelectedFiles("name = *.xml and size > 1024kb", "d:\rawdata)
+ zip.Save(PathToZipArchive)
+ End Using
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ // Use a compound expression in the selectionCriteria string.
+ zip.AddSelectedFiles("name = *.csv and mtime > 2009-02-14", "files", true);
+ zip.Save(PathToZipArchive);
+ }
+
+
+ Using zip As ZipFile = New ZipFile()
+ ' Use a compound expression in the selectionCriteria string.
+ zip.AddSelectedFiles("name = *.csv and mtime > 2009-02-14", "files", true)
+ zip.Save(PathToZipArchive)
+ End Using
+
+
+ Using Zip As ZipFile = New ZipFile(zipfile)
+ Zip.AddSelectedFfiles("name != 'excludethis\*.*'", datapath, True)
+ Zip.Save()
+ End Using
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ // Use a compound expression in the selectionCriteria string.
+ zip.AddSelectedFiles("name = *.psd and mtime > 2009-02-14", "photos", "content");
+ zip.Save(PathToZipArchive);
+ }
+
+
+ Using zip As ZipFile = New ZipFile
+ zip.AddSelectedFiles("name = *.psd and mtime > 2009-02-14", "photos", "content")
+ zip.Save(PathToZipArchive)
+ End Using
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddSelectedFiles("name != *.pst", SourceDirectory, "backup", true);
+ zip.Save(PathToZipArchive);
+ }
+
+
+ Using zip As ZipFile = New ZipFile
+ zip.AddSelectedFiles("name != *.pst", SourceDirectory, "backup", true)
+ zip.Save(PathToZipArchive)
+ End Using
+
+
+ using (ZipFile zip1 = ZipFile.Read(ZipFileName))
+ {
+ var PhotoShopFiles = zip1.SelectEntries("*.psd");
+ foreach (ZipEntry psd in PhotoShopFiles)
+ {
+ psd.Extract();
+ }
+ }
+
+
+ Using zip1 As ZipFile = ZipFile.Read(ZipFileName)
+ Dim PhotoShopFiles as ICollection(Of ZipEntry)
+ PhotoShopFiles = zip1.SelectEntries("*.psd")
+ Dim psd As ZipEntry
+ For Each psd In PhotoShopFiles
+ psd.Extract
+ Next
+ End Using
+
+
+ using (ZipFile zip1 = ZipFile.Read(ZipFileName))
+ {
+ var UpdatedPhotoShopFiles = zip1.SelectEntries("*.psd", "UpdatedFiles");
+ foreach (ZipEntry e in UpdatedPhotoShopFiles)
+ {
+ // prompt for extract here
+ if (WantExtract(e.FileName))
+ e.Extract();
+ }
+ }
+
+
+ Using zip1 As ZipFile = ZipFile.Read(ZipFileName)
+ Dim UpdatedPhotoShopFiles As ICollection(Of ZipEntry) = zip1.SelectEntries("*.psd", "UpdatedFiles")
+ Dim e As ZipEntry
+ For Each e In UpdatedPhotoShopFiles
+ ' prompt for extract here
+ If Me.WantExtract(e.FileName) Then
+ e.Extract
+ End If
+ Next
+ End Using
+
+
+ using (ZipFile zip1 = ZipFile.Read(ZipFileName))
+ {
+ // remove all entries from prior to Jan 1, 2008
+ zip1.RemoveEntries("mtime < 2008-01-01");
+ // don't forget to save the archive!
+ zip1.Save();
+ }
+
+
+ Using zip As ZipFile = ZipFile.Read(ZipFileName)
+ ' remove all entries from prior to Jan 1, 2008
+ zip1.RemoveEntries("mtime < 2008-01-01")
+ ' do not forget to save the archive!
+ zip1.Save
+ End Using
+
+
+ using (ZipFile zip1 = ZipFile.Read(ZipFileName))
+ {
+ // remove all entries from prior to Jan 1, 2008
+ zip1.RemoveEntries("mtime < 2008-01-01", "documents");
+ // a call to ZipFile.Save will make the modifications permanent
+ zip1.Save();
+ }
+
+
+ Using zip As ZipFile = ZipFile.Read(ZipFileName)
+ ' remove all entries from prior to Jan 1, 2008
+ zip1.RemoveEntries("mtime < 2008-01-01", "documents")
+ ' a call to ZipFile.Save will make the modifications permanent
+ zip1.Save
+ End Using
+
+
+ using (ZipFile zip = ZipFile.Read(zipArchiveName))
+ {
+ zip.ExtractSelectedEntries("name = *.xml and mtime > 2009-01-15");
+ }
+
+
+ using (ZipFile zip = ZipFile.Read(zipArchiveName))
+ {
+ zip.ExtractSelectedEntries("name = *.xml and mtime > 2009-01-15",
+ ExtractExistingFileAction.OverwriteSilently);
+ }
+
+
+ using (ZipFile zip = ZipFile.Read(zipArchiveName))
+ {
+ zip.ExtractSelectedEntries("name = *.xml and mtime > 2009-01-15","unpack");
+ }
+
+
+ using (ZipFile zip = ZipFile.Read(zipArchiveName))
+ {
+ zip.ExtractSelectedEntries("name = *.xml or size > 100000",
+ null,
+ "unpack",
+ ExtractExistingFileAction.DontOverwrite);
+ }
+
+
+ string DirectoryPath = "c:\\Documents\\Project7";
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
+ zip.Comment = "This will be embedded into a self-extracting console-based exe";
+ zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication);
+ }
+
+
+ Dim DirectoryPath As String = "c:\Documents\Project7"
+ Using zip As New ZipFile()
+ zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
+ zip.Comment = "This will be embedded into a self-extracting console-based exe"
+ zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication)
+ End Using
+
+
+ string DirectoryPath = "c:\\Documents\\Project7";
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
+ zip.Comment = "This will be embedded into a self-extracting WinForms-based exe";
+ var options = new SelfExtractorOptions
+ {
+ Flavor = SelfExtractorFlavor.WinFormsApplication,
+ DefaultExtractDirectory = "%USERPROFILE%\\ExtractHere",
+ PostExtractCommandLine = ExeToRunAfterExtract,
+ SfxExeWindowTitle = "My Custom Window Title",
+ RemoveUnpackedFilesAfterExecute = true
+ };
+ zip.SaveSelfExtractor("archive.exe", options);
+ }
+
+
+ Dim DirectoryPath As String = "c:\Documents\Project7"
+ Using zip As New ZipFile()
+ zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
+ zip.Comment = "This will be embedded into a self-extracting console-based exe"
+ Dim options As New SelfExtractorOptions()
+ options.Flavor = SelfExtractorFlavor.WinFormsApplication
+ options.DefaultExtractDirectory = "%USERPROFILE%\\ExtractHere"
+ options.PostExtractCommandLine = ExeToRunAfterExtract
+ options.SfxExeWindowTitle = "My Custom Window Title"
+ options.RemoveUnpackedFilesAfterExecute = True
+ zip.SaveSelfExtractor("archive.exe", options)
+ End Using
+
+
+ using (ZipFile zip = ZipFile.Read(zipfile))
+ {
+ bool header = true;
+ foreach (ZipEntry e in zip)
+ {
+ if (header)
+ {
+ System.Console.WriteLine("Zipfile: {0}", zip.Name);
+ System.Console.WriteLine("Version Needed: 0x{0:X2}", e.VersionNeeded);
+ System.Console.WriteLine("BitField: 0x{0:X2}", e.BitField);
+ System.Console.WriteLine("Compression Method: 0x{0:X2}", e.CompressionMethod);
+ System.Console.WriteLine("\n{1,-22} {2,-6} {3,4} {4,-8} {0}",
+ "Filename", "Modified", "Size", "Ratio", "Packed");
+ System.Console.WriteLine(new System.String('-', 72));
+ header = false;
+ }
+
+ System.Console.WriteLine("{1,-22} {2,-6} {3,4:F0}% {4,-8} {0}",
+ e.FileName,
+ e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
+ e.UncompressedSize,
+ e.CompressionRatio,
+ e.CompressedSize);
+
+ e.Extract();
+ }
+ }
+
+
+
+ Dim ZipFileToExtract As String = "c:\foo.zip"
+ Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
+ Dim header As Boolean = True
+ Dim e As ZipEntry
+ For Each e In zip
+ If header Then
+ Console.WriteLine("Zipfile: {0}", zip.Name)
+ Console.WriteLine("Version Needed: 0x{0:X2}", e.VersionNeeded)
+ Console.WriteLine("BitField: 0x{0:X2}", e.BitField)
+ Console.WriteLine("Compression Method: 0x{0:X2}", e.CompressionMethod)
+ Console.WriteLine(ChrW(10) & "{1,-22} {2,-6} {3,4} {4,-8} {0}", _
+ "Filename", "Modified", "Size", "Ratio", "Packed" )
+ Console.WriteLine(New String("-"c, 72))
+ header = False
+ End If
+ Console.WriteLine("{1,-22} {2,-6} {3,4:F0}% {4,-8} {0}", _
+ e.FileName, _
+ e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"), _
+ e.UncompressedSize, _
+ e.CompressionRatio, _
+ e.CompressedSize )
+ e.Extract
+ Next
+ End Using
+
+
+ using (var zip = new ZipFile())
+ {
+ zip.FullScan = true;
+ zip.Initialize(zipFileName);
+ zip.Save(newName);
+ }
+
+
+
+ Using zip As New ZipFile
+ zip.FullScan = True
+ zip.Initialize(zipFileName)
+ zip.Save(newName)
+ End Using
+
+
+ using (var zip = new ZipFile())
+ {
+ zip.AddFiles(filesToAdd);
+ zip.SortEntriesBeforeSaving = true;
+ zip.Save(name);
+ }
+
+
+
+ Using zip As New ZipFile
+ zip.AddFiles(filesToAdd)
+ zip.SortEntriesBeforeSaving = True
+ zip.Save(name)
+ End Using
+
+
+ using (var zip = new ZipFile())
+ {
+ zip.AddDirectoryWillTraverseReparsePoints = false;
+ zip.AddDirectory(dirToZip,"fodder");
+ zip.Save(zipFileToCreate);
+ }
+
+
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.SaveProgress += this.zip1_SaveProgress;
+ zip.AddDirectory(directoryToZip, "");
+ zip.UseZip64WhenSaving = Zip64Option.Always;
+ zip.BufferSize = 65536*8; // 65536 * 8 = 512k
+ zip.Save(ZipFileToCreate);
+ }
+
+
+ using (var zip = new ZipFile())
+ {
+ // produce a zip file the Mac will like
+ zip.EmitTimesInWindowsFormatWhenSaving = false;
+ zip.EmitTimesInUnixFormatWhenSaving = true;
+ zip.AddDirectory(directoryToZip, "files");
+ zip.Save(outputFile);
+ }
+
+
+
+ Using zip As New ZipFile
+ '' produce a zip file the Mac will like
+ zip.EmitTimesInWindowsFormatWhenSaving = False
+ zip.EmitTimesInUnixFormatWhenSaving = True
+ zip.AddDirectory(directoryToZip, "files")
+ zip.Save(outputFile)
+ End Using
+
+
+ using (var zip = ZipFile.Read(zipFileName, System.Text.Encoding.GetEncoding("big5")))
+ {
+ // retrieve and extract an entry using a name encoded with CP950
+ zip[MyDesiredEntry].Extract("unpack");
+ }
+
+
+
+ Using zip As ZipFile = ZipFile.Read(ZipToExtract, System.Text.Encoding.GetEncoding("big5"))
+ ' retrieve and extract an entry using a name encoded with CP950
+ zip(MyDesiredEntry).Extract("unpack")
+ End Using
+
+
+ using (ZipFile zip= ZipFile.Read(FilePath))
+ {
+ zip.StatusMessageTextWriter= System.Console.Out;
+ // messages are sent to the console during extraction
+ zip.ExtractAll();
+ }
+
+
+
+ Using zip As ZipFile = ZipFile.Read(FilePath)
+ zip.StatusMessageTextWriter= System.Console.Out
+ 'Status Messages will be sent to the console during extraction
+ zip.ExtractAll()
+ End Using
+
+
+
+ var sw = new System.IO.StringWriter();
+ using (ZipFile zip= ZipFile.Read(FilePath))
+ {
+ zip.StatusMessageTextWriter= sw;
+ zip.ExtractAll();
+ }
+ Console.WriteLine("{0}", sw.ToString());
+
+
+
+ Dim sw as New System.IO.StringWriter
+ Using zip As ZipFile = ZipFile.Read(FilePath)
+ zip.StatusMessageTextWriter= sw
+ zip.ExtractAll()
+ End Using
+ 'Status Messages are now available in sw
+
+
+
+ // create a file with encryption
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddFile("ReadMe.txt");
+ zip.Password= "!Secret1";
+ zip.AddFile("MapToTheSite-7440-N49th.png");
+ zip.AddFile("2008-Regional-Sales-Report.pdf");
+ zip.Save("EncryptedArchive.zip");
+ }
+
+ // extract entries that use encryption
+ using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
+ {
+ zip.Password= "!Secret1";
+ zip.ExtractAll("extractDir");
+ }
+
+
+
+
+ Using zip As New ZipFile
+ zip.AddFile("ReadMe.txt")
+ zip.Password = "123456!"
+ zip.AddFile("MapToTheSite-7440-N49th.png")
+ zip.Password= "!Secret1";
+ zip.AddFile("2008-Regional-Sales-Report.pdf")
+ zip.Save("EncryptedArchive.zip")
+ End Using
+
+
+ ' extract entries that use encryption
+ Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
+ zip.Password= "!Secret1"
+ zip.ExtractAll("extractDir")
+ End Using
+
+
+
+
+ Public Sub SaveZipFile()
+ Dim SourceFolder As String = "fodder"
+ Dim DestFile As String = "eHandler.zip"
+ Dim sw as New StringWriter
+ Using zipArchive As ZipFile = New ZipFile
+ ' Tell DotNetZip to skip any files for which it encounters an error
+ zipArchive.ZipErrorAction = ZipErrorAction.Skip
+ zipArchive.StatusMessageTextWriter = sw
+ zipArchive.AddDirectory(SourceFolder)
+ zipArchive.Save(DestFile)
+ End Using
+ ' examine sw here to see any messages
+ End Sub
+
+
+
+ // Create a zip archive with AES Encryption.
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddFile("ReadMe.txt");
+ zip.Encryption= EncryptionAlgorithm.WinZipAes256;
+ zip.Password= "Top.Secret.No.Peeking!";
+ zip.AddFile("7440-N49th.png");
+ zip.AddFile("2008-Regional-Sales-Report.pdf");
+ zip.Save("EncryptedArchive.zip");
+ }
+
+ // Extract a zip archive that uses AES Encryption.
+ // You do not need to specify the algorithm during extraction.
+ using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
+ {
+ zip.Password= "Top.Secret.No.Peeking!";
+ zip.ExtractAll("extractDirectory");
+ }
+
+
+
+ ' Create a zip that uses Encryption.
+ Using zip As New ZipFile()
+ zip.Encryption= EncryptionAlgorithm.WinZipAes256
+ zip.Password= "Top.Secret.No.Peeking!"
+ zip.AddFile("ReadMe.txt")
+ zip.AddFile("7440-N49th.png")
+ zip.AddFile("2008-Regional-Sales-Report.pdf")
+ zip.Save("EncryptedArchive.zip")
+ End Using
+
+ ' Extract a zip archive that uses AES Encryption.
+ ' You do not need to specify the algorithm during extraction.
+ Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
+ zip.Password= "Top.Secret.No.Peeking!"
+ zip.ExtractAll("extractDirectory")
+ End Using
+
+
+
+ using (ZipFile zip = ZipFile.Read("PackedDocuments.zip"))
+ {
+ foreach (string s1 in zip.EntryFilenames)
+ {
+ if (s1.EndsWith(".txt"))
+ zip[s1].Extract("textfiles");
+ }
+ }
+
+
+ Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip")
+ Dim s1 As String
+ For Each s1 In zip.EntryFilenames
+ If s1.EndsWith(".txt") Then
+ zip(s1).Extract("textfiles")
+ End If
+ Next
+ End Using
+
+
+ String zipFileToRead= "PackedDocuments.zip";
+ string candidate = "DatedMaterial.xps";
+ using (ZipFile zip = new ZipFile(zipFileToRead))
+ {
+ if (zip.EntryFilenames.Contains(candidate))
+ Console.WriteLine("The file '{0}' exists in the zip archive '{1}'",
+ candidate,
+ zipFileName);
+ else
+ Console.WriteLine("The file, '{0}', does not exist in the zip archive '{1}'",
+ candidate,
+ zipFileName);
+ Console.WriteLine();
+ }
+
+
+ Dim zipFileToRead As String = "PackedDocuments.zip"
+ Dim candidate As String = "DatedMaterial.xps"
+ Using zip As ZipFile.Read(ZipFileToRead)
+ If zip.EntryFilenames.Contains(candidate) Then
+ Console.WriteLine("The file '{0}' exists in the zip archive '{1}'", _
+ candidate, _
+ zipFileName)
+ Else
+ Console.WriteLine("The file, '{0}', does not exist in the zip archive '{1}'", _
+ candidate, _
+ zipFileName)
+ End If
+ Console.WriteLine
+ End Using
+
+
+ using (ZipFile zip = ZipFile.Read(zipFile))
+ {
+ foreach (ZipEntry entry in zip.EntriesSorted)
+ {
+ ListViewItem item = new ListViewItem(n.ToString());
+ n++;
+ string[] subitems = new string[] {
+ entry.FileName.Replace("/","\\"),
+ entry.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
+ entry.UncompressedSize.ToString(),
+ String.Format("{0,5:F0}%", entry.CompressionRatio),
+ entry.CompressedSize.ToString(),
+ (entry.UsesEncryption) ? "Y" : "N",
+ String.Format("{0:X8}", entry.Crc)};
+
+ foreach (String s in subitems)
+ {
+ ListViewItem.ListViewSubItem subitem = new ListViewItem.ListViewSubItem();
+ subitem.Text = s;
+ item.SubItems.Add(subitem);
+ }
+
+ this.listView1.Items.Add(item);
+ }
+ }
+
+
+
+
+ progressBar1.Value = 0;
+ progressBar1.Max = listbox1.Items.Count;
+ using (ZipFile zip = new ZipFile())
+ {
+ // listbox1 contains a list of filenames
+ zip.AddFiles(listbox1.Items);
+
+ // do the progress bar:
+ zip.SaveProgress += (sender, e) => {
+ if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) {
+ progressBar1.PerformStep();
+ }
+ };
+
+ zip.Save(fs);
+ }
+
+
+ static bool justHadByteUpdate= false;
+ public static void SaveProgress(object sender, SaveProgressEventArgs e)
+ {
+ if (e.EventType == ZipProgressEventType.Saving_Started)
+ Console.WriteLine("Saving: {0}", e.ArchiveName);
+
+ else if (e.EventType == ZipProgressEventType.Saving_Completed)
+ {
+ justHadByteUpdate= false;
+ Console.WriteLine();
+ Console.WriteLine("Done: {0}", e.ArchiveName);
+ }
+
+ else if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
+ {
+ if (justHadByteUpdate)
+ Console.WriteLine();
+ Console.WriteLine(" Writing: {0} ({1}/{2})",
+ e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal);
+ justHadByteUpdate= false;
+ }
+
+ else if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead)
+ {
+ if (justHadByteUpdate)
+ Console.SetCursorPosition(0, Console.CursorTop);
+ Console.Write(" {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer,
+ e.BytesTransferred / (0.01 * e.TotalBytesToTransfer ));
+ justHadByteUpdate= true;
+ }
+ }
+
+ public static ZipUp(string targetZip, string directory)
+ {
+ using (var zip = new ZipFile()) {
+ zip.SaveProgress += SaveProgress;
+ zip.AddDirectory(directory);
+ zip.Save(targetZip);
+ }
+ }
+
+
+
+
+ Public Sub ZipUp(ByVal targetZip As String, ByVal directory As String)
+ Using zip As ZipFile = New ZipFile
+ AddHandler zip.SaveProgress, AddressOf MySaveProgress
+ zip.AddDirectory(directory)
+ zip.Save(targetZip)
+ End Using
+ End Sub
+
+ Private Shared justHadByteUpdate As Boolean = False
+
+ Public Shared Sub MySaveProgress(ByVal sender As Object, ByVal e As SaveProgressEventArgs)
+ If (e.EventType Is ZipProgressEventType.Saving_Started) Then
+ Console.WriteLine("Saving: {0}", e.ArchiveName)
+
+ ElseIf (e.EventType Is ZipProgressEventType.Saving_Completed) Then
+ justHadByteUpdate = False
+ Console.WriteLine
+ Console.WriteLine("Done: {0}", e.ArchiveName)
+
+ ElseIf (e.EventType Is ZipProgressEventType.Saving_BeforeWriteEntry) Then
+ If justHadByteUpdate Then
+ Console.WriteLine
+ End If
+ Console.WriteLine(" Writing: {0} ({1}/{2})", e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal)
+ justHadByteUpdate = False
+
+ ElseIf (e.EventType Is ZipProgressEventType.Saving_EntryBytesRead) Then
+ If justHadByteUpdate Then
+ Console.SetCursorPosition(0, Console.CursorTop)
+ End If
+ Console.Write(" {0}/{1} ({2:N0}%)", e.BytesTransferred, _
+ e.TotalBytesToTransfer, _
+ (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)))
+ justHadByteUpdate = True
+ End If
+ End Sub
+
+
+ delegate void SaveEntryProgress(SaveProgressEventArgs e);
+ delegate void ButtonClick(object sender, EventArgs e);
+
+ public class WorkerOptions
+ {
+ public string ZipName;
+ public string Folder;
+ public string Encoding;
+ public string Comment;
+ public int ZipFlavor;
+ public Zip64Option Zip64;
+ }
+
+ private int _progress2MaxFactor;
+ private bool _saveCanceled;
+ private long _totalBytesBeforeCompress;
+ private long _totalBytesAfterCompress;
+ private Thread _workerThread;
+
+
+ private void btnZipup_Click(object sender, EventArgs e)
+ {
+ KickoffZipup();
+ }
+
+ private void btnCancel_Click(object sender, EventArgs e)
+ {
+ if (this.lblStatus.InvokeRequired)
+ {
+ this.lblStatus.Invoke(new ButtonClick(this.btnCancel_Click), new object[] { sender, e });
+ }
+ else
+ {
+ _saveCanceled = true;
+ lblStatus.Text = "Canceled...";
+ ResetState();
+ }
+ }
+
+ private void KickoffZipup()
+ {
+ _folderName = tbDirName.Text;
+
+ if (_folderName == null || _folderName == "") return;
+ if (this.tbZipName.Text == null || this.tbZipName.Text == "") return;
+
+ // check for existence of the zip file:
+ if (System.IO.File.Exists(this.tbZipName.Text))
+ {
+ var dlgResult = MessageBox.Show(String.Format("The file you have specified ({0}) already exists." +
+ " Do you want to overwrite this file?", this.tbZipName.Text),
+ "Confirmation is Required", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
+ if (dlgResult != DialogResult.Yes) return;
+ System.IO.File.Delete(this.tbZipName.Text);
+ }
+
+ _saveCanceled = false;
+ _nFilesCompleted = 0;
+ _totalBytesAfterCompress = 0;
+ _totalBytesBeforeCompress = 0;
+ this.btnOk.Enabled = false;
+ this.btnOk.Text = "Zipping...";
+ this.btnCancel.Enabled = true;
+ lblStatus.Text = "Zipping...";
+
+ var options = new WorkerOptions
+ {
+ ZipName = this.tbZipName.Text,
+ Folder = _folderName,
+ Encoding = "ibm437"
+ };
+
+ if (this.comboBox1.SelectedIndex != 0)
+ {
+ options.Encoding = this.comboBox1.SelectedItem.ToString();
+ }
+
+ if (this.radioFlavorSfxCmd.Checked)
+ options.ZipFlavor = 2;
+ else if (this.radioFlavorSfxGui.Checked)
+ options.ZipFlavor = 1;
+ else options.ZipFlavor = 0;
+
+ if (this.radioZip64AsNecessary.Checked)
+ options.Zip64 = Zip64Option.AsNecessary;
+ else if (this.radioZip64Always.Checked)
+ options.Zip64 = Zip64Option.Always;
+ else options.Zip64 = Zip64Option.Never;
+
+ options.Comment = String.Format("Encoding:{0} || Flavor:{1} || ZIP64:{2}\r\nCreated at {3} || {4}\r\n",
+ options.Encoding,
+ FlavorToString(options.ZipFlavor),
+ options.Zip64.ToString(),
+ System.DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"),
+ this.Text);
+
+ if (this.tbComment.Text != TB_COMMENT_NOTE)
+ options.Comment += this.tbComment.Text;
+
+ _workerThread = new Thread(this.DoSave);
+ _workerThread.Name = "Zip Saver thread";
+ _workerThread.Start(options);
+ this.Cursor = Cursors.WaitCursor;
+ }
+
+
+ private void DoSave(Object p)
+ {
+ WorkerOptions options = p as WorkerOptions;
+ try
+ {
+ using (var zip1 = new ZipFile())
+ {
+ zip1.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(options.Encoding);
+ zip1.Comment = options.Comment;
+ zip1.AddDirectory(options.Folder);
+ _entriesToZip = zip1.EntryFileNames.Count;
+ SetProgressBars();
+ zip1.SaveProgress += this.zip1_SaveProgress;
+
+ zip1.UseZip64WhenSaving = options.Zip64;
+
+ if (options.ZipFlavor == 1)
+ zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.WinFormsApplication);
+ else if (options.ZipFlavor == 2)
+ zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.ConsoleApplication);
+ else
+ zip1.Save(options.ZipName);
+ }
+ }
+ catch (System.Exception exc1)
+ {
+ MessageBox.Show(String.Format("Exception while zipping: {0}", exc1.Message));
+ btnCancel_Click(null, null);
+ }
+ }
+
+
+
+ void zip1_SaveProgress(object sender, SaveProgressEventArgs e)
+ {
+ switch (e.EventType)
+ {
+ case ZipProgressEventType.Saving_AfterWriteEntry:
+ StepArchiveProgress(e);
+ break;
+ case ZipProgressEventType.Saving_EntryBytesRead:
+ StepEntryProgress(e);
+ break;
+ case ZipProgressEventType.Saving_Completed:
+ SaveCompleted();
+ break;
+ case ZipProgressEventType.Saving_AfterSaveTempArchive:
+ // this event only occurs when saving an SFX file
+ TempArchiveSaved();
+ break;
+ }
+ if (_saveCanceled)
+ e.Cancel = true;
+ }
+
+
+
+ private void StepArchiveProgress(SaveProgressEventArgs e)
+ {
+ if (this.progressBar1.InvokeRequired)
+ {
+ this.progressBar1.Invoke(new SaveEntryProgress(this.StepArchiveProgress), new object[] { e });
+ }
+ else
+ {
+ if (!_saveCanceled)
+ {
+ _nFilesCompleted++;
+ this.progressBar1.PerformStep();
+ _totalBytesAfterCompress += e.CurrentEntry.CompressedSize;
+ _totalBytesBeforeCompress += e.CurrentEntry.UncompressedSize;
+
+ // reset the progress bar for the entry:
+ this.progressBar2.Value = this.progressBar2.Maximum = 1;
+
+ this.Update();
+ }
+ }
+ }
+
+
+ private void StepEntryProgress(SaveProgressEventArgs e)
+ {
+ if (this.progressBar2.InvokeRequired)
+ {
+ this.progressBar2.Invoke(new SaveEntryProgress(this.StepEntryProgress), new object[] { e });
+ }
+ else
+ {
+ if (!_saveCanceled)
+ {
+ if (this.progressBar2.Maximum == 1)
+ {
+ // reset
+ Int64 max = e.TotalBytesToTransfer;
+ _progress2MaxFactor = 0;
+ while (max > System.Int32.MaxValue)
+ {
+ max /= 2;
+ _progress2MaxFactor++;
+ }
+ this.progressBar2.Maximum = (int)max;
+ lblStatus.Text = String.Format("{0} of {1} files...({2})",
+ _nFilesCompleted + 1, _entriesToZip, e.CurrentEntry.FileName);
+ }
+
+ int xferred = e.BytesTransferred >> _progress2MaxFactor;
+
+ this.progressBar2.Value = (xferred >= this.progressBar2.Maximum)
+ ? this.progressBar2.Maximum
+ : xferred;
+
+ this.Update();
+ }
+ }
+ }
+
+ private void SaveCompleted()
+ {
+ if (this.lblStatus.InvokeRequired)
+ {
+ this.lblStatus.Invoke(new MethodInvoker(this.SaveCompleted));
+ }
+ else
+ {
+ lblStatus.Text = String.Format("Done, Compressed {0} files, {1:N0}% of original.",
+ _nFilesCompleted, (100.00 * _totalBytesAfterCompress) / _totalBytesBeforeCompress);
+ ResetState();
+ }
+ }
+
+ private void ResetState()
+ {
+ this.btnCancel.Enabled = false;
+ this.btnOk.Enabled = true;
+ this.btnOk.Text = "Zip it!";
+ this.progressBar1.Value = 0;
+ this.progressBar2.Value = 0;
+ this.Cursor = Cursors.Default;
+ if (!_workerThread.IsAlive)
+ _workerThread.Join();
+ }
+
+
+
+
+
+
+
+
+ private static bool justHadByteUpdate = false;
+ public static void ExtractProgress(object sender, ExtractProgressEventArgs e)
+ {
+ if(e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
+ {
+ if (justHadByteUpdate)
+ Console.SetCursorPosition(0, Console.CursorTop);
+
+ Console.Write(" {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer,
+ e.BytesTransferred / (0.01 * e.TotalBytesToTransfer ));
+ justHadByteUpdate = true;
+ }
+ else if(e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
+ {
+ if (justHadByteUpdate)
+ Console.WriteLine();
+ Console.WriteLine("Extracting: {0}", e.CurrentEntry.FileName);
+ justHadByteUpdate= false;
+ }
+ }
+
+ public static ExtractZip(string zipToExtract, string directory)
+ {
+ string TargetDirectory= "extract";
+ using (var zip = ZipFile.Read(zipToExtract)) {
+ zip.ExtractProgress += ExtractProgress;
+ foreach (var e in zip1)
+ {
+ e.Extract(TargetDirectory, true);
+ }
+ }
+ }
+
+
+
+ Public Shared Sub Main(ByVal args As String())
+ Dim ZipToUnpack As String = "C1P3SML.zip"
+ Dim TargetDir As String = "ExtractTest_Extract"
+ Console.WriteLine("Extracting file {0} to {1}", ZipToUnpack, TargetDir)
+ Using zip1 As ZipFile = ZipFile.Read(ZipToUnpack)
+ AddHandler zip1.ExtractProgress, AddressOf MyExtractProgress
+ Dim e As ZipEntry
+ For Each e In zip1
+ e.Extract(TargetDir, True)
+ Next
+ End Using
+ End Sub
+
+ Private Shared justHadByteUpdate As Boolean = False
+
+ Public Shared Sub MyExtractProgress(ByVal sender As Object, ByVal e As ExtractProgressEventArgs)
+ If (e.EventType = ZipProgressEventType.Extracting_EntryBytesWritten) Then
+ If ExtractTest.justHadByteUpdate Then
+ Console.SetCursorPosition(0, Console.CursorTop)
+ End If
+ Console.Write(" {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer, (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)))
+ ExtractTest.justHadByteUpdate = True
+ ElseIf (e.EventType = ZipProgressEventType.Extracting_BeforeExtractEntry) Then
+ If ExtractTest.justHadByteUpdate Then
+ Console.WriteLine
+ End If
+ Console.WriteLine("Extracting: {0}", e.CurrentEntry.FileName)
+ ExtractTest.justHadByteUpdate = False
+ End If
+ End Sub
+
+
+
+ int _numEntriesToAdd= 0;
+ int _numEntriesAdded= 0;
+ void AddProgressHandler(object sender, AddProgressEventArgs e)
+ {
+ switch (e.EventType)
+ {
+ case ZipProgressEventType.Adding_Started:
+ Console.WriteLine("Adding files to the zip...");
+ break;
+ case ZipProgressEventType.Adding_AfterAddEntry:
+ _numEntriesAdded++;
+ Console.WriteLine(String.Format("Adding file {0}/{1} :: {2}",
+ _numEntriesAdded, _numEntriesToAdd, e.CurrentEntry.FileName));
+ break;
+ case ZipProgressEventType.Adding_Completed:
+ Console.WriteLine("Added all files");
+ break;
+ }
+ }
+
+ void CreateTheZip()
+ {
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddProgress += AddProgressHandler;
+ zip.AddDirectory(System.IO.Path.GetFileName(DirToZip));
+ zip.Save(ZipFileToCreate);
+ }
+ }
+
+
+
+
+
+ Private Sub AddProgressHandler(ByVal sender As Object, ByVal e As AddProgressEventArgs)
+ Select Case e.EventType
+ Case ZipProgressEventType.Adding_Started
+ Console.WriteLine("Adding files to the zip...")
+ Exit Select
+ Case ZipProgressEventType.Adding_AfterAddEntry
+ Console.WriteLine(String.Format("Adding file {0}", e.CurrentEntry.FileName))
+ Exit Select
+ Case ZipProgressEventType.Adding_Completed
+ Console.WriteLine("Added all files")
+ Exit Select
+ End Select
+ End Sub
+
+ Sub CreateTheZip()
+ Using zip as ZipFile = New ZipFile
+ AddHandler zip.AddProgress, AddressOf AddProgressHandler
+ zip.AddDirectory(System.IO.Path.GetFileName(DirToZip))
+ zip.Save(ZipFileToCreate);
+ End Using
+ End Sub
+
+
+
+
+
+ public static void MyZipError(object sender, ZipErrorEventArgs e)
+ {
+ Console.WriteLine("Error saving {0}...", e.FileName);
+ Console.WriteLine(" Exception: {0}", e.exception);
+ ZipEntry entry = e.CurrentEntry;
+ string response = null;
+ // Ask the user whether he wants to skip this error or not
+ do
+ {
+ Console.Write("Retry, Skip, Throw, or Cancel ? (R/S/T/C) ");
+ response = Console.ReadLine();
+ Console.WriteLine();
+
+ } while (response != null &&
+ response[0]!='S' && response[0]!='s' &&
+ response[0]!='R' && response[0]!='r' &&
+ response[0]!='T' && response[0]!='t' &&
+ response[0]!='C' && response[0]!='c');
+
+ e.Cancel = (response[0]=='C' || response[0]=='c');
+
+ if (response[0]=='S' || response[0]=='s')
+ entry.ZipErrorAction = ZipErrorAction.Skip;
+ else if (response[0]=='R' || response[0]=='r')
+ entry.ZipErrorAction = ZipErrorAction.Retry;
+ else if (response[0]=='T' || response[0]=='t')
+ entry.ZipErrorAction = ZipErrorAction.Throw;
+ }
+
+ public void SaveTheFile()
+ {
+ string directoryToZip = "fodder";
+ string directoryInArchive = "files";
+ string zipFileToCreate = "Archive.zip";
+ using (var zip = new ZipFile())
+ {
+ // set the event handler before adding any entries
+ zip.ZipError += MyZipError;
+ zip.AddDirectory(directoryToZip, directoryInArchive);
+ zip.Save(zipFileToCreate);
+ }
+ }
+
+
+
+ Private Sub MyZipError(ByVal sender As Object, ByVal e As Ionic.Zip.ZipErrorEventArgs)
+ ' At this point, the application could prompt the user for an action to take.
+ ' But in this case, this application will simply automatically skip the file, in case of error.
+ Console.WriteLine("Zip Error, entry {0}", e.CurrentEntry.FileName)
+ Console.WriteLine(" Exception: {0}", e.exception)
+ ' set the desired ZipErrorAction on the CurrentEntry to communicate that to DotNetZip
+ e.CurrentEntry.ZipErrorAction = Zip.ZipErrorAction.Skip
+ End Sub
+
+ Public Sub SaveTheFile()
+ Dim directoryToZip As String = "fodder"
+ Dim directoryInArchive As String = "files"
+ Dim zipFileToCreate as String = "Archive.zip"
+ Using zipArchive As ZipFile = New ZipFile
+ ' set the event handler before adding any entries
+ AddHandler zipArchive.ZipError, AddressOf MyZipError
+ zipArchive.AddDirectory(directoryToZip, directoryInArchive)
+ zipArchive.Save(zipFileToCreate)
+ End Using
+ End Sub
+
+
+
+
+
+
+
+
+
+ var fname = "logfile.log.bz2";
+ using (var fs = File.OpenRead(fname))
+ {
+ using (var decompressor = new Ionic.BZip2.BZip2InputStream(fs))
+ {
+ var outFname = fname + ".decompressed";
+ using (var output = File.Create(outFname))
+ {
+ byte[] buffer = new byte[2048];
+ int n;
+ while ((n = decompressor.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ output.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+ var fname = "logfile.log";
+ using (var fs = File.OpenRead(fname))
+ {
+ var outFname = fname + ".bz2";
+ using (var output = File.Create(outFname))
+ {
+ using (var compressor = new Ionic.BZip2.BZip2OutputStream(output))
+ {
+ byte[] buffer = new byte[2048];
+ int n;
+ while ((n = fs.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+ var fname = "logfile.log";
+ using (var fs = File.OpenRead(fname))
+ {
+ var outFname = fname + ".bz2";
+ using (var output = File.Create(outFname))
+ {
+ using (var compressor = new Ionic.BZip2.ParallelBZip2OutputStream(output))
+ {
+ byte[] buffer = new byte[2048];
+ int n;
+ while ((n = fs.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))
+ {
+ using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n;
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using raw As FileStream = File.Create(fileToCompress & ".deflated")
+ Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ End Using
+
+
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))
+ {
+ using (Stream compressor = new DeflateStream(raw,
+ CompressionMode.Compress,
+ CompressionLevel.BestCompression))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n= -1;
+ while (n != 0)
+ {
+ if (n > 0)
+ compressor.Write(buffer, 0, n);
+ n= input.Read(buffer, 0, buffer.Length);
+ }
+ }
+ }
+ }
+
+
+
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using raw As FileStream = File.Create(fileToCompress & ".deflated")
+ Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ End Using
+
+
+ using (var output = System.IO.File.Create(fileToCompress + ".deflated"))
+ {
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n= -1;
+ while (n != 0)
+ {
+ if (n > 0)
+ compressor.Write(buffer, 0, n);
+ n= input.Read(buffer, 0, buffer.Length);
+ }
+ }
+ }
+ // can write additional data to the output stream here
+ }
+
+
+
+ Using output As FileStream = File.Create(fileToCompress & ".deflated")
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ ' can write additional data to the output stream here.
+ End Using
+
+
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (var raw = System.IO.File.Create(outputFile))
+ {
+ using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n;
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+ Dim outputFile As String = (fileToCompress & ".compressed")
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using raw As FileStream = File.Create(outputFile)
+ Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ End Using
+
+
+ private void GunZipFile(string filename)
+ {
+ if (!filename.EndsWith(".gz))
+ throw new ArgumentException("filename");
+ var DecompressedFile = filename.Substring(0,filename.Length-3);
+ byte[] working = new byte[WORKING_BUFFER_SIZE];
+ int n= 1;
+ using (System.IO.Stream input = System.IO.File.OpenRead(filename))
+ {
+ using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true))
+ {
+ using (var output = System.IO.File.Create(DecompressedFile))
+ {
+ while (n !=0)
+ {
+ n= decompressor.Read(working, 0, working.Length);
+ if (n > 0)
+ {
+ output.Write(working, 0, n);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+ Private Sub GunZipFile(ByVal filename as String)
+ If Not (filename.EndsWith(".gz)) Then
+ Throw New ArgumentException("filename")
+ End If
+ Dim DecompressedFile as String = filename.Substring(0,filename.Length-3)
+ Dim working(WORKING_BUFFER_SIZE) as Byte
+ Dim n As Integer = 1
+ Using input As Stream = File.OpenRead(filename)
+ Using decompressor As Stream = new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, True)
+ Using output As Stream = File.Create(UncompressedFile)
+ Do
+ n= decompressor.Read(working, 0, working.Length)
+ If n > 0 Then
+ output.Write(working, 0, n)
+ End IF
+ Loop While (n > 0)
+ End Using
+ End Using
+ End Using
+ End Sub
+
+
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (var raw = System.IO.File.Create(fileToCompress + ".gz"))
+ {
+ using (Stream compressor = new GZipStream(raw,
+ CompressionMode.Compress,
+ CompressionLevel.BestCompression))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n;
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using raw As FileStream = File.Create(fileToCompress & ".gz")
+ Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ End Using
+
+
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (var raw = System.IO.File.Create(outputFile))
+ {
+ using (Stream compressor = new GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, true))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n;
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+ Dim outputFile As String = (fileToCompress & ".compressed")
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using raw As FileStream = File.Create(outputFile)
+ Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, True)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ End Using
+
+
+ byte[] working = new byte[WORKING_BUFFER_SIZE];
+ using (System.IO.Stream input = System.IO.File.OpenRead(_CompressedFile))
+ {
+ using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true))
+ {
+ using (var output = System.IO.File.Create(_DecompressedFile))
+ {
+ int n;
+ while ((n= decompressor.Read(working, 0, working.Length)) !=0)
+ {
+ output.Write(working, 0, n);
+ }
+ }
+ }
+ }
+
+
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n= -1;
+ String outputFile = fileToCompress + ".compressed";
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (var raw = System.IO.File.Create(outputFile))
+ {
+ using (Stream compressor = new ParallelDeflateOutputStream(raw))
+ {
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Dim outputFile As String = (fileToCompress & ".compressed")
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using raw As FileStream = File.Create(outputFile)
+ Using compressor As Stream = New ParallelDeflateOutputStream(raw)
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ End Using
+
+
+ ParallelDeflateOutputStream deflater = null;
+ foreach (var inputFile in listOfFiles)
+ {
+ string outputFile = inputFile + ".compressed";
+ using (System.IO.Stream input = System.IO.File.OpenRead(inputFile))
+ {
+ using (var outStream = System.IO.File.Create(outputFile))
+ {
+ if (deflater == null)
+ deflater = new ParallelDeflateOutputStream(outStream,
+ CompressionLevel.Best,
+ CompressionStrategy.Default,
+ true);
+ deflater.Reset(outStream);
+
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ deflater.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+ var adler = Adler.Adler32(0, null, 0, 0);
+ adler = Adler.Adler32(adler, buffer, index, length);
+
+
+ private void InflateBuffer()
+ {
+ int bufferSize = 1024;
+ byte[] buffer = new byte[bufferSize];
+ ZlibCodec decompressor = new ZlibCodec();
+
+ Console.WriteLine("\n============================================");
+ Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length);
+ MemoryStream ms = new MemoryStream(DecompressedBytes);
+
+ int rc = decompressor.InitializeInflate();
+
+ decompressor.InputBuffer = CompressedBytes;
+ decompressor.NextIn = 0;
+ decompressor.AvailableBytesIn = CompressedBytes.Length;
+
+ decompressor.OutputBuffer = buffer;
+
+ // pass 1: inflate
+ do
+ {
+ decompressor.NextOut = 0;
+ decompressor.AvailableBytesOut = buffer.Length;
+ rc = decompressor.Inflate(FlushType.None);
+
+ if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
+ throw new Exception("inflating: " + decompressor.Message);
+
+ ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut);
+ }
+ while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0);
+
+ // pass 2: finish and flush
+ do
+ {
+ decompressor.NextOut = 0;
+ decompressor.AvailableBytesOut = buffer.Length;
+ rc = decompressor.Inflate(FlushType.Finish);
+
+ if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
+ throw new Exception("inflating: " + decompressor.Message);
+
+ if (buffer.Length - decompressor.AvailableBytesOut > 0)
+ ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut);
+ }
+ while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0);
+
+ decompressor.EndInflate();
+ }
+
+
+
+ int bufferSize = 40000;
+ byte[] CompressedBytes = new byte[bufferSize];
+ byte[] DecompressedBytes = new byte[bufferSize];
+
+ ZlibCodec compressor = new ZlibCodec();
+
+ compressor.InitializeDeflate(CompressionLevel.Default);
+
+ compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress);
+ compressor.NextIn = 0;
+ compressor.AvailableBytesIn = compressor.InputBuffer.Length;
+
+ compressor.OutputBuffer = CompressedBytes;
+ compressor.NextOut = 0;
+ compressor.AvailableBytesOut = CompressedBytes.Length;
+
+ while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize)
+ {
+ compressor.Deflate(FlushType.None);
+ }
+
+ while (true)
+ {
+ int rc= compressor.Deflate(FlushType.Finish);
+ if (rc == ZlibConstants.Z_STREAM_END) break;
+ }
+
+ compressor.EndDeflate();
+
+
+
+ private void DeflateBuffer(CompressionLevel level)
+ {
+ int bufferSize = 1024;
+ byte[] buffer = new byte[bufferSize];
+ ZlibCodec compressor = new ZlibCodec();
+
+ Console.WriteLine("\n============================================");
+ Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length);
+ MemoryStream ms = new MemoryStream();
+
+ int rc = compressor.InitializeDeflate(level);
+
+ compressor.InputBuffer = UncompressedBytes;
+ compressor.NextIn = 0;
+ compressor.AvailableBytesIn = UncompressedBytes.Length;
+
+ compressor.OutputBuffer = buffer;
+
+ // pass 1: deflate
+ do
+ {
+ compressor.NextOut = 0;
+ compressor.AvailableBytesOut = buffer.Length;
+ rc = compressor.Deflate(FlushType.None);
+
+ if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
+ throw new Exception("deflating: " + compressor.Message);
+
+ ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut);
+ }
+ while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0);
+
+ // pass 2: finish and flush
+ do
+ {
+ compressor.NextOut = 0;
+ compressor.AvailableBytesOut = buffer.Length;
+ rc = compressor.Deflate(FlushType.Finish);
+
+ if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
+ throw new Exception("deflating: " + compressor.Message);
+
+ if (buffer.Length - compressor.AvailableBytesOut > 0)
+ ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
+ }
+ while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0);
+
+ compressor.EndDeflate();
+
+ ms.Seek(0, SeekOrigin.Begin);
+ CompressedBytes = new byte[compressor.TotalBytesOut];
+ ms.Read(CompressedBytes, 0, CompressedBytes.Length);
+ }
+
+
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (var raw = System.IO.File.Create(fileToCompress + ".zlib"))
+ {
+ using (Stream compressor = new ZlibStream(raw, CompressionMode.Compress))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n;
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using raw As FileStream = File.Create(fileToCompress & ".zlib")
+ Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ End Using
+
+
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (var raw = System.IO.File.Create(fileToCompress + ".zlib"))
+ {
+ using (Stream compressor = new ZlibStream(raw,
+ CompressionMode.Compress,
+ CompressionLevel.BestCompression))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n;
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ }
+
+
+
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using raw As FileStream = File.Create(fileToCompress & ".zlib")
+ Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ End Using
+
+
+ using (var output = System.IO.File.Create(fileToCompress + ".zlib"))
+ {
+ using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
+ {
+ using (Stream compressor = new ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true))
+ {
+ byte[] buffer = new byte[WORKING_BUFFER_SIZE];
+ int n;
+ while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
+ {
+ compressor.Write(buffer, 0, n);
+ }
+ }
+ }
+ // can write additional data to the output stream here
+ }
+
+
+ Using output As FileStream = File.Create(fileToCompress & ".zlib")
+ Using input As Stream = File.OpenRead(fileToCompress)
+ Using compressor As Stream = New ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True)
+ Dim buffer As Byte() = New Byte(4096) {}
+ Dim n As Integer = -1
+ Do While (n <> 0)
+ If (n > 0) Then
+ compressor.Write(buffer, 0, n)
+ End If
+ n = input.Read(buffer, 0, buffer.Length)
+ Loop
+ End Using
+ End Using
+ ' can write additional data to the output stream here.
+ End Using
+
+ Dimension
class encapsulates the width and
+ /// height of a component (in int precision) in a single object.
+ /// Component
class and the
+ /// LayoutManager
interface return a Dimension
object.
+ ///
+ /// Normally the values of width
+ /// and height
are non-negative ints.
+ /// The constructors that allow you to create a dimension do
+ /// not prevent you from setting a negative value for these properties.
+ /// If the value of width
or height
is
+ /// negative, the behavior of some methods defined by other objects is
+ /// undefined.
+ /// Dimension
with a width
+ /// of zero and a height of zero.
+ /// Dimension
whose width
+ /// and height are the same as for the specified dimension.
+ /// width
and
+ /// height
values.
+ ///
+ public Dimension(Dimension d) : this(d.width, d.height) {}
+
+ /// Dimension
object.
+ /// Dimension
object
+ /// to the specified width and height.
+ /// Dimension
object.
+ /// the new height for this Dimension
object.
+ public void SetSize(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ /// Dimension
object's height
and
+ /// width
fields.
+ /// null
.
+ /// Dimension
+ /// object.
+ /// Dimension2D
class is to encapsulate a width
+ /// and a height dimension.
+ /// Dimension
in double
+ /// precision.
+ /// Dimension
in double
+ /// precision.
+ /// Dimension
object to the
+ /// specified width and height.
+ /// Dimension
+ /// object
+ /// the new height for the Dimension
+ /// object
+ public abstract void SetSize(double width, double height);
+
+ /// Dimension2D
object to
+ /// match the specified size.
+ /// Anchor
with a certain Phrase
.
+ *
+ * @param phrase a Phrase
+ */
+ public Anchor(Phrase phrase) : base(phrase) {
+ if (phrase is Anchor) {
+ Anchor a = (Anchor) phrase;
+ Name = a.name;
+ Reference = a.reference;
+ }
+ }
+ // implementation of the Element-methods
+
+ ///
+ /// Table table = new Table(3);
+ /// table.SetBorderWidth(1);
+ /// table.SetBorderColor(new Color(0, 0, 255));
+ /// table.SetCellpadding(5);
+ /// table.SetCellspacing(5);
+ /// Cell cell = new Cell("header");
+ /// cell.SetHeader(true);
+ /// cell.SetColspan(3);
+ /// table.AddCell(cell);
+ /// cell = new Cell("example cell with colspan 1 and rowspan 2");
+ /// cell.SetRowspan(2);
+ /// cell.SetBorderColor(new Color(255, 0, 0));
+ /// table.AddCell(cell);
+ /// table.AddCell("1.1");
+ /// table.AddCell("2.1");
+ /// table.AddCell("1.2");
+ /// table.AddCell("2.2");
+ ///
+ /// Cell
force a group change? Cell
force a group change?
+ ///
+ /// Paragraph title2 = new Paragraph("This is Chapter 2", FontFactory.GetFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
+ /// Chapter chapter2 = new Chapter(title2, 2);
+ /// chapter2.SetNumberDepth(0);
+ /// Paragraph someText = new Paragraph("This is some text");
+ /// chapter2.Add(someText);
+ /// Paragraph title21 = new Paragraph("This is Section 1 in Chapter 2", FontFactory.GetFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
+ /// Section section1 = chapter2.AddSection(title21);
+ /// Paragraph someSectionText = new Paragraph("This is some silly paragraph in a chapter and/or section. It contains some text to test the functionality of Chapters and Section.");
+ /// section1.Add(someSectionText);
+ ///
+ /// Chapter
.
+ * @param number the Chapter number
+ */
+
+ public Chapter(int number) : base (null, 1) {
+ numbers = new ArrayList();
+ numbers.Add(number);
+ triggerNewPage = true;
+ }
+
+ /// Paragraph
)
+ */
+ public ChapterAutoNumber(Paragraph para) : base(para, 0) {
+ }
+
+ /**
+ * Create a new objet.
+ *
+ * @param title the Chapter title (as a String
)
+ */
+ public ChapterAutoNumber(String title) : base(title, 0) {
+ }
+
+ /**
+ * Create a new section for this chapter and ad it.
+ *
+ * @param title the Section title (as a String
)
+ * @return Returns the new section.
+ */
+ public override Section AddSection(String title) {
+ if (AddedCompletely) {
+ throw new InvalidOperationException("This LargeElement has already been added to the Document.");
+ }
+ return AddSection(title, 2);
+ }
+
+ /**
+ * Create a new section for this chapter and add it.
+ *
+ * @param title the Section title (as a Paragraph
)
+ * @return Returns the new section.
+ */
+ public override Section AddSection(Paragraph title) {
+ if (AddedCompletely) {
+ throw new InvalidOperationException("This LargeElement has already been added to the Document.");
+ }
+ return AddSection(title, 2);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/Chunk.cs b/iTechSharp/iTextSharp/text/Chunk.cs
new file mode 100644
index 0000000..ee7377b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/Chunk.cs
@@ -0,0 +1,733 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.util;
+
+using iTextSharp.text.pdf;
+using iTextSharp.text.html;
+using iTextSharp.text.factories;
+using iTextSharp.text.pdf.draw;
+
+/*
+ * $Id: Chunk.cs,v 1.20 2008/05/13 11:25:09 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text {
+ ///
+ /// Chunk chunk = new Chunk("Hello world", FontFactory.GetFont(FontFactory.COURIER, 20, Font.ITALIC, new Color(255, 0, 0)));
+ /// document.Add(chunk);
+ ///
+ /// Chunk
copy constructor.
+ * @param ck the Chunk
to be copied
+ */
+ public Chunk(Chunk ck) {
+ if (ck.content != null) {
+ content = new StringBuilder(ck.content.ToString());
+ }
+ if (ck.font != null) {
+ font = new Font(ck.font);
+ }
+ }
+
+ /// Font
.
+ *
+ * @param c the content
+ * @param font the font
+ */
+ public Chunk(char c, Font font) {
+ this.content = new StringBuilder();
+ this.content.Append(c);
+ this.font = font;
+ }
+
+ /**
+ * Constructs a chunk of text with a char, without specifying a Font
.
+ *
+ * @param c the content
+ */
+ public Chunk(char c) : this(c, new Font()) {
+ }
+
+ /// Chunk
+ */
+ public Chunk SetHorizontalScaling(float scale) {
+ return SetAttribute(HSCALE, scale);
+ }
+
+ /**
+ * Gets the horizontal scaling.
+ * @return a percentage in float
+ */
+ public float HorizontalScaling {
+ get {
+ if (attributes == null) return 1f;
+ Object f = attributes[HSCALE];
+ if (f == null) return 1f;
+ return (float)f;
+ }
+ }
+
+ ///Chunk
width. Multiple call to this method will
+ * produce multiple lines.
+ * @param thickness the absolute thickness of the line
+ * @param yPosition the absolute y position relative to the baseline
+ * @return this Chunk
+ */
+ public Chunk SetUnderline(float thickness, float yPosition) {
+ return SetUnderline(null, thickness, 0f, yPosition, 0f, PdfContentByte.LINE_CAP_BUTT);
+ }
+
+ /**
+ * Sets an horizontal line that can be an underline or a strikethrough.
+ * Actually, the line can be anywhere vertically and has always the
+ * Chunk
width. Multiple call to this method will
+ * produce multiple lines.
+ * @param color the color of the line or null
to follow
+ * the text color
+ * @param thickness the absolute thickness of the line
+ * @param thicknessMul the thickness multiplication factor with the font size
+ * @param yPosition the absolute y position relative to the baseline
+ * @param yPositionMul the position multiplication factor with the font size
+ * @param cap the end line cap. Allowed values are
+ * PdfContentByte.LINE_CAP_BUTT, PdfContentByte.LINE_CAP_ROUND and
+ * PdfContentByte.LINE_CAP_PROJECTING_SQUARE
+ * @return this Chunk
+ */
+ public Chunk SetUnderline(Color color, float thickness, float thicknessMul, float yPosition, float yPositionMul, int cap) {
+ if (attributes == null)
+ attributes = new Hashtable();
+ Object[] obj = {color, new float[]{thickness, thicknessMul, yPosition, yPositionMul, (float)cap}};
+ Object[][] unders = Utilities.AddToArray((Object[][])attributes[UNDERLINE], obj);
+ return SetAttribute(UNDERLINE, unders);
+ }
+
+ ///alpha=0
and beta=12
.
+ * @param alpha the first angle in degrees
+ * @param beta the second angle in degrees
+ * @return this Chunk
+ */
+ public Chunk SetSkew(float alpha, float beta) {
+ alpha = (float)Math.Tan(alpha * Math.PI / 180);
+ beta = (float)Math.Tan(beta * Math.PI / 180);
+ return SetAttribute(SKEW, new float[]{alpha, beta});
+ }
+
+ ///Chunk
.
+ * @param color the color of the background
+ * @param extraLeft increase the size of the rectangle in the left
+ * @param extraBottom increase the size of the rectangle in the bottom
+ * @param extraRight increase the size of the rectangle in the right
+ * @param extraTop increase the size of the rectangle in the top
+ * @return this Chunk
+ */
+ public Chunk SetBackground(Color color, float extraLeft, float extraBottom, float extraRight, float extraTop) {
+ return SetAttribute(BACKGROUND, new Object[]{color, new float[]{extraLeft, extraBottom, extraRight, extraTop}});
+ }
+
+ ///PdfContentByte.TEXT_RENDER_MODE_FILL
,
+ * PdfContentByte.TEXT_RENDER_MODE_STROKE
, PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE
+ * and PdfContentByte.TEXT_RENDER_MODE_INVISIBLE
.
+ * @param strokeWidth the stroke line width for the modes PdfContentByte.TEXT_RENDER_MODE_STROKE
and
+ * PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE
.
+ * @param strokeColor the stroke color or null
to follow the text color
+ * @return this Chunk
+ */
+ public Chunk SetTextRenderMode(int mode, float strokeWidth, Color strokeColor) {
+ return SetAttribute(TEXTRENDERMODE, new Object[]{mode, strokeWidth, strokeColor});
+ }
+
+ ///true
if writing temporarely has to be paused, false
otherwise.
+ */
+
+ public bool IsPaused() {
+ return pause;
+ }
+
+ ///
+ /// Once a document is created you can add some meta information.
+ /// You can also set the headers/footers.
+ /// You have to open the document before you can write content.
+ /// You can only write content (no more meta-formation!) once a document is opened.
+ /// When you change the header/footer on a certain page, this will be effective starting on the next page.
+ /// Ater closing the document, every listener (as well as its OutputStream) is closed too.
+ ///
+ ///
+ /// // creation of the document with a certain size and certain margins
+ /// Document document = new Document(PageSize.A4, 50, 50, 50, 50);
+ /// try {
+ /// // creation of the different writers
+ /// HtmlWriter.GetInstance(document, System.out);
+ /// PdfWriter.GetInstance(document, new FileOutputStream("text.pdf"));
+ /// // we add some meta information to the document
+ /// document.AddAuthor("Bruno Lowagie");
+ /// document.AddSubject("This is the result of a Test.");
+ ///
+ /// // we define a header and a footer
+ /// HeaderFooter header = new HeaderFooter(new Phrase("This is a header."), false);
+ /// HeaderFooter footer = new HeaderFooter(new Phrase("This is page "), new Phrase("."));
+ /// footer.SetAlignment(Element.ALIGN_CENTER);
+ /// document.SetHeader(header);
+ /// document.SetFooter(footer);
+ /// // we open the document for writing
+ /// document.Open();
+ /// document.Add(new Paragraph("Hello world"));
+ /// }
+ /// catch (DocumentException de) {
+ /// Console.Error.WriteLine(de.Message);
+ /// }
+ /// document.Close();
+ ///
+ /// true
to mirror the margins
+ * @return always true
+ */
+ public virtual bool SetMarginMirroring(bool marginMirroring) {
+ this.marginMirroring = marginMirroring;
+ foreach (IDocListener listener in listeners) {
+ listener.SetMarginMirroring(marginMirroring);
+ }
+ return true;
+ }
+
+ /**
+ * Gets the margin mirroring flag.
+ *
+ * @return the margin mirroring flag
+ */
+ public bool IsMarginMirroring() {
+ return marginMirroring;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/DocumentException.cs b/iTechSharp/iTextSharp/text/DocumentException.cs
new file mode 100644
index 0000000..1c2b689
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/DocumentException.cs
@@ -0,0 +1,77 @@
+using System;
+
+/*
+ * $Id: DocumentException.cs,v 1.3 2008/05/13 11:25:09 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ *
+ */
+
+namespace iTextSharp.text {
+ /// Element
. */
+ public const int JPEG2000 = 33;
+
+ /// Element
. Element
. */
+ public const int MARKED = 50;
+
+ /** This is a possible type of Element
.
+ * @since 2.1.2
+ */
+ public const int YMARK = 55;
+
+ // static membervariables (alignment)
+
+ ///
+ /// Paragraph p = new Paragraph("This is a paragraph",
+ /// new Font(Font.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
+ ///
+ /// BaseFont
.
+ * @return the size that can be used with the calculated BaseFont
+ */
+ public float CalculatedSize {
+ get {
+ float s = this.size;
+ if (s == UNDEFINED) {
+ s = DEFAULTSIZE;
+ }
+ return s;
+ }
+ }
+
+ /**
+ * Gets the leading that can be used with this font.
+ *
+ * @param linespacing
+ * a certain linespacing
+ * @return the height of a line
+ */
+ public float GetCalculatedLeading(float linespacing) {
+ return linespacing * CalculatedSize;
+ }
+
+ // STYLE
+
+ /// BaseFont
.
+ * @return the style that can be used with the calculated BaseFont
+ */
+ public int CalculatedStyle {
+ get {
+ int style = this.style;
+ if (style == UNDEFINED) {
+ style = NORMAL;
+ }
+ if (baseFont != null)
+ return style;
+ if (family == SYMBOL || family == ZAPFDINGBATS)
+ return style;
+ else
+ return style & (~BOLDITALIC);
+ }
+ }
+
+ /// BaseFont
this class represents.
+ * For the built-in fonts a BaseFont
is calculated.
+ * @param specialEncoding true
to use the special encoding for Symbol and ZapfDingbats,
+ * false
to always use Cp1252
+ * @return the BaseFont
this class represents
+ */
+ public BaseFont GetCalculatedBaseFont(bool specialEncoding) {
+ if (baseFont != null)
+ return baseFont;
+ int style = this.style;
+ if (style == UNDEFINED) {
+ style = NORMAL;
+ }
+ String fontName = BaseFont.HELVETICA;
+ String encoding = BaseFont.WINANSI;
+ BaseFont cfont = null;
+ switch (family) {
+ case COURIER:
+ switch (style & BOLDITALIC) {
+ case BOLD:
+ fontName = BaseFont.COURIER_BOLD;
+ break;
+ case ITALIC:
+ fontName = BaseFont.COURIER_OBLIQUE;
+ break;
+ case BOLDITALIC:
+ fontName = BaseFont.COURIER_BOLDOBLIQUE;
+ break;
+ default:
+ //case NORMAL:
+ fontName = BaseFont.COURIER;
+ break;
+ }
+ break;
+ case TIMES_ROMAN:
+ switch (style & BOLDITALIC) {
+ case BOLD:
+ fontName = BaseFont.TIMES_BOLD;
+ break;
+ case ITALIC:
+ fontName = BaseFont.TIMES_ITALIC;
+ break;
+ case BOLDITALIC:
+ fontName = BaseFont.TIMES_BOLDITALIC;
+ break;
+ default:
+ //case NORMAL:
+ fontName = BaseFont.TIMES_ROMAN;
+ break;
+ }
+ break;
+ case SYMBOL:
+ fontName = BaseFont.SYMBOL;
+ if (specialEncoding)
+ encoding = BaseFont.SYMBOL;
+ break;
+ case ZAPFDINGBATS:
+ fontName = BaseFont.ZAPFDINGBATS;
+ if (specialEncoding)
+ encoding = BaseFont.ZAPFDINGBATS;
+ break;
+ default:
+ //case Font.HELVETICA:
+ switch (style & BOLDITALIC) {
+ case BOLD:
+ fontName = BaseFont.HELVETICA_BOLD;
+ break;
+ case ITALIC:
+ fontName = BaseFont.HELVETICA_OBLIQUE;
+ break;
+ case BOLDITALIC:
+ fontName = BaseFont.HELVETICA_BOLDOBLIQUE;
+ break;
+ default:
+ //case NORMAL:
+ fontName = BaseFont.HELVETICA;
+ break;
+ }
+ break;
+ }
+ cfont = BaseFont.CreateFont(fontName, encoding, false);
+ return cfont;
+ }
+
+ // Helper methods
+
+ /// true
+ * @return the number of fonts registered
+ * @since 2.1.2
+ */
+ public static int RegisterDirectory(String dir, bool scanSubdirectories) {
+ return fontImp.RegisterDirectory(dir, scanSubdirectories);
+ }
+
+ /** Register fonts in some probable directories. It usually works in Windows,
+ * Linux and Solaris.
+ * @return the number of fonts registered
+ */
+ public static int RegisterDirectories() {
+ return fontImp.RegisterDirectories();
+ }
+
+ ///
Document
+ */
+
+ protected void InitHeader() {
+ if (header != null) {
+ Add(header.Paragraph);
+ }
+ }
+
+ /**
+ * Adds the header to the top of the Document
+ */
+
+ protected void InitFooter() {
+ if (footer != null) {
+ // Set the page number. HTML has no notion of a page, so it should always
+ // add up to 1
+ footer.PageNumber = pageN + 1;
+ Add(footer.Paragraph);
+ }
+ }
+
+ /**
+ * Writes a Metatag in the header.
+ *
+ * @param meta the element that has to be written
+ * @throws IOException
+ */
+
+ protected void WriteHeader(Meta meta) {
+ AddTabs(2);
+ WriteStart(HtmlTags.META);
+ switch (meta.Type) {
+ case Element.HEADER:
+ Write(HtmlTags.NAME, ((Header) meta).Name);
+ break;
+ case Element.SUBJECT:
+ Write(HtmlTags.NAME, HtmlTags.SUBJECT);
+ break;
+ case Element.KEYWORDS:
+ Write(HtmlTags.NAME, HtmlTags.KEYWORDS);
+ break;
+ case Element.AUTHOR:
+ Write(HtmlTags.NAME, HtmlTags.AUTHOR);
+ break;
+ }
+ Write(HtmlTags.CONTENT, HtmlEncoder.Encode(meta.Content));
+ WriteEnd();
+ }
+
+ /**
+ * Writes a link in the header.
+ *
+ * @param header the element that has to be written
+ * @throws IOException
+ */
+
+ protected void WriteLink(Header header) {
+ AddTabs(2);
+ WriteStart(HtmlTags.LINK);
+ Write(HtmlTags.REL, header.Name);
+ Write(HtmlTags.TYPE, HtmlTags.TEXT_CSS);
+ Write(HtmlTags.REFERENCE, header.Content);
+ WriteEnd();
+ }
+
+ /**
+ * Writes a JavaScript section or, if the markup attribute HtmlTags.URL is set, a JavaScript reference in the header.
+ *
+ * @param header the element that has to be written
+ * @throws IOException
+ */
+
+ protected void WriteJavaScript(Header header) {
+ AddTabs(2);
+ WriteStart(HtmlTags.SCRIPT);
+ Write(HtmlTags.LANGUAGE, HtmlTags.JAVASCRIPT);
+ if (markup.Count > 0) {
+ /* JavaScript reference example:
+ *
+ *
+ */
+ WriteMarkupAttributes(markup);
+ os.WriteByte(GT);
+ WriteEnd(HtmlTags.SCRIPT);
+ }
+ else {
+ /* JavaScript coding convention:
+ *
+ *
+ */
+ Write(HtmlTags.TYPE, Markup.HTML_VALUE_JAVASCRIPT);
+ os.WriteByte(GT);
+ AddTabs(2);
+ Write(Encoding.ASCII.GetString(BEGINCOMMENT) + "\n");
+ Write(header.Content);
+ AddTabs(2);
+ Write("//" + Encoding.ASCII.GetString(ENDCOMMENT));
+ AddTabs(2);
+ WriteEnd(HtmlTags.SCRIPT);
+ }
+ }
+
+ /**
+ * Writes some comment.
+ * true
+ * @return the number of fonts registered
+ * @since 2.1.2
+ */
+ public int RegisterDirectory(String dir, bool scanSubdirectories) {
+ int count = 0;
+ try {
+ if (!Directory.Exists(dir))
+ return 0;
+ string[] files = Directory.GetFiles(dir);
+ if (files == null)
+ return 0;
+ for (int k = 0; k < files.Length; ++k) {
+ try {
+ if (Directory.Exists(files[k])) {
+ if (scanSubdirectories) {
+ count += RegisterDirectory(Path.GetFullPath(files[k]), true);
+ }
+ } else {
+ String name = Path.GetFullPath(files[k]);
+ String suffix = name.Length < 4 ? null : name.Substring(name.Length - 4).ToLower(CultureInfo.InvariantCulture);
+ if (".afm".Equals(suffix) || ".pfm".Equals(suffix)) {
+ /* Only register Type 1 fonts with matching .pfb files */
+ string pfb = name.Substring(0, name.Length - 4) + ".pfb";
+ if (File.Exists(pfb)) {
+ Register(name, null);
+ ++count;
+ }
+ } else if (".ttf".Equals(suffix) || ".otf".Equals(suffix) || ".ttc".Equals(suffix)) {
+ Register(name, null);
+ ++count;
+ }
+ }
+ }
+ catch {
+ //empty on purpose
+ }
+ }
+ }
+ catch {
+ //empty on purpose
+ }
+ return count;
+ }
+
+ /** Register fonts in some probable directories. It usually works in Windows,
+ * Linux and Solaris.
+ * @return the number of fonts registered
+ */
+ public virtual int RegisterDirectories() {
+ int count = 0;
+ count += RegisterDirectory("c:/windows/fonts");
+ count += RegisterDirectory("c:/winnt/fonts");
+ count += RegisterDirectory("d:/windows/fonts");
+ count += RegisterDirectory("d:/winnt/fonts");
+ count += RegisterDirectory("/usr/share/X11/fonts", true);
+ count += RegisterDirectory("/usr/X/lib/X11/fonts", true);
+ count += RegisterDirectory("/usr/openwin/lib/X11/fonts", true);
+ count += RegisterDirectory("/usr/share/fonts", true);
+ count += RegisterDirectory("/usr/X11R6/lib/X11/fonts", true);
+ count += RegisterDirectory("/Library/Fonts");
+ count += RegisterDirectory("/System/Library/Fonts");
+ return count;
+ }
+
+ ///
+ *
+ */
+
+ public class HtmlWriter : DocWriter {
+
+ // static membervariables (tags)
+
+ /** This is a possible HTML-tag. */
+ public static byte[] BEGINCOMMENT = GetISOBytes("");
+
+ /** This is a possible HTML-tag. */
+ public const string NBSP = " ";
+
+ // membervariables
+
+ /** This is the current font of the HTML. */
+ protected Stack currentfont = new Stack();
+
+ /** This is the standard font of the HTML. */
+ protected Font standardfont = new Font();
+
+ /** This is a path for images. */
+ protected String imagepath = null;
+
+ /** Stores the page number. */
+ protected int pageN = 0;
+
+ /** This is the textual part of a header */
+ protected HeaderFooter header = null;
+
+ /** This is the textual part of the footer */
+ protected HeaderFooter footer = null;
+
+ /** Store the markup properties of a MarkedObject. */
+ protected Properties markup = new Properties();
+
+ // constructor
+
+ /**
+ * Constructs a LIST
whitch use greek-letters.
+ *
+ * @see com.lowagie.text.List
+ */
+ public class GreekList : List {
+ /**
+ * Initialization
+ *
+ * @param symbolIndent indent
+ */
+ public GreekList() : base(true) {
+ SetGreekFont();
+ }
+
+ /**
+ * Initialisierung
+ *
+ * @param symbolIndent indent
+ */
+ public GreekList(int symbolIndent) : base(true, symbolIndent) {
+ SetGreekFont();
+ }
+
+ /**
+ * Initialisierung
+ * @param greeklower greek-char in lowercase
+ * @param symbolIndent indent
+ */
+ public GreekList(bool greeklower, int symbolIndent) : base(true, symbolIndent) {
+ lowercase = greeklower;
+ SetGreekFont();
+ }
+
+ /**
+ * change the font to SYMBOL
+ */
+ protected void SetGreekFont() {
+ float fontsize = symbol.Font.Size;
+ symbol.Font = FontFactory.GetFont(FontFactory.SYMBOL, fontsize, Font.NORMAL);
+ }
+
+ /**
+ * Adds an Object
to the List
.
+ *
+ * @param o the object to add.
+ * @return true if adding the object succeeded
+ */
+ public override bool Add(Object o) {
+ if (o is ListItem) {
+ ListItem item = (ListItem) o;
+ Chunk chunk = new Chunk(preSymbol, symbol.Font);
+ chunk.Append(GreekAlphabetFactory.GetString(first + list.Count, lowercase));
+ chunk.Append(postSymbol);
+ item.ListSymbol = chunk;
+ item.SetIndentationLeft(symbolIndent, autoindent);
+ item.IndentationRight = 0;
+ list.Add(item);
+ return true;
+ } else if (o is List) {
+ List nested = (List) o;
+ nested.IndentationLeft = nested.IndentationLeft + symbolIndent;
+ first--;
+ list.Add(nested);
+ return true;
+ } else if (o is string) {
+ return this.Add(new ListItem((string)o));
+ }
+ return false;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/Header.cs b/iTechSharp/iTextSharp/text/Header.cs
new file mode 100644
index 0000000..e8a37eb
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/Header.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Text;
+
+/*
+ * $Id: Header.cs,v 1.4 2008/05/13 11:25:10 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text {
+ ///
+ /// Header header = new Header("inspired by", "William Shakespeare");
+ ///
+ ///
+ /// HeaderFooter header = new HeaderFooter(new Phrase("This is a header."), false);
+ /// HeaderFooter footer = new HeaderFooter(new Phrase("This is page "), new Phrase("."));
+ /// document.SetHeader(header);
+ /// document.SetFooter(footer);
+ ///
+ /// true
if the character can split a line. The splitting implementation
+ * is free to look ahead or look behind characters to make a decision.
+ *
+ * public boolean IsSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) {
+ * char c;
+ * if (ck == null)
+ * c = cc[current];
+ * else
+ * c = ck[Math.Min(current, ck.length - 1)].GetUnicodeEquivalent(cc[current]);
+ * if (c <= ' ' || c == '-') {
+ * return true;
+ * }
+ * if (c < 0x2e80)
+ * return false;
+ * return ((c >= 0x2e80 && c < 0xd7a0)
+ * || (c >= 0xf900 && c < 0xfb00)
+ * || (c >= 0xfe30 && c < 0xfe50)
+ * || (c >= 0xff61 && c < 0xffa0));
+ * }
+ *
+ * @param start the lower limit of cc
inclusive
+ * @param current the pointer to the character in cc
+ * @param end the upper limit of cc
exclusive
+ * @param cc an array of characters at least end
sized
+ * @param ck an array of PdfChunk
. The main use is to be able to call
+ * {@link PdfChunk#getUnicodeEquivalent(char)}. It may be null
+ * or shorter than end
. If null
no convertion takes place.
+ * If shorter than end
the last element is used
+ * @return true
if the Character(s) can split a line
+ */
+
+ bool IsSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck);
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/ITextElementArray.cs b/iTechSharp/iTextSharp/text/ITextElementArray.cs
new file mode 100644
index 0000000..8df3bf4
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/ITextElementArray.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace iTextSharp.text {
+ /// Jpeg2000
is the representation of a graphic element (JPEG)
+ * that has to be inserted into the document
+ *
+ * @see Element
+ * @see Image
+ */
+
+ public class Jpeg2000 : Image {
+
+ // public static final membervariables
+
+ public const int JP2_JP = 0x6a502020;
+ public const int JP2_IHDR = 0x69686472;
+ public const int JPIP_JPIP = 0x6a706970;
+
+ public const int JP2_FTYP = 0x66747970;
+ public const int JP2_JP2H = 0x6a703268;
+ public const int JP2_COLR = 0x636f6c72;
+ public const int JP2_JP2C = 0x6a703263;
+ public const int JP2_URL = 0x75726c20;
+ public const int JP2_DBTL = 0x6474626c;
+ public const int JP2_BPCC = 0x62706363;
+ public const int JP2_JP2 = 0x6a703220;
+
+ private Stream inp;
+ private int boxLength;
+ private int boxType;
+
+ // Constructors
+
+ public Jpeg2000(Image image) : base(image) {
+ }
+
+ /**
+ * Constructs a Jpeg2000
-object, using an url.
+ *
+ * @param url the URL
where the image can be found
+ * @throws BadElementException
+ * @throws IOException
+ */
+ public Jpeg2000(Uri url) : base(url) {
+ ProcessParameters();
+ }
+
+ /**
+ * Constructs a Jpeg2000
-object from memory.
+ *
+ * @param img the memory image
+ * @throws BadElementException
+ * @throws IOException
+ */
+
+ public Jpeg2000(byte[] img) : base((Uri)null) {
+ rawData = img;
+ originalData = img;
+ ProcessParameters();
+ }
+
+ /**
+ * Constructs a Jpeg2000
-object from memory.
+ *
+ * @param img the memory image.
+ * @param width the width you want the image to have
+ * @param height the height you want the image to have
+ * @throws BadElementException
+ * @throws IOException
+ */
+
+ public Jpeg2000(byte[] img, float width, float height) : this(img) {
+ scaledWidth = width;
+ scaledHeight = height;
+ }
+
+ private int Cio_read(int n) {
+ int v = 0;
+ for (int i = n - 1; i >= 0; i--) {
+ v += inp.ReadByte() << (i << 3);
+ }
+ return v;
+ }
+
+ public void Jp2_read_boxhdr() {
+ boxLength = Cio_read(4);
+ boxType = Cio_read(4);
+ if (boxLength == 1) {
+ if (Cio_read(4) != 0) {
+ throw new IOException("Cannot handle box sizes higher than 2^32");
+ }
+ boxLength = Cio_read(4);
+ if (boxLength == 0)
+ throw new IOException("Unsupported box size == 0");
+ }
+ else if (boxLength == 0) {
+ throw new IOException("Unsupported box size == 0");
+ }
+ }
+
+ /**
+ * This method checks if the image is a valid JPEG and processes some parameters.
+ * @throws BadElementException
+ * @throws IOException
+ */
+ private void ProcessParameters() {
+ type = JPEG2000;
+ originalType = ORIGINAL_JPEG2000;
+ inp = null;
+ try {
+ string errorID;
+ if (rawData == null){
+ WebRequest w = WebRequest.Create(url);
+ inp = w.GetResponse().GetResponseStream();
+ errorID = url.ToString();
+ }
+ else{
+ inp = new MemoryStream(rawData);
+ errorID = "Byte array";
+ }
+ boxLength = Cio_read(4);
+ if (boxLength == 0x0000000c) {
+ boxType = Cio_read(4);
+ if (JP2_JP != boxType) {
+ throw new IOException("Expected JP Marker");
+ }
+ if (0x0d0a870a != Cio_read(4)) {
+ throw new IOException("Error with JP Marker");
+ }
+
+ Jp2_read_boxhdr();
+ if (JP2_FTYP != boxType) {
+ throw new IOException("Expected FTYP Marker");
+ }
+ Utilities.Skip(inp, boxLength - 8);
+ Jp2_read_boxhdr();
+ do {
+ if (JP2_JP2H != boxType) {
+ if (boxType == JP2_JP2C) {
+ throw new IOException("Expected JP2H Marker");
+ }
+ Utilities.Skip(inp, boxLength - 8);
+ Jp2_read_boxhdr();
+ }
+ } while (JP2_JP2H != boxType);
+ Jp2_read_boxhdr();
+ if (JP2_IHDR != boxType) {
+ throw new IOException("Expected IHDR Marker");
+ }
+ scaledHeight = Cio_read(4);
+ Top = scaledHeight;
+ scaledWidth = Cio_read(4);
+ Right = scaledWidth;
+ bpc = -1;
+ }
+ else if ((uint)boxLength == 0xff4fff51) {
+ Utilities.Skip(inp, 4);
+ int x1 = Cio_read(4);
+ int y1 = Cio_read(4);
+ int x0 = Cio_read(4);
+ int y0 = Cio_read(4);
+ Utilities.Skip(inp, 16);
+ colorspace = Cio_read(2);
+ bpc = 8;
+ scaledHeight = y1 - y0;
+ Top = scaledHeight;
+ scaledWidth = x1 - x0;
+ Right = scaledWidth;
+ }
+ else {
+ throw new IOException("Not a valid Jpeg2000 file");
+ }
+ }
+ finally {
+ if (inp != null) {
+ try{inp.Close();}catch{}
+ inp = null;
+ }
+ }
+ plainWidth = this.Width;
+ plainHeight = this.Height;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/List.cs b/iTechSharp/iTextSharp/text/List.cs
new file mode 100644
index 0000000..192cee2
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/List.cs
@@ -0,0 +1,555 @@
+using System;
+using System.Collections;
+using System.util;
+using iTextSharp.text.factories;
+
+/*
+ * $Id: List.cs,v 1.20 2008/05/13 11:25:11 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text {
+ ///
+ /// List list = new List(true, 20);
+ /// list.Add(new ListItem("First line"));
+ /// list.Add(new ListItem("The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?"));
+ /// list.Add(new ListItem("Third line"));
+ ///
+ ///
+ /// The result of this code looks like this:
+ ///
+ ///
+ ///
+ /// Example 2:
+ ///
+ /// List overview = new List(false, 10);
+ /// overview.Add(new ListItem("This is an item"));
+ /// overview.Add("This is another item");
+ ///
+ ///
+ /// The result of this code looks like this:
+ ///
+ ///
+ /// List
.
+ */
+ public List() : this(false, false) {
+ }
+
+ /**
+ * Constructs a List
with a specific symbol indentation.
+ * @param symbolIndent the symbol indentation
+ * @since iText 2.0.8
+ */
+ public List(float symbolIndent) {
+ this.symbolIndent = symbolIndent;
+ }
+
+ /**
+ * Constructs a List
.
+ *
+ * @param numbered a bool
+ */
+ public List(bool numbered) : this(numbered, false) {
+ }
+
+ /**
+ * Constructs a List
.
+ *
+ * @param numbered a bool
+ * @param lettered has the list to be 'numbered' with letters
+ */
+ public List(bool numbered, bool lettered) {
+ this.numbered = numbered;
+ this.lettered = lettered;
+ this.autoindent = true;
+ this.alignindent = true;
+ }
+
+
+ /// true
if the list is empty.
+ *
+ * @return true
if the list is empty
+ */
+ public virtual bool IsEmpty() {
+ return list.Count == 0;
+ }
+
+ ///
+ /// List list = new List(true, 20);
+ /// list.Add(new ListItem("First line"));
+ /// list.Add(new ListItem("The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?"));
+ /// list.Add(new ListItem("Third line"));
+ ///
+ ///
+ /// The result of this code looks like this:
+ ///
+ ///
+ ///
+ /// Example 2:
+ ///
+ /// List overview = new List(false, 10);
+ /// overview.Add(new ListItem("This is an item"));
+ /// overview.Add("This is another item");
+ ///
+ ///
+ /// The result of this code looks like this:
+ ///
+ ///
+ /// ArrayList
+ */
+ public virtual ArrayList Chunks {
+ get {
+ return element.Chunks;
+ }
+ }
+
+ /**
+ * Processes the element by adding it (or the different parts) to an
+ * ElementListener
.
+ *
+ * @param listener an ElementListener
+ * @return true
if the element was processed successfully
+ */
+ public virtual bool Process(IElementListener listener) {
+ try {
+ return listener.Add(element);
+ }
+ catch (DocumentException) {
+ return false;
+ }
+ }
+
+ /**
+ * Gets the type of the text element.
+ *
+ * @return a type
+ */
+ public virtual int Type {
+ get {
+ return Element.MARKED;
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.Element#isContent()
+ * @since iText 2.0.8
+ */
+ public bool IsContent() {
+ return true;
+ }
+
+ /**
+ * @see com.lowagie.text.Element#isNestable()
+ * @since iText 2.0.8
+ */
+ public bool IsNestable() {
+ return true;
+ }
+
+ /**
+ * @return the markupAttributes
+ */
+ public virtual Properties MarkupAttributes {
+ get {
+ return markupAttributes;
+ }
+ }
+
+ public virtual void SetMarkupAttribute(String key, String value) {
+ markupAttributes.Add(key, value);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/MarkedSection.cs b/iTechSharp/iTextSharp/text/MarkedSection.cs
new file mode 100644
index 0000000..9acff78
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/MarkedSection.cs
@@ -0,0 +1,297 @@
+using System;
+using System.Collections;
+using System.Text;
+using System.util;
+/*
+ * $Id: MarkedSection.cs,v 1.7 2008/05/13 11:25:12 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text {
+
+ /**
+ * Wrapper that allows to add properties to a Chapter/Section object.
+ * Before iText 1.5 every 'basic building block' implemented the MarkupAttributes interface.
+ * By setting attributes, you could add markup to the corresponding XML and/or HTML tag.
+ * This functionality was hardly used by anyone, so it was removed, and replaced by
+ * the MarkedObject functionality.
+ */
+
+ public class MarkedSection : MarkedObject {
+
+ /** This is the title of this section. */
+ protected MarkedObject title = null;
+
+ /**
+ * Creates a MarkedObject with a Section or Chapter object.
+ * @param section the marked section
+ */
+ public MarkedSection(Section section) : base() {
+ if (section.Title != null) {
+ title = new MarkedObject(section.Title);
+ section.Title = null;
+ }
+ this.element = section;
+ }
+
+ /**
+ * Adds a Paragraph
, List
or Table
+ * to this Section
.
+ *
+ * @param index index at which the specified element is to be inserted
+ * @param o an object of type Paragraph
, List
or Table
=
+ * @throws ClassCastException if the object is not a Paragraph
, List
or Table
+ */
+
+ public void Add(int index, Object o) {
+ ((Section)element).Add(index, o);
+ }
+
+ /**
+ * Adds a Paragraph
, List
, Table
or another Section
+ * to this Section
.
+ *
+ * @param o an object of type Paragraph
, List
, Table
or another Section
+ * @return a bool
+ * @throws ClassCastException if the object is not a Paragraph
, List
, Table
or Section
+ */
+
+ public bool Add(Object o) {
+ return ((Section)element).Add(o);
+ }
+
+ /**
+ * Processes the element by adding it (or the different parts) to an
+ * ElementListener
.
+ *
+ * @param listener an ElementListener
+ * @return true
if the element was processed successfully
+ */
+ public override bool Process(IElementListener listener) {
+ try {
+ foreach (IElement element in ((Section)this.element)) {
+ listener.Add(element);
+ }
+ return true;
+ }
+ catch (DocumentException) {
+ return false;
+ }
+ }
+
+ /**
+ * Adds a collection of Element
s
+ * to this Section
.
+ *
+ * @param collection a collection of Paragraph
s, List
s and/or Table
s
+ * @return true
if the action succeeded, false
if not.
+ * @throws ClassCastException if one of the objects isn't a Paragraph
, List
, Table
+ */
+
+ public bool AddAll(ICollection collection) {
+ return ((Section)element).AddAll(collection);
+ }
+
+ /**
+ * Creates a Section
, adds it to this Section
and returns it.
+ *
+ * @param indentation the indentation of the new section
+ * @param numberDepth the numberDepth of the section
+ * @return a new Section object
+ */
+
+ public MarkedSection AddSection(float indentation, int numberDepth) {
+ MarkedSection section = ((Section)element).AddMarkedSection();
+ section.Indentation = indentation;
+ section.NumberDepth = numberDepth;
+ return section;
+ }
+
+ /**
+ * Creates a Section
, adds it to this Section
and returns it.
+ *
+ * @param indentation the indentation of the new section
+ * @return a new Section object
+ */
+
+ public MarkedSection AddSection(float indentation) {
+ MarkedSection section = ((Section)element).AddMarkedSection();
+ section.Indentation = indentation;
+ return section;
+ }
+
+ /**
+ * Creates a Section
, add it to this Section
and returns it.
+ *
+ * @param numberDepth the numberDepth of the section
+ * @return a new Section object
+ */
+ public MarkedSection AddSection(int numberDepth) {
+ MarkedSection section = ((Section)element).AddMarkedSection();
+ section.NumberDepth = numberDepth;
+ return section;
+ }
+
+ /**
+ * Creates a Section
, adds it to this Section
and returns it.
+ *
+ * @return a new Section object
+ */
+ public MarkedSection AddSection() {
+ return ((Section)element).AddMarkedSection();
+ }
+
+ // public methods
+
+ /**
+ * Sets the title of this section.
+ *
+ * @param title the new title
+ */
+ public MarkedObject Title {
+ set {
+ if (value.element is Paragraph)
+ this.title = value;
+ }
+ get {
+ Paragraph result = Section.ConstructTitle((Paragraph)title.element, ((Section)element).numbers, ((Section)element).NumberDepth, ((Section)element).NumberStyle);
+ MarkedObject mo = new MarkedObject(result);
+ mo.markupAttributes = title.MarkupAttributes;
+ return mo;
+ }
+ }
+
+ /**
+ * Sets the depth of the sectionnumbers that will be shown preceding the title.
+ * Section
on the left side.
+ *
+ * @param indentation the indentation
+ */
+ public float IndentationLeft {
+ set {
+ ((Section)element).IndentationLeft = value;
+ }
+ }
+
+ /**
+ * Sets the indentation of this Section
on the right side.
+ *
+ * @param indentation the indentation
+ */
+
+ public float IndentationRight {
+ set {
+ ((Section)element).IndentationRight = value;
+ }
+ }
+
+ /**
+ * Sets the indentation of the content of this Section
.
+ *
+ * @param indentation the indentation
+ */
+ public float Indentation {
+ set {
+ ((Section)element).Indentation = value;
+ }
+ }
+
+ /** Setter for property bookmarkOpen.
+ * @param bookmarkOpen false if the bookmark children are not
+ * visible.
+ */
+ public bool BookmarkOpen {
+ set {
+ ((Section)element).BookmarkOpen = value;
+ }
+ }
+
+ /**
+ * Setter for property triggerNewPage.
+ * @param triggerNewPage true if a new page has to be triggered.
+ */
+ public bool TriggerNewPage {
+ set {
+ ((Section)element).TriggerNewPage = value;
+ }
+ }
+
+ /**
+ * Sets the bookmark title. The bookmark title is the same as the section title but
+ * can be changed with this method.
+ * @param bookmarkTitle the bookmark title
+ */
+ public String BookmarkTitle {
+ set {
+ ((Section)element).BookmarkTitle = value;
+ }
+ }
+
+ /**
+ * Adds a new page to the section.
+ * @since 2.1.1
+ */
+ public void NewPage() {
+ ((Section)element).NewPage();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/Meta.cs b/iTechSharp/iTextSharp/text/Meta.cs
new file mode 100644
index 0000000..130bd75
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/Meta.cs
@@ -0,0 +1,234 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.util;
+
+/*
+ * $Id: Meta.cs,v 1.6 2008/05/13 11:25:12 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text {
+ ///
+ /// the indentation
+ /// the alignment of the text
+ ///
+ ///
+ /// Paragraph p = new Paragraph("This is a paragraph",
+ /// FontFactory.GetFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
+ ///
+ ///
+ /// // When no parameters are passed, the default leading = 16
+ /// Phrase phrase0 = new Phrase();
+ /// Phrase phrase1 = new Phrase("this is a phrase");
+ /// // In this example the leading is passed as a parameter
+ /// Phrase phrase2 = new Phrase(16, "this is a phrase with leading 16");
+ /// // When a Font is passed (explicitely or embedded in a chunk), the default leading = 1.5 * size of the font
+ /// Phrase phrase3 = new Phrase("this is a phrase with a red, normal font Courier, size 12", FontFactory.GetFont(FontFactory.COURIER, 12, Font.NORMAL, new Color(255, 0, 0)));
+ /// Phrase phrase4 = new Phrase(new Chunk("this is a phrase"));
+ /// Phrase phrase5 = new Phrase(18, new Chunk("this is a phrase", FontFactory.GetFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
+ ///
+ /// Phrase
.
+ */
+ public Phrase(Phrase phrase) : base() {
+ this.AddAll(phrase);
+ leading = phrase.Leading;
+ font = phrase.Font;
+ hyphenation = phrase.hyphenation;
+ }
+
+ /// Rectangle
object
+ * except the position.
+ *
+ * @param rect
+ * Rectangle
to copy from
+ */
+
+ public virtual void CloneNonPositionParameters(Rectangle rect) {
+ this.rotation = rect.rotation;
+ this.border = rect.border;
+ this.borderWidth = rect.borderWidth;
+ this.borderColor = rect.borderColor;
+ this.backgroundColor = rect.backgroundColor;
+ this.borderColorLeft = rect.borderColorLeft;
+ this.borderColorRight = rect.borderColorRight;
+ this.borderColorTop = rect.borderColorTop;
+ this.borderColorBottom = rect.borderColorBottom;
+ this.borderWidthLeft = rect.borderWidthLeft;
+ this.borderWidthRight = rect.borderWidthRight;
+ this.borderWidthTop = rect.borderWidthTop;
+ this.borderWidthBottom = rect.borderWidthBottom;
+ this.useVariableBorders = rect.useVariableBorders;
+ }
+
+ /**
+ * Copies all of the parameters from a Rectangle
object
+ * except the position.
+ *
+ * @param rect
+ * Rectangle
to copy from
+ */
+
+ public virtual void SoftCloneNonPositionParameters(Rectangle rect) {
+ if (rect.rotation != 0)
+ this.rotation = rect.rotation;
+ if (rect.border != UNDEFINED)
+ this.border = rect.border;
+ if (rect.borderWidth != UNDEFINED)
+ this.borderWidth = rect.borderWidth;
+ if (rect.borderColor != null)
+ this.borderColor = rect.borderColor;
+ if (rect.backgroundColor != null)
+ this.backgroundColor = rect.backgroundColor;
+ if (rect.borderColorLeft != null)
+ this.borderColorLeft = rect.borderColorLeft;
+ if (rect.borderColorRight != null)
+ this.borderColorRight = rect.borderColorRight;
+ if (rect.borderColorTop != null)
+ this.borderColorTop = rect.borderColorTop;
+ if (rect.borderColorBottom != null)
+ this.borderColorBottom = rect.borderColorBottom;
+ if (rect.borderWidthLeft != UNDEFINED)
+ this.borderWidthLeft = rect.borderWidthLeft;
+ if (rect.borderWidthRight != UNDEFINED)
+ this.borderWidthRight = rect.borderWidthRight;
+ if (rect.borderWidthTop != UNDEFINED)
+ this.borderWidthTop = rect.borderWidthTop;
+ if (rect.borderWidthBottom != UNDEFINED)
+ this.borderWidthBottom = rect.borderWidthBottom;
+ if (useVariableBorders)
+ this.useVariableBorders = rect.useVariableBorders;
+ }
+
+ // implementation of the Element interface
+
+ /// LEFT, RIGHT, TOP, BOTTOM
+ *
+ */
+ public virtual void EnableBorderSide(int side) {
+ if (border == UNDEFINED) {
+ border = 0;
+ }
+ border |= side;
+ }
+
+ /**
+ * Disables the border on the specified side.
+ *
+ * @param side
+ * the side to disable. One of LEFT, RIGHT, TOP, BOTTOM
+ *
+ */
+ public virtual void DisableBorderSide(int side) {
+ if (border == UNDEFINED) {
+ border = 0;
+ }
+ border &= ~side;
+ }
+
+
+ /// Rectangle
object
+ * except the position.
+ *
+ * @param rect
+ * Rectangle
to copy from
+ */
+ public override void CloneNonPositionParameters(Rectangle rect) {
+ ThrowReadOnlyError();
+ }
+
+ private void ThrowReadOnlyError() {
+ throw new InvalidOperationException("RectangleReadOnly: this Rectangle is read only.");
+ }
+
+ /**
+ * Copies all of the parameters from a Rectangle
object
+ * except the position.
+ *
+ * @param rect
+ * Rectangle
to copy from
+ */
+
+ public override void SoftCloneNonPositionParameters(Rectangle rect) {
+ ThrowReadOnlyError();
+ }
+
+ // methods
+
+ /**
+ * Switches lowerleft with upperright
+ */
+ public override void Normalize() {
+ ThrowReadOnlyError();
+ }
+
+ // methods to set the membervariables
+
+ /// LEFT, RIGHT, TOP, BOTTOM
+ *
+ */
+ public override void EnableBorderSide(int side) {
+ ThrowReadOnlyError();
+ }
+
+ /**
+ * Disables the border on the specified side.
+ *
+ * @param side
+ * the side to disable. One of LEFT, RIGHT, TOP, BOTTOM
+ *
+ */
+ public override void DisableBorderSide(int side) {
+ ThrowReadOnlyError();
+ }
+
+
+ /// LIST
which use roman-letters.
+ *
+ * @see com.lowagie.text.List
+ * @version 2003-06-22
+ * @author Michael Niedermair
+ */
+
+ public class RomanList : List {
+
+ /**
+ * Initialization
+ */
+ public RomanList() : base(true) {
+ }
+
+ /**
+ * Initialization
+ *
+ * @param symbolIndent indent
+ */
+ public RomanList(int symbolIndent) : base(true, symbolIndent){
+ }
+
+ /**
+ * Initialization
+ * @param romanlower roman-char in lowercase
+ * @param symbolIndent indent
+ */
+ public RomanList(bool romanlower, int symbolIndent) : base(true, symbolIndent) {
+ this.lowercase = romanlower;
+ }
+
+ /**
+ * Adds an Object
to the List
.
+ *
+ * @param o the object to add.
+ * @return true if adding the object succeeded
+ */
+ public override bool Add(Object o) {
+ if (o is ListItem) {
+ ListItem item = (ListItem) o;
+ Chunk chunk = new Chunk(preSymbol, symbol.Font);
+ chunk.Append(RomanNumberFactory.GetString(first + list.Count, lowercase));
+ chunk.Append(postSymbol);
+ item.ListSymbol = chunk;
+ item.SetIndentationLeft(symbolIndent, autoindent);
+ item.IndentationRight = 0;
+ list.Add(item);
+ return true;
+ } else if (o is List) {
+ List nested = (List) o;
+ nested.IndentationLeft = nested.IndentationLeft + symbolIndent;
+ first--;
+ list.Add(nested);
+ return true;
+ } else if (o is string) {
+ return this.Add(new ListItem((string) o));
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/Row.cs b/iTechSharp/iTextSharp/text/Row.cs
new file mode 100644
index 0000000..256542c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/Row.cs
@@ -0,0 +1,376 @@
+using System;
+using System.Collections;
+using System.util;
+
+/*
+ * $Id: Row.cs,v 1.10 2008/05/13 11:25:12 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text {
+ ///
+ /// Paragraph title2 = new Paragraph("This is Chapter 2", FontFactory.GetFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
+ /// Chapter chapter2 = new Chapter(title2, 2);
+ /// Paragraph someText = new Paragraph("This is some text");
+ /// chapter2.Add(someText);
+ /// Paragraph title21 = new Paragraph("This is Section 1 in Chapter 2", FontFactory.GetFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
+ /// Section section1 = chapter2.AddSection(title21);
+ /// Paragraph someSectionText = new Paragraph("This is some silly paragraph in a chapter and/or section. It contains some text to test the functionality of Chapters and Section.");
+ /// section1.Add(someSectionText);
+ /// Paragraph title211 = new Paragraph("This is SubSection 1 in Section 1 in Chapter 2", FontFactory.GetFont(FontFactory.HELVETICA, 14, Font.BOLD, new Color(255, 0, 0)));
+ /// Section section11 = section1.AddSection(40, title211, 2);
+ /// section11.Add(someSectionText);strong>
+ ///
+ /// String
.
+ *
+ * @param string a String
+ * @return an index of -1 if no special symbol was found
+ */
+
+ public static int Index(string str) {
+ int length = str.Length;
+ for (int i = 0; i < length; i++) {
+ if (GetCorrespondingSymbol(str[i]) != ' ') {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Gets a chunk with a symbol character.
+ * @param c a character that has to be changed into a symbol
+ * @param font Font if there is no SYMBOL character corresponding with c
+ * @return a SYMBOL version of a character
+ */
+
+ public static Chunk Get(char c, Font font) {
+ char greek = SpecialSymbol.GetCorrespondingSymbol(c);
+ if (greek == ' ') {
+ return new Chunk(c.ToString(), font);
+ }
+ Font symbol = new Font(Font.SYMBOL, font.Size, font.Style, font.Color);
+ return new Chunk(greek.ToString(), symbol);
+ }
+
+ /**
+ * Looks for the corresponding symbol in the font Symbol.
+ *
+ * @param c the original ASCII-char
+ * @return the corresponding symbol in font Symbol
+ */
+
+ public static char GetCorrespondingSymbol(char c) {
+ switch (c) {
+ case (char)913:
+ return 'A'; // ALFA
+ case (char)914:
+ return 'B'; // BETA
+ case (char)915:
+ return 'G'; // GAMMA
+ case (char)916:
+ return 'D'; // DELTA
+ case (char)917:
+ return 'E'; // EPSILON
+ case (char)918:
+ return 'Z'; // ZETA
+ case (char)919:
+ return 'H'; // ETA
+ case (char)920:
+ return 'Q'; // THETA
+ case (char)921:
+ return 'I'; // IOTA
+ case (char)922:
+ return 'K'; // KAPPA
+ case (char)923:
+ return 'L'; // LAMBDA
+ case (char)924:
+ return 'M'; // MU
+ case (char)925:
+ return 'N'; // NU
+ case (char)926:
+ return 'X'; // XI
+ case (char)927:
+ return 'O'; // OMICRON
+ case (char)928:
+ return 'P'; // PI
+ case (char)929:
+ return 'R'; // RHO
+ case (char)931:
+ return 'S'; // SIGMA
+ case (char)932:
+ return 'T'; // TAU
+ case (char)933:
+ return 'U'; // UPSILON
+ case (char)934:
+ return 'J'; // PHI
+ case (char)935:
+ return 'C'; // CHI
+ case (char)936:
+ return 'Y'; // PSI
+ case (char)937:
+ return 'W'; // OMEGA
+ case (char)945:
+ return 'a'; // alfa
+ case (char)946:
+ return 'b'; // beta
+ case (char)947:
+ return 'g'; // gamma
+ case (char)948:
+ return 'd'; // delta
+ case (char)949:
+ return 'e'; // epsilon
+ case (char)950:
+ return 'z'; // zeta
+ case (char)951:
+ return 'h'; // eta
+ case (char)952:
+ return 'q'; // theta
+ case (char)953:
+ return 'i'; // iota
+ case (char)954:
+ return 'k'; // kappa
+ case (char)955:
+ return 'l'; // lambda
+ case (char)956:
+ return 'm'; // mu
+ case (char)957:
+ return 'n'; // nu
+ case (char)958:
+ return 'x'; // xi
+ case (char)959:
+ return 'o'; // omicron
+ case (char)960:
+ return 'p'; // pi
+ case (char)961:
+ return 'r'; // rho
+ case (char)962:
+ return 'V'; // sigma
+ case (char)963:
+ return 's'; // sigma
+ case (char)964:
+ return 't'; // tau
+ case (char)965:
+ return 'u'; // upsilon
+ case (char)966:
+ return 'j'; // phi
+ case (char)967:
+ return 'c'; // chi
+ case (char)968:
+ return 'y'; // psi
+ case (char)969:
+ return 'w'; // omega
+ default:
+ return ' ';
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/Table.cs b/iTechSharp/iTextSharp/text/Table.cs
new file mode 100644
index 0000000..4699bca
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/Table.cs
@@ -0,0 +1,1577 @@
+using System;
+using System.Collections;
+using System.util;
+
+using iTextSharp.text.html;
+using iTextSharp.text.pdf;
+
+/*
+ * $Id: Table.cs,v 1.23 2008/05/13 11:25:13 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ *
+ * Some methods in this class were contributed by Geert Poels, Kris Jespers and
+ * Steve Ogryzek. Check the CVS repository.
+ */
+
+namespace iTextSharp.text {
+ ///
+ /// // Remark: You MUST know the number of columns when constructing a Table.
+ /// // The number of rows is not important.
+ /// Table table = new Table(3);
+ /// table.SetBorderWidth(1);
+ /// table.SetBorderColor(new Color(0, 0, 255));
+ /// table.SetPadding(5);
+ /// table.SetSpacing(5);
+ /// Cell cell = new Cell("header");
+ /// cell.SetHeader(true);
+ /// cell.SetColspan(3);
+ /// table.AddCell(cell);
+ /// table.EndHeaders();
+ /// cell = new Cell("example cell with colspan 1 and rowspan 2");
+ /// cell.SetRowspan(2);
+ /// cell.SetBorderColor(new Color(255, 0, 0));
+ /// table.AddCell(cell);
+ /// table.AddCell("1.1");
+ /// table.AddCell("2.1");
+ /// table.AddCell("1.2");
+ /// table.AddCell("2.2");
+ /// table.AddCell("cell test1");
+ /// cell = new Cell("big cell");
+ /// cell.SetRowspan(2);
+ /// cell.SetColspan(2);
+ /// table.AddCell(cell);
+ /// table.AddCell("cell test2");
+ ///
+ ///
+ /// The result of this code is a table:
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// header
+ ///
+ ///
+ ///
+ ///
+ /// example cell with colspan 1 and rowspan 2
+ ///
+ ///
+ /// 1.1
+ ///
+ ///
+ /// 2.1
+ ///
+ ///
+ ///
+ ///
+ /// 1.2
+ ///
+ ///
+ /// 2.2
+ ///
+ ///
+ ///
+ ///
+ /// cell test1
+ ///
+ ///
+ /// big cell
+ ///
+ ///
+ ///
+ ///
+ /// cell test2
+ ///
+ ///
+ ///
+ /// The widths will be: a width of 50% for the first column,
+ /// 25% for the second and third column.
+ ///
+ /// float[] widths = {2, 1, 1};
+ /// table.SetWidths(widths)
+ ///
rowspan/colspan not beyond borders
+ /// spanned cell don't overlap existing cells
+ /// null
+ * @param item the item to be added to the array
+ * @return a new array with the item appended
+ */
+ public static Object[][] AddToArray(Object[][] original, Object[] item) {
+ if (original == null) {
+ original = new Object[1][];
+ original[0] = item;
+ return original;
+ }
+ else {
+ Object[][] original2 = new Object[original.Length + 1][];
+ Array.Copy(original, 0, original2, 0, original.Length);
+ original2[original.Length] = item;
+ return original2;
+ }
+ }
+
+ /**
+ * Checks for a true/false value of a key in a Properties object.
+ * @param attributes
+ * @param key
+ * @return
+ */
+ public static bool CheckTrueOrFalse(Properties attributes, String key) {
+ return Util.EqualsIgnoreCase("true", attributes[key]);
+ }
+
+ /// LIST
whitch use zapfdingbats-letters.
+ *
+ * @see com.lowagie.text.List
+ * @author Michael Niedermair and Bruno Lowagie
+ */
+ public class ZapfDingbatsList : List {
+ /**
+ * char-number in zapfdingbats
+ */
+ protected int zn;
+
+ /**
+ * Creates a ZapfDingbatsList
+ *
+ * @param zn a char-number
+ */
+ public ZapfDingbatsList(int zn) : base(true) {
+ this.zn = zn;
+ float fontsize = symbol.Font.Size;
+ symbol.Font = FontFactory.GetFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL);
+ postSymbol = " ";
+ }
+
+ /**
+ * Creates a ZapfDingbatsList
+ *
+ * @param zn a char-number
+ * @param symbolIndent indent
+ */
+ public ZapfDingbatsList(int zn, int symbolIndent) : base(true, symbolIndent) {
+ this.zn = zn;
+ float fontsize = symbol.Font.Size;
+ symbol.Font = FontFactory.GetFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL);
+ postSymbol = " ";
+ }
+
+ /**
+ * set the char-number
+ * @param zn a char-number
+ */
+ public int CharNumber {
+ set {
+ this.zn = value;
+ }
+ get {
+ return this.zn;
+ }
+ }
+
+ /**
+ * Adds an Object
to the List
.
+ *
+ * @param o the object to add.
+ * @return true if adding the object succeeded
+ */
+ public override bool Add(Object o) {
+ if (o is ListItem) {
+ ListItem item = (ListItem) o;
+ Chunk chunk = new Chunk(preSymbol, symbol.Font);
+ chunk.Append(((char)zn).ToString());
+ chunk.Append(postSymbol);
+ item.ListSymbol = chunk;
+ item.SetIndentationLeft(symbolIndent, autoindent);
+ item.IndentationRight = 0;
+ list.Add(item);
+ return true;
+ } else if (o is List) {
+ List nested = (List) o;
+ nested.IndentationLeft = nested.IndentationLeft + symbolIndent;
+ first--;
+ list.Add(nested);
+ return true;
+ } else if (o is String) {
+ return this.Add(new ListItem((string) o));
+ }
+ return false;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/ZapfDingbatsNumberList.cs b/iTechSharp/iTextSharp/text/ZapfDingbatsNumberList.cs
new file mode 100644
index 0000000..5b0d108
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/ZapfDingbatsNumberList.cs
@@ -0,0 +1,100 @@
+using System;
+
+namespace iTextSharp.text
+{
+ /**
+ *
+ * A special-version of LIST
whitch use zapfdingbats-numbers (1..10).
+ *
+ * @see com.lowagie.text.List
+ * @version 2003-06-22
+ * @author Michael Niedermair
+ */
+ public class ZapfDingbatsNumberList : List {
+
+ /**
+ * which type
+ */
+ protected int type;
+
+ /**
+ * Creates a ZapdDingbatsNumberList
+ * @param type the type of list
+ * @param symbolIndent indent
+ */
+ public ZapfDingbatsNumberList(int type) : base(true) {
+ this.type = type;
+ float fontsize = symbol.Font.Size;
+ symbol.Font = FontFactory.GetFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL);
+ postSymbol = " ";
+ }
+
+ /**
+ * Creates a ZapdDingbatsNumberList
+ * @param type the type of list
+ * @param symbolIndent indent
+ */
+ public ZapfDingbatsNumberList(int type, int symbolIndent) : base(true, symbolIndent) {
+ this.type = type;
+ float fontsize = symbol.Font.Size;
+ symbol.Font = FontFactory.GetFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL);
+ postSymbol = " ";
+ }
+
+ /**
+ * get the type
+ *
+ * @return char-number
+ */
+ public int NumberType {
+ get {
+ return type;
+ }
+ set {
+ type = value;
+ }
+ }
+
+ /**
+ * Adds an Object
to the List
.
+ *
+ * @param o the object to add.
+ * @return true if adding the object succeeded
+ */
+ public override bool Add(Object o) {
+ if (o is ListItem) {
+ ListItem item = (ListItem) o;
+ Chunk chunk = new Chunk(preSymbol, symbol.Font);
+ switch (type ) {
+ case 0:
+ chunk.Append(((char)(first + list.Count + 171)).ToString());
+ break;
+ case 1:
+ chunk.Append(((char)(first + list.Count + 181)).ToString());
+ break;
+ case 2:
+ chunk.Append(((char)(first + list.Count + 191)).ToString());
+ break;
+ default:
+ chunk.Append(((char)(first + list.Count + 201)).ToString());
+ break;
+ }
+ chunk.Append(postSymbol);
+ item.ListSymbol = chunk;
+ item.SetIndentationLeft(symbolIndent, autoindent);
+ item.IndentationRight = 0;
+ list.Add(item);
+ return true;
+ } else if (o is List) {
+ List nested = (List) o;
+ nested.IndentationLeft = nested.IndentationLeft + symbolIndent;
+ first--;
+ list.Add(nested);
+ return true;
+ } else if (o is String) {
+ return this.Add(new ListItem((string) o));
+ }
+ return false;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/factories/ElementFactory.cs b/iTechSharp/iTextSharp/text/factories/ElementFactory.cs
new file mode 100644
index 0000000..06e52b0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/factories/ElementFactory.cs
@@ -0,0 +1,533 @@
+using System;
+using System.Collections;
+using System.util;
+using iTextSharp.text;
+using iTextSharp.text.html;
+using iTextSharp.text.factories;
+/*
+ * $Id: ElementFactory.cs,v 1.9 2008/05/13 11:25:14 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.factories {
+
+ /**
+ * This class is able to create Element objects based on a list of properties.
+ */
+
+ public class ElementFactory {
+
+ public static Chunk GetChunk(Properties attributes) {
+ Chunk chunk = new Chunk();
+
+ chunk.Font = FontFactory.GetFont(attributes);
+ String value;
+
+ value = attributes[ElementTags.ITEXT];
+ if (value != null) {
+ chunk.Append(value);
+ }
+ value = attributes[ElementTags.LOCALGOTO];
+ if (value != null) {
+ chunk.SetLocalGoto(value);
+ }
+ value = attributes[ElementTags.REMOTEGOTO];
+ if (value != null) {
+ String page = attributes[ElementTags.PAGE];
+ if (page != null) {
+ chunk.SetRemoteGoto(value, int.Parse(page));
+ }
+ else {
+ String destination = attributes[ElementTags.DESTINATION];
+ if (destination != null) {
+ chunk.SetRemoteGoto(value, destination);
+ }
+ }
+ }
+ value = attributes[ElementTags.LOCALDESTINATION];
+ if (value != null) {
+ chunk.SetLocalDestination(value);
+ }
+ value = attributes[ElementTags.SUBSUPSCRIPT];
+ if (value != null) {
+ chunk.SetTextRise(float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo));
+ }
+ value = attributes[Markup.CSS_KEY_VERTICALALIGN];
+ if (value != null && value.EndsWith("%")) {
+ float p = float.Parse(value.Substring(0, value.Length - 1), System.Globalization.NumberFormatInfo.InvariantInfo) / 100f;
+ chunk.SetTextRise(p * chunk.Font.Size);
+ }
+ value = attributes[ElementTags.GENERICTAG];
+ if (value != null) {
+ chunk.SetGenericTag(value);
+ }
+ value = attributes[ElementTags.BACKGROUNDCOLOR];
+ if (value != null) {
+ chunk.SetBackground(Markup.DecodeColor(value));
+ }
+ return chunk;
+ }
+
+ public static Phrase GetPhrase(Properties attributes) {
+ Phrase phrase = new Phrase();
+ phrase.Font = FontFactory.GetFont(attributes);
+ String value;
+ value = attributes[ElementTags.LEADING];
+ if (value != null) {
+ phrase.Leading = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ value = attributes[Markup.CSS_KEY_LINEHEIGHT];
+ if (value != null) {
+ phrase.Leading = Markup.ParseLength(value);
+ }
+ value = attributes[ElementTags.ITEXT];
+ if (value != null) {
+ Chunk chunk = new Chunk(value);
+ if ((value = attributes[ElementTags.GENERICTAG]) != null) {
+ chunk.SetGenericTag(value);
+ }
+ phrase.Add(chunk);
+ }
+ return phrase;
+ }
+
+ public static Anchor GetAnchor(Properties attributes) {
+ Anchor anchor = new Anchor(GetPhrase(attributes));
+ String value;
+ value = attributes[ElementTags.NAME];
+ if (value != null) {
+ anchor.Name = value;
+ }
+ value = (String)attributes.Remove(ElementTags.REFERENCE);
+ if (value != null) {
+ anchor.Reference = value;
+ }
+ return anchor;
+ }
+
+ public static Paragraph GetParagraph(Properties attributes) {
+ Paragraph paragraph = new Paragraph(GetPhrase(attributes));
+ String value;
+ value = attributes[ElementTags.ALIGN];
+ if (value != null) {
+ paragraph.SetAlignment(value);
+ }
+ value = attributes[ElementTags.INDENTATIONLEFT];
+ if (value != null) {
+ paragraph.IndentationLeft = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ value = attributes[ElementTags.INDENTATIONRIGHT];
+ if (value != null) {
+ paragraph.IndentationRight = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ return paragraph;
+ }
+
+ public static ListItem GetListItem(Properties attributes) {
+ ListItem item = new ListItem(GetParagraph(attributes));
+ return item;
+ }
+
+ public static List GetList(Properties attributes) {
+ List list = new List();
+
+ list.Numbered = Utilities.CheckTrueOrFalse(attributes, ElementTags.NUMBERED);
+ list.Lettered = Utilities.CheckTrueOrFalse(attributes, ElementTags.LETTERED);
+ list.Lowercase = Utilities.CheckTrueOrFalse(attributes, ElementTags.LOWERCASE);
+ list.Autoindent = Utilities.CheckTrueOrFalse(attributes, ElementTags.AUTO_INDENT_ITEMS);
+ list.Alignindent = Utilities.CheckTrueOrFalse(attributes, ElementTags.ALIGN_INDENTATION_ITEMS);
+
+ String value;
+
+ value = attributes[ElementTags.FIRST];
+ if (value != null) {
+ char character = value[0];
+ if (char.IsLetter(character) ) {
+ list.First = (int)character;
+ }
+ else {
+ list.First = int.Parse(value);
+ }
+ }
+
+ value = attributes[ElementTags.LISTSYMBOL];
+ if (value != null) {
+ list.ListSymbol = new Chunk(value, FontFactory.GetFont(attributes));
+ }
+
+ value = attributes[ElementTags.INDENTATIONLEFT];
+ if (value != null) {
+ list.IndentationLeft = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+
+ value = attributes[ElementTags.INDENTATIONRIGHT];
+ if (value != null) {
+ list.IndentationRight = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+
+ value = attributes[ElementTags.SYMBOLINDENT];
+ if (value != null) {
+ list.SymbolIndent = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+
+ return list;
+ }
+
+ public static Cell GetCell(Properties attributes) {
+ Cell cell = new Cell();
+ String value;
+
+ cell.SetHorizontalAlignment(attributes[ElementTags.HORIZONTALALIGN]);
+ cell.SetVerticalAlignment(attributes[ElementTags.VERTICALALIGN]);
+ value = attributes[ElementTags.WIDTH];
+ if (value != null) {
+ cell.SetWidth(value);
+ }
+ value = attributes[ElementTags.COLSPAN];
+ if (value != null) {
+ cell.Colspan = int.Parse(value);
+ }
+ value = attributes[ElementTags.ROWSPAN];
+ if (value != null) {
+ cell.Rowspan = int.Parse(value);
+ }
+ value = attributes[ElementTags.LEADING];
+ if (value != null) {
+ cell.Leading = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ cell.Header = Utilities.CheckTrueOrFalse(attributes, ElementTags.HEADER);
+ if (Utilities.CheckTrueOrFalse(attributes, ElementTags.NOWRAP)) {
+ cell.MaxLines = 1;
+ }
+ SetRectangleProperties(cell, attributes);
+ return cell;
+ }
+
+ /**
+ * Creates an Table object based on a list of properties.
+ * @param attributes
+ * @return a Table
+ */
+ public static Table GetTable(Properties attributes) {
+ String value;
+ Table table;
+
+ value = attributes[ElementTags.WIDTHS];
+ if (value != null) {
+ StringTokenizer widthTokens = new StringTokenizer(value, ";");
+ ArrayList values = new ArrayList();
+ while (widthTokens.HasMoreTokens()) {
+ values.Add(widthTokens.NextToken());
+ }
+ table = new Table(values.Count);
+ float[] widths = new float[table.Columns];
+ for (int i = 0; i < values.Count; i++) {
+ value = (String)values[i];
+ widths[i] = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ table.Widths = widths;
+ }
+ else {
+ value = attributes[ElementTags.COLUMNS];
+ try {
+ table = new Table(int.Parse(value));
+ }
+ catch {
+ table = new Table(1);
+ }
+ }
+
+ table.Border = Table.BOX;
+ table.BorderWidth = 1;
+ table.DefaultCell.Border = Table.BOX;
+
+ value = attributes[ElementTags.LASTHEADERROW];
+ if (value != null) {
+ table.LastHeaderRow = int.Parse(value);
+ }
+ value = attributes[ElementTags.ALIGN];
+ if (value != null) {
+ table.SetAlignment(value);
+ }
+ value = attributes[ElementTags.CELLSPACING];
+ if (value != null) {
+ table.Spacing = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ value = attributes[ElementTags.CELLPADDING];
+ if (value != null) {
+ table.Padding = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ value = attributes[ElementTags.OFFSET];
+ if (value != null) {
+ table.Offset = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ value = attributes[ElementTags.WIDTH];
+ if (value != null) {
+ if (value.EndsWith("%"))
+ table.Width = float.Parse(value.Substring(0, value.Length - 1), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else {
+ table.Width = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ table.Locked = true;
+ }
+ }
+ table.TableFitsPage = Utilities.CheckTrueOrFalse(attributes, ElementTags.TABLEFITSPAGE);
+ table.CellsFitPage = Utilities.CheckTrueOrFalse(attributes, ElementTags.CELLSFITPAGE);
+ table.Convert2pdfptable = Utilities.CheckTrueOrFalse(attributes, ElementTags.CONVERT2PDFP);
+
+ SetRectangleProperties(table, attributes);
+ return table;
+ }
+
+ /**
+ * Sets some Rectangle properties (for a Cell, Table,...).
+ */
+ private static void SetRectangleProperties(Rectangle rect, Properties attributes) {
+ String value;
+ value = attributes[ElementTags.BORDERWIDTH];
+ if (value != null) {
+ rect.BorderWidth = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ int border = 0;
+ if (Utilities.CheckTrueOrFalse(attributes, ElementTags.LEFT)) {
+ border |= Rectangle.LEFT_BORDER;
+ }
+ if (Utilities.CheckTrueOrFalse(attributes, ElementTags.RIGHT)) {
+ border |= Rectangle.RIGHT_BORDER;
+ }
+ if (Utilities.CheckTrueOrFalse(attributes, ElementTags.TOP)) {
+ border |= Rectangle.TOP_BORDER;
+ }
+ if (Utilities.CheckTrueOrFalse(attributes, ElementTags.BOTTOM)) {
+ border |= Rectangle.BOTTOM_BORDER;
+ }
+ rect.Border = border;
+
+ String r = attributes[ElementTags.RED];
+ String g = attributes[ElementTags.GREEN];
+ String b = attributes[ElementTags.BLUE];
+ if (r != null || g != null || b != null) {
+ int red = 0;
+ int green = 0;
+ int blue = 0;
+ if (r != null) red = int.Parse(r);
+ if (g != null) green = int.Parse(g);
+ if (b != null) blue = int.Parse(b);
+ rect.BorderColor = new Color(red, green, blue);
+ }
+ else {
+ rect.BorderColor = Markup.DecodeColor(attributes[ElementTags.BORDERCOLOR]);
+ }
+ r = (String)attributes.Remove(ElementTags.BGRED);
+ g = (String)attributes.Remove(ElementTags.BGGREEN);
+ b = (String)attributes.Remove(ElementTags.BGBLUE);
+ value = attributes[ElementTags.BACKGROUNDCOLOR];
+ if (r != null || g != null || b != null) {
+ int red = 0;
+ int green = 0;
+ int blue = 0;
+ if (r != null) red = int.Parse(r);
+ if (g != null) green = int.Parse(g);
+ if (b != null) blue = int.Parse(b);
+ rect.BackgroundColor = new Color(red, green, blue);
+ }
+ else if (value != null) {
+ rect.BackgroundColor = Markup.DecodeColor(value);
+ }
+ else {
+ value = attributes[ElementTags.GRAYFILL];
+ if (value != null) {
+ rect.GrayFill = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ }
+ }
+
+ public static ChapterAutoNumber GetChapter(Properties attributes) {
+ ChapterAutoNumber chapter = new ChapterAutoNumber("");
+ SetSectionParameters(chapter, attributes);
+ return chapter;
+ }
+
+ public static Section GetSection(Section parent, Properties attributes) {
+ Section section = parent.AddSection("");
+ SetSectionParameters(section, attributes);
+ return section;
+ }
+
+ private static void SetSectionParameters(Section section, Properties attributes) {
+ String value;
+ value = attributes[ElementTags.NUMBERDEPTH];
+ if (value != null) {
+ section.NumberDepth = int.Parse(value);
+ }
+ value = attributes[ElementTags.INDENT];
+ if (value != null) {
+ section.Indentation = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ value = attributes[ElementTags.INDENTATIONLEFT];
+ if (value != null) {
+ section.IndentationLeft = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ value = attributes[ElementTags.INDENTATIONRIGHT];
+ if (value != null) {
+ section.IndentationRight = float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ }
+
+ /// String
to the HTML-format of a String.
+ * String
, each character is examined:
+ *
+ *
+ *
+ * (with xxx = the value of the character)
+ *
+ *
+ *
+ * (with xxx = the value of the character)
+ *
+ * String htmlPresentation = HtmlEncoder.Encode("Marie-Thérèse Sørensen");
+ *
String
to the HTML-format of this String
.
+ *
+ * @param string The String
to convert
+ * @return a String
+ */
+
+ public static String Encode(String str) {
+ int n = str.Length;
+ char character;
+ StringBuilder buffer = new StringBuilder();
+ // loop over all the characters of the String.
+ for (int i = 0; i < n; i++) {
+ character = str[i];
+ // the Htmlcode of these characters are added to a StringBuilder one by one
+ if (character < 256) {
+ buffer.Append(htmlCode[character]);
+ }
+ else {
+ // Improvement posted by Joachim Eyrich
+ buffer.Append("").Append((int)character).Append(';');
+ }
+ }
+ return buffer.ToString();
+ }
+
+ /**
+ * Converts a Color
into a HTML representation of this Color
.
+ *
+ * @param color the Color
that has to be converted.
+ * @return the HTML representation of this Tags
-class maps several XHTML-tags to iText-objects.
+ */
+
+ public class HtmlTagMap : Hashtable {
+
+ /**
+ * Constructs an HtmlTagMap.
+ */
+
+ public HtmlTagMap() {
+ HtmlPeer peer;
+
+ peer = new HtmlPeer(ElementTags.ITEXT, HtmlTags.HTML);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.SPAN);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.CHUNK);
+ peer.AddAlias(ElementTags.FONT, HtmlTags.FONT);
+ peer.AddAlias(ElementTags.SIZE, HtmlTags.SIZE);
+ peer.AddAlias(ElementTags.COLOR, HtmlTags.COLOR);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.ANCHOR, HtmlTags.ANCHOR);
+ peer.AddAlias(ElementTags.NAME, HtmlTags.NAME);
+ peer.AddAlias(ElementTags.REFERENCE, HtmlTags.REFERENCE);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.PARAGRAPH);
+ peer.AddAlias(ElementTags.ALIGN, HtmlTags.ALIGN);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.DIV);
+ peer.AddAlias(ElementTags.ALIGN, HtmlTags.ALIGN);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[0]);
+ peer.AddValue(ElementTags.SIZE, "20");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[1]);
+ peer.AddValue(ElementTags.SIZE, "18");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[2]);
+ peer.AddValue(ElementTags.SIZE, "16");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[3]);
+ peer.AddValue(ElementTags.SIZE, "14");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[4]);
+ peer.AddValue(ElementTags.SIZE, "12");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[5]);
+ peer.AddValue(ElementTags.SIZE, "10");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.LIST, HtmlTags.ORDEREDLIST);
+ peer.AddValue(ElementTags.NUMBERED, "true");
+ peer.AddValue(ElementTags.SYMBOLINDENT, "20");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.LIST, HtmlTags.UNORDEREDLIST);
+ peer.AddValue(ElementTags.NUMBERED, "false");
+ peer.AddValue(ElementTags.SYMBOLINDENT, "20");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.LISTITEM, HtmlTags.LISTITEM);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.I);
+ peer.AddValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.EM);
+ peer.AddValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.B);
+ peer.AddValue(ElementTags.STYLE, Markup.CSS_VALUE_BOLD);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.STRONG);
+ peer.AddValue(ElementTags.STYLE, Markup.CSS_VALUE_BOLD);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.S);
+ peer.AddValue(ElementTags.STYLE, Markup.CSS_VALUE_LINETHROUGH);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.CODE);
+ peer.AddValue(ElementTags.FONT, FontFactory.COURIER);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.VAR);
+ peer.AddValue(ElementTags.FONT, FontFactory.COURIER);
+ peer.AddValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.U);
+ peer.AddValue(ElementTags.STYLE, Markup.CSS_VALUE_UNDERLINE);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.SUP);
+ peer.AddValue(ElementTags.SUBSUPSCRIPT, "6.0");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.SUB);
+ peer.AddValue(ElementTags.SUBSUPSCRIPT, "-6.0");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.HORIZONTALRULE, HtmlTags.HORIZONTALRULE);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.TABLE, HtmlTags.TABLE);
+ peer.AddAlias(ElementTags.WIDTH, HtmlTags.WIDTH);
+ peer.AddAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR);
+ peer.AddAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR);
+ peer.AddAlias(ElementTags.COLUMNS, HtmlTags.COLUMNS);
+ peer.AddAlias(ElementTags.CELLPADDING, HtmlTags.CELLPADDING);
+ peer.AddAlias(ElementTags.CELLSPACING, HtmlTags.CELLSPACING);
+ peer.AddAlias(ElementTags.BORDERWIDTH, HtmlTags.BORDERWIDTH);
+ peer.AddAlias(ElementTags.ALIGN, HtmlTags.ALIGN);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.ROW, HtmlTags.ROW);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.CELL, HtmlTags.CELL);
+ peer.AddAlias(ElementTags.WIDTH, HtmlTags.WIDTH);
+ peer.AddAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR);
+ peer.AddAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR);
+ peer.AddAlias(ElementTags.COLSPAN, HtmlTags.COLSPAN);
+ peer.AddAlias(ElementTags.ROWSPAN, HtmlTags.ROWSPAN);
+ peer.AddAlias(ElementTags.NOWRAP, HtmlTags.NOWRAP);
+ peer.AddAlias(ElementTags.HORIZONTALALIGN, HtmlTags.HORIZONTALALIGN);
+ peer.AddAlias(ElementTags.VERTICALALIGN, HtmlTags.VERTICALALIGN);
+ peer.AddValue(ElementTags.HEADER, "false");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.CELL, HtmlTags.HEADERCELL);
+ peer.AddAlias(ElementTags.WIDTH, HtmlTags.WIDTH);
+ peer.AddAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR);
+ peer.AddAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR);
+ peer.AddAlias(ElementTags.COLSPAN, HtmlTags.COLSPAN);
+ peer.AddAlias(ElementTags.ROWSPAN, HtmlTags.ROWSPAN);
+ peer.AddAlias(ElementTags.NOWRAP, HtmlTags.NOWRAP);
+ peer.AddAlias(ElementTags.HORIZONTALALIGN, HtmlTags.HORIZONTALALIGN);
+ peer.AddAlias(ElementTags.VERTICALALIGN, HtmlTags.VERTICALALIGN);
+ peer.AddValue(ElementTags.HEADER, "true");
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.IMAGE, HtmlTags.IMAGE);
+ peer.AddAlias(ElementTags.URL, HtmlTags.URL);
+ peer.AddAlias(ElementTags.ALT, HtmlTags.ALT);
+ peer.AddAlias(ElementTags.PLAINWIDTH, HtmlTags.PLAINWIDTH);
+ peer.AddAlias(ElementTags.PLAINHEIGHT, HtmlTags.PLAINHEIGHT);
+ this[peer.Alias] = peer;
+
+ peer = new HtmlPeer(ElementTags.NEWLINE, HtmlTags.NEWLINE);
+ this[peer.Alias] = peer;
+ }
+
+ /**
+ * Checks if this is the root tag.
+ * @param tag a tagvalue
+ * @return true if tag is HTML or html
+ */
+ public static bool IsHtml(String tag) {
+ return Util.EqualsIgnoreCase(HtmlTags.HTML, tag);
+ }
+
+ /**
+ * Checks if this is the head tag.
+ * @param tag a tagvalue
+ * @return true if tag is HEAD or head
+ */
+ public static bool IsHead(String tag) {
+ return Util.EqualsIgnoreCase(HtmlTags.HEAD, tag);
+ }
+
+ /**
+ * Checks if this is the meta tag.
+ * @param tag a tagvalue
+ * @return true if tag is META or meta
+ */
+ public static bool IsMeta(String tag) {
+ return Util.EqualsIgnoreCase(HtmlTags.META, tag);
+ }
+
+ /**
+ * Checks if this is the linl tag.
+ * @param tag a tagvalue
+ * @return true if tag is LINK or link
+ */
+ public static bool IsLink(String tag) {
+ return Util.EqualsIgnoreCase(HtmlTags.LINK, tag);
+ }
+
+ /**
+ * Checks if this is the title tag.
+ * @param tag a tagvalue
+ * @return true if tag is TITLE or title
+ */
+ public static bool IsTitle(String tag) {
+ return Util.EqualsIgnoreCase(HtmlTags.TITLE, tag);
+ }
+
+ /**
+ * Checks if this is the root tag.
+ * @param tag a tagvalue
+ * @return true if tag is BODY or body
+ */
+ public static bool IsBody(String tag) {
+ return Util.EqualsIgnoreCase(HtmlTags.BODY, tag);
+ }
+
+ /**
+ * Checks if this is a special tag.
+ * @param tag a tagvalue
+ * @return true if tag is a HTML, HEAD, META, LINK or BODY tag (case insensitive)
+ */
+ public static bool IsSpecialTag(String tag) {
+ return IsHtml(tag) || IsHead(tag) || IsMeta(tag) || IsLink(tag) || IsBody(tag);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/html/HtmlTags.cs b/iTechSharp/iTextSharp/text/html/HtmlTags.cs
new file mode 100644
index 0000000..760ba03
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/html/HtmlTags.cs
@@ -0,0 +1,325 @@
+using System;
+
+/*
+ * $Id: HtmlTags.cs,v 1.4 2008/05/13 11:25:15 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.html {
+
+ /**
+ * A class that contains all the possible tagnames and their attributes.
+ */
+
+ public class HtmlTags {
+
+ /** the root tag. */
+ public const string HTML = "html";
+
+ /** the head tag */
+ public const string HEAD = "head";
+
+ /** This is a possible HTML attribute for the HEAD tag. */
+ public const string CONTENT = "content";
+
+ /** the meta tag */
+ public const string META = "meta";
+
+ /** attribute of the root tag */
+ public const string SUBJECT = "subject";
+
+ /** attribute of the root tag */
+ public const string KEYWORDS = "keywords";
+
+ /** attribute of the root tag */
+ public const string AUTHOR = "author";
+
+ /** the title tag. */
+ public const string TITLE = "title";
+
+ /** the script tag. */
+ public const string SCRIPT = "script";
+
+ /** This is a possible HTML attribute for the SCRIPT tag. */
+ public const string LANGUAGE = "language";
+
+ /** This is a possible value for the LANGUAGE attribute. */
+ public const string JAVASCRIPT = "JavaScript";
+
+ /** the body tag. */
+ public const string BODY = "body";
+
+ /** This is a possible HTML attribute for the BODY tag */
+ public const string JAVASCRIPT_ONLOAD = "onLoad";
+
+ /** This is a possible HTML attribute for the BODY tag */
+ public const string JAVASCRIPT_ONUNLOAD = "onUnLoad";
+
+ /** This is a possible HTML attribute for the BODY tag. */
+ public const string TOPMARGIN = "topmargin";
+
+ /** This is a possible HTML attribute for the BODY tag. */
+ public const string BOTTOMMARGIN = "bottommargin";
+
+ /** This is a possible HTML attribute for the BODY tag. */
+ public const string LEFTMARGIN = "leftmargin";
+
+ /** This is a possible HTML attribute for the BODY tag. */
+ public const string RIGHTMARGIN = "rightmargin";
+
+ // Phrases, Anchors, Lists and Paragraphs
+
+ /** the chunk tag */
+ public const string CHUNK = "font";
+
+ /** the phrase tag */
+ public const string CODE = "code";
+
+ /** the phrase tag */
+ public const string VAR = "var";
+
+ /** the anchor tag */
+ public const string ANCHOR = "a";
+
+ /** the list tag */
+ public const string ORDEREDLIST = "ol";
+
+ /** the list tag */
+ public const string UNORDEREDLIST = "ul";
+
+ /** the listitem tag */
+ public const string LISTITEM = "li";
+
+ /** the paragraph tag */
+ public const string PARAGRAPH = "p";
+
+ /** attribute of anchor tag */
+ public const string NAME = "name";
+
+ /** attribute of anchor tag */
+ public const string REFERENCE = "href";
+
+ /** attribute of anchor tag */
+ public static string[] H = {"h1", "h2", "h3", "h4", "h5", "h6"};
+
+ // Chunks
+
+ /** attribute of the chunk tag */
+ public const string FONT = "face";
+
+ /** attribute of the chunk tag */
+ public const string SIZE = "point-size";
+
+ /** attribute of the chunk/table/cell tag */
+ public const string COLOR = "color";
+
+ /** some phrase tag */
+ public const string EM = "em";
+
+ /** some phrase tag */
+ public const string I = "i";
+
+ /** some phrase tag */
+ public const string STRONG = "strong";
+
+ /** some phrase tag */
+ public const string B = "b";
+
+ /** some phrase tag */
+ public const string S = "s";
+
+ /** some phrase tag */
+ public const string U = "u";
+
+ /** some phrase tag */
+ public const string SUB = "sub";
+
+ /** some phrase tag */
+ public const string SUP = "sup";
+
+ /** the possible value of a tag */
+ public const string HORIZONTALRULE = "hr";
+
+ // tables/cells
+
+ /** the table tag */
+ public const string TABLE = "table";
+
+ /** the cell tag */
+ public const string ROW = "tr";
+
+ /** the cell tag */
+ public const string CELL = "td";
+
+ /** attribute of the cell tag */
+ public const string HEADERCELL = "th";
+
+ /** attribute of the table tag */
+ public const string COLUMNS = "cols";
+
+ /** attribute of the table tag */
+ public const string CELLPADDING = "cellpadding";
+
+ /** attribute of the table tag */
+ public const string CELLSPACING = "cellspacing";
+
+ /** attribute of the cell tag */
+ public const string COLSPAN = "colspan";
+
+ /** attribute of the cell tag */
+ public const string ROWSPAN = "rowspan";
+
+ /** attribute of the cell tag */
+ public const string NOWRAP = "nowrap";
+
+ /** attribute of the table/cell tag */
+ public const string BORDERWIDTH = "border";
+
+ /** attribute of the table/cell tag */
+ public const string WIDTH = "width";
+
+ /** attribute of the table/cell tag */
+ public const string BACKGROUNDCOLOR = "bgcolor";
+
+ /** attribute of the table/cell tag */
+ public const string BORDERCOLOR = "bordercolor";
+
+ /** attribute of paragraph/image/table tag */
+ public const string ALIGN = "align";
+
+ /** attribute of chapter/section/paragraph/table/cell tag */
+ public const string LEFT = "left";
+
+ /** attribute of chapter/section/paragraph/table/cell tag */
+ public const string RIGHT = "right";
+
+ /** attribute of the cell tag */
+ public const string HORIZONTALALIGN = "align";
+
+ /** attribute of the cell tag */
+ public const string VERTICALALIGN = "valign";
+
+ /** attribute of the table/cell tag */
+ public const string TOP = "top";
+
+ /** attribute of the table/cell tag */
+ public const string BOTTOM = "bottom";
+
+ // Misc
+
+ /** the image tag */
+ public const string IMAGE = "img";
+
+ /** attribute of the image tag */
+ public const string URL = "src";
+
+ /** attribute of the image tag */
+ public const string ALT = "alt";
+
+ /** attribute of the image tag */
+ public const string PLAINWIDTH = "width";
+
+ /** attribute of the image tag */
+ public const string PLAINHEIGHT = "height";
+
+ /** the newpage tag */
+ public const string NEWLINE = "br";
+
+ // alignment attribute values
+
+ /** the possible value of an alignment attribute */
+ public const string ALIGN_LEFT = "Left";
+
+ /** the possible value of an alignment attribute */
+ public const string ALIGN_CENTER = "Center";
+
+ /** the possible value of an alignment attribute */
+ public const string ALIGN_RIGHT = "Right";
+
+ /** the possible value of an alignment attribute */
+ public const string ALIGN_JUSTIFIED = "Justify";
+
+ /** the possible value of an alignment attribute */
+ public const string ALIGN_TOP = "Top";
+
+ /** the possible value of an alignment attribute */
+ public const string ALIGN_MIDDLE = "Middle";
+
+ /** the possible value of an alignment attribute */
+ public const string ALIGN_BOTTOM = "Bottom";
+
+ /** the possible value of an alignment attribute */
+ public const string ALIGN_BASELINE = "Baseline";
+
+ /** the possible value of an alignment attribute */
+ public const string DEFAULT = "Default";
+
+ /** The DIV tag. */
+ public const string DIV = "div";
+
+ /** The SPAN tag. */
+ public const string SPAN = "span";
+ /** The LINK tag. */
+ public const string LINK = "link";
+
+ /** This is a possible HTML attribute for the LINK tag. */
+ public const string TEXT_CSS = "text/css";
+
+ /** This is a possible HTML attribute for the LINK tag. */
+ public const string REL = "rel";
+
+ /** This is used for inline css style information */
+ public const string STYLE = "style";
+
+ /** This is a possible HTML attribute for the LINK tag. */
+ public const string TYPE = "type";
+
+ /** This is a possible HTML attribute. */
+ public const string STYLESHEET = "stylesheet";
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/html/HtmlWriter.cs b/iTechSharp/iTextSharp/text/html/HtmlWriter.cs
new file mode 100644
index 0000000..4e6f8d9
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/html/HtmlWriter.cs
@@ -0,0 +1,1041 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+using System.util;
+
+using iTextSharp.text;
+using iTextSharp.text.pdf;
+
+/*
+ * $Id: HtmlWriter.cs,v 1.24 2008/05/13 11:25:15 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.html {
+ /**
+ * A DocWriter
class for HTML.
+ * HtmlWriter
can be added as a DocListener
+ * to a certain Document
by getting an instance.
+ * Every Element
added to the original Document
+ * will be written to the Stream
of this HtmlWriter
.
+ *
+ * // creation of the document with a certain size and certain margins
+ * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
+ * try {
+ * // this will write HTML to the Standard Stream
+ * HtmlWriter.GetInstance(document, System.out);
+ * // this will write HTML to a file called text.html
+ * HtmlWriter.GetInstance(document, new FileOutputStream("text.html"));
+ * // this will write HTML to for instance the Stream of a HttpServletResponse-object
+ * HtmlWriter.GetInstance(document, response.GetOutputStream());
+ * }
+ * catch (DocumentException de) {
+ * System.err.Println(de.GetMessage());
+ * }
+ * // this will close the document and all the OutputStreams listening to it
+ * document.Close();
HtmlWriter
.
+ *
+ * @param doc The Document
that has to be written as HTML
+ * @param os The Stream
the writer has to write to.
+ */
+
+ protected HtmlWriter(Document doc, Stream os) : base(doc, os){
+
+ document.AddDocListener(this);
+ this.pageN = document.PageNumber;
+ os.WriteByte(LT);
+ byte[] tmp = GetISOBytes(HtmlTags.HTML);
+ os.Write(tmp, 0, tmp.Length);
+ os.WriteByte(GT);
+ os.WriteByte(NEWLINE);
+ os.WriteByte(TAB);
+ os.WriteByte(LT);
+ tmp = GetISOBytes(HtmlTags.HEAD);
+ os.Write(tmp, 0, tmp.Length);
+ os.WriteByte(GT);
+ }
+
+ // get an instance of the HtmlWriter
+
+ /**
+ * Gets an instance of the HtmlWriter
.
+ *
+ * @param document The Document
that has to be written
+ * @param os The Stream
the writer has to write to.
+ * @return a new HtmlWriter
+ */
+
+ public static HtmlWriter GetInstance(Document document, Stream os) {
+ return new HtmlWriter(document, os);
+ }
+
+ // implementation of the DocListener methods
+
+ /**
+ * Signals that an new page has to be started.
+ *
+ * @return true
if this action succeeded, false
if not.
+ * @throws DocumentException when a document isn't open yet, or has been closed
+ */
+
+ public override bool NewPage() {
+ try {
+ WriteStart(HtmlTags.DIV);
+ Write(" ");
+ Write(HtmlTags.STYLE);
+ Write("=\"");
+ WriteCssProperty(Markup.CSS_KEY_PAGE_BREAK_BEFORE, Markup.CSS_VALUE_ALWAYS);
+ Write("\" /");
+ os.WriteByte(GT);
+ }
+ catch (IOException ioe) {
+ throw new DocumentException(ioe.Message);
+ }
+ return true;
+ }
+
+ /**
+ * Signals that an Element
was added to the Document
.
+ *
+ * @return true
if the element was added, false
if not.
+ * @throws DocumentException when a document isn't open yet, or has been closed
+ */
+
+ public override bool Add(IElement element) {
+ if (pause) {
+ return false;
+ }
+ if (open && !element.IsContent()) {
+ throw new DocumentException("The document is open; you can only add Elements with content.");
+ }
+ switch (element.Type) {
+ case Element.HEADER:
+ try {
+ Header h = (Header) element;
+ if (HtmlTags.STYLESHEET.Equals(h.Name)) {
+ WriteLink(h);
+ }
+ else if (HtmlTags.JAVASCRIPT.Equals(h.Name)) {
+ WriteJavaScript(h);
+ }
+ else {
+ WriteHeader(h);
+ }
+ }
+ catch (InvalidCastException) {
+ }
+ return true;
+ case Element.SUBJECT:
+ case Element.KEYWORDS:
+ case Element.AUTHOR:
+ Meta meta = (Meta) element;
+ WriteHeader(meta);
+ return true;
+ case Element.TITLE:
+ AddTabs(2);
+ WriteStart(HtmlTags.TITLE);
+ os.WriteByte(GT);
+ AddTabs(3);
+ Write(HtmlEncoder.Encode(((Meta)element).Content));
+ AddTabs(2);
+ WriteEnd(HtmlTags.TITLE);
+ return true;
+ case Element.CREATOR:
+ WriteComment("Creator: " + HtmlEncoder.Encode(((Meta)element).Content));
+ return true;
+ case Element.PRODUCER:
+ WriteComment("Producer: " + HtmlEncoder.Encode(((Meta)element).Content));
+ return true;
+ case Element.CREATIONDATE:
+ WriteComment("Creationdate: " + HtmlEncoder.Encode(((Meta)element).Content));
+ return true;
+ case Element.MARKED:
+ if (element is MarkedSection) {
+ MarkedSection ms = (MarkedSection)element;
+ AddTabs(1);
+ WriteStart(HtmlTags.DIV);
+ WriteMarkupAttributes(ms.MarkupAttributes);
+ os.WriteByte(GT);
+ MarkedObject mo = ((MarkedSection)element).Title;
+ if (mo != null) {
+ markup = mo.MarkupAttributes;
+ mo.Process(this);
+ }
+ ms.Process(this);
+ WriteEnd(HtmlTags.DIV);
+ return true;
+ }
+ else {
+ MarkedObject mo = (MarkedObject) element;
+ markup = mo.MarkupAttributes;
+ return mo.Process(this);
+ }
+ default:
+ Write(element, 2);
+ return true;
+ }
+ }
+
+ /**
+ * Signals that the Document
has been opened and that
+ * Elements
can be added.
+ * HEAD
-section of the HTML-document is written.
+ */
+
+ public override void Open() {
+ base.Open();
+ WriteComment(Document.Version);
+ WriteComment("CreationDate: " + DateTime.Now.ToString());
+ AddTabs(1);
+ WriteEnd(HtmlTags.HEAD);
+ AddTabs(1);
+ WriteStart(HtmlTags.BODY);
+ if (document.LeftMargin > 0) {
+ Write(HtmlTags.LEFTMARGIN, document.LeftMargin.ToString());
+ }
+ if (document.RightMargin > 0) {
+ Write(HtmlTags.RIGHTMARGIN, document.RightMargin.ToString());
+ }
+ if (document.TopMargin > 0) {
+ Write(HtmlTags.TOPMARGIN, document.TopMargin.ToString());
+ }
+ if (document.BottomMargin > 0) {
+ Write(HtmlTags.BOTTOMMARGIN, document.BottomMargin.ToString());
+ }
+ if (pageSize.BackgroundColor != null) {
+ Write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.Encode(pageSize.BackgroundColor));
+ }
+ if (document.JavaScript_onLoad != null) {
+ Write(HtmlTags.JAVASCRIPT_ONLOAD, HtmlEncoder.Encode(document.JavaScript_onLoad));
+ }
+ if (document.JavaScript_onUnLoad != null) {
+ Write(HtmlTags.JAVASCRIPT_ONUNLOAD, HtmlEncoder.Encode(document.JavaScript_onUnLoad));
+ }
+ if (document.HtmlStyleClass != null) {
+ Write(Markup.HTML_ATTR_CSS_CLASS, document.HtmlStyleClass);
+ }
+ os.WriteByte(GT);
+ InitHeader(); // line added by David Freels
+ }
+
+ /**
+ * Signals that the Document
was closed and that no other
+ * Elements
will be added.
+ */
+
+ public override void Close() {
+ InitFooter(); // line added by David Freels
+ AddTabs(1);
+ WriteEnd(HtmlTags.BODY);
+ os.WriteByte(NEWLINE);
+ WriteEnd(HtmlTags.HTML);
+ base.Close();
+ }
+
+ // some protected methods
+
+ /**
+ * Adds the header to the top of the String
was added to the Document
.
+ *
+ * @return true
if the string was added, false
if not.
+ * @throws DocumentException when a document isn't open yet, or has been closed
+ */
+
+ public bool Add(String str) {
+ if (pause) {
+ return false;
+ }
+ Write(str);
+ return true;
+ }
+
+ /**
+ * Writes the HTML representation of an element.
+ *
+ * @param element the element
+ * @param indent the indentation
+ */
+
+ protected void Write(IElement element, int indent) {
+ Properties styleAttributes = null;
+ switch (element.Type) {
+ case Element.MARKED: {
+ try {
+ Add(element);
+ } catch (DocumentException) {
+ }
+ return;
+ }
+ case Element.CHUNK: {
+ Chunk chunk = (Chunk) element;
+ // if the chunk contains an image, return the image representation
+ Image image = chunk.GetImage();
+ if (image != null) {
+ Write(image, indent);
+ return;
+ }
+
+ if (chunk.IsEmpty()) return;
+ Hashtable attributes = chunk.Attributes;
+ if (attributes != null && attributes[Chunk.NEWPAGE] != null) {
+ return;
+ }
+ bool tag = IsOtherFont(chunk.Font) || markup.Count > 0;
+ if (tag) {
+ // start span tag
+ AddTabs(indent);
+ WriteStart(HtmlTags.SPAN);
+ if (IsOtherFont(chunk.Font)) {
+ Write(chunk.Font, null);
+ }
+ WriteMarkupAttributes(markup);
+ os.WriteByte(GT);
+ }
+ if (attributes != null && attributes[Chunk.SUBSUPSCRIPT] != null) {
+ // start sup or sub tag
+ if ((float)attributes[Chunk.SUBSUPSCRIPT] > 0) {
+ WriteStart(HtmlTags.SUP);
+ }
+ else {
+ WriteStart(HtmlTags.SUB);
+ }
+ os.WriteByte(GT);
+ }
+ // contents
+ Write(HtmlEncoder.Encode(chunk.Content));
+ if (attributes != null && attributes[Chunk.SUBSUPSCRIPT] != null) {
+ // end sup or sub tag
+ os.WriteByte(LT);
+ os.WriteByte(FORWARD);
+ if ((float)attributes[Chunk.SUBSUPSCRIPT] > 0) {
+ Write(HtmlTags.SUP);
+ }
+ else {
+ Write(HtmlTags.SUB);
+ }
+ os.WriteByte(GT);
+ }
+ if (tag) {
+ // end tag
+ WriteEnd(Markup.HTML_TAG_SPAN);
+ }
+ return;
+ }
+ case Element.PHRASE: {
+ Phrase phrase = (Phrase) element;
+ styleAttributes = new Properties();
+ if (phrase.HasLeading()) styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = phrase.Leading.ToString() + "pt";
+
+ // start tag
+ AddTabs(indent);
+ WriteStart(Markup.HTML_TAG_SPAN);
+ WriteMarkupAttributes(markup);
+ Write(phrase.Font, styleAttributes);
+ os.WriteByte(GT);
+ currentfont.Push(phrase.Font);
+ // contents
+ foreach (IElement i in phrase) {
+ Write(i, indent + 1);
+ }
+ // end tag
+ AddTabs(indent);
+ WriteEnd(Markup.HTML_TAG_SPAN);
+ currentfont.Pop();
+ return;
+ }
+ case Element.ANCHOR: {
+ Anchor anchor = (Anchor) element;
+ styleAttributes = new Properties();
+ if (anchor.HasLeading()) styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = anchor.Leading.ToString() + "pt";
+
+ // start tag
+ AddTabs(indent);
+ WriteStart(HtmlTags.ANCHOR);
+ if (anchor.Name != null) {
+ Write(HtmlTags.NAME, anchor.Name);
+ }
+ if (anchor.Reference != null) {
+ Write(HtmlTags.REFERENCE, anchor.Reference);
+ }
+ WriteMarkupAttributes(markup);
+ Write(anchor.Font, styleAttributes);
+ os.WriteByte(GT);
+ currentfont.Push(anchor.Font);
+ // contents
+ foreach (IElement i in anchor) {
+ Write(i, indent + 1);
+ }
+ // end tag
+ AddTabs(indent);
+ WriteEnd(HtmlTags.ANCHOR);
+ currentfont.Pop();
+ return;
+ }
+ case Element.PARAGRAPH: {
+ Paragraph paragraph = (Paragraph) element;
+ styleAttributes = new Properties();
+ if (paragraph.HasLeading()) styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = paragraph.TotalLeading.ToString() + "pt";
+
+ // start tag
+ AddTabs(indent);
+ WriteStart(HtmlTags.DIV);
+ WriteMarkupAttributes(markup);
+ String alignment = HtmlEncoder.GetAlignment(paragraph.Alignment);
+ if (!"".Equals(alignment)) {
+ Write(HtmlTags.ALIGN, alignment);
+ }
+ Write(paragraph.Font, styleAttributes);
+ os.WriteByte(GT);
+ currentfont.Push(paragraph.Font);
+ // contents
+ foreach (IElement i in paragraph) {
+ Write(i, indent + 1);
+ }
+ // end tag
+ AddTabs(indent);
+ WriteEnd(HtmlTags.DIV);
+ currentfont.Pop();
+ return;
+ }
+ case Element.SECTION:
+ case Element.CHAPTER: {
+ // part of the start tag + contents
+ WriteSection((Section) element, indent);
+ return;
+ }
+ case Element.LIST: {
+ List list = (List) element;
+ // start tag
+ AddTabs(indent);
+ if (list.Numbered) {
+ WriteStart(HtmlTags.ORDEREDLIST);
+ }
+ else {
+ WriteStart(HtmlTags.UNORDEREDLIST);
+ }
+ WriteMarkupAttributes(markup);
+ os.WriteByte(GT);
+ // contents
+ foreach (IElement i in list.Items) {
+ Write(i, indent + 1);
+ }
+ // end tag
+ AddTabs(indent);
+ if (list.Numbered) {
+ WriteEnd(HtmlTags.ORDEREDLIST);
+ }
+ else {
+ WriteEnd(HtmlTags.UNORDEREDLIST);
+ }
+ return;
+ }
+ case Element.LISTITEM: {
+ ListItem listItem = (ListItem) element;
+ styleAttributes = new Properties();
+ if (listItem.HasLeading()) styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = listItem.TotalLeading.ToString() + "pt";
+
+ // start tag
+ AddTabs(indent);
+ WriteStart(HtmlTags.LISTITEM);
+ WriteMarkupAttributes(markup);
+ Write(listItem.Font, styleAttributes);
+ os.WriteByte(GT);
+ currentfont.Push(listItem.Font);
+ // contents
+ foreach (IElement i in listItem) {
+ Write(i, indent + 1);
+ }
+ // end tag
+ AddTabs(indent);
+ WriteEnd(HtmlTags.LISTITEM);
+ currentfont.Pop();
+ return;
+ }
+ case Element.CELL: {
+ Cell cell = (Cell) element;
+
+ // start tag
+ AddTabs(indent);
+ if (cell.Header) {
+ WriteStart(HtmlTags.HEADERCELL);
+ }
+ else {
+ WriteStart(HtmlTags.CELL);
+ }
+ WriteMarkupAttributes(markup);
+ if (cell.BorderWidth != Rectangle.UNDEFINED) {
+ Write(HtmlTags.BORDERWIDTH, cell.BorderWidth.ToString());
+ }
+ if (cell.BorderColor != null) {
+ Write(HtmlTags.BORDERCOLOR, HtmlEncoder.Encode(cell.BorderColor));
+ }
+ if (cell.BackgroundColor != null) {
+ Write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.Encode(cell.BackgroundColor));
+ }
+ String alignment = HtmlEncoder.GetAlignment(cell.HorizontalAlignment);
+ if (!"".Equals(alignment)) {
+ Write(HtmlTags.HORIZONTALALIGN, alignment);
+ }
+ alignment = HtmlEncoder.GetAlignment(cell.VerticalAlignment);
+ if (!"".Equals(alignment)) {
+ Write(HtmlTags.VERTICALALIGN, alignment);
+ }
+ if (cell.GetWidthAsString() != null) {
+ Write(HtmlTags.WIDTH, cell.GetWidthAsString());
+ }
+ if (cell.Colspan != 1) {
+ Write(HtmlTags.COLSPAN, cell.Colspan.ToString());
+ }
+ if (cell.Rowspan != 1) {
+ Write(HtmlTags.ROWSPAN, cell.Rowspan.ToString());
+ }
+ if (cell.MaxLines == 1) {
+ Write(HtmlTags.STYLE, "white-space: nowrap;");
+ }
+ os.WriteByte(GT);
+ // contents
+ if (cell.IsEmpty()) {
+ Write(NBSP);
+ } else {
+ foreach (IElement i in cell.Elements) {
+ Write(i, indent + 1);
+ }
+ }
+ // end tag
+ AddTabs(indent);
+ if (cell.Header) {
+ WriteEnd(HtmlTags.HEADERCELL);
+ }
+ else {
+ WriteEnd(HtmlTags.CELL);
+ }
+ return;
+ }
+ case Element.ROW: {
+ Row row = (Row) element;
+
+ // start tag
+ AddTabs(indent);
+ WriteStart(HtmlTags.ROW);
+ WriteMarkupAttributes(markup);
+ os.WriteByte(GT);
+ // contents
+ IElement cell;
+ for (int i = 0; i < row.Columns; i++) {
+ if ((cell = (IElement)row.GetCell(i)) != null) {
+ Write(cell, indent + 1);
+ }
+ }
+ // end tag
+ AddTabs(indent);
+ WriteEnd(HtmlTags.ROW);
+ return;
+ }
+ case Element.TABLE: {
+ Table table;
+ try {
+ table = (Table) element;
+ }
+ catch (InvalidCastException) {
+ table = ((SimpleTable)element).CreateTable();
+ }
+ table.Complete();
+ // start tag
+ AddTabs(indent);
+ WriteStart(HtmlTags.TABLE);
+ WriteMarkupAttributes(markup);
+ os.WriteByte(SPACE);
+ Write(HtmlTags.WIDTH);
+ os.WriteByte(EQUALS);
+ os.WriteByte(QUOTE);
+ Write(table.Width.ToString(System.Globalization.CultureInfo.InvariantCulture));
+ if (!table.Locked){
+ Write("%");
+ }
+ os.WriteByte(QUOTE);
+ String alignment = HtmlEncoder.GetAlignment(table.Alignment);
+ if (!"".Equals(alignment)) {
+ Write(HtmlTags.ALIGN, alignment);
+ }
+ Write(HtmlTags.CELLPADDING, table.Cellpadding.ToString(System.Globalization.CultureInfo.InvariantCulture));
+ Write(HtmlTags.CELLSPACING, table.Cellspacing.ToString(System.Globalization.CultureInfo.InvariantCulture));
+ if (table.BorderWidth != Rectangle.UNDEFINED) {
+ Write(HtmlTags.BORDERWIDTH, table.BorderWidth.ToString(System.Globalization.CultureInfo.InvariantCulture));
+ }
+ if (table.BorderColor != null) {
+ Write(HtmlTags.BORDERCOLOR, HtmlEncoder.Encode(table.BorderColor));
+ }
+ if (table.BackgroundColor != null) {
+ Write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.Encode(table.BackgroundColor));
+ }
+ os.WriteByte(GT);
+ // contents
+ foreach (Row row in table) {
+ Write(row, indent + 1);
+ }
+ // end tag
+ AddTabs(indent);
+ WriteEnd(HtmlTags.TABLE);
+ return;
+ }
+ case Element.ANNOTATION: {
+ Annotation annotation = (Annotation) element;
+ WriteComment(annotation.Title + ": " + annotation.Content);
+ return;
+ }
+ case Element.IMGRAW:
+ case Element.JPEG:
+ case Element.JPEG2000:
+ case Element.IMGTEMPLATE: {
+ Image image = (Image) element;
+ if (image.Url == null) {
+ return;
+ }
+
+ // start tag
+ AddTabs(indent);
+ WriteStart(HtmlTags.IMAGE);
+ String path = image.Url.ToString();
+ if (imagepath != null) {
+ if (path.IndexOf('/') > 0) {
+ path = imagepath + path.Substring(path.LastIndexOf('/') + 1);
+ }
+ else {
+ path = imagepath + path;
+ }
+ }
+ Write(HtmlTags.URL, path);
+ if ((image.Alignment & Image.RIGHT_ALIGN) > 0) {
+ Write(HtmlTags.ALIGN, HtmlTags.ALIGN_RIGHT);
+ }
+ else if ((image.Alignment & Image.MIDDLE_ALIGN) > 0) {
+ Write(HtmlTags.ALIGN, HtmlTags.ALIGN_MIDDLE);
+ }
+ else {
+ Write(HtmlTags.ALIGN, HtmlTags.ALIGN_LEFT);
+ }
+ if (image.Alt != null) {
+ Write(HtmlTags.ALT, image.Alt);
+ }
+ Write(HtmlTags.PLAINWIDTH, image.ScaledWidth.ToString());
+ Write(HtmlTags.PLAINHEIGHT, image.ScaledHeight.ToString());
+ WriteMarkupAttributes(markup);
+ WriteEnd();
+ return;
+ }
+
+ default:
+ return;
+ }
+ }
+
+ /**
+ * Writes the HTML representation of a section.
+ *
+ * @param section the section to write
+ * @param indent the indentation
+ */
+
+ protected void WriteSection(Section section, int indent) {
+ if (section.Title != null) {
+ int depth = section.Depth - 1;
+ if (depth > 5) {
+ depth = 5;
+ }
+ Properties styleAttributes = new Properties();
+ if (section.Title.HasLeading()) styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = section.Title.TotalLeading.ToString() + "pt";
+ // start tag
+ AddTabs(indent);
+ WriteStart(HtmlTags.H[depth]);
+ Write(section.Title.Font, styleAttributes);
+ String alignment = HtmlEncoder.GetAlignment(section.Title.Alignment);
+ if (!"".Equals(alignment)) {
+ Write(HtmlTags.ALIGN, alignment);
+ }
+ WriteMarkupAttributes(markup);
+ os.WriteByte(GT);
+ currentfont.Push(section.Title.Font);
+ // contents
+ foreach (IElement i in section.Title) {
+ Write(i, indent + 1);
+ }
+ // end tag
+ AddTabs(indent);
+ WriteEnd(HtmlTags.H[depth]);
+ currentfont.Pop();
+ }
+ foreach (IElement i in section) {
+ Write(i, indent);
+ }
+ }
+
+ /**
+ * Writes the representation of a Font
.
+ *
+ * @param font a Font
+ * @param styleAttributes the style of the font
+ */
+
+ protected void Write(Font font, Properties styleAttributes) {
+ if (font == null || !IsOtherFont(font) /*|| styleAttributes == null*/) return;
+ Write(" ");
+ Write(HtmlTags.STYLE);
+ Write("=\"");
+ if (styleAttributes != null) {
+ foreach (String key in styleAttributes.Keys) {
+ WriteCssProperty(key, styleAttributes[key]);
+ }
+ }
+ if (IsOtherFont(font)) {
+ WriteCssProperty(Markup.CSS_KEY_FONTFAMILY, font.Familyname);
+
+ if (font.Size != Font.UNDEFINED) {
+ WriteCssProperty(Markup.CSS_KEY_FONTSIZE, font.Size.ToString() + "pt");
+ }
+ if (font.Color != null) {
+ WriteCssProperty(Markup.CSS_KEY_COLOR, HtmlEncoder.Encode(font.Color));
+ }
+
+ int fontstyle = font.Style;
+ BaseFont bf = font.BaseFont;
+ if (bf != null) {
+ String ps = bf.PostscriptFontName.ToLower(CultureInfo.InvariantCulture);
+ if (ps.IndexOf("bold") >= 0) {
+ if (fontstyle == Font.UNDEFINED)
+ fontstyle = 0;
+ fontstyle |= Font.BOLD;
+ }
+ if (ps.IndexOf("italic") >= 0 || ps.IndexOf("oblique") >= 0) {
+ if (fontstyle == Font.UNDEFINED)
+ fontstyle = 0;
+ fontstyle |= Font.ITALIC;
+ }
+ }
+ if (fontstyle != Font.UNDEFINED && fontstyle != Font.NORMAL) {
+ switch (fontstyle & Font.BOLDITALIC) {
+ case Font.BOLD:
+ WriteCssProperty(Markup.CSS_KEY_FONTWEIGHT, Markup.CSS_VALUE_BOLD);
+ break;
+ case Font.ITALIC:
+ WriteCssProperty(Markup.CSS_KEY_FONTSTYLE, Markup.CSS_VALUE_ITALIC);
+ break;
+ case Font.BOLDITALIC:
+ WriteCssProperty(Markup.CSS_KEY_FONTWEIGHT, Markup.CSS_VALUE_BOLD);
+ WriteCssProperty(Markup.CSS_KEY_FONTSTYLE, Markup.CSS_VALUE_ITALIC);
+ break;
+ }
+
+ // CSS only supports one decoration tag so if both are specified
+ // only one of the two will display
+ if ((fontstyle & Font.UNDERLINE) > 0) {
+ WriteCssProperty(Markup.CSS_KEY_TEXTDECORATION, Markup.CSS_VALUE_UNDERLINE);
+ }
+ if ((fontstyle & Font.STRIKETHRU) > 0) {
+ WriteCssProperty(Markup.CSS_KEY_TEXTDECORATION, Markup.CSS_VALUE_LINETHROUGH);
+ }
+ }
+ }
+ Write("\"");
+ }
+
+ /**
+ * Writes out a CSS property.
+ */
+ protected void WriteCssProperty(String prop, String value) {
+ Write(new StringBuilder(prop).Append(": ").Append(value).Append("; ").ToString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/html/ITextmyHtmlHandler.cs b/iTechSharp/iTextSharp/text/html/ITextmyHtmlHandler.cs
new file mode 100644
index 0000000..2d6fa50
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/html/ITextmyHtmlHandler.cs
@@ -0,0 +1,239 @@
+using System;
+using System.Collections;
+using System.Globalization;
+using System.util;
+using iTextSharp.text;
+using iTextSharp.text.xml;
+using iTextSharp.text.pdf;
+using iTextSharp.text.factories;
+
+/*
+ * $Id: ITextmyHtmlHandler.cs,v 1.9 2008/05/13 11:25:15 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.html {
+
+ /**
+ * The Tags
-class maps several XHTML-tags to iText-objects.
+ */
+
+ public class ITextmyHtmlHandler : ITextHandler {
+
+ /** These are the properties of the body section. */
+ private Properties bodyAttributes = new Properties();
+
+ /** This is the status of the table border. */
+ private bool tableBorder = false;
+
+ /**
+ * Constructs a new SAXiTextHandler that will translate all the events
+ * triggered by the parser to actions on the Document
-object.
+ *
+ * @param document this is the document on which events must be triggered
+ */
+
+ public ITextmyHtmlHandler(IDocListener document) : base(document, new HtmlTagMap()) {
+ }
+
+ public ITextmyHtmlHandler(IDocListener document, BaseFont bf) : base(document, new HtmlTagMap(), bf) {
+ }
+
+ /**
+ * Constructs a new SAXiTextHandler that will translate all the events
+ * triggered by the parser to actions on the Document
-object.
+ *
+ * @param document this is the document on which events must be triggered
+ * @param htmlTags a tagmap translating HTML tags to iText tags
+ */
+
+ public ITextmyHtmlHandler(IDocListener document, Hashtable htmlTags) : base(document, htmlTags) {
+ }
+
+ /**
+ * This method gets called when a start tag is encountered.
+ *
+ * @param uri the Uniform Resource Identifier
+ * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed.
+ * @param name the name of the tag that is encountered
+ * @param attrs the list of attributes
+ */
+
+ public override void StartElement(String uri, String lname, String name, Hashtable attrs) {
+ //System.err.Println("Start: " + name);
+
+ // super.handleStartingTags is replaced with handleStartingTags
+ // suggestion by Vu Ngoc Tan/Hop
+ name = name.ToLower(CultureInfo.InvariantCulture);
+ if (HtmlTagMap.IsHtml(name)) {
+ // we do nothing
+ return;
+ }
+ if (HtmlTagMap.IsHead(name)) {
+ // we do nothing
+ return;
+ }
+ if (HtmlTagMap.IsTitle(name)) {
+ // we do nothing
+ return;
+ }
+ if (HtmlTagMap.IsMeta(name)) {
+ // we look if we can change the body attributes
+ String meta = null;
+ String content = null;
+ if (attrs != null) {
+ foreach (String attribute in attrs.Keys) {
+ if (Util.EqualsIgnoreCase(attribute, HtmlTags.CONTENT))
+ content = (String)attrs[attribute];
+ else if (Util.EqualsIgnoreCase(attribute, HtmlTags.NAME))
+ meta = (String)attrs[attribute];
+ }
+ }
+ if (meta != null && content != null) {
+ bodyAttributes.Add(meta, content);
+ }
+ return;
+ }
+ if (HtmlTagMap.IsLink(name)) {
+ // we do nothing for the moment, in a later version we could extract the style sheet
+ return;
+ }
+ if (HtmlTagMap.IsBody(name)) {
+ // maybe we could extract some info about the document: color, margins,...
+ // but that's for a later version...
+ XmlPeer peer = new XmlPeer(ElementTags.ITEXT, name);
+ peer.AddAlias(ElementTags.TOP, HtmlTags.TOPMARGIN);
+ peer.AddAlias(ElementTags.BOTTOM, HtmlTags.BOTTOMMARGIN);
+ peer.AddAlias(ElementTags.RIGHT, HtmlTags.RIGHTMARGIN);
+ peer.AddAlias(ElementTags.LEFT, HtmlTags.LEFTMARGIN);
+ bodyAttributes.AddAll(peer.GetAttributes(attrs));
+ HandleStartingTags(peer.Tag, bodyAttributes);
+ return;
+ }
+ if (myTags.ContainsKey(name)) {
+ XmlPeer peer = (XmlPeer) myTags[name];
+ if (ElementTags.TABLE.Equals(peer.Tag) || ElementTags.CELL.Equals(peer.Tag)) {
+ Properties p = peer.GetAttributes(attrs);
+ String value;
+ if (ElementTags.TABLE.Equals(peer.Tag) && (value = p[ElementTags.BORDERWIDTH]) != null) {
+ if (float.Parse(value, System.Globalization.NumberFormatInfo.InvariantInfo) > 0) {
+ tableBorder = true;
+ }
+ }
+ if (tableBorder) {
+ p.Add(ElementTags.LEFT, "true");
+ p.Add(ElementTags.RIGHT, "true");
+ p.Add(ElementTags.TOP, "true");
+ p.Add(ElementTags.BOTTOM, "true");
+ }
+ HandleStartingTags(peer.Tag, p);
+ return;
+ }
+ HandleStartingTags(peer.Tag, peer.GetAttributes(attrs));
+ return;
+ }
+ Properties attributes = new Properties();
+ if (attrs != null) {
+ foreach (String attribute in attrs.Keys) {
+ attributes.Add(attribute.ToLower(CultureInfo.InvariantCulture), ((String)attrs[attribute]).ToLower(CultureInfo.InvariantCulture));
+ }
+ }
+ HandleStartingTags(name, attributes);
+ }
+
+ /**
+ * This method gets called when an end tag is encountered.
+ *
+ * @param uri the Uniform Resource Identifier
+ * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed.
+ * @param name the name of the tag that ends
+ */
+
+ public override void EndElement(String uri, String lname, String name) {
+ //System.err.Println("End: " + name);
+ name = name.ToLower(CultureInfo.InvariantCulture);
+ if (ElementTags.PARAGRAPH.Equals(name)) {
+ document.Add((IElement) stack.Pop());
+ return;
+ }
+ if (HtmlTagMap.IsHead(name)) {
+ // we do nothing
+ return;
+ }
+ if (HtmlTagMap.IsTitle(name)) {
+ if (currentChunk != null) {
+ bodyAttributes.Add(ElementTags.TITLE, currentChunk.Content);
+ }
+ return;
+ }
+ if (HtmlTagMap.IsMeta(name)) {
+ // we do nothing
+ return;
+ }
+ if (HtmlTagMap.IsLink(name)) {
+ // we do nothing
+ return;
+ }
+ if (HtmlTagMap.IsBody(name)) {
+ // we do nothing
+ return;
+ }
+ if (myTags.ContainsKey(name)) {
+ XmlPeer peer = (XmlPeer) myTags[name];
+ if (ElementTags.TABLE.Equals(peer.Tag)) {
+ tableBorder = false;
+ }
+ base.HandleEndingTags(peer.Tag);
+ return;
+ }
+ // super.handleEndingTags is replaced with handleEndingTags
+ // suggestion by Ken Auer
+ HandleEndingTags(name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/html/Markup.cs b/iTechSharp/iTextSharp/text/html/Markup.cs
new file mode 100644
index 0000000..f2a56c4
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/html/Markup.cs
@@ -0,0 +1,427 @@
+using System;
+using System.util;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+using iTextSharp.text;
+
+/*
+ * $Id: Markup.cs,v 1.2 2008/05/13 11:25:16 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.html {
+ /// Color
into a HTML representation of this Color
.
+ /// Color
that has to be converted.
+ /// Color
null
if the field does not exist
+ */
+ public String[] GetAppearanceStates(String fieldName) {
+ Item fd = (Item)fields[fieldName];
+ if (fd == null)
+ return null;
+ Hashtable names = new Hashtable();
+ PdfDictionary vals = (PdfDictionary)fd.values[0];
+ PdfObject opts = PdfReader.GetPdfObject(vals.Get(PdfName.OPT));
+ if (opts != null) {
+ if (opts.IsString())
+ names[((PdfString)opts).ToUnicodeString()] = null;
+ else if (opts.IsArray()) {
+ ArrayList list = ((PdfArray)opts).ArrayList;
+ for (int k = 0; k < list.Count; ++k) {
+ PdfObject v = PdfReader.GetPdfObject((PdfObject)list[k]);
+ if (v != null && v.IsString())
+ names[((PdfString)v).ToUnicodeString()] = null;
+ }
+ }
+ }
+ ArrayList wd = fd.widgets;
+ for (int k = 0; k < wd.Count; ++k) {
+ PdfDictionary dic = (PdfDictionary)wd[k];
+ dic = (PdfDictionary)PdfReader.GetPdfObject(dic.Get(PdfName.AP));
+ if (dic == null)
+ continue;
+ PdfObject ob = PdfReader.GetPdfObject(dic.Get(PdfName.N));
+ if (ob == null || !ob.IsDictionary())
+ continue;
+ dic = (PdfDictionary)ob;
+ foreach (PdfName pname in dic.Keys) {
+ String name = PdfName.DecodeName(pname.ToString());
+ names[name] = null;
+ }
+ }
+ string[] outs = new string[names.Count];
+ names.Keys.CopyTo(outs, 0);
+ return outs;
+ }
+
+ private String[] GetListOption(String fieldName, int idx) {
+ Item fd = GetFieldItem(fieldName);
+ if (fd == null)
+ return null;
+ PdfObject obj = PdfReader.GetPdfObject(((PdfDictionary)fd.merged[0]).Get(PdfName.OPT));
+ if (obj == null || !obj.IsArray())
+ return null;
+ PdfArray ar = (PdfArray)obj;
+ String[] ret = new String[ar.Size];
+ ArrayList a = ar.ArrayList;
+ for (int k = 0; k < a.Count; ++k) {
+ obj = PdfReader.GetPdfObject((PdfObject)a[k]);
+ try {
+ if (obj.IsArray()) {
+ obj = (PdfObject)((PdfArray)obj).ArrayList[idx];
+ }
+ if (obj.IsString())
+ ret[k] = ((PdfString)obj).ToUnicodeString();
+ else
+ ret[k] = obj.ToString();
+ }
+ catch {
+ ret[k] = "";
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the list of export option values from fields of type list or combo.
+ * If the field doesn't exist or the field type is not list or combo it will return
+ * null
.
+ * @param fieldName the field name
+ * @return the list of export option values from fields of type list or combo
+ */
+ public String[] GetListOptionExport(String fieldName) {
+ return GetListOption(fieldName, 0);
+ }
+
+ /**
+ * Gets the list of display option values from fields of type list or combo.
+ * If the field doesn't exist or the field type is not list or combo it will return
+ * null
.
+ * @param fieldName the field name
+ * @return the list of export option values from fields of type list or combo
+ */
+ public String[] GetListOptionDisplay(String fieldName) {
+ return GetListOption(fieldName, 1);
+ }
+
+ /**
+ * Sets the option list for fields of type list or combo. One of exportValues
+ * or displayValues
may be null
but not both. This method will only
+ * set the list but will not set the value or appearance. For that, calling setField()
+ * is required.
+ *
+ * PdfReader pdf = new PdfReader("input.pdf");
+ * PdfStamper stp = new PdfStamper(pdf, new FileOutputStream("output.pdf"));
+ * AcroFields af = stp.GetAcroFields();
+ * af.SetListOption("ComboBox", new String[]{"a", "b", "c"}, new String[]{"first", "second", "third"});
+ * af.SetField("ComboBox", "b");
+ * stp.Close();
+ *
+ * @param fieldName the field name
+ * @param exportValues the export values
+ * @param displayValues the display values
+ * @return true
if the operation succeeded, false
otherwise
+ */
+ public bool SetListOption(String fieldName, String[] exportValues, String[] displayValues) {
+ if (exportValues == null && displayValues == null)
+ return false;
+ if (exportValues != null && displayValues != null && exportValues.Length != displayValues.Length)
+ throw new ArgumentException("The export and the display array must have the same size.");
+ int ftype = GetFieldType(fieldName);
+ if (ftype != FIELD_TYPE_COMBO && ftype != FIELD_TYPE_LIST)
+ return false;
+ Item fd = (Item)fields[fieldName];
+ String[] sing = null;
+ if (exportValues == null && displayValues != null)
+ sing = displayValues;
+ else if (exportValues != null && displayValues == null)
+ sing = exportValues;
+ PdfArray opt = new PdfArray();
+ if (sing != null) {
+ for (int k = 0; k < sing.Length; ++k)
+ opt.Add(new PdfString(sing[k], PdfObject.TEXT_UNICODE));
+ }
+ else {
+ for (int k = 0; k < exportValues.Length; ++k) {
+ PdfArray a = new PdfArray();
+ a.Add(new PdfString(exportValues[k], PdfObject.TEXT_UNICODE));
+ a.Add(new PdfString(displayValues[k], PdfObject.TEXT_UNICODE));
+ opt.Add(a);
+ }
+ }
+ ((PdfDictionary)fd.values[0]).Put(PdfName.OPT, opt);
+ for (int j = 0; j < fd.merged.Count; ++j)
+ ((PdfDictionary)fd.merged[j]).Put(PdfName.OPT, opt);
+ return true;
+ }
+
+ /**
+ * Gets the field type. The type can be one of: FIELD_TYPE_PUSHBUTTON
,
+ * FIELD_TYPE_CHECKBOX
, FIELD_TYPE_RADIOBUTTON
,
+ * FIELD_TYPE_TEXT
, FIELD_TYPE_LIST
,
+ * FIELD_TYPE_COMBO
or FIELD_TYPE_SIGNATURE
.
+ * FIELD_TYPE_NONE
.
+ * @param fieldName the field name
+ * @return the field type
+ */
+ public int GetFieldType(String fieldName) {
+ Item fd = GetFieldItem(fieldName);
+ if (fd == null)
+ return FIELD_TYPE_NONE;
+ PdfObject type = PdfReader.GetPdfObject(((PdfDictionary)fd.merged[0]).Get(PdfName.FT));
+ if (type == null)
+ return FIELD_TYPE_NONE;
+ int ff = 0;
+ PdfObject ffo = PdfReader.GetPdfObject(((PdfDictionary)fd.merged[0]).Get(PdfName.FF));
+ if (ffo != null && ffo.Type == PdfObject.NUMBER)
+ ff = ((PdfNumber)ffo).IntValue;
+ if (PdfName.BTN.Equals(type)) {
+ if ((ff & PdfFormField.FF_PUSHBUTTON) != 0)
+ return FIELD_TYPE_PUSHBUTTON;
+ if ((ff & PdfFormField.FF_RADIO) != 0)
+ return FIELD_TYPE_RADIOBUTTON;
+ else
+ return FIELD_TYPE_CHECKBOX;
+ }
+ else if (PdfName.TX.Equals(type)) {
+ return FIELD_TYPE_TEXT;
+ }
+ else if (PdfName.CH.Equals(type)) {
+ if ((ff & PdfFormField.FF_COMBO) != 0)
+ return FIELD_TYPE_COMBO;
+ else
+ return FIELD_TYPE_LIST;
+ }
+ else if (PdfName.SIG.Equals(type)) {
+ return FIELD_TYPE_SIGNATURE;
+ }
+ return FIELD_TYPE_NONE;
+ }
+
+ /**
+ * Export the fields as a FDF.
+ * @param writer the FDF writer
+ */
+ public void ExportAsFdf(FdfWriter writer) {
+ foreach (DictionaryEntry entry in fields) {
+ Item item = (Item)entry.Value;
+ string name = (String)entry.Key;
+ PdfObject v = PdfReader.GetPdfObject(((PdfDictionary)item.merged[0]).Get(PdfName.V));
+ if (v == null)
+ continue;
+ string value = GetField(name);
+ if (lastWasString)
+ writer.SetFieldAsString(name, value);
+ else
+ writer.SetFieldAsName(name, value);
+ }
+ }
+
+ /**
+ * Renames a field. Only the last part of the name can be renamed. For example,
+ * if the original field is "ab.cd.ef" only the "ef" part can be renamed.
+ * @param oldName the old field name
+ * @param newName the new field name
+ * @return true
if the renaming was successful, false
+ * otherwise
+ */
+ public bool RenameField(String oldName, String newName) {
+ int idx1 = oldName.LastIndexOf('.') + 1;
+ int idx2 = newName.LastIndexOf('.') + 1;
+ if (idx1 != idx2)
+ return false;
+ if (!oldName.Substring(0, idx1).Equals(newName.Substring(0, idx2)))
+ return false;
+ if (fields.ContainsKey(newName))
+ return false;
+ Item item = (Item)fields[oldName];
+ if (item == null)
+ return false;
+ newName = newName.Substring(idx2);
+ PdfString ss = new PdfString(newName, PdfObject.TEXT_UNICODE);
+ for (int k = 0; k < item.merged.Count; ++k) {
+ PdfDictionary dic = (PdfDictionary)item.values[k];
+ dic.Put(PdfName.T, ss);
+ MarkUsed(dic);
+ dic = (PdfDictionary)item.merged[k];
+ dic.Put(PdfName.T, ss);
+ }
+ fields.Remove(oldName);
+ fields[newName] = item;
+ return true;
+ }
+
+ public static Object[] SplitDAelements(String da) {
+ PRTokeniser tk = new PRTokeniser(PdfEncodings.ConvertToBytes(da, null));
+ ArrayList stack = new ArrayList();
+ Object[] ret = new Object[3];
+ while (tk.NextToken()) {
+ if (tk.TokenType == PRTokeniser.TK_COMMENT)
+ continue;
+ if (tk.TokenType == PRTokeniser.TK_OTHER) {
+ String oper = tk.StringValue;
+ if (oper.Equals("Tf")) {
+ if (stack.Count >= 2) {
+ ret[DA_FONT] = stack[stack.Count - 2];
+ ret[DA_SIZE] = float.Parse((String)stack[stack.Count - 1], System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ }
+ else if (oper.Equals("g")) {
+ if (stack.Count >= 1) {
+ float gray = float.Parse((String)stack[stack.Count - 1], System.Globalization.NumberFormatInfo.InvariantInfo);
+ if (gray != 0)
+ ret[DA_COLOR] = new GrayColor(gray);
+ }
+ }
+ else if (oper.Equals("rg")) {
+ if (stack.Count >= 3) {
+ float red = float.Parse((String)stack[stack.Count - 3], System.Globalization.NumberFormatInfo.InvariantInfo);
+ float green = float.Parse((String)stack[stack.Count - 2], System.Globalization.NumberFormatInfo.InvariantInfo);
+ float blue = float.Parse((String)stack[stack.Count - 1], System.Globalization.NumberFormatInfo.InvariantInfo);
+ ret[DA_COLOR] = new Color(red, green, blue);
+ }
+ }
+ else if (oper.Equals("k")) {
+ if (stack.Count >= 4) {
+ float cyan = float.Parse((String)stack[stack.Count - 4], System.Globalization.NumberFormatInfo.InvariantInfo);
+ float magenta = float.Parse((String)stack[stack.Count - 3], System.Globalization.NumberFormatInfo.InvariantInfo);
+ float yellow = float.Parse((String)stack[stack.Count - 2], System.Globalization.NumberFormatInfo.InvariantInfo);
+ float black = float.Parse((String)stack[stack.Count - 1], System.Globalization.NumberFormatInfo.InvariantInfo);
+ ret[DA_COLOR] = new CMYKColor(cyan, magenta, yellow, black);
+ }
+ }
+ stack.Clear();
+ }
+ else
+ stack.Add(tk.StringValue);
+ }
+ return ret;
+ }
+
+ public void DecodeGenericDictionary(PdfDictionary merged, BaseField tx) {
+ int flags = 0;
+ // the text size and color
+ PdfString da = (PdfString)PdfReader.GetPdfObject(merged.Get(PdfName.DA));
+ if (da != null) {
+ Object[] dab = SplitDAelements(da.ToUnicodeString());
+ if (dab[DA_SIZE] != null)
+ tx.FontSize = (float)dab[DA_SIZE];
+ if (dab[DA_COLOR] != null)
+ tx.TextColor = (Color)dab[DA_COLOR];
+ if (dab[DA_FONT] != null) {
+ PdfDictionary font = (PdfDictionary)PdfReader.GetPdfObject(merged.Get(PdfName.DR));
+ if (font != null) {
+ font = (PdfDictionary)PdfReader.GetPdfObject(font.Get(PdfName.FONT));
+ if (font != null) {
+ PdfObject po = font.Get(new PdfName((String)dab[DA_FONT]));
+ if (po != null && po.Type == PdfObject.INDIRECT) {
+ PRIndirectReference por = (PRIndirectReference)po;
+ BaseFont bp = new DocumentFont((PRIndirectReference)po);
+ tx.Font = bp;
+ int porkey = por.Number;
+ BaseFont porf = (BaseFont)extensionFonts[porkey];
+ if (porf == null) {
+ if (!extensionFonts.ContainsKey(porkey)) {
+ PdfDictionary fo = (PdfDictionary)PdfReader.GetPdfObject(po);
+ PdfDictionary fd = (PdfDictionary)PdfReader.GetPdfObject(fo.Get(PdfName.FONTDESCRIPTOR));
+ if (fd != null) {
+ PRStream prs = (PRStream)PdfReader.GetPdfObject(fd.Get(PdfName.FONTFILE2));
+ if (prs == null)
+ prs = (PRStream)PdfReader.GetPdfObject(fd.Get(PdfName.FONTFILE3));
+ if (prs == null) {
+ extensionFonts[porkey] = null;
+ }
+ else {
+ try {
+ porf = BaseFont.CreateFont("font.ttf", BaseFont.IDENTITY_H, true, false, PdfReader.GetStreamBytes(prs), null);
+ }
+ catch {
+ }
+ extensionFonts[porkey] = porf;
+ }
+ }
+ }
+ }
+ if (tx is TextField)
+ ((TextField)tx).ExtensionFont = porf;
+ }
+ else {
+ BaseFont bf = (BaseFont)localFonts[dab[DA_FONT]];
+ if (bf == null) {
+ String[] fn = (String[])stdFieldFontNames[dab[DA_FONT]];
+ if (fn != null) {
+ try {
+ String enc = "winansi";
+ if (fn.Length > 1)
+ enc = fn[1];
+ bf = BaseFont.CreateFont(fn[0], enc, false);
+ tx.Font = bf;
+ }
+ catch {
+ // empty
+ }
+ }
+ }
+ else
+ tx.Font = bf;
+ }
+ }
+ }
+ }
+ }
+ //rotation, border and backgound color
+ PdfDictionary mk = (PdfDictionary)PdfReader.GetPdfObject(merged.Get(PdfName.MK));
+ if (mk != null) {
+ PdfArray ar = (PdfArray)PdfReader.GetPdfObject(mk.Get(PdfName.BC));
+ Color border = GetMKColor(ar);
+ tx.BorderColor = border;
+ if (border != null)
+ tx.BorderWidth = 1;
+ ar = (PdfArray)PdfReader.GetPdfObject(mk.Get(PdfName.BG));
+ tx.BackgroundColor = GetMKColor(ar);
+ PdfNumber rotation = (PdfNumber)PdfReader.GetPdfObject(mk.Get(PdfName.R));
+ if (rotation != null)
+ tx.Rotation = rotation.IntValue;
+ }
+ //flags
+ PdfNumber nfl = (PdfNumber)PdfReader.GetPdfObject(merged.Get(PdfName.F));
+ flags = 0;
+ tx.Visibility = BaseField.VISIBLE_BUT_DOES_NOT_PRINT;
+ if (nfl != null) {
+ flags = nfl.IntValue;
+ if ((flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_HIDDEN) != 0)
+ tx.Visibility = BaseField.HIDDEN;
+ else if ((flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_NOVIEW) != 0)
+ tx.Visibility = BaseField.HIDDEN_BUT_PRINTABLE;
+ else if ((flags & PdfFormField.FLAGS_PRINT) != 0)
+ tx.Visibility = BaseField.VISIBLE;
+ }
+ //multiline
+ nfl = (PdfNumber)PdfReader.GetPdfObject(merged.Get(PdfName.FF));
+ flags = 0;
+ if (nfl != null)
+ flags = nfl.IntValue;
+ tx.Options = flags;
+ if ((flags & PdfFormField.FF_COMB) != 0) {
+ PdfNumber maxLen = (PdfNumber)PdfReader.GetPdfObject(merged.Get(PdfName.MAXLEN));
+ int len = 0;
+ if (maxLen != null)
+ len = maxLen.IntValue;
+ tx.MaxCharacterLength = len;
+ }
+ //alignment
+ nfl = (PdfNumber)PdfReader.GetPdfObject(merged.Get(PdfName.Q));
+ if (nfl != null) {
+ if (nfl.IntValue == PdfFormField.Q_CENTER)
+ tx.Alignment = Element.ALIGN_CENTER;
+ else if (nfl.IntValue == PdfFormField.Q_RIGHT)
+ tx.Alignment = Element.ALIGN_RIGHT;
+ }
+ //border styles
+ PdfDictionary bs = (PdfDictionary)PdfReader.GetPdfObject(merged.Get(PdfName.BS));
+ if (bs != null) {
+ PdfNumber w = (PdfNumber)PdfReader.GetPdfObject(bs.Get(PdfName.W));
+ if (w != null)
+ tx.BorderWidth = w.FloatValue;
+ PdfName s = (PdfName)PdfReader.GetPdfObject(bs.Get(PdfName.S));
+ if (PdfName.D.Equals(s))
+ tx.BorderStyle = PdfBorderDictionary.STYLE_DASHED;
+ else if (PdfName.B.Equals(s))
+ tx.BorderStyle = PdfBorderDictionary.STYLE_BEVELED;
+ else if (PdfName.I.Equals(s))
+ tx.BorderStyle = PdfBorderDictionary.STYLE_INSET;
+ else if (PdfName.U.Equals(s))
+ tx.BorderStyle = PdfBorderDictionary.STYLE_UNDERLINE;
+ }
+ else {
+ PdfArray bd = (PdfArray)PdfReader.GetPdfObject(merged.Get(PdfName.BORDER));
+ if (bd != null) {
+ ArrayList ar = bd.ArrayList;
+ if (ar.Count >= 3)
+ tx.BorderWidth = ((PdfNumber)ar[2]).FloatValue;
+ if (ar.Count >= 4)
+ tx.BorderStyle = PdfBorderDictionary.STYLE_DASHED;
+ }
+ }
+ }
+
+ internal PdfAppearance GetAppearance(PdfDictionary merged, String text, String fieldName) {
+ topFirst = 0;
+ TextField tx = null;
+ if (fieldCache == null || !fieldCache.ContainsKey(fieldName)) {
+ tx = new TextField(writer, null, null);
+ tx.SetExtraMargin(extraMarginLeft, extraMarginTop);
+ tx.BorderWidth = 0;
+ tx.SubstitutionFonts = substitutionFonts;
+ DecodeGenericDictionary(merged, tx);
+ //rect
+ PdfArray rect = (PdfArray)PdfReader.GetPdfObject(merged.Get(PdfName.RECT));
+ Rectangle box = PdfReader.GetNormalizedRectangle(rect);
+ if (tx.Rotation == 90 || tx.Rotation == 270)
+ box = box.Rotate();
+ tx.Box = box;
+ if (fieldCache != null)
+ fieldCache[fieldName] = tx;
+ }
+ else {
+ tx = (TextField)fieldCache[fieldName];
+ tx.Writer = writer;
+ }
+ PdfName fieldType = (PdfName)PdfReader.GetPdfObject(merged.Get(PdfName.FT));
+ if (PdfName.TX.Equals(fieldType)) {
+ tx.Text = text;
+ return tx.GetAppearance();
+ }
+ if (!PdfName.CH.Equals(fieldType))
+ throw new DocumentException("An appearance was requested without a variable text field.");
+ PdfArray opt = (PdfArray)PdfReader.GetPdfObject(merged.Get(PdfName.OPT));
+ int flags = 0;
+ PdfNumber nfl = (PdfNumber)PdfReader.GetPdfObject(merged.Get(PdfName.FF));
+ if (nfl != null)
+ flags = nfl.IntValue;
+ if ((flags & PdfFormField.FF_COMBO) != 0 && opt == null) {
+ tx.Text = text;
+ return tx.GetAppearance();
+ }
+ if (opt != null) {
+ ArrayList op = opt.ArrayList;
+ String[] choices = new String[op.Count];
+ String[] choicesExp = new String[op.Count];
+ for (int k = 0; k < op.Count; ++k) {
+ PdfObject obj = (PdfObject)op[k];
+ if (obj.IsString()) {
+ choices[k] = choicesExp[k] = ((PdfString)obj).ToUnicodeString();
+ }
+ else {
+ ArrayList opar = ((PdfArray)obj).ArrayList;
+ choicesExp[k] = ((PdfString)opar[0]).ToUnicodeString();
+ choices[k] = ((PdfString)opar[1]).ToUnicodeString();
+ }
+ }
+ if ((flags & PdfFormField.FF_COMBO) != 0) {
+ for (int k = 0; k < choices.Length; ++k) {
+ if (text.Equals(choicesExp[k])) {
+ text = choices[k];
+ break;
+ }
+ }
+ tx.Text = text;
+ return tx.GetAppearance();
+ }
+ int idx = 0;
+ for (int k = 0; k < choicesExp.Length; ++k) {
+ if (text.Equals(choicesExp[k])) {
+ idx = k;
+ break;
+ }
+ }
+ tx.Choices = choices;
+ tx.ChoiceExports = choicesExp;
+ tx.ChoiceSelection = idx;
+ }
+ PdfAppearance app = tx.GetListAppearance();
+ topFirst = tx.TopFirst;
+ return app;
+ }
+
+ internal Color GetMKColor(PdfArray ar) {
+ if (ar == null)
+ return null;
+ ArrayList cc = ar.ArrayList;
+ switch (cc.Count) {
+ case 1:
+ return new GrayColor(((PdfNumber)cc[0]).FloatValue);
+ case 3:
+ return new Color(ExtendedColor.Normalize(((PdfNumber)cc[0]).FloatValue), ExtendedColor.Normalize(((PdfNumber)cc[1]).FloatValue), ExtendedColor.Normalize(((PdfNumber)cc[2]).FloatValue));
+ case 4:
+ return new CMYKColor(((PdfNumber)cc[0]).FloatValue, ((PdfNumber)cc[1]).FloatValue, ((PdfNumber)cc[2]).FloatValue, ((PdfNumber)cc[3]).FloatValue);
+ default:
+ return null;
+ }
+ }
+
+ /** Gets the field value.
+ * @param name the fully qualified field name
+ * @return the field value
+ */
+ public String GetField(String name) {
+ if (xfa.XfaPresent) {
+ name = xfa.FindFieldName(name, this);
+ if (name == null)
+ return null;
+ name = XfaForm.Xml2Som.GetShortName(name);
+ return XfaForm.GetNodeText(xfa.FindDatasetsNode(name));
+ }
+ Item item = (Item)fields[name];
+ if (item == null)
+ return null;
+ lastWasString = false;
+ PdfObject v = PdfReader.GetPdfObject(((PdfDictionary)item.merged[0]).Get(PdfName.V));
+ if (v == null)
+ return "";
+ PdfName type = (PdfName)PdfReader.GetPdfObject(((PdfDictionary)item.merged[0]).Get(PdfName.FT));
+ if (PdfName.BTN.Equals(type)) {
+ PdfNumber ff = (PdfNumber)PdfReader.GetPdfObject(((PdfDictionary)item.merged[0]).Get(PdfName.FF));
+ int flags = 0;
+ if (ff != null)
+ flags = ff.IntValue;
+ if ((flags & PdfFormField.FF_PUSHBUTTON) != 0)
+ return "";
+ String value = "";
+ if (v.IsName())
+ value = PdfName.DecodeName(v.ToString());
+ else if (v.IsString())
+ value = ((PdfString)v).ToUnicodeString();
+ PdfObject opts = PdfReader.GetPdfObject(((PdfDictionary)item.values[0]).Get(PdfName.OPT));
+ if (opts != null && opts.IsArray()) {
+ ArrayList list = ((PdfArray)opts).ArrayList;
+ int idx = 0;
+ try {
+ idx = int.Parse(value);
+ PdfString ps = (PdfString)list[idx];
+ value = ps.ToUnicodeString();
+ lastWasString = true;
+ }
+ catch {
+ }
+ }
+ return value;
+ }
+ if (v.IsString()) {
+ lastWasString = true;
+ return ((PdfString)v).ToUnicodeString();
+ }
+ return PdfName.DecodeName(v.ToString());
+ }
+
+ /**
+ * Sets a field property. Valid property names are:
+ *
+ *
+ * @param field the field name
+ * @param name the property name
+ * @param value the property value
+ * @param inst an array of BaseFont
.
+ * java.awt.Color
.
+ * Float
.
+ * java.awt.Color
.
+ * If null
removes the background.
+ * java.awt.Color
.
+ * If null
removes the border.
+ * int
indexing into AcroField.Item.merged
elements to process.
+ * Set to null
to process all
+ * @return true
if the property exists, false
otherwise
+ */
+ public bool SetFieldProperty(String field, String name, Object value, int[] inst) {
+ if (writer == null)
+ throw new Exception("This AcroFields instance is read-only.");
+ Item item = (Item)fields[field];
+ if (item == null)
+ return false;
+ InstHit hit = new InstHit(inst);
+ if (Util.EqualsIgnoreCase(name, "textfont")) {
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ PdfString da = (PdfString)PdfReader.GetPdfObject(((PdfDictionary)item.merged[k]).Get(PdfName.DA));
+ PdfDictionary dr = (PdfDictionary)PdfReader.GetPdfObject(((PdfDictionary)item.merged[k]).Get(PdfName.DR));
+ if (da != null && dr != null) {
+ Object[] dao = SplitDAelements(da.ToUnicodeString());
+ PdfAppearance cb = new PdfAppearance();
+ if (dao[DA_FONT] != null) {
+ BaseFont bf = (BaseFont)value;
+ PdfName psn = (PdfName)PdfAppearance.stdFieldFontNames[bf.PostscriptFontName];
+ if (psn == null) {
+ psn = new PdfName(bf.PostscriptFontName);
+ }
+ PdfDictionary fonts = (PdfDictionary)PdfReader.GetPdfObject(dr.Get(PdfName.FONT));
+ if (fonts == null) {
+ fonts = new PdfDictionary();
+ dr.Put(PdfName.FONT, fonts);
+ }
+ PdfIndirectReference fref = (PdfIndirectReference)fonts.Get(psn);
+ PdfDictionary top = (PdfDictionary)PdfReader.GetPdfObject(reader.Catalog.Get(PdfName.ACROFORM));
+ MarkUsed(top);
+ dr = (PdfDictionary)PdfReader.GetPdfObject(top.Get(PdfName.DR));
+ if (dr == null) {
+ dr = new PdfDictionary();
+ top.Put(PdfName.DR, dr);
+ }
+ MarkUsed(dr);
+ PdfDictionary fontsTop = (PdfDictionary)PdfReader.GetPdfObject(dr.Get(PdfName.FONT));
+ if (fontsTop == null) {
+ fontsTop = new PdfDictionary();
+ dr.Put(PdfName.FONT, fontsTop);
+ }
+ MarkUsed(fontsTop);
+ PdfIndirectReference frefTop = (PdfIndirectReference)fontsTop.Get(psn);
+ if (frefTop != null) {
+ if (fref == null)
+ fonts.Put(psn, frefTop);
+ }
+ else if (fref == null) {
+ FontDetails fd;
+ if (bf.FontType == BaseFont.FONT_TYPE_DOCUMENT) {
+ fd = new FontDetails(null, ((DocumentFont)bf).IndirectReference, bf);
+ }
+ else {
+ bf.Subset = false;
+ fd = writer.AddSimple(bf);
+ localFonts[psn.ToString().Substring(1)] = bf;
+ }
+ fontsTop.Put(psn, fd.IndirectReference);
+ fonts.Put(psn, fd.IndirectReference);
+ }
+ ByteBuffer buf = cb.InternalBuffer;
+ buf.Append(psn.GetBytes()).Append(' ').Append((float)dao[DA_SIZE]).Append(" Tf ");
+ if (dao[DA_COLOR] != null)
+ cb.SetColorFill((Color)dao[DA_COLOR]);
+ PdfString s = new PdfString(cb.ToString());
+ ((PdfDictionary)item.merged[k]).Put(PdfName.DA, s);
+ ((PdfDictionary)item.widgets[k]).Put(PdfName.DA, s);
+ MarkUsed((PdfDictionary)item.widgets[k]);
+ }
+ }
+ }
+ }
+ }
+ else if (Util.EqualsIgnoreCase(name, "textcolor")) {
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ PdfString da = (PdfString)PdfReader.GetPdfObject(((PdfDictionary)item.merged[k]).Get(PdfName.DA));
+ if (da != null) {
+ Object[] dao = SplitDAelements(da.ToUnicodeString());
+ PdfAppearance cb = new PdfAppearance();
+ if (dao[DA_FONT] != null) {
+ ByteBuffer buf = cb.InternalBuffer;
+ buf.Append(new PdfName((String)dao[DA_FONT]).GetBytes()).Append(' ').Append((float)dao[DA_SIZE]).Append(" Tf ");
+ cb.SetColorFill((Color)value);
+ PdfString s = new PdfString(cb.ToString());
+ ((PdfDictionary)item.merged[k]).Put(PdfName.DA, s);
+ ((PdfDictionary)item.widgets[k]).Put(PdfName.DA, s);
+ MarkUsed((PdfDictionary)item.widgets[k]);
+ }
+ }
+ }
+ }
+ }
+ else if (Util.EqualsIgnoreCase(name, "textsize")) {
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ PdfString da = (PdfString)PdfReader.GetPdfObject(((PdfDictionary)item.merged[k]).Get(PdfName.DA));
+ if (da != null) {
+ Object[] dao = SplitDAelements(da.ToUnicodeString());
+ PdfAppearance cb = new PdfAppearance();
+ if (dao[DA_FONT] != null) {
+ ByteBuffer buf = cb.InternalBuffer;
+ buf.Append(new PdfName((String)dao[DA_FONT]).GetBytes()).Append(' ').Append((float)value).Append(" Tf ");
+ if (dao[DA_COLOR] != null)
+ cb.SetColorFill((Color)dao[DA_COLOR]);
+ PdfString s = new PdfString(cb.ToString());
+ ((PdfDictionary)item.merged[k]).Put(PdfName.DA, s);
+ ((PdfDictionary)item.widgets[k]).Put(PdfName.DA, s);
+ MarkUsed((PdfDictionary)item.widgets[k]);
+ }
+ }
+ }
+ }
+ }
+ else if (Util.EqualsIgnoreCase(name, "bgcolor") || Util.EqualsIgnoreCase(name, "bordercolor")) {
+ PdfName dname = (Util.EqualsIgnoreCase(name, "bgcolor") ? PdfName.BG : PdfName.BC);
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ PdfObject obj = PdfReader.GetPdfObject(((PdfDictionary)item.merged[k]).Get(PdfName.MK));
+ MarkUsed(obj);
+ PdfDictionary mk = (PdfDictionary)obj;
+ if (mk == null) {
+ if (value == null)
+ return true;
+ mk = new PdfDictionary();
+ ((PdfDictionary)item.merged[k]).Put(PdfName.MK, mk);
+ ((PdfDictionary)item.widgets[k]).Put(PdfName.MK, mk);
+ MarkUsed((PdfDictionary)item.widgets[k]);
+ }
+ if (value == null)
+ mk.Remove(dname);
+ else
+ mk.Put(dname, PdfFormField.GetMKColor((Color)value));
+ }
+ }
+ }
+ else
+ return false;
+ return true;
+ }
+
+ /**
+ * Sets a field property. Valid property names are:
+ *
+ *
+ * @param field the field name
+ * @param name the property name
+ * @param value the property value
+ * @param inst an array of
+ *
+ *
+ *
+ *
+ *
+ * int
indexing into AcroField.Item.merged
elements to process.
+ * Set to null
to process all
+ * @return true
if the property exists, false
otherwise
+ */
+ public bool SetFieldProperty(String field, String name, int value, int[] inst) {
+ if (writer == null)
+ throw new Exception("This AcroFields instance is read-only.");
+ Item item = (Item)fields[field];
+ if (item == null)
+ return false;
+ InstHit hit = new InstHit(inst);
+ if (Util.EqualsIgnoreCase(name, "flags")) {
+ PdfNumber num = new PdfNumber(value);
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ ((PdfDictionary)item.merged[k]).Put(PdfName.F, num);
+ ((PdfDictionary)item.widgets[k]).Put(PdfName.F, num);
+ MarkUsed((PdfDictionary)item.widgets[k]);
+ }
+ }
+ }
+ else if (Util.EqualsIgnoreCase(name, "setflags")) {
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ PdfNumber num = (PdfNumber)PdfReader.GetPdfObject(((PdfDictionary)item.widgets[k]).Get(PdfName.F));
+ int val = 0;
+ if (num != null)
+ val = num.IntValue;
+ num = new PdfNumber(val | value);
+ ((PdfDictionary)item.merged[k]).Put(PdfName.F, num);
+ ((PdfDictionary)item.widgets[k]).Put(PdfName.F, num);
+ MarkUsed((PdfDictionary)item.widgets[k]);
+ }
+ }
+ }
+ else if (Util.EqualsIgnoreCase(name, "clrflags")) {
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ PdfNumber num = (PdfNumber)PdfReader.GetPdfObject(((PdfDictionary)item.widgets[k]).Get(PdfName.F));
+ int val = 0;
+ if (num != null)
+ val = num.IntValue;
+ num = new PdfNumber(val & (~value));
+ ((PdfDictionary)item.merged[k]).Put(PdfName.F, num);
+ ((PdfDictionary)item.widgets[k]).Put(PdfName.F, num);
+ MarkUsed((PdfDictionary)item.widgets[k]);
+ }
+ }
+ }
+ else if (Util.EqualsIgnoreCase(name, "fflags")) {
+ PdfNumber num = new PdfNumber(value);
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ ((PdfDictionary)item.merged[k]).Put(PdfName.FF, num);
+ ((PdfDictionary)item.values[k]).Put(PdfName.FF, num);
+ MarkUsed((PdfDictionary)item.values[k]);
+ }
+ }
+ }
+ else if (Util.EqualsIgnoreCase(name, "setfflags")) {
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ PdfNumber num = (PdfNumber)PdfReader.GetPdfObject(((PdfDictionary)item.values[k]).Get(PdfName.FF));
+ int val = 0;
+ if (num != null)
+ val = num.IntValue;
+ num = new PdfNumber(val | value);
+ ((PdfDictionary)item.merged[k]).Put(PdfName.FF, num);
+ ((PdfDictionary)item.values[k]).Put(PdfName.FF, num);
+ MarkUsed((PdfDictionary)item.values[k]);
+ }
+ }
+ }
+ else if (Util.EqualsIgnoreCase(name, "clrfflags")) {
+ for (int k = 0; k < item.merged.Count; ++k) {
+ if (hit.IsHit(k)) {
+ PdfNumber num = (PdfNumber)PdfReader.GetPdfObject(((PdfDictionary)item.values[k]).Get(PdfName.FF));
+ int val = 0;
+ if (num != null)
+ val = num.IntValue;
+ num = new PdfNumber(val & (~value));
+ ((PdfDictionary)item.merged[k]).Put(PdfName.FF, num);
+ ((PdfDictionary)item.values[k]).Put(PdfName.FF, num);
+ MarkUsed((PdfDictionary)item.values[k]);
+ }
+ }
+ }
+ else
+ return false;
+ return true;
+ }
+
+ /**
+ * Merges an XML data structure into this form.
+ * @param n the top node of the data structure
+ * @throws java.io.IOException on error
+ * @throws com.lowagie.text.DocumentException o error
+ */
+ public void MergeXfaData(XmlNode n) {
+ XfaForm.Xml2SomDatasets data = new XfaForm.Xml2SomDatasets(n);
+ foreach (String name in data.Order) {
+ String text = XfaForm.GetNodeText((XmlNode)data.Name2Node[name]);
+ SetField(name, text);
+ }
+ }
+
+ /** Sets the fields by FDF merging.
+ * @param fdf the FDF form
+ * @throws IOException on error
+ * @throws DocumentException on error
+ */
+ public void SetFields(FdfReader fdf) {
+ Hashtable fd = fdf.Fields;
+ foreach (string f in fd.Keys) {
+ String v = fdf.GetFieldValue(f);
+ if (v != null)
+ SetField(f, v);
+ }
+ }
+
+ /** Sets the fields by XFDF merging.
+ * @param xfdf the XFDF form
+ * @throws IOException on error
+ * @throws DocumentException on error
+ */
+
+ public void SetFields(XfdfReader xfdf) {
+ Hashtable fd = xfdf.Fields;
+ foreach (string f in fd.Keys) {
+ String v = xfdf.GetFieldValue(f);
+ if (v != null)
+ SetField(f, v);
+ }
+ }
+
+ /**
+ * Regenerates the field appearance.
+ * This is usefull when you change a field property, but not its value,
+ * for instance form.SetFieldProperty("f", "bgcolor", Color.BLUE, null);
+ * This won't have any effect, unless you use RegenerateField("f") after changing
+ * the property.
+ *
+ * @param name the fully qualified field name or the partial name in the case of XFA forms
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return true
if the field was found and changed,
+ * false
otherwise
+ */
+ public bool RegenerateField(String name) {
+ String value = GetField(name);
+ return SetField(name, value, value);
+ }
+
+ /** Sets the field value.
+ * @param name the fully qualified field name or the partial name in the case of XFA forms
+ * @param value the field value
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return true
if the field was found and changed,
+ * false
otherwise
+ */
+ public bool SetField(String name, String value) {
+ return SetField(name, value, null);
+ }
+
+ /** Sets the field value and the display string. The display string
+ * is used to build the appearance in the cases where the value
+ * is modified by Acrobat with JavaScript and the algorithm is
+ * known.
+ * @param name the fully qualified field name or the partial name in the case of XFA forms
+ * @param value the field value
+ * @param display the string that is used for the appearance. If null
+ * the value
parameter will be used
+ * @return true
if the field was found and changed,
+ * false
otherwise
+ * @throws IOException on error
+ * @throws DocumentException on error
+ */
+ public bool SetField(String name, String value, String display) {
+ if (writer == null)
+ throw new DocumentException("This AcroFields instance is read-only.");
+ if (xfa.XfaPresent) {
+ name = xfa.FindFieldName(name, this);
+ if (name == null)
+ return false;
+ String shortName = XfaForm.Xml2Som.GetShortName(name);
+ XmlNode xn = xfa.FindDatasetsNode(shortName);
+ if (xn == null) {
+ xn = xfa.DatasetsSom.InsertNode(xfa.DatasetsNode, shortName);
+ }
+ xfa.SetNodeText(xn, value);
+ }
+ Item item = (Item)fields[name];
+ if (item == null)
+ return false;
+ PdfName type = (PdfName)PdfReader.GetPdfObject(((PdfDictionary)item.merged[0]).Get(PdfName.FT));
+ if (PdfName.TX.Equals(type)) {
+ PdfNumber maxLen = (PdfNumber)PdfReader.GetPdfObject(((PdfDictionary)item.merged[0]).Get(PdfName.MAXLEN));
+ int len = 0;
+ if (maxLen != null)
+ len = maxLen.IntValue;
+ if (len > 0)
+ value = value.Substring(0, Math.Min(len, value.Length));
+ }
+ if (display == null)
+ display = value;
+ if (PdfName.TX.Equals(type) || PdfName.CH.Equals(type)) {
+ PdfString v = new PdfString(value, PdfObject.TEXT_UNICODE);
+ for (int idx = 0; idx < item.values.Count; ++idx) {
+ PdfDictionary valueDic = (PdfDictionary)item.values[idx];
+ valueDic.Put(PdfName.V, v);
+ valueDic.Remove(PdfName.I);
+ MarkUsed(valueDic);
+ PdfDictionary merged = (PdfDictionary)item.merged[idx];
+ merged.Remove(PdfName.I);
+ merged.Put(PdfName.V, v);
+ PdfDictionary widget = (PdfDictionary)item.widgets[idx];
+ if (generateAppearances) {
+ PdfAppearance app = GetAppearance(merged, display, name);
+ if (PdfName.CH.Equals(type)) {
+ PdfNumber n = new PdfNumber(topFirst);
+ widget.Put(PdfName.TI, n);
+ merged.Put(PdfName.TI, n);
+ }
+ PdfDictionary appDic = (PdfDictionary)PdfReader.GetPdfObject(widget.Get(PdfName.AP));
+ if (appDic == null) {
+ appDic = new PdfDictionary();
+ widget.Put(PdfName.AP, appDic);
+ merged.Put(PdfName.AP, appDic);
+ }
+ appDic.Put(PdfName.N, app.IndirectReference);
+ writer.ReleaseTemplate(app);
+ }
+ else {
+ widget.Remove(PdfName.AP);
+ merged.Remove(PdfName.AP);
+ }
+ MarkUsed(widget);
+ }
+ return true;
+ }
+ else if (PdfName.BTN.Equals(type)) {
+ PdfNumber ff = (PdfNumber)PdfReader.GetPdfObject(((PdfDictionary)item.merged[0]).Get(PdfName.FF));
+ int flags = 0;
+ if (ff != null)
+ flags = ff.IntValue;
+ if ((flags & PdfFormField.FF_PUSHBUTTON) != 0) {
+ //we'll assume that the value is an image in base64
+ Image img;
+ try {
+ img = Image.GetInstance(Convert.FromBase64String(value));
+ }
+ catch {
+ return false;
+ }
+ PushbuttonField pb = GetNewPushbuttonFromField(name);
+ pb.Image = img;
+ ReplacePushbuttonField(name, pb.Field);
+ return true;
+ }
+ PdfName v = new PdfName(value);
+ ArrayList lopt = new ArrayList();
+ PdfObject opts = PdfReader.GetPdfObject(((PdfDictionary)item.values[0]).Get(PdfName.OPT));
+ if (opts != null && opts.IsArray()) {
+ ArrayList list = ((PdfArray)opts).ArrayList;
+ for (int k = 0; k < list.Count; ++k) {
+ PdfObject vv = PdfReader.GetPdfObject((PdfObject)list[k]);
+ if (vv != null && vv.IsString())
+ lopt.Add(((PdfString)vv).ToUnicodeString());
+ else
+ lopt.Add(null);
+ }
+ }
+ int vidx = lopt.IndexOf(value);
+ PdfName valt = null;
+ PdfName vt;
+ if (vidx >= 0) {
+ vt = valt = new PdfName(vidx.ToString());
+ }
+ else
+ vt = v;
+ for (int idx = 0; idx < item.values.Count; ++idx) {
+ PdfDictionary merged = (PdfDictionary)item.merged[idx];
+ PdfDictionary widget = (PdfDictionary)item.widgets[idx];
+ MarkUsed((PdfDictionary)item.values[idx]);
+ if (valt != null) {
+ PdfString ps = new PdfString(value, PdfObject.TEXT_UNICODE);
+ ((PdfDictionary)item.values[idx]).Put(PdfName.V, ps);
+ merged.Put(PdfName.V, ps);
+ }
+ else {
+ ((PdfDictionary)item.values[idx]).Put(PdfName.V, v);
+ merged.Put(PdfName.V, v);
+ }
+ MarkUsed(widget);
+ if (IsInAP(widget, vt)) {
+ merged.Put(PdfName.AS, vt);
+ widget.Put(PdfName.AS, vt);
+ }
+ else {
+ merged.Put(PdfName.AS, PdfName.Off_);
+ widget.Put(PdfName.AS, PdfName.Off_);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ internal bool IsInAP(PdfDictionary dic, PdfName check) {
+ PdfDictionary appDic = (PdfDictionary)PdfReader.GetPdfObject(dic.Get(PdfName.AP));
+ if (appDic == null)
+ return false;
+ PdfDictionary NDic = (PdfDictionary)PdfReader.GetPdfObject(appDic.Get(PdfName.N));
+ return (NDic != null && NDic.Get(check) != null);
+ }
+
+ /** Gets all the fields. The fields are keyed by the fully qualified field name and
+ * the value is an instance of AcroFields.Item
.
+ * @return all the fields
+ */
+ public Hashtable Fields {
+ get {
+ return fields;
+ }
+ }
+
+ /**
+ * Gets the field structure.
+ * @param name the name of the field
+ * @return the field structure or null
if the field
+ * does not exist
+ */
+ public Item GetFieldItem(String name) {
+ if (xfa.XfaPresent) {
+ name = xfa.FindFieldName(name, this);
+ if (name == null)
+ return null;
+ }
+ return (Item)fields[name];
+ }
+
+ /**
+ * Gets the long XFA translated name.
+ * @param name the name of the field
+ * @return the long field name
+ */
+ public String GetTranslatedFieldName(String name) {
+ if (xfa.XfaPresent) {
+ String namex = xfa.FindFieldName(name, this);
+ if (namex != null)
+ name = namex;
+ }
+ return name;
+ }
+
+ /**
+ * Gets the field box positions in the document. The return is an array of float
+ * multiple of 5. For each of this groups the values are: [page, llx, lly, urx,
+ * ury]. The coordinates have the page rotation in consideration.
+ * @param name the field name
+ * @return the positions or null
if field does not exist
+ */
+ public float[] GetFieldPositions(String name) {
+ Item item = GetFieldItem(name);
+ if (item == null)
+ return null;
+ float[] ret = new float[item.page.Count * 5];
+ int ptr = 0;
+ for (int k = 0; k < item.page.Count; ++k) {
+ try {
+ PdfDictionary wd = (PdfDictionary)item.widgets[k];
+ PdfArray rect = (PdfArray)wd.Get(PdfName.RECT);
+ if (rect == null)
+ continue;
+ Rectangle r = PdfReader.GetNormalizedRectangle(rect);
+ int page = (int)item.page[k];
+ int rotation = reader.GetPageRotation(page);
+ ret[ptr++] = page;
+ if (rotation != 0) {
+ Rectangle pageSize = reader.GetPageSize(page);
+ switch (rotation) {
+ case 270:
+ r = new Rectangle(
+ pageSize.Top - r.Bottom,
+ r.Left,
+ pageSize.Top - r.Top,
+ r.Right);
+ break;
+ case 180:
+ r = new Rectangle(
+ pageSize.Right - r.Left,
+ pageSize.Top - r.Bottom,
+ pageSize.Right - r.Right,
+ pageSize.Top - r.Top);
+ break;
+ case 90:
+ r = new Rectangle(
+ r.Bottom,
+ pageSize.Right - r.Left,
+ r.Top,
+ pageSize.Right - r.Right);
+ break;
+ }
+ r.Normalize();
+ }
+ ret[ptr++] = r.Left;
+ ret[ptr++] = r.Bottom;
+ ret[ptr++] = r.Right;
+ ret[ptr++] = r.Top;
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ if (ptr < ret.Length) {
+ float[] ret2 = new float[ptr];
+ System.Array.Copy(ret, 0, ret2, 0, ptr);
+ return ret2;
+ }
+ return ret;
+ }
+
+ private int RemoveRefFromArray(PdfArray array, PdfObject refo) {
+ ArrayList ar = array.ArrayList;
+ if (refo == null || !refo.IsIndirect())
+ return ar.Count;
+ PdfIndirectReference refi = (PdfIndirectReference)refo;
+ for (int j = 0; j < ar.Count; ++j) {
+ PdfObject obj = (PdfObject)ar[j];
+ if (!obj.IsIndirect())
+ continue;
+ if (((PdfIndirectReference)obj).Number == refi.Number)
+ ar.RemoveAt(j--);
+ }
+ return ar.Count;
+ }
+
+ /**
+ * Removes all the fields from page
.
+ * @param page the page to remove the fields from
+ * @return true
if any field was removed, false otherwise
+ */
+ public bool RemoveFieldsFromPage(int page) {
+ if (page < 1)
+ return false;
+ String[] names = new String[fields.Count];
+ fields.Keys.CopyTo(names, 0);
+ bool found = false;
+ for (int k = 0; k < names.Length; ++k) {
+ bool fr = RemoveField(names[k], page);
+ found = (found || fr);
+ }
+ return found;
+ }
+
+ /**
+ * Removes a field from the document. If page equals -1 all the fields with this
+ * name
are removed from the document otherwise only the fields in
+ * that particular page are removed.
+ * @param name the field name
+ * @param page the page to remove the field from or -1 to remove it from all the pages
+ * @return true
if the field exists, false otherwise
+ */
+ public bool RemoveField(String name, int page) {
+ Item item = GetFieldItem(name);
+ if (item == null)
+ return false;
+ PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(reader.Catalog.Get(PdfName.ACROFORM), reader.Catalog);
+
+ if (acroForm == null)
+ return false;
+ PdfArray arrayf = (PdfArray)PdfReader.GetPdfObject(acroForm.Get(PdfName.FIELDS), acroForm);
+ if (arrayf == null)
+ return false;
+ for (int k = 0; k < item.widget_refs.Count; ++k) {
+ int pageV = (int)item.page[k];
+ if (page != -1 && page != pageV)
+ continue;
+ PdfIndirectReference refi = (PdfIndirectReference)item.widget_refs[k];
+ PdfDictionary wd = (PdfDictionary)PdfReader.GetPdfObject(refi);
+ PdfDictionary pageDic = reader.GetPageN(pageV);
+ PdfArray annots = (PdfArray)PdfReader.GetPdfObject(pageDic.Get(PdfName.ANNOTS), pageDic);
+ if (annots != null) {
+ if (RemoveRefFromArray(annots, refi) == 0) {
+ pageDic.Remove(PdfName.ANNOTS);
+ MarkUsed(pageDic);
+ }
+ else
+ MarkUsed(annots);
+ }
+ PdfReader.KillIndirect(refi);
+ PdfIndirectReference kid = refi;
+ while ((refi = (PdfIndirectReference)wd.Get(PdfName.PARENT)) != null) {
+ wd = (PdfDictionary)PdfReader.GetPdfObject(refi);
+ PdfArray kids = (PdfArray)PdfReader.GetPdfObject(wd.Get(PdfName.KIDS));
+ if (RemoveRefFromArray(kids, kid) != 0)
+ break;
+ kid = refi;
+ PdfReader.KillIndirect(refi);
+ }
+ if (refi == null) {
+ RemoveRefFromArray(arrayf, kid);
+ MarkUsed(arrayf);
+ }
+ if (page != -1) {
+ item.merged.RemoveAt(k);
+ item.page.RemoveAt(k);
+ item.values.RemoveAt(k);
+ item.widget_refs.RemoveAt(k);
+ item.widgets.RemoveAt(k);
+ --k;
+ }
+ }
+ if (page == -1 || item.merged.Count == 0)
+ fields.Remove(name);
+ return true;
+ }
+
+ /**
+ * Removes a field from the document.
+ * @param name the field name
+ * @return true
if the field exists, false otherwise
+ */
+ public bool RemoveField(String name) {
+ return RemoveField(name, -1);
+ }
+
+ /** Sets the option to generate appearances. Not generating apperances
+ * will speed-up form filling but the results can be
+ * unexpected in Acrobat. Don't use it unless your environment is well
+ * controlled. The default is true
.
+ * @param generateAppearances the option to generate appearances
+ */
+ public bool GenerateAppearances {
+ set {
+ generateAppearances = value;
+ PdfDictionary top = (PdfDictionary)PdfReader.GetPdfObject(reader.Catalog.Get(PdfName.ACROFORM));
+ if (generateAppearances)
+ top.Remove(PdfName.NEEDAPPEARANCES);
+ else
+ top.Put(PdfName.NEEDAPPEARANCES, PdfBoolean.PDFTRUE);
+ }
+ get {
+ return generateAppearances;
+ }
+ }
+
+ /** The field representations for retrieval and modification. */
+ public class Item {
+ /** An array of PdfDictionary
where the value tag /V
+ * is present.
+ */
+ public ArrayList values = new ArrayList();
+ /** An array of PdfDictionary
with the widgets.
+ */
+ public ArrayList widgets = new ArrayList();
+ /** An array of PdfDictionary
with the widget references.
+ */
+ public ArrayList widget_refs = new ArrayList();
+ /** An array of PdfDictionary
with all the field
+ * and widget tags merged.
+ */
+ public ArrayList merged = new ArrayList();
+ /** An array of Integer
with the page numbers where
+ * the widgets are displayed.
+ */
+ public ArrayList page = new ArrayList();
+ /** An array of Integer
with the tab order of the field in the page.
+ */
+ public ArrayList tabOrder = new ArrayList();
+ }
+
+ private class InstHit {
+ IntHashtable hits;
+ public InstHit(int[] inst) {
+ if (inst == null)
+ return;
+ hits = new IntHashtable();
+ for (int k = 0; k < inst.Length; ++k)
+ hits[inst[k]] = 1;
+ }
+
+ public bool IsHit(int n) {
+ if (hits == null)
+ return true;
+ return hits.ContainsKey(n);
+ }
+ }
+
+ private void FindSignatureNames() {
+ if (sigNames != null)
+ return;
+ sigNames = new Hashtable();
+ ArrayList sorter = new ArrayList();
+ foreach (DictionaryEntry entry in fields) {
+ Item item = (Item)entry.Value;
+ PdfDictionary merged = (PdfDictionary)item.merged[0];
+ if (!PdfName.SIG.Equals(merged.Get(PdfName.FT)))
+ continue;
+ PdfObject vo = PdfReader.GetPdfObject(merged.Get(PdfName.V));
+ if (vo == null || vo.Type != PdfObject.DICTIONARY)
+ continue;
+ PdfDictionary v = (PdfDictionary)vo;
+ PdfObject contents = v.Get(PdfName.CONTENTS);
+ if (contents == null || contents.Type != PdfObject.STRING)
+ continue;
+ PdfObject ro = v.Get(PdfName.BYTERANGE);
+ if (ro == null || ro.Type != PdfObject.ARRAY)
+ continue;
+ ArrayList ra = ((PdfArray)ro).ArrayList;
+ if (ra.Count < 2)
+ continue;
+ int length = ((PdfNumber)ra[ra.Count - 1]).IntValue + ((PdfNumber)ra[ra.Count - 2]).IntValue;
+ sorter.Add(new Object[]{entry.Key, new int[]{length, 0}});
+ }
+ sorter.Sort(new AcroFields.ISorterComparator());
+ if (sorter.Count > 0) {
+ if (((int[])((Object[])sorter[sorter.Count - 1])[1])[0] == reader.FileLength)
+ totalRevisions = sorter.Count;
+ else
+ totalRevisions = sorter.Count + 1;
+ for (int k = 0; k < sorter.Count; ++k) {
+ Object[] objs = (Object[])sorter[k];
+ String name = (String)objs[0];
+ int[] p = (int[])objs[1];
+ p[1] = k + 1;
+ sigNames[name] = p;
+ }
+ }
+ }
+
+ /**
+ * Gets the field names that have signatures and are signed.
+ * @return the field names that have signatures and are signed
+ */
+ public ArrayList GetSignatureNames() {
+ FindSignatureNames();
+ return new ArrayList(sigNames.Keys);
+ }
+
+ /**
+ * Gets the field names that have blank signatures.
+ * @return the field names that have blank signatures
+ */
+ public ArrayList GetBlankSignatureNames() {
+ FindSignatureNames();
+ ArrayList sigs = new ArrayList();
+ foreach (DictionaryEntry entry in fields) {
+ Item item = (Item)entry.Value;
+ PdfDictionary merged = (PdfDictionary)item.merged[0];
+ if (!PdfName.SIG.Equals(merged.Get(PdfName.FT)))
+ continue;
+ if (sigNames.ContainsKey(entry.Key))
+ continue;
+ sigs.Add(entry.Key);
+ }
+ return sigs;
+ }
+
+ /**
+ * Gets the signature dictionary, the one keyed by /V.
+ * @param name the field name
+ * @return the signature dictionary keyed by /V or null
if the field is not
+ * a signature
+ */
+ public PdfDictionary GetSignatureDictionary(String name) {
+ FindSignatureNames();
+ name = GetTranslatedFieldName(name);
+ if (!sigNames.ContainsKey(name))
+ return null;
+ Item item = (Item)fields[name];
+ PdfDictionary merged = (PdfDictionary)item.merged[0];
+ return (PdfDictionary)PdfReader.GetPdfObject(merged.Get(PdfName.V));
+ }
+
+ /**
+ * Checks is the signature covers the entire document or just part of it.
+ * @param name the signature field name
+ * @return true
if the signature covers the entire document,
+ * false
otherwise
+ */
+ public bool SignatureCoversWholeDocument(String name) {
+ FindSignatureNames();
+ name = GetTranslatedFieldName(name);
+ if (!sigNames.ContainsKey(name))
+ return false;
+ return ((int[])sigNames[name])[0] == reader.FileLength;
+ }
+
+ /**
+ * Verifies a signature. An example usage is:
+ *
+ * KeyStore kall = PdfPKCS7.LoadCacertsKeyStore();
+ * PdfReader reader = new PdfReader("my_signed_doc.pdf");
+ * AcroFields af = reader.GetAcroFields();
+ * ArrayList names = af.GetSignatureNames();
+ * for (int k = 0; k < names.Size(); ++k) {
+ * String name = (String)names.Get(k);
+ * System.out.Println("Signature name: " + name);
+ * System.out.Println("Signature covers whole document: " + af.SignatureCoversWholeDocument(name));
+ * PdfPKCS7 pk = af.VerifySignature(name);
+ * Calendar cal = pk.GetSignDate();
+ * Certificate pkc[] = pk.GetCertificates();
+ * System.out.Println("Subject: " + PdfPKCS7.GetSubjectFields(pk.GetSigningCertificate()));
+ * System.out.Println("Document modified: " + !pk.Verify());
+ * Object fails[] = PdfPKCS7.VerifyCertificates(pkc, kall, null, cal);
+ * if (fails == null)
+ * System.out.Println("Certificates verified against the KeyStore");
+ * else
+ * System.out.Println("Certificate failed: " + fails[1]);
+ * }
+ *
+ * @param name the signature field name
+ * @return a PdfPKCS7
class to continue the verification
+ */
+ public PdfPKCS7 VerifySignature(String name) {
+ PdfDictionary v = GetSignatureDictionary(name);
+ if (v == null)
+ return null;
+ PdfName sub = (PdfName)PdfReader.GetPdfObject(v.Get(PdfName.SUBFILTER));
+ PdfString contents = (PdfString)PdfReader.GetPdfObject(v.Get(PdfName.CONTENTS));
+ PdfPKCS7 pk = null;
+ if (sub.Equals(PdfName.ADBE_X509_RSA_SHA1)) {
+ PdfString cert = (PdfString)PdfReader.GetPdfObject(v.Get(PdfName.CERT));
+ pk = new PdfPKCS7(contents.GetOriginalBytes(), cert.GetBytes());
+ }
+ else
+ pk = new PdfPKCS7(contents.GetOriginalBytes());
+ UpdateByteRange(pk, v);
+ PdfString str = (PdfString)PdfReader.GetPdfObject(v.Get(PdfName.M));
+ if (str != null)
+ pk.SignDate = PdfDate.Decode(str.ToString());
+ PdfObject obj = PdfReader.GetPdfObject(v.Get(PdfName.NAME));
+ if (obj != null) {
+ if (obj.IsString())
+ pk.SignName = ((PdfString)obj).ToUnicodeString();
+ else if(obj.IsName())
+ pk.SignName = PdfName.DecodeName(obj.ToString());
+ }
+ str = (PdfString)PdfReader.GetPdfObject(v.Get(PdfName.REASON));
+ if (str != null)
+ pk.Reason = str.ToUnicodeString();
+ str = (PdfString)PdfReader.GetPdfObject(v.Get(PdfName.LOCATION));
+ if (str != null)
+ pk.Location = str.ToUnicodeString();
+ return pk;
+ }
+
+ private void UpdateByteRange(PdfPKCS7 pkcs7, PdfDictionary v) {
+ PdfArray b = (PdfArray)PdfReader.GetPdfObject(v.Get(PdfName.BYTERANGE));
+ RandomAccessFileOrArray rf = reader.SafeFile;
+ try {
+ rf.ReOpen();
+ byte[] buf = new byte[8192];
+ ArrayList ar = b.ArrayList;
+ for (int k = 0; k < ar.Count; ++k) {
+ int start = ((PdfNumber)ar[k]).IntValue;
+ int length = ((PdfNumber)ar[++k]).IntValue;
+ rf.Seek(start);
+ while (length > 0) {
+ int rd = rf.Read(buf, 0, Math.Min(length, buf.Length));
+ if (rd <= 0)
+ break;
+ length -= rd;
+ pkcs7.Update(buf, 0, rd);
+ }
+ }
+ }
+ finally {
+ try{rf.Close();}catch{}
+ }
+ }
+
+ /**
+ * Gets the total number of revisions this document has.
+ * @return the total number of revisions
+ */
+ public int TotalRevisions {
+ get {
+ FindSignatureNames();
+ return this.totalRevisions;
+ }
+ }
+
+ /**
+ * Gets this field
revision.
+ * @param field the signature field name
+ * @return the revision or zero if it's not a signature field
+ */
+ public int GetRevision(String field) {
+ FindSignatureNames();
+ field = GetTranslatedFieldName(field);
+ if (!sigNames.ContainsKey(field))
+ return 0;
+ return ((int[])sigNames[field])[1];
+ }
+
+ /**
+ * Extracts a revision from the document.
+ * @param field the signature field name
+ * @return an Stream
covering the revision. Returns null
if
+ * it's not a signature field
+ * @throws IOException on error
+ */
+ public Stream ExtractRevision(String field) {
+ FindSignatureNames();
+ field = GetTranslatedFieldName(field);
+ if (!sigNames.ContainsKey(field))
+ return null;
+ int length = ((int[])sigNames[field])[0];
+ RandomAccessFileOrArray raf = reader.SafeFile;
+ raf.ReOpen();
+ raf.Seek(0);
+ return new RevisionStream(raf, length);
+ }
+
+ /**
+ * Sets a cache for field appearances. Parsing the existing PDF to
+ * create a new TextField is time expensive. For those tasks that repeatedly
+ * fill the same PDF with different field values the use of the cache has dramatic
+ * speed advantages. An example usage:
+ *
+ * String pdfFile = ...;// the pdf file used as template
+ * ArrayList xfdfFiles = ...;// the xfdf file names
+ * ArrayList pdfOutFiles = ...;// the output file names, one for each element in xpdfFiles
+ * Hashtable cache = new Hashtable();// the appearances cache
+ * PdfReader originalReader = new PdfReader(pdfFile);
+ * for (int k = 0; k < xfdfFiles.Size(); ++k) {
+ * PdfReader reader = new PdfReader(originalReader);
+ * XfdfReader xfdf = new XfdfReader((String)xfdfFiles.Get(k));
+ * PdfStamper stp = new PdfStamper(reader, new FileOutputStream((String)pdfOutFiles.Get(k)));
+ * AcroFields af = stp.GetAcroFields();
+ * af.SetFieldCache(cache);
+ * af.SetFields(xfdf);
+ * stp.Close();
+ * }
+ *
+ * @param fieldCache an HasMap that will carry the cached appearances
+ */
+ public Hashtable FieldCache {
+ set {
+ fieldCache = value;
+ }
+ get {
+ return fieldCache;
+ }
+ }
+
+ private void MarkUsed(PdfObject obj) {
+ if (!append)
+ return;
+ ((PdfStamperImp)writer).MarkUsed(obj);
+ }
+
+ /**
+ * Sets extra margins in text fields to better mimic the Acrobat layout.
+ * @param extraMarginLeft the extra marging left
+ * @param extraMarginTop the extra margin top
+ */
+ public void SetExtraMargin(float extraMarginLeft, float extraMarginTop) {
+ this.extraMarginLeft = extraMarginLeft;
+ this.extraMarginTop = extraMarginTop;
+ }
+
+ /**
+ * Adds a substitution font to the list. The fonts in this list will be used if the original
+ * font doesn't contain the needed glyphs.
+ * @param font the font
+ */
+ public void AddSubstitutionFont(BaseFont font) {
+ if (substitutionFonts == null)
+ substitutionFonts = new ArrayList();
+ substitutionFonts.Add(font);
+ }
+
+ private static Hashtable stdFieldFontNames = new Hashtable();
+
+ /**
+ * Holds value of property fieldCache.
+ */
+ private Hashtable fieldCache;
+
+ private int totalRevisions;
+
+ static AcroFields() {
+ stdFieldFontNames["CoBO"] = new String[]{"Courier-BoldOblique"};
+ stdFieldFontNames["CoBo"] = new String[]{"Courier-Bold"};
+ stdFieldFontNames["CoOb"] = new String[]{"Courier-Oblique"};
+ stdFieldFontNames["Cour"] = new String[]{"Courier"};
+ stdFieldFontNames["HeBO"] = new String[]{"Helvetica-BoldOblique"};
+ stdFieldFontNames["HeBo"] = new String[]{"Helvetica-Bold"};
+ stdFieldFontNames["HeOb"] = new String[]{"Helvetica-Oblique"};
+ stdFieldFontNames["Helv"] = new String[]{"Helvetica"};
+ stdFieldFontNames["Symb"] = new String[]{"Symbol"};
+ stdFieldFontNames["TiBI"] = new String[]{"Times-BoldItalic"};
+ stdFieldFontNames["TiBo"] = new String[]{"Times-Bold"};
+ stdFieldFontNames["TiIt"] = new String[]{"Times-Italic"};
+ stdFieldFontNames["TiRo"] = new String[]{"Times-Roman"};
+ stdFieldFontNames["ZaDb"] = new String[]{"ZapfDingbats"};
+ stdFieldFontNames["HySm"] = new String[]{"HYSMyeongJo-Medium", "UniKS-UCS2-H"};
+ stdFieldFontNames["HyGo"] = new String[]{"HYGoThic-Medium", "UniKS-UCS2-H"};
+ stdFieldFontNames["KaGo"] = new String[]{"HeiseiKakuGo-W5", "UniKS-UCS2-H"};
+ stdFieldFontNames["KaMi"] = new String[]{"HeiseiMin-W3", "UniJIS-UCS2-H"};
+ stdFieldFontNames["MHei"] = new String[]{"MHei-Medium", "UniCNS-UCS2-H"};
+ stdFieldFontNames["MSun"] = new String[]{"MSung-Light", "UniCNS-UCS2-H"};
+ stdFieldFontNames["STSo"] = new String[]{"STSong-Light", "UniGB-UCS2-H"};
+ }
+
+ public class RevisionStream : Stream {
+ private byte[] b = new byte[1];
+ private RandomAccessFileOrArray raf;
+ private int length;
+ private int rangePosition = 0;
+ private bool closed;
+
+ internal RevisionStream(RandomAccessFileOrArray raf, int length) {
+ this.raf = raf;
+ this.length = length;
+ }
+
+ public override int ReadByte() {
+ int n = Read(b, 0, 1);
+ if (n != 1)
+ return -1;
+ return b[0] & 0xff;
+ }
+
+ public override int Read(byte[] b, int off, int len) {
+ if (b == null) {
+ throw new ArgumentNullException();
+ } else if ((off < 0) || (off > b.Length) || (len < 0) ||
+ ((off + len) > b.Length) || ((off + len) < 0)) {
+ throw new ArgumentOutOfRangeException();
+ } else if (len == 0) {
+ return 0;
+ }
+ if (rangePosition >= length) {
+ Close();
+ return -1;
+ }
+ int elen = Math.Min(len, length - rangePosition);
+ raf.ReadFully(b, off, elen);
+ rangePosition += elen;
+ return elen;
+ }
+
+ public override void Close() {
+ if (!closed) {
+ raf.Close();
+ closed = true;
+ }
+ }
+
+ public override bool CanRead {
+ get {
+ return true;
+ }
+ }
+
+ public override bool CanSeek {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanWrite {
+ get {
+ return false;
+ }
+ }
+
+ public override long Length {
+ get {
+ return 0;
+ }
+ }
+
+ public override long Position {
+ get {
+ return 0;
+ }
+ set {
+ }
+ }
+
+ public override void Flush() {
+ }
+
+ public override long Seek(long offset, SeekOrigin origin) {
+ return 0;
+ }
+
+ public override void SetLength(long value) {
+ }
+
+ public override void Write(byte[] buffer, int offset, int count) {
+ }
+ }
+
+ private class ISorterComparator : IComparer {
+ public int Compare(Object o1, Object o2) {
+ int n1 = ((int[])((Object[])o1)[1])[0];
+ int n2 = ((int[])((Object[])o2)[1])[0];
+ return n1 - n2;
+ }
+ }
+
+ /**
+ * Sets a list of substitution fonts. The list is composed of BaseFont
and can also be null
. The fonts in this list will be used if the original
+ * font doesn't contain the needed glyphs.
+ * @param substitutionFonts the list
+ */
+ public ArrayList SubstitutionFonts {
+ set {
+ substitutionFonts = value;
+ }
+ get {
+ return substitutionFonts;
+ }
+ }
+
+ /**
+ * Gets the XFA form processor.
+ * @return the XFA form processor
+ */
+ public XfaForm Xfa {
+ get {
+ return xfa;
+ }
+ }
+
+ private static readonly PdfName[] buttonRemove = {PdfName.MK, PdfName.F , PdfName.FF , PdfName.Q , PdfName.BS , PdfName.BORDER};
+
+ /**
+ * Creates a new pushbutton from an existing field. If there are several pushbuttons with the same name
+ * only the first one is used. This pushbutton can be changed and be used to replace
+ * an existing one, with the same name or other name, as long is it is in the same document. To replace an existing pushbutton
+ * call {@link #replacePushbuttonField(String,PdfFormField)}.
+ * @param field the field name that should be a pushbutton
+ * @return a new pushbutton or null
if the field is not a pushbutton
+ */
+ public PushbuttonField GetNewPushbuttonFromField(String field) {
+ return GetNewPushbuttonFromField(field, 0);
+ }
+
+ /**
+ * Creates a new pushbutton from an existing field. This pushbutton can be changed and be used to replace
+ * an existing one, with the same name or other name, as long is it is in the same document. To replace an existing pushbutton
+ * call {@link #replacePushbuttonField(String,PdfFormField,int)}.
+ * @param field the field name that should be a pushbutton
+ * @param order the field order in fields with same name
+ * @return a new pushbutton or null
if the field is not a pushbutton
+ */
+ public PushbuttonField GetNewPushbuttonFromField(String field, int order) {
+ if (GetFieldType(field) != FIELD_TYPE_PUSHBUTTON)
+ return null;
+ Item item = GetFieldItem(field);
+ if (order >= item.merged.Count)
+ return null;
+ int posi = order * 5;
+ float[] pos = GetFieldPositions(field);
+ Rectangle box = new Rectangle(pos[posi + 1], pos[posi + 2], pos[posi + 3], pos[posi + 4]);
+ PushbuttonField newButton = new PushbuttonField(writer, box, null);
+ PdfDictionary dic = (PdfDictionary)item.merged[order];
+ DecodeGenericDictionary(dic, newButton);
+ PdfDictionary mk = (PdfDictionary)PdfReader.GetPdfObject(dic.Get(PdfName.MK));
+ if (mk != null) {
+ PdfString text = (PdfString)PdfReader.GetPdfObject(mk.Get(PdfName.CA));
+ if (text != null)
+ newButton.Text = text.ToUnicodeString();
+ PdfNumber tp = (PdfNumber)PdfReader.GetPdfObject(mk.Get(PdfName.TP));
+ if (tp != null)
+ newButton.Layout = tp.IntValue + 1;
+ PdfDictionary ifit = (PdfDictionary)PdfReader.GetPdfObject(mk.Get(PdfName.IF));
+ if (ifit != null) {
+ PdfName sw = (PdfName)PdfReader.GetPdfObject(ifit.Get(PdfName.SW));
+ if (sw != null) {
+ int scale = PushbuttonField.SCALE_ICON_ALWAYS;
+ if (sw.Equals(PdfName.B))
+ scale = PushbuttonField.SCALE_ICON_IS_TOO_BIG;
+ else if (sw.Equals(PdfName.S))
+ scale = PushbuttonField.SCALE_ICON_IS_TOO_SMALL;
+ else if (sw.Equals(PdfName.N))
+ scale = PushbuttonField.SCALE_ICON_NEVER;
+ newButton.ScaleIcon = scale;
+ }
+ sw = (PdfName)PdfReader.GetPdfObject(ifit.Get(PdfName.S));
+ if (sw != null) {
+ if (sw.Equals(PdfName.A))
+ newButton.ProportionalIcon = false;
+ }
+ PdfArray aj = (PdfArray)PdfReader.GetPdfObject(ifit.Get(PdfName.A));
+ if (aj != null && aj.Size == 2) {
+ float left = ((PdfNumber)PdfReader.GetPdfObject((PdfObject)aj.ArrayList[0])).FloatValue;
+ float bottom = ((PdfNumber)PdfReader.GetPdfObject((PdfObject)aj.ArrayList[1])).FloatValue;
+ newButton.IconHorizontalAdjustment = left;
+ newButton.IconVerticalAdjustment = bottom;
+ }
+ PdfObject fb = PdfReader.GetPdfObject(ifit.Get(PdfName.FB));
+ if (fb != null && fb.ToString().Equals("true"))
+ newButton.IconFitToBounds = true;
+ }
+ PdfObject i = mk.Get(PdfName.I);
+ if (i != null && i.IsIndirect())
+ newButton.IconReference = (PRIndirectReference)i;
+ }
+ return newButton;
+ }
+
+ /**
+ * Replaces the first field with a new pushbutton. The pushbutton can be created with
+ * {@link #getNewPushbuttonFromField(String)} from the same document or it can be a
+ * generic PdfFormField of the type pushbutton.
+ * @param field the field name
+ * @param button the PdfFormField
representing the pushbutton
+ * @return true
if the field was replaced, false
if the field
+ * was not a pushbutton
+ */
+ public bool ReplacePushbuttonField(String field, PdfFormField button) {
+ return ReplacePushbuttonField(field, button, 0);
+ }
+
+ /**
+ * Replaces the designated field with a new pushbutton. The pushbutton can be created with
+ * {@link #getNewPushbuttonFromField(String,int)} from the same document or it can be a
+ * generic PdfFormField of the type pushbutton.
+ * @param field the field name
+ * @param button the PdfFormField
representing the pushbutton
+ * @param order the field order in fields with same name
+ * @return true
if the field was replaced, false
if the field
+ * was not a pushbutton
+ */
+ public bool ReplacePushbuttonField(String field, PdfFormField button, int order) {
+ if (GetFieldType(field) != FIELD_TYPE_PUSHBUTTON)
+ return false;
+ Item item = GetFieldItem(field);
+ if (order >= item.merged.Count)
+ return false;
+ PdfDictionary merged = (PdfDictionary)item.merged[order];
+ PdfDictionary values = (PdfDictionary)item.values[order];
+ PdfDictionary widgets = (PdfDictionary)item.widgets[order];
+ for (int k = 0; k < buttonRemove.Length; ++k) {
+ merged.Remove(buttonRemove[k]);
+ values.Remove(buttonRemove[k]);
+ widgets.Remove(buttonRemove[k]);
+ }
+ foreach (PdfName key in button.Keys) {
+ if (key.Equals(PdfName.T) || key.Equals(PdfName.RECT))
+ continue;
+ if (key.Equals(PdfName.FF))
+ values.Put(key, button.Get(key));
+ else
+ widgets.Put(key, button.Get(key));
+ merged.Put(key, button.Get(key));
+ }
+ return true;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/ArabicLigaturizer.cs b/iTechSharp/iTextSharp/text/pdf/ArabicLigaturizer.cs
new file mode 100644
index 0000000..684515e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/ArabicLigaturizer.cs
@@ -0,0 +1,772 @@
+using System;
+using System.Text;
+/*
+ * Copyright 2003 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * Shape arabic characters. This code was inspired by an LGPL'ed C library:
+ * Pango ( see http://www.pango.com/ ). Note that the code of this is the
+ * original work of Paulo Soares. Hence it is perfectly justifiable to distribute
+ * it under the MPL.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class ArabicLigaturizer {
+
+ static bool IsVowel(char s) {
+ return ((s >= '\u064B') && (s <= '\u0655')) || (s == '\u0670');
+ }
+
+ static char Charshape(char s, int which)
+ /* which 0=isolated 1=final 2=initial 3=medial */
+ {
+ int l, r, m;
+ if ((s >= '\u0621') && (s <= '\u06D3')) {
+ l = 0;
+ r = chartable.Length - 1;
+ while (l <= r) {
+ m = (l + r) / 2;
+ if (s == chartable[m][0]) {
+ return chartable[m][which + 1];
+ }
+ else if (s < chartable[m][0]) {
+ r = m - 1;
+ }
+ else {
+ l = m + 1;
+ }
+ }
+ }
+ else if (s >= '\ufef5' && s <= '\ufefb')
+ return (char)(s + which);
+ return s;
+ }
+
+ static int Shapecount(char s) {
+ int l, r, m;
+ if ((s >= '\u0621') && (s <= '\u06D3') && !IsVowel(s)) {
+ l = 0;
+ r = chartable.Length - 1;
+ while (l <= r) {
+ m = (l + r) / 2;
+ if (s == chartable[m][0]) {
+ return chartable[m].Length - 1;
+ }
+ else if (s < chartable[m][0]) {
+ r = m - 1;
+ }
+ else {
+ l = m + 1;
+ }
+ }
+ }
+ else if (s == ZWJ) {
+ return 4;
+ }
+ return 1;
+ }
+
+ static int Ligature(char newchar, Charstruct oldchar) {
+ /* 0 == no ligature possible; 1 == vowel; 2 == two chars; 3 == Lam+Alef */
+ int retval = 0;
+
+ if (oldchar.basechar == 0)
+ return 0;
+ if (IsVowel(newchar)) {
+ retval = 1;
+ if ((oldchar.vowel != 0) && (newchar != SHADDA)) {
+ retval = 2; /* we eliminate the old vowel .. */
+ }
+ switch (newchar) {
+ case SHADDA:
+ if (oldchar.mark1 == 0) {
+ oldchar.mark1 = SHADDA;
+ }
+ else {
+ return 0; /* no ligature possible */
+ }
+ break;
+ case HAMZABELOW:
+ switch (oldchar.basechar) {
+ case ALEF:
+ oldchar.basechar = ALEFHAMZABELOW;
+ retval = 2;
+ break;
+ case LAM_ALEF:
+ oldchar.basechar = LAM_ALEFHAMZABELOW;
+ retval = 2;
+ break;
+ default:
+ oldchar.mark1 = HAMZABELOW;
+ break;
+ }
+ break;
+ case HAMZAABOVE:
+ switch (oldchar.basechar) {
+ case ALEF:
+ oldchar.basechar = ALEFHAMZA;
+ retval = 2;
+ break;
+ case LAM_ALEF:
+ oldchar.basechar = LAM_ALEFHAMZA;
+ retval = 2;
+ break;
+ case WAW:
+ oldchar.basechar = WAWHAMZA;
+ retval = 2;
+ break;
+ case YEH:
+ case ALEFMAKSURA:
+ case FARSIYEH:
+ oldchar.basechar = YEHHAMZA;
+ retval = 2;
+ break;
+ default: /* whatever sense this may make .. */
+ oldchar.mark1 = HAMZAABOVE;
+ break;
+ }
+ break;
+ case MADDA:
+ switch (oldchar.basechar) {
+ case ALEF:
+ oldchar.basechar = ALEFMADDA;
+ retval = 2;
+ break;
+ }
+ break;
+ default:
+ oldchar.vowel = newchar;
+ break;
+ }
+ if (retval == 1) {
+ oldchar.lignum++;
+ }
+ return retval;
+ }
+ if (oldchar.vowel != 0) { /* if we already joined a vowel, we can't join a Hamza */
+ return 0;
+ }
+
+ switch (oldchar.basechar) {
+ case LAM:
+ switch (newchar) {
+ case ALEF:
+ oldchar.basechar = LAM_ALEF;
+ oldchar.numshapes = 2;
+ retval = 3;
+ break;
+ case ALEFHAMZA:
+ oldchar.basechar = LAM_ALEFHAMZA;
+ oldchar.numshapes = 2;
+ retval = 3;
+ break;
+ case ALEFHAMZABELOW:
+ oldchar.basechar = LAM_ALEFHAMZABELOW;
+ oldchar.numshapes = 2;
+ retval = 3;
+ break;
+ case ALEFMADDA:
+ oldchar.basechar = LAM_ALEFMADDA;
+ oldchar.numshapes = 2;
+ retval = 3;
+ break;
+ }
+ break;
+ case (char)0:
+ oldchar.basechar = newchar;
+ oldchar.numshapes = Shapecount(newchar);
+ retval = 1;
+ break;
+ }
+ return retval;
+ }
+
+ static void Copycstostring(StringBuilder str, Charstruct s, int level) {
+ /* s is a shaped charstruct; i is the index into the string */
+ if (s.basechar == 0)
+ return;
+
+ str.Append(s.basechar);
+ s.lignum--;
+ if (s.mark1 != 0) {
+ if ((level & ar_novowel) == 0) {
+ str.Append(s.mark1);
+ s.lignum--;
+ }
+ else {
+ s.lignum--;
+ }
+ }
+ if (s.vowel != 0) {
+ if ((level & ar_novowel) == 0) {
+ str.Append(s.vowel);
+ s.lignum--;
+ }
+ else { /* vowel elimination */
+ s.lignum--;
+ }
+ }
+ }
+
+ // return len
+ internal static void Doublelig(StringBuilder str, int level)
+ /* Ok. We have presentation ligatures in our font. */
+ {
+ int len;
+ int olen = len = str.Length;
+ int j = 0, si = 1;
+ char lapresult;
+
+ while (si < olen) {
+ lapresult = (char)0;
+ if ((level & ar_composedtashkeel) != 0) {
+ switch (str[j]) {
+ case SHADDA:
+ switch (str[si]) {
+ case KASRA:
+ lapresult = '\uFC62';
+ break;
+ case FATHA:
+ lapresult = '\uFC60';
+ break;
+ case DAMMA:
+ lapresult = '\uFC61';
+ break;
+ case '\u064C':
+ lapresult = '\uFC5E';
+ break;
+ case '\u064D':
+ lapresult = '\uFC5F';
+ break;
+ }
+ break;
+ case KASRA:
+ if (str[si] == SHADDA)
+ lapresult = '\uFC62';
+ break;
+ case FATHA:
+ if (str[si] == SHADDA)
+ lapresult = '\uFC60';
+ break;
+ case DAMMA:
+ if (str[si] == SHADDA)
+ lapresult = '\uFC61';
+ break;
+ }
+ }
+
+ if ((level & ar_lig) != 0) {
+ switch (str[j]) {
+ case '\uFEDF': /* LAM initial */
+ switch (str[si]) {
+ case '\uFE9E':
+ lapresult = '\uFC3F';
+ break; /* JEEM final */
+ case '\uFEA0':
+ lapresult = '\uFCC9';
+ break; /* JEEM medial */
+ case '\uFEA2':
+ lapresult = '\uFC40';
+ break; /* HAH final */
+ case '\uFEA4':
+ lapresult = '\uFCCA';
+ break; /* HAH medial */
+ case '\uFEA6':
+ lapresult = '\uFC41';
+ break; /* KHAH final */
+ case '\uFEA8':
+ lapresult = '\uFCCB';
+ break; /* KHAH medial */
+ case '\uFEE2':
+ lapresult = '\uFC42';
+ break; /* MEEM final */
+ case '\uFEE4':
+ lapresult = '\uFCCC';
+ break; /* MEEM medial */
+ }
+ break;
+ case '\uFE97': /* TEH inital */
+ switch (str[si]) {
+ case '\uFEA0':
+ lapresult = '\uFCA1';
+ break; /* JEEM medial */
+ case '\uFEA4':
+ lapresult = '\uFCA2';
+ break; /* HAH medial */
+ case '\uFEA8':
+ lapresult = '\uFCA3';
+ break; /* KHAH medial */
+ }
+ break;
+ case '\uFE91': /* BEH inital */
+ switch (str[si]) {
+ case '\uFEA0':
+ lapresult = '\uFC9C';
+ break; /* JEEM medial */
+ case '\uFEA4':
+ lapresult = '\uFC9D';
+ break; /* HAH medial */
+ case '\uFEA8':
+ lapresult = '\uFC9E';
+ break; /* KHAH medial */
+ }
+ break;
+ case '\uFEE7': /* NOON inital */
+ switch (str[si]) {
+ case '\uFEA0':
+ lapresult = '\uFCD2';
+ break; /* JEEM initial */
+ case '\uFEA4':
+ lapresult = '\uFCD3';
+ break; /* HAH medial */
+ case '\uFEA8':
+ lapresult = '\uFCD4';
+ break; /* KHAH medial */
+ }
+ break;
+
+ case '\uFEE8': /* NOON medial */
+ switch (str[si]) {
+ case '\uFEAE':
+ lapresult = '\uFC8A';
+ break; /* REH final */
+ case '\uFEB0':
+ lapresult = '\uFC8B';
+ break; /* ZAIN final */
+ }
+ break;
+ case '\uFEE3': /* MEEM initial */
+ switch (str[si]) {
+ case '\uFEA0':
+ lapresult = '\uFCCE';
+ break; /* JEEM medial */
+ case '\uFEA4':
+ lapresult = '\uFCCF';
+ break; /* HAH medial */
+ case '\uFEA8':
+ lapresult = '\uFCD0';
+ break; /* KHAH medial */
+ case '\uFEE4':
+ lapresult = '\uFCD1';
+ break; /* MEEM medial */
+ }
+ break;
+
+ case '\uFED3': /* FEH initial */
+ switch (str[si]) {
+ case '\uFEF2':
+ lapresult = '\uFC32';
+ break; /* YEH final */
+ }
+ break;
+
+ default:
+ break;
+ } /* end switch string[si] */
+ }
+ if (lapresult != 0) {
+ str[j] = lapresult;
+ len--;
+ si++; /* jump over one character */
+ /* we'll have to change this, too. */
+ }
+ else {
+ j++;
+ str[j] = str[si];
+ si++;
+ }
+ }
+ str.Length = len;
+ }
+
+ static bool Connects_to_left(Charstruct a) {
+ return a.numshapes > 2;
+ }
+
+ internal static void Shape(char[] text, StringBuilder str, int level) {
+ /* string is assumed to be empty and big enough.
+ * text is the original text.
+ * This routine does the basic arabic reshaping.
+ * *len the number of non-null characters.
+ *
+ * Note: We have to unshape each character first!
+ */
+ int join;
+ int which;
+ char nextletter;
+
+ int p = 0; /* initialize for output */
+ Charstruct oldchar = new Charstruct();
+ Charstruct curchar = new Charstruct();
+ while (p < text.Length) {
+ nextletter = text[p++];
+ //nextletter = unshape (nextletter);
+
+ join = Ligature(nextletter, curchar);
+ if (join == 0) { /* shape curchar */
+ int nc = Shapecount(nextletter);
+ //(*len)++;
+ if (nc == 1) {
+ which = 0; /* final or isolated */
+ }
+ else {
+ which = 2; /* medial or initial */
+ }
+ if (Connects_to_left(oldchar)) {
+ which++;
+ }
+
+ which = which % (curchar.numshapes);
+ curchar.basechar = Charshape(curchar.basechar, which);
+
+ /* get rid of oldchar */
+ Copycstostring(str, oldchar, level);
+ oldchar = curchar; /* new values in oldchar */
+
+ /* init new curchar */
+ curchar = new Charstruct();
+ curchar.basechar = nextletter;
+ curchar.numshapes = nc;
+ curchar.lignum++;
+ // (*len) += unligature (&curchar, level);
+ }
+ else if (join == 1) {
+ }
+ // else
+ // {
+ // (*len) += unligature (&curchar, level);
+ // }
+ // p = g_utf8_next_char (p);
+ }
+
+ /* Handle last char */
+ if (Connects_to_left(oldchar))
+ which = 1;
+ else
+ which = 0;
+ which = which % (curchar.numshapes);
+ curchar.basechar = Charshape(curchar.basechar, which);
+
+ /* get rid of oldchar */
+ Copycstostring(str, oldchar, level);
+ Copycstostring(str, curchar, level);
+ }
+
+ internal static int Arabic_shape(char[] src, int srcoffset, int srclength, char[] dest, int destoffset, int destlength, int level) {
+ char[] str = new char[srclength];
+ for (int k = srclength + srcoffset - 1; k >= srcoffset; --k)
+ str[k - srcoffset] = src[k];
+ StringBuilder str2 = new StringBuilder(srclength);
+ Shape(str, str2, level);
+ if ((level & (ar_composedtashkeel | ar_lig)) != 0)
+ Doublelig(str2, level);
+ // string.Reverse();
+ System.Array.Copy(str2.ToString().ToCharArray(), 0, dest, destoffset, str2.Length);
+ return str2.Length;
+ }
+
+ internal static void ProcessNumbers(char[] text, int offset, int length, int options) {
+ int limit = offset + length;
+ if ((options & DIGITS_MASK) != 0) {
+ char digitBase = '\u0030'; // European digits
+ switch (options & DIGIT_TYPE_MASK) {
+ case DIGIT_TYPE_AN:
+ digitBase = '\u0660'; // Arabic-Indic digits
+ break;
+
+ case DIGIT_TYPE_AN_EXTENDED:
+ digitBase = '\u06f0'; // Eastern Arabic-Indic digits (Persian and Urdu)
+ break;
+
+ default:
+ break;
+ }
+
+ switch (options & DIGITS_MASK) {
+ case DIGITS_EN2AN: {
+ int digitDelta = digitBase - '\u0030';
+ for (int i = offset; i < limit; ++i) {
+ char ch = text[i];
+ if (ch <= '\u0039' && ch >= '\u0030') {
+ text[i] += (char)digitDelta;
+ }
+ }
+ }
+ break;
+
+ case DIGITS_AN2EN: {
+ char digitTop = (char)(digitBase + 9);
+ int digitDelta = '\u0030' - digitBase;
+ for (int i = offset; i < limit; ++i) {
+ char ch = text[i];
+ if (ch <= digitTop && ch >= digitBase) {
+ text[i] += (char)digitDelta;
+ }
+ }
+ }
+ break;
+
+ case DIGITS_EN2AN_INIT_LR:
+ ShapeToArabicDigitsWithContext(text, 0, length, digitBase, false);
+ break;
+
+ case DIGITS_EN2AN_INIT_AL:
+ ShapeToArabicDigitsWithContext(text, 0, length, digitBase, true);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ internal static void ShapeToArabicDigitsWithContext(char[] dest, int start, int length, char digitBase, bool lastStrongWasAL) {
+ digitBase -= '0'; // move common adjustment out of loop
+
+ int limit = start + length;
+ for (int i = start; i < limit; ++i) {
+ char ch = dest[i];
+ switch (BidiOrder.GetDirection(ch)) {
+ case BidiOrder.L:
+ case BidiOrder.R:
+ lastStrongWasAL = false;
+ break;
+ case BidiOrder.AL:
+ lastStrongWasAL = true;
+ break;
+ case BidiOrder.EN:
+ if (lastStrongWasAL && ch <= '\u0039') {
+ dest[i] = (char)(ch + digitBase);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private const char ALEF = '\u0627';
+ private const char ALEFHAMZA = '\u0623';
+ private const char ALEFHAMZABELOW = '\u0625';
+ private const char ALEFMADDA = '\u0622';
+ private const char LAM = '\u0644';
+ private const char HAMZA = '\u0621';
+ private const char TATWEEL = '\u0640';
+ private const char ZWJ = '\u200D';
+
+ private const char HAMZAABOVE = '\u0654';
+ private const char HAMZABELOW = '\u0655';
+
+ private const char WAWHAMZA = '\u0624';
+ private const char YEHHAMZA = '\u0626';
+ private const char WAW = '\u0648';
+ private const char ALEFMAKSURA = '\u0649';
+ private const char YEH = '\u064A';
+ private const char FARSIYEH = '\u06CC';
+
+ private const char SHADDA = '\u0651';
+ private const char KASRA = '\u0650';
+ private const char FATHA = '\u064E';
+ private const char DAMMA = '\u064F';
+ private const char MADDA = '\u0653';
+
+ private const char LAM_ALEF = '\uFEFB';
+ private const char LAM_ALEFHAMZA = '\uFEF7';
+ private const char LAM_ALEFHAMZABELOW = '\uFEF9';
+ private const char LAM_ALEFMADDA = '\uFEF5';
+
+ private static char[][] chartable = {
+ new char[]{'\u0621', '\uFE80'}, /* HAMZA */
+ new char[]{'\u0622', '\uFE81', '\uFE82'}, /* ALEF WITH MADDA ABOVE */
+ new char[]{'\u0623', '\uFE83', '\uFE84'}, /* ALEF WITH HAMZA ABOVE */
+ new char[]{'\u0624', '\uFE85', '\uFE86'}, /* WAW WITH HAMZA ABOVE */
+ new char[]{'\u0625', '\uFE87', '\uFE88'}, /* ALEF WITH HAMZA BELOW */
+ new char[]{'\u0626', '\uFE89', '\uFE8A', '\uFE8B', '\uFE8C'}, /* YEH WITH HAMZA ABOVE */
+ new char[]{'\u0627', '\uFE8D', '\uFE8E'}, /* ALEF */
+ new char[]{'\u0628', '\uFE8F', '\uFE90', '\uFE91', '\uFE92'}, /* BEH */
+ new char[]{'\u0629', '\uFE93', '\uFE94'}, /* TEH MARBUTA */
+ new char[]{'\u062A', '\uFE95', '\uFE96', '\uFE97', '\uFE98'}, /* TEH */
+ new char[]{'\u062B', '\uFE99', '\uFE9A', '\uFE9B', '\uFE9C'}, /* THEH */
+ new char[]{'\u062C', '\uFE9D', '\uFE9E', '\uFE9F', '\uFEA0'}, /* JEEM */
+ new char[]{'\u062D', '\uFEA1', '\uFEA2', '\uFEA3', '\uFEA4'}, /* HAH */
+ new char[]{'\u062E', '\uFEA5', '\uFEA6', '\uFEA7', '\uFEA8'}, /* KHAH */
+ new char[]{'\u062F', '\uFEA9', '\uFEAA'}, /* DAL */
+ new char[]{'\u0630', '\uFEAB', '\uFEAC'}, /* THAL */
+ new char[]{'\u0631', '\uFEAD', '\uFEAE'}, /* REH */
+ new char[]{'\u0632', '\uFEAF', '\uFEB0'}, /* ZAIN */
+ new char[]{'\u0633', '\uFEB1', '\uFEB2', '\uFEB3', '\uFEB4'}, /* SEEN */
+ new char[]{'\u0634', '\uFEB5', '\uFEB6', '\uFEB7', '\uFEB8'}, /* SHEEN */
+ new char[]{'\u0635', '\uFEB9', '\uFEBA', '\uFEBB', '\uFEBC'}, /* SAD */
+ new char[]{'\u0636', '\uFEBD', '\uFEBE', '\uFEBF', '\uFEC0'}, /* DAD */
+ new char[]{'\u0637', '\uFEC1', '\uFEC2', '\uFEC3', '\uFEC4'}, /* TAH */
+ new char[]{'\u0638', '\uFEC5', '\uFEC6', '\uFEC7', '\uFEC8'}, /* ZAH */
+ new char[]{'\u0639', '\uFEC9', '\uFECA', '\uFECB', '\uFECC'}, /* AIN */
+ new char[]{'\u063A', '\uFECD', '\uFECE', '\uFECF', '\uFED0'}, /* GHAIN */
+ new char[]{'\u0640', '\u0640', '\u0640', '\u0640', '\u0640'}, /* TATWEEL */
+ new char[]{'\u0641', '\uFED1', '\uFED2', '\uFED3', '\uFED4'}, /* FEH */
+ new char[]{'\u0642', '\uFED5', '\uFED6', '\uFED7', '\uFED8'}, /* QAF */
+ new char[]{'\u0643', '\uFED9', '\uFEDA', '\uFEDB', '\uFEDC'}, /* KAF */
+ new char[]{'\u0644', '\uFEDD', '\uFEDE', '\uFEDF', '\uFEE0'}, /* LAM */
+ new char[]{'\u0645', '\uFEE1', '\uFEE2', '\uFEE3', '\uFEE4'}, /* MEEM */
+ new char[]{'\u0646', '\uFEE5', '\uFEE6', '\uFEE7', '\uFEE8'}, /* NOON */
+ new char[]{'\u0647', '\uFEE9', '\uFEEA', '\uFEEB', '\uFEEC'}, /* HEH */
+ new char[]{'\u0648', '\uFEED', '\uFEEE'}, /* WAW */
+ new char[]{'\u0649', '\uFEEF', '\uFEF0', '\uFBE8', '\uFBE9'}, /* ALEF MAKSURA */
+ new char[]{'\u064A', '\uFEF1', '\uFEF2', '\uFEF3', '\uFEF4'}, /* YEH */
+ new char[]{'\u0671', '\uFB50', '\uFB51'}, /* ALEF WASLA */
+ new char[]{'\u0679', '\uFB66', '\uFB67', '\uFB68', '\uFB69'}, /* TTEH */
+ new char[]{'\u067A', '\uFB5E', '\uFB5F', '\uFB60', '\uFB61'}, /* TTEHEH */
+ new char[]{'\u067B', '\uFB52', '\uFB53', '\uFB54', '\uFB55'}, /* BEEH */
+ new char[]{'\u067E', '\uFB56', '\uFB57', '\uFB58', '\uFB59'}, /* PEH */
+ new char[]{'\u067F', '\uFB62', '\uFB63', '\uFB64', '\uFB65'}, /* TEHEH */
+ new char[]{'\u0680', '\uFB5A', '\uFB5B', '\uFB5C', '\uFB5D'}, /* BEHEH */
+ new char[]{'\u0683', '\uFB76', '\uFB77', '\uFB78', '\uFB79'}, /* NYEH */
+ new char[]{'\u0684', '\uFB72', '\uFB73', '\uFB74', '\uFB75'}, /* DYEH */
+ new char[]{'\u0686', '\uFB7A', '\uFB7B', '\uFB7C', '\uFB7D'}, /* TCHEH */
+ new char[]{'\u0687', '\uFB7E', '\uFB7F', '\uFB80', '\uFB81'}, /* TCHEHEH */
+ new char[]{'\u0688', '\uFB88', '\uFB89'}, /* DDAL */
+ new char[]{'\u068C', '\uFB84', '\uFB85'}, /* DAHAL */
+ new char[]{'\u068D', '\uFB82', '\uFB83'}, /* DDAHAL */
+ new char[]{'\u068E', '\uFB86', '\uFB87'}, /* DUL */
+ new char[]{'\u0691', '\uFB8C', '\uFB8D'}, /* RREH */
+ new char[]{'\u0698', '\uFB8A', '\uFB8B'}, /* JEH */
+ new char[]{'\u06A4', '\uFB6A', '\uFB6B', '\uFB6C', '\uFB6D'}, /* VEH */
+ new char[]{'\u06A6', '\uFB6E', '\uFB6F', '\uFB70', '\uFB71'}, /* PEHEH */
+ new char[]{'\u06A9', '\uFB8E', '\uFB8F', '\uFB90', '\uFB91'}, /* KEHEH */
+ new char[]{'\u06AD', '\uFBD3', '\uFBD4', '\uFBD5', '\uFBD6'}, /* NG */
+ new char[]{'\u06AF', '\uFB92', '\uFB93', '\uFB94', '\uFB95'}, /* GAF */
+ new char[]{'\u06B1', '\uFB9A', '\uFB9B', '\uFB9C', '\uFB9D'}, /* NGOEH */
+ new char[]{'\u06B3', '\uFB96', '\uFB97', '\uFB98', '\uFB99'}, /* GUEH */
+ new char[]{'\u06BA', '\uFB9E', '\uFB9F'}, /* NOON GHUNNA */
+ new char[]{'\u06BB', '\uFBA0', '\uFBA1', '\uFBA2', '\uFBA3'}, /* RNOON */
+ new char[]{'\u06BE', '\uFBAA', '\uFBAB', '\uFBAC', '\uFBAD'}, /* HEH DOACHASHMEE */
+ new char[]{'\u06C0', '\uFBA4', '\uFBA5'}, /* HEH WITH YEH ABOVE */
+ new char[]{'\u06C1', '\uFBA6', '\uFBA7', '\uFBA8', '\uFBA9'}, /* HEH GOAL */
+ new char[]{'\u06C5', '\uFBE0', '\uFBE1'}, /* KIRGHIZ OE */
+ new char[]{'\u06C6', '\uFBD9', '\uFBDA'}, /* OE */
+ new char[]{'\u06C7', '\uFBD7', '\uFBD8'}, /* U */
+ new char[]{'\u06C8', '\uFBDB', '\uFBDC'}, /* YU */
+ new char[]{'\u06C9', '\uFBE2', '\uFBE3'}, /* KIRGHIZ YU */
+ new char[]{'\u06CB', '\uFBDE', '\uFBDF'}, /* VE */
+ new char[]{'\u06CC', '\uFBFC', '\uFBFD', '\uFBFE', '\uFBFF'}, /* FARSI YEH */
+ new char[]{'\u06D0', '\uFBE4', '\uFBE5', '\uFBE6', '\uFBE7'}, /* E */
+ new char[]{'\u06D2', '\uFBAE', '\uFBAF'}, /* YEH BARREE */
+ new char[]{'\u06D3', '\uFBB0', '\uFBB1'} /* YEH BARREE WITH HAMZA ABOVE */
+ };
+
+ public const int ar_nothing = 0x0;
+ public const int ar_novowel = 0x1;
+ public const int ar_composedtashkeel = 0x4;
+ public const int ar_lig = 0x8;
+ /**
+ * Digit shaping option: Replace European digits (U+0030...U+0039) by Arabic-Indic digits.
+ */
+ public const int DIGITS_EN2AN = 0x20;
+
+ /**
+ * Digit shaping option: Replace Arabic-Indic digits by European digits (U+0030...U+0039).
+ */
+ public const int DIGITS_AN2EN = 0x40;
+
+ /**
+ * Digit shaping option:
+ * Replace European digits (U+0030...U+0039) by Arabic-Indic digits
+ * if the most recent strongly directional character
+ * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC).
+ * The initial state at the start of the text is assumed to be not an Arabic,
+ * letter, so European digits at the start of the text will not change.
+ * Compare to DIGITS_ALEN2AN_INIT_AL.
+ */
+ public const int DIGITS_EN2AN_INIT_LR = 0x60;
+
+ /**
+ * Digit shaping option:
+ * Replace European digits (U+0030...U+0039) by Arabic-Indic digits
+ * if the most recent strongly directional character
+ * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC).
+ * The initial state at the start of the text is assumed to be an Arabic,
+ * letter, so European digits at the start of the text will change.
+ * Compare to DIGITS_ALEN2AN_INT_LR.
+ */
+ public const int DIGITS_EN2AN_INIT_AL = 0x80;
+
+ /** Not a valid option value. */
+ private const int DIGITS_RESERVED = 0xa0;
+
+ /**
+ * Bit mask for digit shaping options.
+ */
+ public const int DIGITS_MASK = 0xe0;
+
+ /**
+ * Digit type option: Use Arabic-Indic digits (U+0660...U+0669).
+ */
+ public const int DIGIT_TYPE_AN = 0;
+
+ /**
+ * Digit type option: Use Eastern (Extended) Arabic-Indic digits (U+06f0...U+06f9).
+ */
+ public const int DIGIT_TYPE_AN_EXTENDED = 0x100;
+
+ /**
+ * Bit mask for digit type options.
+ */
+ public const int DIGIT_TYPE_MASK = '\u0100'; // '\u3f00'?
+
+ private class Charstruct {
+ internal char basechar;
+ internal char mark1; /* has to be initialized to zero */
+ internal char vowel;
+ internal int lignum; /* is a ligature with lignum aditional characters */
+ internal int numshapes = 1;
+ };
+
+
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BadPasswordException.cs b/iTechSharp/iTextSharp/text/pdf/BadPasswordException.cs
new file mode 100644
index 0000000..65ead6c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BadPasswordException.cs
@@ -0,0 +1,59 @@
+using System;
+using System.IO;
+
+/*
+ * $Id: BadPasswordException.cs,v 1.1 2008/01/10 15:49:39 psoares33 Exp $
+ *
+ * Copyright 2008 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ public class BadPasswordException : IOException {
+ public BadPasswordException() : base("Bad user Password") {
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/BadPdfFormatException.cs b/iTechSharp/iTextSharp/text/pdf/BadPdfFormatException.cs
new file mode 100644
index 0000000..db72d7c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BadPdfFormatException.cs
@@ -0,0 +1,72 @@
+using System;
+
+/*
+ * $Id: BadPdfFormatException.cs,v 1.3 2008/05/13 11:25:16 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf
+{
+ /**
+ * Signals that a bad PDF format has been used to construct a PdfObject
.
+ *
+ * @see PdfException
+ * @see PdfBoolean
+ * @see PdfNumber
+ * @see PdfString
+ * @see PdfName
+ * @see PdfDictionary
+ * @see PdfFont
+ */
+
+ public class BadPdfFormatException : Exception
+ {
+ public BadPdfFormatException() : base() {}
+ public BadPdfFormatException(string message) : base(message) {}
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/Barcode.cs b/iTechSharp/iTextSharp/text/pdf/Barcode.cs
new file mode 100644
index 0000000..22ef490
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/Barcode.cs
@@ -0,0 +1,430 @@
+using System;
+using iTextSharp.text;
+/*
+ * $Id: Barcode.cs,v 1.4 2006/07/31 13:51:38 psoares33 Exp $
+ *
+ * Copyright 2002-2006 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /** Base class containing properties and methods commom to all
+ * barcode types.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public abstract class Barcode {
+ /** A type of barcode */
+ public const int EAN13 = 1;
+ /** A type of barcode */
+ public const int EAN8 = 2;
+ /** A type of barcode */
+ public const int UPCA = 3;
+ /** A type of barcode */
+ public const int UPCE = 4;
+ /** A type of barcode */
+ public const int SUPP2 = 5;
+ /** A type of barcode */
+ public const int SUPP5 = 6;
+ /** A type of barcode */
+ public const int POSTNET = 7;
+ /** A type of barcode */
+ public const int PLANET = 8;
+ /** A type of barcode */
+ public const int CODE128 = 9;
+ /** A type of barcode */
+ public const int CODE128_UCC = 10;
+ /** A type of barcode */
+ public const int CODE128_RAW = 11;
+ /** A type of barcode */
+ public const int CODABAR = 12;
+
+ /** The minimum bar width.
+ */
+ protected float x;
+
+ /** The bar multiplier for wide bars or the distance between
+ * bars for Postnet and Planet.
+ */
+ protected float n;
+
+ /** The text font. null
if no text.
+ */
+ protected BaseFont font;
+
+ /** The size of the text or the height of the shorter bar
+ * in Postnet.
+ */
+ protected float size;
+
+ /** If positive, the text distance under the bars. If zero or negative,
+ * the text distance above the bars.
+ */
+ protected float baseline;
+
+ /** The height of the bars.
+ */
+ protected float barHeight;
+
+ /** The text Element. Can be Element.ALIGN_LEFT
,
+ * Element.ALIGN_CENTER
or Element.ALIGN_RIGHT
.
+ */
+ protected int textAlignment;
+
+ /** The optional checksum generation.
+ */
+ protected bool generateChecksum;
+
+ /** Shows the generated checksum in the the text.
+ */
+ protected bool checksumText;
+
+ /** Show the start and stop character '*' in the text for
+ * the barcode 39 or 'ABCD' for codabar.
+ */
+ protected bool startStopText;
+
+ /** Generates extended barcode 39.
+ */
+ protected bool extended;
+
+ /** The code to generate.
+ */
+ protected string code = "";
+
+ /** Show the guard bars for barcode EAN.
+ */
+ protected bool guardBars;
+
+ /** The code type.
+ */
+ protected int codeType;
+
+ /** The ink spreading. */
+ protected float inkSpreading = 0;
+
+ /** Gets the minimum bar width.
+ * @return the minimum bar width
+ */
+ public float X {
+ get {
+ return x;
+ }
+
+ set {
+ this.x = value;
+ }
+ }
+
+ /** Gets the bar multiplier for wide bars.
+ * @return the bar multiplier for wide bars
+ */
+ public float N {
+ get {
+ return n;
+ }
+
+ set {
+ this.n = value;
+ }
+ }
+
+ /** Gets the text font. null
if no text.
+ * @return the text font. null
if no text
+ */
+ public BaseFont Font {
+ get {
+ return font;
+ }
+
+ set {
+ this.font = value;
+ }
+ }
+
+ /** Gets the size of the text.
+ * @return the size of the text
+ */
+ public float Size {
+ get {
+ return size;
+ }
+
+ set {
+ this.size = value;
+ }
+ }
+
+ /** Gets the text baseline.
+ * If positive, the text distance under the bars. If zero or negative,
+ * the text distance above the bars.
+ * @return the baseline.
+ */
+ public float Baseline {
+ get {
+ return baseline;
+ }
+
+ set {
+ this.baseline = value;
+ }
+ }
+
+ /** Gets the height of the bars.
+ * @return the height of the bars
+ */
+ public float BarHeight {
+ get {
+ return barHeight;
+ }
+
+ set {
+ this.barHeight = value;
+ }
+ }
+
+ /** Gets the text Element. Can be Element.ALIGN_LEFT
,
+ * Element.ALIGN_CENTER
or Element.ALIGN_RIGHT
.
+ * @return the text alignment
+ */
+ public int TextAlignment{
+ get {
+ return textAlignment;
+ }
+
+ set {
+ this.textAlignment = value;
+ }
+ }
+
+ /** The property for the optional checksum generation.
+ */
+ public bool GenerateChecksum {
+ set {
+ this.generateChecksum = value;
+ }
+ get {
+ return generateChecksum;
+ }
+ }
+
+ /** Sets the property to show the generated checksum in the the text.
+ * @param checksumText new value of property checksumText
+ */
+ public bool ChecksumText {
+ set {
+ this.checksumText = value;
+ }
+ get {
+ return checksumText;
+ }
+ }
+
+ /** Gets the property to show the start and stop character '*' in the text for
+ * the barcode 39.
+ * @param startStopText new value of property startStopText
+ */
+ public bool StartStopText {
+ set {
+ this.startStopText = value;
+ }
+ get {
+ return startStopText;
+ }
+ }
+
+ /** Sets the property to generate extended barcode 39.
+ * @param extended new value of property extended
+ */
+ public bool Extended {
+ set {
+ this.extended = value;
+ }
+ get {
+ return extended;
+ }
+ }
+
+ /** Gets the code to generate.
+ * @return the code to generate
+ */
+ public virtual string Code {
+ get {
+ return code;
+ }
+
+ set {
+ this.code = value;
+ }
+ }
+
+ /** Sets the property to show the guard bars for barcode EAN.
+ * @param guardBars new value of property guardBars
+ */
+ public bool GuardBars {
+ set {
+ this.guardBars = value;
+ }
+ get {
+ return guardBars;
+ }
+ }
+
+ /** Gets the code type.
+ * @return the code type
+ */
+ public int CodeType {
+ get {
+ return codeType;
+ }
+
+ set {
+ this.codeType = value;
+ }
+ }
+
+ /** Gets the maximum area that the barcode and the text, if
+ * any, will occupy. The lower left corner is always (0, 0).
+ * @return the size the barcode occupies.
+ */
+ public abstract Rectangle BarcodeSize {
+ get;
+ }
+
+ public float InkSpreading {
+ set {
+ inkSpreading = value;
+ }
+ get {
+ return inkSpreading;
+ }
+ }
+
+ /** Places the barcode in a PdfContentByte
. The
+ * barcode is always placed at coodinates (0, 0). Use the
+ * translation matrix to move it elsewhere.
+ *
+ * @param cb the
+ *
+ *
+ * barColor
+ * textColor
+ *
+ *
+ *
+ * null
+ * null
+ *
+ *
+ *
+ * barColor
+ * null
+ * barColor
+ *
+ *
+ * null
+ * textColor
+ *
text painted with textColor
+ *
+ *
+ * barColor
+ * textColor
+ * barColor
text painted with textColor
PdfContentByte
where the barcode will be placed
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the dimensions the barcode occupies
+ */
+ public abstract Rectangle PlaceBarcode(PdfContentByte cb, Color barColor, Color textColor);
+
+ /** Creates a template with the barcode.
+ * @param cb the PdfContentByte
to create the template. It
+ * serves no other use
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the template
+ * @see #placeBarcode(PdfContentByte cb, Color barColor, Color textColor)
+ */
+ public PdfTemplate CreateTemplateWithBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ PdfTemplate tp = cb.CreateTemplate(0, 0);
+ Rectangle rect = PlaceBarcode(tp, barColor, textColor);
+ tp.BoundingBox = rect;
+ return tp;
+ }
+
+ /** Creates an Image
with the barcode.
+ * @param cb the PdfContentByte
to create the Image
. It
+ * serves no other use
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the Image
+ * @see #placeBarcode(PdfContentByte cb, Color barColor, Color textColor)
+ */
+ public Image CreateImageWithBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ return Image.GetInstance(CreateTemplateWithBarcode(cb, barColor, textColor));
+ }
+
+ /**
+ * The alternate text to be used, if present.
+ */
+ protected String altText;
+
+ /**
+ * Sets the alternate text. If present, this text will be used instead of the
+ * text derived from the supplied code.
+ * @param altText the alternate text
+ */
+ public String AltText {
+ set {
+ altText = value;
+ }
+ get {
+ return altText;
+ }
+ }
+
+ public abstract System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background);
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/Barcode128.cs b/iTechSharp/iTextSharp/text/pdf/Barcode128.cs
new file mode 100644
index 0000000..96c4807
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/Barcode128.cs
@@ -0,0 +1,809 @@
+using System;
+using System.Text;
+using iTextSharp.text;
+/*
+ * $Id: Barcode128.cs,v 1.6 2007/10/24 16:31:54 psoares33 Exp $
+ *
+ * Copyright 2002-2006 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /** Implements the code 128 and UCC/EAN-128. Other symbologies are allowed in raw mode.
+ *
+ *
+ * The default parameters are:
+ *
+ * x = 0.8f;
+ * font = BaseFont.CreateFont("Helvetica", "winansi", false);
+ * size = 8;
+ * baseline = size;
+ * barHeight = size * 3;
+ * textint= Element.ALIGN_CENTER;
+ * codeType = CODE128;
+ *
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class Barcode128 : Barcode {
+
+ /** The bars to generate the code.
+ */
+ private static readonly byte[][] BARS =
+ {
+ new byte[] {2, 1, 2, 2, 2, 2},
+ new byte[] {2, 2, 2, 1, 2, 2},
+ new byte[] {2, 2, 2, 2, 2, 1},
+ new byte[] {1, 2, 1, 2, 2, 3},
+ new byte[] {1, 2, 1, 3, 2, 2},
+ new byte[] {1, 3, 1, 2, 2, 2},
+ new byte[] {1, 2, 2, 2, 1, 3},
+ new byte[] {1, 2, 2, 3, 1, 2},
+ new byte[] {1, 3, 2, 2, 1, 2},
+ new byte[] {2, 2, 1, 2, 1, 3},
+ new byte[] {2, 2, 1, 3, 1, 2},
+ new byte[] {2, 3, 1, 2, 1, 2},
+ new byte[] {1, 1, 2, 2, 3, 2},
+ new byte[] {1, 2, 2, 1, 3, 2},
+ new byte[] {1, 2, 2, 2, 3, 1},
+ new byte[] {1, 1, 3, 2, 2, 2},
+ new byte[] {1, 2, 3, 1, 2, 2},
+ new byte[] {1, 2, 3, 2, 2, 1},
+ new byte[] {2, 2, 3, 2, 1, 1},
+ new byte[] {2, 2, 1, 1, 3, 2},
+ new byte[] {2, 2, 1, 2, 3, 1},
+ new byte[] {2, 1, 3, 2, 1, 2},
+ new byte[] {2, 2, 3, 1, 1, 2},
+ new byte[] {3, 1, 2, 1, 3, 1},
+ new byte[] {3, 1, 1, 2, 2, 2},
+ new byte[] {3, 2, 1, 1, 2, 2},
+ new byte[] {3, 2, 1, 2, 2, 1},
+ new byte[] {3, 1, 2, 2, 1, 2},
+ new byte[] {3, 2, 2, 1, 1, 2},
+ new byte[] {3, 2, 2, 2, 1, 1},
+ new byte[] {2, 1, 2, 1, 2, 3},
+ new byte[] {2, 1, 2, 3, 2, 1},
+ new byte[] {2, 3, 2, 1, 2, 1},
+ new byte[] {1, 1, 1, 3, 2, 3},
+ new byte[] {1, 3, 1, 1, 2, 3},
+ new byte[] {1, 3, 1, 3, 2, 1},
+ new byte[] {1, 1, 2, 3, 1, 3},
+ new byte[] {1, 3, 2, 1, 1, 3},
+ new byte[] {1, 3, 2, 3, 1, 1},
+ new byte[] {2, 1, 1, 3, 1, 3},
+ new byte[] {2, 3, 1, 1, 1, 3},
+ new byte[] {2, 3, 1, 3, 1, 1},
+ new byte[] {1, 1, 2, 1, 3, 3},
+ new byte[] {1, 1, 2, 3, 3, 1},
+ new byte[] {1, 3, 2, 1, 3, 1},
+ new byte[] {1, 1, 3, 1, 2, 3},
+ new byte[] {1, 1, 3, 3, 2, 1},
+ new byte[] {1, 3, 3, 1, 2, 1},
+ new byte[] {3, 1, 3, 1, 2, 1},
+ new byte[] {2, 1, 1, 3, 3, 1},
+ new byte[] {2, 3, 1, 1, 3, 1},
+ new byte[] {2, 1, 3, 1, 1, 3},
+ new byte[] {2, 1, 3, 3, 1, 1},
+ new byte[] {2, 1, 3, 1, 3, 1},
+ new byte[] {3, 1, 1, 1, 2, 3},
+ new byte[] {3, 1, 1, 3, 2, 1},
+ new byte[] {3, 3, 1, 1, 2, 1},
+ new byte[] {3, 1, 2, 1, 1, 3},
+ new byte[] {3, 1, 2, 3, 1, 1},
+ new byte[] {3, 3, 2, 1, 1, 1},
+ new byte[] {3, 1, 4, 1, 1, 1},
+ new byte[] {2, 2, 1, 4, 1, 1},
+ new byte[] {4, 3, 1, 1, 1, 1},
+ new byte[] {1, 1, 1, 2, 2, 4},
+ new byte[] {1, 1, 1, 4, 2, 2},
+ new byte[] {1, 2, 1, 1, 2, 4},
+ new byte[] {1, 2, 1, 4, 2, 1},
+ new byte[] {1, 4, 1, 1, 2, 2},
+ new byte[] {1, 4, 1, 2, 2, 1},
+ new byte[] {1, 1, 2, 2, 1, 4},
+ new byte[] {1, 1, 2, 4, 1, 2},
+ new byte[] {1, 2, 2, 1, 1, 4},
+ new byte[] {1, 2, 2, 4, 1, 1},
+ new byte[] {1, 4, 2, 1, 1, 2},
+ new byte[] {1, 4, 2, 2, 1, 1},
+ new byte[] {2, 4, 1, 2, 1, 1},
+ new byte[] {2, 2, 1, 1, 1, 4},
+ new byte[] {4, 1, 3, 1, 1, 1},
+ new byte[] {2, 4, 1, 1, 1, 2},
+ new byte[] {1, 3, 4, 1, 1, 1},
+ new byte[] {1, 1, 1, 2, 4, 2},
+ new byte[] {1, 2, 1, 1, 4, 2},
+ new byte[] {1, 2, 1, 2, 4, 1},
+ new byte[] {1, 1, 4, 2, 1, 2},
+ new byte[] {1, 2, 4, 1, 1, 2},
+ new byte[] {1, 2, 4, 2, 1, 1},
+ new byte[] {4, 1, 1, 2, 1, 2},
+ new byte[] {4, 2, 1, 1, 1, 2},
+ new byte[] {4, 2, 1, 2, 1, 1},
+ new byte[] {2, 1, 2, 1, 4, 1},
+ new byte[] {2, 1, 4, 1, 2, 1},
+ new byte[] {4, 1, 2, 1, 2, 1},
+ new byte[] {1, 1, 1, 1, 4, 3},
+ new byte[] {1, 1, 1, 3, 4, 1},
+ new byte[] {1, 3, 1, 1, 4, 1},
+ new byte[] {1, 1, 4, 1, 1, 3},
+ new byte[] {1, 1, 4, 3, 1, 1},
+ new byte[] {4, 1, 1, 1, 1, 3},
+ new byte[] {4, 1, 1, 3, 1, 1},
+ new byte[] {1, 1, 3, 1, 4, 1},
+ new byte[] {1, 1, 4, 1, 3, 1},
+ new byte[] {3, 1, 1, 1, 4, 1},
+ new byte[] {4, 1, 1, 1, 3, 1},
+ new byte[] {2, 1, 1, 4, 1, 2},
+ new byte[] {2, 1, 1, 2, 1, 4},
+ new byte[] {2, 1, 1, 2, 3, 2}
+ };
+
+ /** The stop bars.
+ */
+ private static readonly byte[] BARS_STOP = {2, 3, 3, 1, 1, 1, 2};
+ /** The charset code change.
+ */
+ public const char CODE_AB_TO_C = (char)99;
+ /** The charset code change.
+ */
+ public const char CODE_AC_TO_B = (char)100;
+ /** The charset code change.
+ */
+ public const char CODE_BC_TO_A = (char)101;
+ /** The code for UCC/EAN-128.
+ */
+ public const char FNC1_INDEX = (char)102;
+ /** The start code.
+ */
+ public const char START_A = (char)103;
+ /** The start code.
+ */
+ public const char START_B = (char)104;
+ /** The start code.
+ */
+ public const char START_C = (char)105;
+
+ public const char FNC1 = '\u00ca';
+ public const char DEL = '\u00c3';
+ public const char FNC3 = '\u00c4';
+ public const char FNC2 = '\u00c5';
+ public const char SHIFT = '\u00c6';
+ public const char CODE_C = '\u00c7';
+ public const char CODE_A = '\u00c8';
+ public const char FNC4 = '\u00c8';
+ public const char STARTA = '\u00cb';
+ public const char STARTB = '\u00cc';
+ public const char STARTC = '\u00cd';
+
+ private static IntHashtable ais = new IntHashtable();
+
+ /** Creates new Barcode128 */
+ public Barcode128() {
+ x = 0.8f;
+ font = BaseFont.CreateFont("Helvetica", "winansi", false);
+ size = 8;
+ baseline = size;
+ barHeight = size * 3;
+ textAlignment = Element.ALIGN_CENTER;
+ codeType = CODE128;
+ }
+
+ /**
+ * Removes the FNC1 codes in the text.
+ * @param code the text to clean
+ * @return the cleaned text
+ */
+ public static String RemoveFNC1(String code) {
+ int len = code.Length;
+ StringBuilder buf = new StringBuilder(len);
+ for (int k = 0; k < len; ++k) {
+ char c = code[k];
+ if (c >= 32 && c <= 126)
+ buf.Append(c);
+ }
+ return buf.ToString();
+ }
+
+ /**
+ * Gets the human readable text of a sequence of AI.
+ * @param code the text
+ * @return the human readable text
+ */
+ public static String GetHumanReadableUCCEAN(String code) {
+ StringBuilder buf = new StringBuilder();
+ String fnc1 = FNC1.ToString();
+ try {
+ while (true) {
+ if (code.StartsWith(fnc1)) {
+ code = code.Substring(1);
+ continue;
+ }
+ int n = 0;
+ int idlen = 0;
+ for (int k = 2; k < 5; ++k) {
+ if (code.Length < k)
+ break;
+ if ((n = ais[int.Parse(code.Substring(0, k))]) != 0) {
+ idlen = k;
+ break;
+ }
+ }
+ if (idlen == 0)
+ break;
+ buf.Append('(').Append(code.Substring(0, idlen)).Append(')');
+ code = code.Substring(idlen);
+ if (n > 0) {
+ n -= idlen;
+ if (code.Length <= n)
+ break;
+ buf.Append(RemoveFNC1(code.Substring(0, n)));
+ code = code.Substring(n);
+ }
+ else {
+ int idx = code.IndexOf(FNC1);
+ if (idx < 0)
+ break;
+ buf.Append(code.Substring(0,idx));
+ code = code.Substring(idx + 1);
+ }
+ }
+ }
+ catch {
+ //empty
+ }
+ buf.Append(RemoveFNC1(code));
+ return buf.ToString();
+ }
+
+ /** Returns true
if the next numDigits
+ * starting from index textIndex
are numeric skipping any FNC1.
+ * @param text the text to check
+ * @param textIndex where to check from
+ * @param numDigits the number of digits to check
+ * @return the check result
+ */
+ internal static bool IsNextDigits(string text, int textIndex, int numDigits) {
+ int len = text.Length;
+ while (textIndex < len && numDigits > 0) {
+ if (text[textIndex] == FNC1) {
+ ++textIndex;
+ continue;
+ }
+ int n = Math.Min(2, numDigits);
+ if (textIndex + n > len)
+ return false;
+ while (n-- > 0) {
+ char c = text[textIndex++];
+ if (c < '0' || c > '9')
+ return false;
+ --numDigits;
+ }
+ }
+ return numDigits == 0;
+ }
+
+ /** Packs the digits for charset C also considering FNC1. It assumes that all the parameters
+ * are valid.
+ * @param text the text to pack
+ * @param textIndex where to pack from
+ * @param numDigits the number of digits to pack. It is always an even number
+ * @return the packed digits, two digits per character
+ */
+ internal static String GetPackedRawDigits(String text, int textIndex, int numDigits) {
+ String outs = "";
+ int start = textIndex;
+ while (numDigits > 0) {
+ if (text[textIndex] == FNC1) {
+ outs += FNC1_INDEX;
+ ++textIndex;
+ continue;
+ }
+ numDigits -= 2;
+ int c1 = text[textIndex++] - '0';
+ int c2 = text[textIndex++] - '0';
+ outs += (char)(c1 * 10 + c2);
+ }
+ return (char)(textIndex - start) + outs;
+ }
+
+ /** Converts the human readable text to the characters needed to
+ * create a barcode. Some optimization is done to get the shortest code.
+ * @param text the text to convert
+ * @param ucc true
if it is an UCC/EAN-128. In this case
+ * the character FNC1 is added
+ * @return the code ready to be fed to GetBarsCode128Raw()
+ */
+ public static string GetRawText(string text, bool ucc) {
+ String outs = "";
+ int tLen = text.Length;
+ if (tLen == 0) {
+ outs += START_B;
+ if (ucc)
+ outs += FNC1_INDEX;
+ return outs;
+ }
+ int c = 0;
+ for (int k = 0; k < tLen; ++k) {
+ c = text[k];
+ if (c > 127 && c != FNC1)
+ throw new ArgumentException("There are illegal characters for barcode 128 in '" + text + "'.");
+ }
+ c = text[0];
+ char currentCode = START_B;
+ int index = 0;
+ if (IsNextDigits(text, index, 2)) {
+ currentCode = START_C;
+ outs += currentCode;
+ if (ucc)
+ outs += FNC1_INDEX;
+ String out2 = GetPackedRawDigits(text, index, 2);
+ index += (int)out2[0];
+ outs += out2.Substring(1);
+ }
+ else if (c < ' ') {
+ currentCode = START_A;
+ outs += currentCode;
+ if (ucc)
+ outs += FNC1_INDEX;
+ outs += (char)(c + 64);
+ ++index;
+ }
+ else {
+ outs += currentCode;
+ if (ucc)
+ outs += FNC1_INDEX;
+ if (c == FNC1)
+ outs += FNC1_INDEX;
+ else
+ outs += (char)(c - ' ');
+ ++index;
+ }
+ while (index < tLen) {
+ switch (currentCode) {
+ case START_A:
+ {
+ if (IsNextDigits(text, index, 4)) {
+ currentCode = START_C;
+ outs += CODE_AB_TO_C;
+ String out2 = GetPackedRawDigits(text, index, 4);
+ index += (int)out2[0];
+ outs += out2.Substring(1);
+ }
+ else {
+ c = text[index++];
+ if (c == FNC1)
+ outs += FNC1_INDEX;
+ else if (c > '_') {
+ currentCode = START_B;
+ outs += CODE_AC_TO_B;
+ outs += (char)(c - ' ');
+ }
+ else if (c < ' ')
+ outs += (char)(c + 64);
+ else
+ outs += (char)(c - ' ');
+ }
+ }
+ break;
+ case START_B:
+ {
+ if (IsNextDigits(text, index, 4)) {
+ currentCode = START_C;
+ outs += CODE_AB_TO_C;
+ String out2 = GetPackedRawDigits(text, index, 4);
+ index += (int)out2[0];
+ outs += out2.Substring(1);
+ }
+ else {
+ c = text[index++];
+ if (c == FNC1)
+ outs += FNC1_INDEX;
+ else if (c < ' ') {
+ currentCode = START_A;
+ outs += CODE_BC_TO_A;
+ outs += (char)(c + 64);
+ }
+ else {
+ outs += (char)(c - ' ');
+ }
+ }
+ }
+ break;
+ case START_C:
+ {
+ if (IsNextDigits(text, index, 2)) {
+ String out2 = GetPackedRawDigits(text, index, 2);
+ index += (int)out2[0];
+ outs += out2.Substring(1);
+ }
+ else {
+ c = text[index++];
+ if (c == FNC1)
+ outs += FNC1_INDEX;
+ else if (c < ' ') {
+ currentCode = START_A;
+ outs += CODE_BC_TO_A;
+ outs += (char)(c + 64);
+ }
+ else {
+ currentCode = START_B;
+ outs += CODE_AC_TO_B;
+ outs += (char)(c - ' ');
+ }
+ }
+ }
+ break;
+ }
+ }
+ return outs;
+ }
+
+ /** Generates the bars. The input has the actual barcodes, not
+ * the human readable text.
+ * @param text the barcode
+ * @return the bars
+ */
+ public static byte[] GetBarsCode128Raw(string text) {
+ int k;
+ int idx = text.IndexOf('\uffff');
+ if (idx >= 0)
+ text = text.Substring(0, idx);
+ int chk = text[0];
+ for (k = 1; k < text.Length; ++k)
+ chk += k * text[k];
+ chk = chk % 103;
+ text += (char)chk;
+ byte[] bars = new byte[(text.Length + 1) * 6 + 7];
+ for (k = 0; k < text.Length; ++k)
+ Array.Copy(BARS[text[k]], 0, bars, k * 6, 6);
+ Array.Copy(BARS_STOP, 0, bars, k * 6, 7);
+ return bars;
+ }
+
+ /** Gets the maximum area that the barcode and the text, if
+ * any, will occupy. The lower left corner is always (0, 0).
+ * @return the size the barcode occupies.
+ */
+ public override Rectangle BarcodeSize {
+ get {
+ float fontX = 0;
+ float fontY = 0;
+ string fullCode;
+ if (font != null) {
+ if (baseline > 0)
+ fontY = baseline - font.GetFontDescriptor(BaseFont.DESCENT, size);
+ else
+ fontY = -baseline + size;
+ if (codeType == CODE128_RAW) {
+ int idx = code.IndexOf('\uffff');
+ if (idx < 0)
+ fullCode = "";
+ else
+ fullCode = code.Substring(idx + 1);
+ }
+ else if (codeType == CODE128_UCC)
+ fullCode = GetHumanReadableUCCEAN(code);
+ else
+ fullCode = RemoveFNC1(code);
+ fontX = font.GetWidthPoint(altText != null ? altText : fullCode, size);
+ }
+ if (codeType == CODE128_RAW) {
+ int idx = code.IndexOf('\uffff');
+ if (idx >= 0)
+ fullCode = code.Substring(0, idx);
+ else
+ fullCode = code;
+ }
+ else {
+ fullCode = GetRawText(code, codeType == CODE128_UCC);
+ }
+ int len = fullCode.Length;
+ float fullWidth = (len + 2) * 11 * x + 2 * x;
+ fullWidth = Math.Max(fullWidth, fontX);
+ float fullHeight = barHeight + fontY;
+ return new Rectangle(fullWidth, fullHeight);
+ }
+ }
+
+ /** Places the barcode in a PdfContentByte
. The
+ * barcode is always placed at coodinates (0, 0). Use the
+ * translation matrix to move it elsewhere.
+ *
+ * @param cb the
+ *
+ *
+ * barColor
+ * textColor
+ *
+ *
+ *
+ * null
+ * null
+ *
+ *
+ *
+ * barColor
+ * null
+ * barColor
+ *
+ *
+ * null
+ * textColor
+ *
text painted with textColor
+ *
+ *
+ * barColor
+ * textColor
+ * barColor
text painted with textColor
PdfContentByte
where the barcode will be placed
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the dimensions the barcode occupies
+ */
+ public override Rectangle PlaceBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ string fullCode;
+ if (codeType == CODE128_RAW) {
+ int idx = code.IndexOf('\uffff');
+ if (idx < 0)
+ fullCode = "";
+ else
+ fullCode = code.Substring(idx + 1);
+ }
+ else if (codeType == CODE128_UCC)
+ fullCode = GetHumanReadableUCCEAN(code);
+ else
+ fullCode = RemoveFNC1(code);
+ float fontX = 0;
+ if (font != null) {
+ fontX = font.GetWidthPoint(fullCode = altText != null ? altText : fullCode, size);
+ }
+ string bCode;
+ if (codeType == CODE128_RAW) {
+ int idx = code.IndexOf('\uffff');
+ if (idx >= 0)
+ bCode = code.Substring(0, idx);
+ else
+ bCode = code;
+ }
+ else {
+ bCode = GetRawText(code, codeType == CODE128_UCC);
+ }
+ int len = bCode.Length;
+ float fullWidth = (len + 2) * 11 * x + 2 * x;
+ float barStartX = 0;
+ float textStartX = 0;
+ switch (textAlignment) {
+ case Element.ALIGN_LEFT:
+ break;
+ case Element.ALIGN_RIGHT:
+ if (fontX > fullWidth)
+ barStartX = fontX - fullWidth;
+ else
+ textStartX = fullWidth - fontX;
+ break;
+ default:
+ if (fontX > fullWidth)
+ barStartX = (fontX - fullWidth) / 2;
+ else
+ textStartX = (fullWidth - fontX) / 2;
+ break;
+ }
+ float barStartY = 0;
+ float textStartY = 0;
+ if (font != null) {
+ if (baseline <= 0)
+ textStartY = barHeight - baseline;
+ else {
+ textStartY = -font.GetFontDescriptor(BaseFont.DESCENT, size);
+ barStartY = textStartY + baseline;
+ }
+ }
+ byte[] bars = GetBarsCode128Raw(bCode);
+ bool print = true;
+ if (barColor != null)
+ cb.SetColorFill(barColor);
+ for (int k = 0; k < bars.Length; ++k) {
+ float w = bars[k] * x;
+ if (print)
+ cb.Rectangle(barStartX, barStartY, w - inkSpreading, barHeight);
+ print = !print;
+ barStartX += w;
+ }
+ cb.Fill();
+ if (font != null) {
+ if (textColor != null)
+ cb.SetColorFill(textColor);
+ cb.BeginText();
+ cb.SetFontAndSize(font, size);
+ cb.SetTextMatrix(textStartX, textStartY);
+ cb.ShowText(fullCode);
+ cb.EndText();
+ }
+ return this.BarcodeSize;
+ }
+
+ public override System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) {
+ String bCode;
+ if (codeType == CODE128_RAW) {
+ int idx = code.IndexOf('\uffff');
+ if (idx >= 0)
+ bCode = code.Substring(0, idx);
+ else
+ bCode = code;
+ }
+ else {
+ bCode = GetRawText(code, codeType == CODE128_UCC);
+ }
+ int len = bCode.Length;
+ int fullWidth = (len + 2) * 11 + 2;
+ byte[] bars = GetBarsCode128Raw(bCode);
+ int height = (int)barHeight;
+ System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(fullWidth, height);
+ for (int h = 0; h < height; ++h) {
+ bool print = true;
+ int ptr = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ int w = bars[k];
+ System.Drawing.Color c = background;
+ if (print)
+ c = foreground;
+ print = !print;
+ for (int j = 0; j < w; ++j)
+ bmp.SetPixel(ptr++, h, c);
+ }
+ }
+ return bmp;
+ }
+
+ /**
+ * Sets the code to generate. If it's an UCC code and starts with '(' it will
+ * be split by the AI. This code in UCC mode is valid:
+ * (01)00000090311314(10)ABC123(15)060916
+ * @param code the code to generate
+ */
+ public override string Code {
+ set {
+ string code = value;
+ if (CodeType == Barcode128.CODE128_UCC && code.StartsWith("(")) {
+ int idx = 0;
+ String ret = "";
+ while (idx >= 0) {
+ int end = code.IndexOf(')', idx);
+ if (end < 0)
+ throw new ArgumentException("Badly formed UCC string: " + code);
+ String sai = code.Substring(idx + 1, end - (idx + 1));
+ if (sai.Length < 2)
+ throw new ArgumentException("AI too short: (" + sai + ")");
+ int ai = int.Parse(sai);
+ int len = ais[ai];
+ if (len == 0)
+ throw new ArgumentException("AI not found: (" + sai + ")");
+ sai = ai.ToString();
+ if (sai.Length == 1)
+ sai = "0" + sai;
+ idx = code.IndexOf('(', end);
+ int next = (idx < 0 ? code.Length : idx);
+ ret += sai + code.Substring(end + 1, next - (end + 1));
+ if (len < 0) {
+ if (idx >= 0)
+ ret += FNC1;
+ }
+ else if (next - end - 1 + sai.Length != len)
+ throw new ArgumentException("Invalid AI length: (" + sai + ")");
+ }
+ base.Code = ret;
+ }
+ else
+ base.Code = code;
+ }
+ }
+
+ static Barcode128 () {
+ ais[0] = 20;
+ ais[1] = 16;
+ ais[2] = 16;
+ ais[10] = -1;
+ ais[11] = 9;
+ ais[12] = 8;
+ ais[13] = 8;
+ ais[15] = 8;
+ ais[17] = 8;
+ ais[20] = 4;
+ ais[21] = -1;
+ ais[22] = -1;
+ ais[23] = -1;
+ ais[240] = -1;
+ ais[241] = -1;
+ ais[250] = -1;
+ ais[251] = -1;
+ ais[252] = -1;
+ ais[30] = -1;
+ for (int k = 3100; k < 3700; ++k)
+ ais[k] = 10;
+ ais[37] = -1;
+ for (int k = 3900; k < 3940; ++k)
+ ais[k] = -1;
+ ais[400] = -1;
+ ais[401] = -1;
+ ais[402] = 20;
+ ais[403] = -1;
+ for (int k = 410; k < 416; ++k)
+ ais[k] = 16;
+ ais[420] = -1;
+ ais[421] = -1;
+ ais[422] = 6;
+ ais[423] = -1;
+ ais[424] = 6;
+ ais[425] = 6;
+ ais[426] = 6;
+ ais[7001] = 17;
+ ais[7002] = -1;
+ for (int k = 7030; k < 7040; ++k)
+ ais[k] = -1;
+ ais[8001] = 18;
+ ais[8002] = -1;
+ ais[8003] = -1;
+ ais[8004] = -1;
+ ais[8005] = 10;
+ ais[8006] = 22;
+ ais[8007] = -1;
+ ais[8008] = -1;
+ ais[8018] = 22;
+ ais[8020] = -1;
+ ais[8100] = 10;
+ ais[8101] = 14;
+ ais[8102] = 6;
+ for (int k = 90; k < 100; ++k)
+ ais[k] = -1;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/Barcode39.cs b/iTechSharp/iTextSharp/text/pdf/Barcode39.cs
new file mode 100644
index 0000000..f93dea7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/Barcode39.cs
@@ -0,0 +1,370 @@
+using System;
+using iTextSharp.text;
+/*
+ * $Id: Barcode39.cs,v 1.6 2007/05/03 19:36:07 psoares33 Exp $
+ *
+ * Copyright 2002-2006 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /** Implements the code 39 and code 39 extended. The default parameters are:
+ *
+ *x = 0.8f;
+ *n = 2;
+ *font = BaseFont.CreateFont("Helvetica", "winansi", false);
+ *size = 8;
+ *baseline = size;
+ *barHeight = size * 3;
+ *textint= Element.ALIGN_CENTER;
+ *generateChecksum = false;
+ *checksumText = false;
+ *startStopText = true;
+ *extended = false;
+ *
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class Barcode39 : Barcode {
+
+ /** The bars to generate the code.
+ */
+ private static readonly byte[][] BARS =
+ {
+ new byte[] {0,0,0,1,1,0,1,0,0},
+ new byte[] {1,0,0,1,0,0,0,0,1},
+ new byte[] {0,0,1,1,0,0,0,0,1},
+ new byte[] {1,0,1,1,0,0,0,0,0},
+ new byte[] {0,0,0,1,1,0,0,0,1},
+ new byte[] {1,0,0,1,1,0,0,0,0},
+ new byte[] {0,0,1,1,1,0,0,0,0},
+ new byte[] {0,0,0,1,0,0,1,0,1},
+ new byte[] {1,0,0,1,0,0,1,0,0},
+ new byte[] {0,0,1,1,0,0,1,0,0},
+ new byte[] {1,0,0,0,0,1,0,0,1},
+ new byte[] {0,0,1,0,0,1,0,0,1},
+ new byte[] {1,0,1,0,0,1,0,0,0},
+ new byte[] {0,0,0,0,1,1,0,0,1},
+ new byte[] {1,0,0,0,1,1,0,0,0},
+ new byte[] {0,0,1,0,1,1,0,0,0},
+ new byte[] {0,0,0,0,0,1,1,0,1},
+ new byte[] {1,0,0,0,0,1,1,0,0},
+ new byte[] {0,0,1,0,0,1,1,0,0},
+ new byte[] {0,0,0,0,1,1,1,0,0},
+ new byte[] {1,0,0,0,0,0,0,1,1},
+ new byte[] {0,0,1,0,0,0,0,1,1},
+ new byte[] {1,0,1,0,0,0,0,1,0},
+ new byte[] {0,0,0,0,1,0,0,1,1},
+ new byte[] {1,0,0,0,1,0,0,1,0},
+ new byte[] {0,0,1,0,1,0,0,1,0},
+ new byte[] {0,0,0,0,0,0,1,1,1},
+ new byte[] {1,0,0,0,0,0,1,1,0},
+ new byte[] {0,0,1,0,0,0,1,1,0},
+ new byte[] {0,0,0,0,1,0,1,1,0},
+ new byte[] {1,1,0,0,0,0,0,0,1},
+ new byte[] {0,1,1,0,0,0,0,0,1},
+ new byte[] {1,1,1,0,0,0,0,0,0},
+ new byte[] {0,1,0,0,1,0,0,0,1},
+ new byte[] {1,1,0,0,1,0,0,0,0},
+ new byte[] {0,1,1,0,1,0,0,0,0},
+ new byte[] {0,1,0,0,0,0,1,0,1},
+ new byte[] {1,1,0,0,0,0,1,0,0},
+ new byte[] {0,1,1,0,0,0,1,0,0},
+ new byte[] {0,1,0,1,0,1,0,0,0},
+ new byte[] {0,1,0,1,0,0,0,1,0},
+ new byte[] {0,1,0,0,0,1,0,1,0},
+ new byte[] {0,0,0,1,0,1,0,1,0},
+ new byte[] {0,1,0,0,1,0,1,0,0}
+ };
+
+ /** The index chars to BARS
.
+ */
+ private const string CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*";
+
+ /** The character combinations to make the code 39 extended.
+ */
+ private const string EXTENDED = "%U" +
+ "$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$Y$Z" +
+ "%A%B%C%D%E /A/B/C/D/E/F/G/H/I/J/K/L - ./O" +
+ " 0 1 2 3 4 5 6 7 8 9/Z%F%G%H%I%J%V" +
+ " A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" +
+ "%K%L%M%N%O%W" +
+ "+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z" +
+ "%P%Q%R%S%T";
+
+ /** Creates a new Barcode39.
+ */
+ public Barcode39() {
+ x = 0.8f;
+ n = 2;
+ font = BaseFont.CreateFont("Helvetica", "winansi", false);
+ size = 8;
+ baseline = size;
+ barHeight = size * 3;
+ textAlignment = Element.ALIGN_CENTER;
+ generateChecksum = false;
+ checksumText = false;
+ startStopText = true;
+ extended = false;
+ }
+
+ /** Creates the bars.
+ * @param text the text to create the bars. This text does not include the start and
+ * stop characters
+ * @return the bars
+ */
+ public static byte[] GetBarsCode39(string text) {
+ text = "*" + text + "*";
+ byte[] bars = new byte[text.Length * 10 - 1];
+ for (int k = 0; k < text.Length; ++k) {
+ int idx = CHARS.IndexOf(text[k]);
+ if (idx < 0)
+ throw new ArgumentException("The character '" + text[k] + "' is illegal in code 39.");
+ Array.Copy(BARS[idx], 0, bars, k * 10, 9);
+ }
+ return bars;
+ }
+
+ /** Converts the extended text into a normal, escaped text,
+ * ready to generate bars.
+ * @param text the extended text
+ * @return the escaped text
+ */
+ public static string GetCode39Ex(string text) {
+ string ret = "";
+ for (int k = 0; k < text.Length; ++k) {
+ char c = text[k];
+ if (c > 127)
+ throw new ArgumentException("The character '" + c + "' is illegal in code 39 extended.");
+ char c1 = EXTENDED[c * 2];
+ char c2 = EXTENDED[c * 2 + 1];
+ if (c1 != ' ')
+ ret += c1;
+ ret += c2;
+ }
+ return ret;
+ }
+
+ /** Calculates the checksum.
+ * @param text the text
+ * @return the checksum
+ */
+ internal static char GetChecksum(string text) {
+ int chk = 0;
+ for (int k = 0; k < text.Length; ++k) {
+ int idx = CHARS.IndexOf(text[k]);
+ if (idx < 0)
+ throw new ArgumentException("The character '" + text[k] + "' is illegal in code 39.");
+ chk += idx;
+ }
+ return CHARS[chk % 43];
+ }
+
+ /** Gets the maximum area that the barcode and the text, if
+ * any, will occupy. The lower left corner is always (0, 0).
+ * @return the size the barcode occupies.
+ */
+ public override Rectangle BarcodeSize {
+ get {
+ float fontX = 0;
+ float fontY = 0;
+ string fCode = code;
+ if (extended)
+ fCode = GetCode39Ex(code);
+ if (font != null) {
+ if (baseline > 0)
+ fontY = baseline - font.GetFontDescriptor(BaseFont.DESCENT, size);
+ else
+ fontY = -baseline + size;
+ string fullCode = code;
+ if (generateChecksum && checksumText)
+ fullCode += GetChecksum(fCode);
+ if (startStopText)
+ fullCode = "*" + fullCode + "*";
+ fontX = font.GetWidthPoint(altText != null ? altText : fullCode, size);
+ }
+ int len = fCode.Length + 2;
+ if (generateChecksum)
+ ++len;
+ float fullWidth = len * (6 * x + 3 * x * n) + (len - 1) * x;
+ fullWidth = Math.Max(fullWidth, fontX);
+ float fullHeight = barHeight + fontY;
+ return new Rectangle(fullWidth, fullHeight);
+ }
+ }
+
+ /** Places the barcode in a PdfContentByte
. The
+ * barcode is always placed at coodinates (0, 0). Use the
+ * translation matrix to move it elsewhere.
+ *
+ * @param cb the
+ *
+ *
+ * barColor
+ * textColor
+ *
+ *
+ *
+ * null
+ * null
+ *
+ *
+ *
+ * barColor
+ * null
+ * barColor
+ *
+ *
+ * null
+ * textColor
+ *
text painted with textColor
+ *
+ *
+ * barColor
+ * textColor
+ * barColor
text painted with textColor
PdfContentByte
where the barcode will be placed
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the dimensions the barcode occupies
+ */
+ public override Rectangle PlaceBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ string fullCode = code;
+ float fontX = 0;
+ string bCode = code;
+ if (extended)
+ bCode = GetCode39Ex(code);
+ if (font != null) {
+ if (generateChecksum && checksumText)
+ fullCode += GetChecksum(bCode);
+ if (startStopText)
+ fullCode = "*" + fullCode + "*";
+ fontX = font.GetWidthPoint(fullCode = altText != null ? altText : fullCode, size);
+ }
+ if (generateChecksum)
+ bCode += GetChecksum(bCode);
+ int len = bCode.Length + 2;
+ float fullWidth = len * (6 * x + 3 * x * n) + (len - 1) * x;
+ float barStartX = 0;
+ float textStartX = 0;
+ switch (textAlignment) {
+ case Element.ALIGN_LEFT:
+ break;
+ case Element.ALIGN_RIGHT:
+ if (fontX > fullWidth)
+ barStartX = fontX - fullWidth;
+ else
+ textStartX = fullWidth - fontX;
+ break;
+ default:
+ if (fontX > fullWidth)
+ barStartX = (fontX - fullWidth) / 2;
+ else
+ textStartX = (fullWidth - fontX) / 2;
+ break;
+ }
+ float barStartY = 0;
+ float textStartY = 0;
+ if (font != null) {
+ if (baseline <= 0)
+ textStartY = barHeight - baseline;
+ else {
+ textStartY = -font.GetFontDescriptor(BaseFont.DESCENT, size);
+ barStartY = textStartY + baseline;
+ }
+ }
+ byte[] bars = GetBarsCode39(bCode);
+ bool print = true;
+ if (barColor != null)
+ cb.SetColorFill(barColor);
+ for (int k = 0; k < bars.Length; ++k) {
+ float w = (bars[k] == 0 ? x : x * n);
+ if (print)
+ cb.Rectangle(barStartX, barStartY, w - inkSpreading, barHeight);
+ print = !print;
+ barStartX += w;
+ }
+ cb.Fill();
+ if (font != null) {
+ if (textColor != null)
+ cb.SetColorFill(textColor);
+ cb.BeginText();
+ cb.SetFontAndSize(font, size);
+ cb.SetTextMatrix(textStartX, textStartY);
+ cb.ShowText(fullCode);
+ cb.EndText();
+ }
+ return this.BarcodeSize;
+ }
+
+ public override System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) {
+ String bCode = code;
+ if (extended)
+ bCode = GetCode39Ex(code);
+ if (generateChecksum)
+ bCode += GetChecksum(bCode);
+ int len = bCode.Length + 2;
+ int nn = (int)n;
+ int fullWidth = len * (6 + 3 * nn) + (len - 1);
+ int height = (int)barHeight;
+ System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(fullWidth, height);
+ byte[] bars = GetBarsCode39(bCode);
+ for (int h = 0; h < height; ++h) {
+ bool print = true;
+ int ptr = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ int w = (bars[k] == 0 ? 1 : nn);
+ System.Drawing.Color c = background;
+ if (print)
+ c = foreground;
+ print = !print;
+ for (int j = 0; j < w; ++j)
+ bmp.SetPixel(ptr++, h, c);
+ }
+ }
+ return bmp;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BarcodeCodabar.cs b/iTechSharp/iTextSharp/text/pdf/BarcodeCodabar.cs
new file mode 100644
index 0000000..d80ab49
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BarcodeCodabar.cs
@@ -0,0 +1,324 @@
+using System;
+using iTextSharp.text;
+/*
+ * $Id: BarcodeCodabar.cs,v 1.7 2007/02/22 20:48:38 psoares33 Exp $
+ *
+ * Copyright 2002-2006 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf
+{
+ /** Implements the code codabar. The default parameters are:
+ *
+ *x = 0.8f;
+ *n = 2;
+ *font = BaseFont.CreateFont("Helvetica", "winansi", false);
+ *size = 8;
+ *baseline = size;
+ *barHeight = size * 3;
+ *textAlignment = Element.ALIGN_CENTER;
+ *generateChecksum = false;
+ *checksumText = false;
+ *startStopText = false;
+ *
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class BarcodeCodabar : Barcode{
+
+ /** The bars to generate the code.
+ */
+ private static readonly byte[][] BARS = new byte[][] {
+ new byte[]{0,0,0,0,0,1,1}, // 0
+ new byte[]{0,0,0,0,1,1,0}, // 1
+ new byte[]{0,0,0,1,0,0,1}, // 2
+ new byte[]{1,1,0,0,0,0,0}, // 3
+ new byte[]{0,0,1,0,0,1,0}, // 4
+ new byte[]{1,0,0,0,0,1,0}, // 5
+ new byte[]{0,1,0,0,0,0,1}, // 6
+ new byte[]{0,1,0,0,1,0,0}, // 7
+ new byte[]{0,1,1,0,0,0,0}, // 8
+ new byte[]{1,0,0,1,0,0,0}, // 9
+ new byte[]{0,0,0,1,1,0,0}, // -
+ new byte[]{0,0,1,1,0,0,0}, // $
+ new byte[]{1,0,0,0,1,0,1}, // :
+ new byte[]{1,0,1,0,0,0,1}, // /
+ new byte[]{1,0,1,0,1,0,0}, // .
+ new byte[]{0,0,1,0,1,0,1}, // +
+ new byte[]{0,0,1,1,0,1,0}, // a
+ new byte[]{0,1,0,1,0,0,1}, // b
+ new byte[]{0,0,0,1,0,1,1}, // c
+ new byte[]{0,0,0,1,1,1,0} // d
+ };
+
+ /** The index chars to BARS
.
+ */
+ private const string CHARS = "0123456789-$:/.+ABCD";
+
+ private const int START_STOP_IDX = 16;
+ /** Creates a new BarcodeCodabar.
+ */
+ public BarcodeCodabar() {
+ x = 0.8f;
+ n = 2;
+ font = BaseFont.CreateFont("Helvetica", "winansi", false);
+ size = 8;
+ baseline = size;
+ barHeight = size * 3;
+ textAlignment = Element.ALIGN_CENTER;
+ generateChecksum = false;
+ checksumText = false;
+ startStopText = false;
+ codeType = CODABAR;
+ }
+
+ /** Creates the bars.
+ * @param text the text to create the bars
+ * @return the bars
+ */
+ public static byte[] GetBarsCodabar(String text) {
+ text = text.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
+ int len = text.Length;
+ if (len < 2)
+ throw new ArgumentException("Codabar must have at least a start and stop character.");
+ if (CHARS.IndexOf(text[0]) < START_STOP_IDX || CHARS.IndexOf(text[len - 1]) < START_STOP_IDX)
+ throw new ArgumentException("Codabar must have one of 'ABCD' as start/stop character.");
+ byte[] bars = new byte[text.Length * 8 - 1];
+ for (int k = 0; k < len; ++k) {
+ int idx = CHARS.IndexOf(text[k]);
+ if (idx >= START_STOP_IDX && k > 0 && k < len - 1)
+ throw new ArgumentException("In codabar, start/stop characters are only allowed at the extremes.");
+ if (idx < 0)
+ throw new ArgumentException("The character '" + text[k] + "' is illegal in codabar.");
+ Array.Copy(BARS[idx], 0, bars, k * 8, 7);
+ }
+ return bars;
+ }
+
+ public static String CalculateChecksum(String code) {
+ if (code.Length < 2)
+ return code;
+ String text = code.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
+ int sum = 0;
+ int len = text.Length;
+ for (int k = 0; k < len; ++k)
+ sum += CHARS.IndexOf(text[k]);
+ sum = (sum + 15) / 16 * 16 - sum;
+ return code.Substring(0, len - 1) + CHARS[sum] + code.Substring(len - 1);
+ }
+
+ /** Gets the maximum area that the barcode and the text, if
+ * any, will occupy. The lower left corner is always (0, 0).
+ * @return the size the barcode occupies.
+ */
+ public override Rectangle BarcodeSize {
+ get {
+ float fontX = 0;
+ float fontY = 0;
+ String text = code;
+ if (generateChecksum && checksumText)
+ text = CalculateChecksum(code);
+ if (!startStopText)
+ text = text.Substring(1, text.Length - 2);
+ if (font != null) {
+ if (baseline > 0)
+ fontY = baseline - font.GetFontDescriptor(BaseFont.DESCENT, size);
+ else
+ fontY = -baseline + size;
+ fontX = font.GetWidthPoint(altText != null ? altText : text, size);
+ }
+ text = code;
+ if (generateChecksum)
+ text = CalculateChecksum(code);
+ byte[] bars = GetBarsCodabar(text);
+ int wide = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ wide += (int)bars[k];
+ }
+ int narrow = bars.Length - wide;
+ float fullWidth = x * (narrow + wide * n);
+ fullWidth = Math.Max(fullWidth, fontX);
+ float fullHeight = barHeight + fontY;
+ return new Rectangle(fullWidth, fullHeight);
+ }
+ }
+
+ /** Places the barcode in a PdfContentByte
. The
+ * barcode is always placed at coodinates (0, 0). Use the
+ * translation matrix to move it elsewhere.
+ *
+ * @param cb the
+ *
+ *
+ * barColor
+ * textColor
+ *
+ *
+ *
+ * null
+ * null
+ *
+ *
+ *
+ * barColor
+ * null
+ * barColor
+ *
+ *
+ * null
+ * textColor
+ *
text painted with textColor
+ *
+ *
+ * barColor
+ * textColor
+ * barColor
text painted with textColor
PdfContentByte
where the barcode will be placed
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the dimensions the barcode occupies
+ */
+ public override Rectangle PlaceBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ String fullCode = code;
+ if (generateChecksum && checksumText)
+ fullCode = CalculateChecksum(code);
+ if (!startStopText)
+ fullCode = fullCode.Substring(1, fullCode.Length - 2);
+ float fontX = 0;
+ if (font != null) {
+ fontX = font.GetWidthPoint(fullCode = altText != null ? altText : fullCode, size);
+ }
+ byte[] bars = GetBarsCodabar(generateChecksum ? CalculateChecksum(code) : code);
+ int wide = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ wide += (int)bars[k];
+ }
+ int narrow = bars.Length - wide;
+ float fullWidth = x * (narrow + wide * n);
+ float barStartX = 0;
+ float textStartX = 0;
+ switch (textAlignment) {
+ case Element.ALIGN_LEFT:
+ break;
+ case Element.ALIGN_RIGHT:
+ if (fontX > fullWidth)
+ barStartX = fontX - fullWidth;
+ else
+ textStartX = fullWidth - fontX;
+ break;
+ default:
+ if (fontX > fullWidth)
+ barStartX = (fontX - fullWidth) / 2;
+ else
+ textStartX = (fullWidth - fontX) / 2;
+ break;
+ }
+ float barStartY = 0;
+ float textStartY = 0;
+ if (font != null) {
+ if (baseline <= 0)
+ textStartY = barHeight - baseline;
+ else {
+ textStartY = -font.GetFontDescriptor(BaseFont.DESCENT, size);
+ barStartY = textStartY + baseline;
+ }
+ }
+ bool print = true;
+ if (barColor != null)
+ cb.SetColorFill(barColor);
+ for (int k = 0; k < bars.Length; ++k) {
+ float w = (bars[k] == 0 ? x : x * n);
+ if (print)
+ cb.Rectangle(barStartX, barStartY, w - inkSpreading, barHeight);
+ print = !print;
+ barStartX += w;
+ }
+ cb.Fill();
+ if (font != null) {
+ if (textColor != null)
+ cb.SetColorFill(textColor);
+ cb.BeginText();
+ cb.SetFontAndSize(font, size);
+ cb.SetTextMatrix(textStartX, textStartY);
+ cb.ShowText(fullCode);
+ cb.EndText();
+ }
+ return BarcodeSize;
+ }
+
+ public override System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) {
+ String fullCode = code;
+ if (generateChecksum && checksumText)
+ fullCode = CalculateChecksum(code);
+ if (!startStopText)
+ fullCode = fullCode.Substring(1, fullCode.Length - 2);
+ byte[] bars = GetBarsCodabar(generateChecksum ? CalculateChecksum(code) : code);
+ int wide = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ wide += (int)bars[k];
+ }
+ int narrow = bars.Length - wide;
+ int fullWidth = narrow + wide * (int)n;
+ int height = (int)barHeight;
+ System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(fullWidth, height);
+ for (int h = 0; h < height; ++h) {
+ bool print = true;
+ int ptr = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ int w = (bars[k] == 0 ? 1 : (int)n);
+ System.Drawing.Color c = background;
+ if (print)
+ c = foreground;
+ print = !print;
+ for (int j = 0; j < w; ++j)
+ bmp.SetPixel(ptr++, h, c);
+ }
+ }
+ return bmp;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BarcodeDatamatrix.cs b/iTechSharp/iTextSharp/text/pdf/BarcodeDatamatrix.cs
new file mode 100644
index 0000000..48e5e1d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BarcodeDatamatrix.cs
@@ -0,0 +1,1265 @@
+using System;
+using iTextSharp.text;
+using iTextSharp.text.pdf.codec;
+using System.Collections;
+/*
+ * $Id: BarcodeDatamatrix.cs,v 1.3 2007/05/21 10:56:38 psoares33 Exp $
+ *
+ * Copyright 2007 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ public class BarcodeDatamatrix {
+ /**
+ * No error.
+ */
+ public const int DM_NO_ERROR = 0;
+ /**
+ * The text is too big for the symbology capabilities.
+ */
+ public const int DM_ERROR_TEXT_TOO_BIG = 1;
+ /**
+ * The dimensions given for the symbol are illegal.
+ */
+ public const int DM_ERROR_INVALID_SQUARE = 3;
+ /**
+ * An error while parsing an extension.
+ */
+ public const int DM_ERROR_EXTENSION = 5;
+
+ /**
+ * The best encodation will be used.
+ */
+ public const int DM_AUTO = 0;
+ /**
+ * ASCII encodation.
+ */
+ public const int DM_ASCII = 1;
+ /**
+ * C40 encodation.
+ */
+ public const int DM_C40 = 2;
+ /**
+ * TEXT encodation.
+ */
+ public const int DM_TEXT = 3;
+ /**
+ * Binary encodation.
+ */
+ public const int DM_B256 = 4;
+ /**
+ * X21 encodation.
+ */
+ public const int DM_X21 = 5;
+ /**
+ * EDIFACT encodation.
+ */
+ public const int DM_EDIFACT = 6;
+ /**
+ * No encodation needed. The bytes provided are already encoded.
+ */
+ public const int DM_RAW = 7;
+
+ /**
+ * Allows extensions to be embedded at the start of the text.
+ */
+ public const int DM_EXTENSION = 32;
+ /**
+ * Doesn't generate the image but returns all the other information.
+ */
+ public const int DM_TEST = 64;
+
+ private static readonly DmParams[] dmSizes = {
+ new DmParams(10, 10, 10, 10, 3, 3, 5),
+ new DmParams(12, 12, 12, 12, 5, 5, 7),
+ new DmParams(8, 18, 8, 18, 5, 5, 7),
+ new DmParams(14, 14, 14, 14, 8, 8, 10),
+ new DmParams(8, 32, 8, 16, 10, 10, 11),
+ new DmParams(16, 16, 16, 16, 12, 12, 12),
+ new DmParams(12, 26, 12, 26, 16, 16, 14),
+ new DmParams(18, 18, 18, 18, 18, 18, 14),
+ new DmParams(20, 20, 20, 20, 22, 22, 18),
+ new DmParams(12, 36, 12, 18, 22, 22, 18),
+ new DmParams(22, 22, 22, 22, 30, 30, 20),
+ new DmParams(16, 36, 16, 18, 32, 32, 24),
+ new DmParams(24, 24, 24, 24, 36, 36, 24),
+ new DmParams(26, 26, 26, 26, 44, 44, 28),
+ new DmParams(16, 48, 16, 24, 49, 49, 28),
+ new DmParams(32, 32, 16, 16, 62, 62, 36),
+ new DmParams(36, 36, 18, 18, 86, 86, 42),
+ new DmParams(40, 40, 20, 20, 114, 114, 48),
+ new DmParams(44, 44, 22, 22, 144, 144, 56),
+ new DmParams(48, 48, 24, 24, 174, 174, 68),
+ new DmParams(52, 52, 26, 26, 204, 102, 42),
+ new DmParams(64, 64, 16, 16, 280, 140, 56),
+ new DmParams(72, 72, 18, 18, 368, 92, 36),
+ new DmParams(80, 80, 20, 20, 456, 114, 48),
+ new DmParams(88, 88, 22, 22, 576, 144, 56),
+ new DmParams(96, 96, 24, 24, 696, 174, 68),
+ new DmParams(104, 104, 26, 26, 816, 136, 56),
+ new DmParams(120, 120, 20, 20, 1050, 175, 68),
+ new DmParams(132, 132, 22, 22, 1304, 163, 62),
+ new DmParams(144, 144, 24, 24, 1558, 156, 62)};
+
+ private const String x12 = "\r*> 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ private int extOut;
+ private short[] place;
+ private byte[] image;
+ private int height;
+ private int width;
+ private int ws;
+ private int options;
+
+ /**
+ * Creates an instance of this class.
+ */
+ public BarcodeDatamatrix() {
+ }
+
+ private void SetBit(int x, int y, int xByte) {
+ image[y * xByte + x / 8] |= (byte)(128 >> (x & 7));
+ }
+
+ private void Draw(byte[] data, int dataSize, DmParams dm) {
+ int i, j, p, x, y, xs, ys, z;
+ int xByte = (dm.width + ws * 2 + 7) / 8;
+ for (int k = 0; k < image.Length; ++k)
+ image[k] = 0;
+ //alignment patterns
+ //dotted horizontal line
+ for (i = ws; i < dm.height + ws; i += dm.heightSection) {
+ for (j = ws; j < dm.width + ws; j += 2) {
+ SetBit(j, i, xByte);
+ }
+ }
+ //solid horizontal line
+ for (i = dm.heightSection - 1 + ws; i < dm.height + ws; i += dm.heightSection) {
+ for (j = ws; j < dm.width + ws; ++j) {
+ SetBit(j, i, xByte);
+ }
+ }
+ //solid vertical line
+ for (i = ws; i < dm.width + ws; i += dm.widthSection) {
+ for (j = ws; j < dm.height + ws; ++j) {
+ SetBit(i, j, xByte);
+ }
+ }
+ //dotted vertical line
+ for (i = dm.widthSection - 1 + ws; i < dm.width + ws; i += dm.widthSection) {
+ for (j = 1 + ws; j < dm.height + ws; j += 2) {
+ SetBit(i, j, xByte);
+ }
+ }
+ p = 0;
+ for (ys = 0; ys < dm.height; ys += dm.heightSection) {
+ for (y = 1; y < dm.heightSection - 1; ++y) {
+ 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))
+ SetBit(x + xs + ws, y + ys + ws, xByte);
+ }
+ }
+ }
+ }
+ }
+
+ private static void MakePadding(byte[] data, int position, int count) {
+ //already in ascii mode
+ if (count <= 0)
+ return;
+ data[position++] = (byte)129;
+ while (--count > 0) {
+ int t = 129 + (((position + 1) * 149) % 253) + 1;
+ if (t > 254)
+ t -= 254;
+ data[position++] = (byte)t;
+ }
+ }
+
+ 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) {
+ int ptrIn, ptrOut, c;
+ ptrIn = textOffset;
+ ptrOut = dataOffset;
+ textLength += textOffset;
+ dataLength += dataOffset;
+ while (ptrIn < textLength) {
+ if (ptrOut >= dataLength)
+ return -1;
+ c = text[ptrIn++] & 0xff;
+ if (IsDigit(c) && 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++] = (byte)(c - 128 + 1);
+ }
+ else {
+ data[ptrOut++] = (byte)(c + 1);
+ }
+ }
+ return ptrOut - dataOffset;
+ }
+
+ private static int B256Encodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) {
+ int k, j, prn, tv, c;
+ 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;
+ if (textLength < 250) {
+ data[dataOffset + 1] = (byte)textLength;
+ k = 2;
+ }
+ 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;
+ }
+
+ private static int X12Encodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) {
+ int ptrIn, ptrOut, count, k, n, ci;
+ byte c;
+ if (textLength == 0)
+ return 0;
+ ptrIn = 0;
+ ptrOut = 0;
+ byte[] x = new byte[textLength];
+ count = 0;
+ for (; ptrIn < textLength; ++ptrIn) {
+ int i = x12.IndexOf((char)text[ptrIn + textOffset]);
+ if (i >= 0) {
+ x[ptrIn] = (byte)i;
+ ++count;
+ }
+ else {
+ x[ptrIn] = 100;
+ if (count >= 6)
+ count -= (count / 3) * 3;
+ for (k = 0; k < count; ++k)
+ x[ptrIn - k - 1] = 100;
+ count = 0;
+ }
+ }
+ if (count >= 6)
+ 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)
+ break;
+ if (c < 40) {
+ if (ptrIn == 0 || (ptrIn > 0 && x[ptrIn - 1] > 40))
+ data[dataOffset + ptrOut++] = (byte)238;
+ if (ptrOut + 2 > dataLength)
+ break;
+ n = 1600 * x[ptrIn] + 40 * x[ptrIn + 1] + x[ptrIn + 2] + 1;
+ data[dataOffset + ptrOut++] = (byte)(n / 256);
+ data[dataOffset + ptrOut++] = (byte)n;
+ 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;
+ }
+ 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))
+ return -1;
+ if (c < 40)
+ data[dataOffset + ptrOut++] = (byte)(254);
+ return ptrOut;
+ }
+
+ private static int EdifactEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) {
+ int ptrIn, ptrOut, edi, pedi, c;
+ if (textLength == 0)
+ return 0;
+ ptrIn = 0;
+ ptrOut = 0;
+ edi = 0;
+ pedi = 18;
+ bool ascii = true;
+ 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;
+ ascii = false;
+ }
+ c &= 0x3f;
+ edi |= c << pedi;
+ if (pedi == 0) {
+ if (ptrOut + 3 > dataLength)
+ break;
+ data[dataOffset + ptrOut++] = (byte)(edi >> 16);
+ data[dataOffset + ptrOut++] = (byte)(edi >> 8);
+ data[dataOffset + ptrOut++] = (byte)edi;
+ edi = 0;
+ pedi = 18;
+ }
+ else
+ pedi -= 6;
+ }
+ else {
+ if (!ascii) {
+ edi |= ('_' & 0x3f) << pedi;
+ if (ptrOut + (3 - pedi / 8) > dataLength)
+ break;
+ data[dataOffset + ptrOut++] = (byte)(edi >> 16);
+ if (pedi <= 12)
+ data[dataOffset + ptrOut++] = (byte)(edi >> 8);
+ if (pedi <= 6)
+ data[dataOffset + ptrOut++] = (byte)edi;
+ ascii = true;
+ pedi = 18;
+ edi = 0;
+ }
+ if (c > 127) {
+ if (ptrOut >= dataLength)
+ break;
+ data[dataOffset + ptrOut++] = (byte)235;
+ c -= 128;
+ }
+ if (ptrOut >= dataLength)
+ break;
+ data[dataOffset + ptrOut++] = (byte)(c + 1);
+ }
+ }
+ if (ptrIn != textLength)
+ return -1;
+ if (!ascii) {
+ edi |= ('_' & 0x3f) << pedi;
+ if (ptrOut + (3 - pedi / 8) > dataLength)
+ return -1;
+ data[dataOffset + ptrOut++] = (byte)(edi >> 16);
+ if (pedi <= 12)
+ data[dataOffset + ptrOut++] = (byte)(edi >> 8);
+ if (pedi <= 6)
+ data[dataOffset + ptrOut++] = (byte)edi;
+ }
+ return ptrOut;
+ }
+
+ private static int C40OrTextEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength, bool c40) {
+ 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";
+ }
+ else {
+ basic = " 0123456789abcdefghijklmnopqrstuvwxyz";
+ shift3 = "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\u007f";
+ }
+ int[] enc = new int[textLength * 4 + 10];
+ encPtr = 0;
+ last0 = 0;
+ last1 = 0;
+ while (ptrIn < textLength) {
+ if ((encPtr % 3) == 0) {
+ last0 = ptrIn;
+ last1 = encPtr;
+ }
+ c = text[textOffset + ptrIn++] & 0xff;
+ if (c > 127) {
+ c -= 128;
+ enc[encPtr++] = 1;
+ enc[encPtr++] = 30;
+ }
+ int idx = basic.IndexOf((char)c);
+ if (idx >= 0) {
+ enc[encPtr++] = idx + 3;
+ }
+ else if (c < 32) {
+ enc[encPtr++] = 0;
+ enc[encPtr++] = c;
+ }
+ else if ((idx = shift2.IndexOf((char)c)) >= 0) {
+ enc[encPtr++] = 1;
+ enc[encPtr++] = idx;
+ }
+ else if ((idx = shift3.IndexOf((char)c)) >= 0) {
+ enc[encPtr++] = 2;
+ enc[encPtr++] = idx;
+ }
+ }
+ if ((encPtr % 3) != 0) {
+ ptrIn = last0;
+ encPtr = last1;
+ }
+ if (encPtr / 3 * 2 > dataLength - 2) {
+ return -1;
+ }
+ i = 0;
+ for (; i < encPtr; i += 3) {
+ a = 1600 * enc[i] + 40 * enc[i + 1] + enc[i + 2] + 1;
+ data[dataOffset + ptrOut++] = (byte)(a / 256);
+ data[dataOffset + ptrOut++] = (byte)a;
+ }
+ data[ptrOut++] = (byte)254;
+ i = AsciiEncodation(text, ptrIn, textLength - ptrIn, data, ptrOut, dataLength - ptrOut);
+ if (i < 0)
+ return i;
+ return ptrOut + i;
+ }
+
+ 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];
+ 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;
+ }
+ j = 0;
+ e = 99999;
+ for (k = 0; k < 6; ++k) {
+ if (e1[k] >= 0 && e1[k] < e) {
+ e = e1[k];
+ j = k;
+ }
+ }
+ 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);
+ 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;
+ }
+ return -1;
+ }
+
+ 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;
+ if (c < '0' || c > '9')
+ return -1;
+ v = v * 10 + c - '0';
+ }
+ return v;
+ }
+
+ private int ProcessExtensions(byte[] text, int textOffset, int textSize, byte[] data) {
+ int order, ptrIn, ptrOut, eci, fn, ft, fi, c;
+ if ((options & DM_EXTENSION) == 0)
+ return 0;
+ order = 0;
+ ptrIn = 0;
+ ptrOut = 0;
+ while (ptrIn < textSize) {
+ if (order > 20)
+ return -1;
+ 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;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Creates a barcode. The String
is interpreted with the ISO-8859-1 encoding
+ * @param text the text
+ * @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
+ */
+ public int Generate(String text) {
+ byte[] t = System.Text.Encoding.GetEncoding(1252).GetBytes(text);
+ return Generate(t, 0, t.Length);
+ }
+
+ /**
+ * Creates a barcode.
+ * @param text the text
+ * @param textOffset the offset to the start of the text
+ * @param textSize the text size
+ * @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.
+ */
+ public int Generate(byte[] text, int textOffset, int textSize) {
+ int extCount, e, k, full;
+ DmParams dm, last;
+ byte[] data = new byte[2500];
+ extOut = 0;
+ extCount = ProcessExtensions(text, textOffset, textSize, data);
+ if (extCount < 0) {
+ return DM_ERROR_EXTENSION;
+ }
+ e = -1;
+ if (height == 0 || width == 0) {
+ last = dmSizes[dmSizes.Length - 1];
+ e = GetEncodation(text, textOffset + extOut, textSize - extOut, data, extCount, last.dataSize - extCount, options, false);
+ if (e < 0) {
+ return DM_ERROR_TEXT_TOO_BIG;
+ }
+ e += extCount;
+ for (k = 0; k < dmSizes.Length; ++k) {
+ if (dmSizes[k].dataSize >= e)
+ break;
+ }
+ dm = dmSizes[k];
+ height = dm.height;
+ width = dm.width;
+ }
+ else {
+ for (k = 0; k < dmSizes.Length; ++k) {
+ if (height == dmSizes[k].height && width == dmSizes[k].width)
+ break;
+ }
+ if (k == dmSizes.Length) {
+ return DM_ERROR_INVALID_SQUARE;
+ }
+ dm = dmSizes[k];
+ e = GetEncodation(text, textOffset + extOut, textSize - extOut, data, extCount, dm.dataSize - extCount, options, true);
+ if (e < 0) {
+ return DM_ERROR_TEXT_TOO_BIG;
+ }
+ e += extCount;
+ }
+ if ((options & DM_TEST) != 0) {
+ return DM_NO_ERROR;
+ }
+ image = new byte[(((dm.width + 2 * ws) + 7) / 8) * (dm.height + 2 * ws)];
+ MakePadding(data, e, dm.dataSize - e);
+ place = Placement.DoPlacement(dm.height - (dm.height / dm.heightSection * 2), dm.width - (dm.width / dm.widthSection * 2));
+ full = dm.dataSize + ((dm.dataSize + 2) / dm.dataBlock) * dm.errorBlock;
+ ReedSolomon.GenerateECC(data, dm.dataSize, dm.dataBlock, dm.errorBlock);
+ Draw(data, full, dm);
+ return DM_NO_ERROR;
+ }
+
+ /** 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
+ */
+ public Image CreateImage() {
+ if (image == null)
+ return null;
+ byte[] g4 = CCITTG4Encoder.Compress(image, width + 2 * ws, height + 2 * ws);
+ return Image.GetInstance(width + 2 * ws, height + 2 * ws, false, Image.CCITTG4, 0, g4, null);
+ }
+
+ /**
+ * Creates a java.awt.Image
. A successful call to the method generate()
+ * before calling this method is required.
+ * @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;
+ int h = height + 2 * ws;
+ int w = width + 2 * ws;
+ int stride = (w + 7) / 8;
+ System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(w, h);
+ for (int k = 0; k < h; ++k) {
+ int p = k * stride;
+ for (int j = 0; j < w; ++j) {
+ int b = image[p + (j / 8)] & 0xff;
+ b <<= j % 8;
+ bmp.SetPixel(j, k, (b & 0x80) == 0 ? background : foreground);
+ }
+ }
+ return bmp;
+ }
+
+ private class DmParams {
+ internal DmParams(int height, int width, int heightSection, int widthSection, int dataSize, int dataBlock, int errorBlock) {
+ this.height = height;
+ this.width = width;
+ this.heightSection = heightSection;
+ this.widthSection = widthSection;
+ this.dataSize = dataSize;
+ this.dataBlock = dataBlock;
+ this.errorBlock = errorBlock;
+ }
+
+ internal int height;
+ internal int width;
+ internal int heightSection;
+ internal int widthSection;
+ internal int dataSize;
+ internal int dataBlock;
+ internal int errorBlock;
+ };
+
+ /**
+ * Gets the generated image. The image is represented as a stream of bytes, each byte representing
+ * 8 pixels, 0 for white and 1 for black, with the high-order bit of each byte first. Each row
+ * is aligned at byte boundaries. The dimensions of the image are defined by height and width
+ * plus 2 * ws.
+ * @return the generated image
+ */
+ public byte[] BitImage {
+ get {
+ return image;
+ }
+ }
+
+ /**
+ * Gets/sets the height of the barcode. If the height is zero it will be calculated. This height doesn't include the whitespace border, if any.
+ *
+ * 12, 12
+ * 8, 18
+ * 14, 14
+ * 8, 32
+ * 16, 16
+ * 12, 26
+ * 18, 18
+ * 20, 20
+ * 12, 36
+ * 22, 22
+ * 16, 36
+ * 24, 24
+ * 26, 26
+ * 16, 48
+ * 32, 32
+ * 36, 36
+ * 40, 40
+ * 44, 44
+ * 48, 48
+ * 52, 52
+ * 64, 64
+ * 72, 72
+ * 80, 80
+ * 88, 88
+ * 96, 96
+ * 104, 104
+ * 120, 120
+ * 132, 132
+ * 144, 144
+ * @param height the height of the barcode
+ */
+ public int Height {
+ get {
+ return height;
+ }
+ set {
+ height = value;
+ }
+ }
+
+ /**
+ * Gets/sets the width of the barcode. If the width is zero it will be calculated. This width doesn't include the whitespace border, if any.
+ *
+ * 12, 12
+ * 8, 18
+ * 14, 14
+ * 8, 32
+ * 16, 16
+ * 12, 26
+ * 18, 18
+ * 20, 20
+ * 12, 36
+ * 22, 22
+ * 16, 36
+ * 24, 24
+ * 26, 26
+ * 16, 48
+ * 32, 32
+ * 36, 36
+ * 40, 40
+ * 44, 44
+ * 48, 48
+ * 52, 52
+ * 64, 64
+ * 72, 72
+ * 80, 80
+ * 88, 88
+ * 96, 96
+ * 104, 104
+ * 120, 120
+ * 132, 132
+ * 144, 144
+ * @param width the width of the barcode
+ */
+ public int Width {
+ get {
+ return width;
+ }
+ set {
+ width = value;
+ }
+ }
+
+ /**
+ * Gets/sets the whitespace border around the barcode.
+ * @param ws the whitespace border around the barcode
+ */
+ public int Ws {
+ get {
+ return ws;
+ }
+ set {
+ ws = value;
+ }
+ }
+
+ /**
+ * Gets/sets the options for the barcode generation. The options can be:
+ * DM_AUTO
- the best encodation will be used
+ * DM_ASCII
- ASCII encodation
+ * DM_C40
- C40 encodation
+ * DM_TEXT
- TEXT encodation
+ * DM_B256
- binary encodation
+ * DM_X21
- X21 encodation
+ * DM_EDIFACT
- EDIFACT encodation
+ * DM_RAW
- no encodation. The bytes provided are already encoded and will be added directly to the barcode, using padding if needed. It assumes that the encodation state is left at ASCII after the last byte.
+ *
+ * DM_EXTENSION
- allows extensions to be embedded at the start of the text:
+ * m5 - macro 5
+ * m6 - macro 6
+ * f - FNC1
+ * saabbccccc - Structured Append, aa symbol position (1-16), bb total number of symbols (2-16), ccccc file identification (0-64515)
+ * p - Reader programming
+ * . - extension terminator
+ * DM_TEST
- doesn't generate the image but returns all the other information.
+ * @param options the barcode options
+ */
+ public int Options {
+ get {
+ return options;
+ }
+ set {
+ options = value;
+ }
+ }
+
+ internal class Placement {
+ private int nrow;
+ private int ncol;
+ private short[] array;
+ private static Hashtable cache = Hashtable.Synchronized(new Hashtable());
+
+ private Placement() {
+ }
+
+ internal static short[] DoPlacement(int nrow, int ncol) {
+ int key = nrow * 1000 + ncol;
+ short[] pc = (short[])cache[key];
+ if (pc != null)
+ return pc;
+ Placement p = new Placement();
+ p.nrow = nrow;
+ p.ncol = ncol;
+ p.array = new short[nrow * ncol];
+ p.Ecc200();
+ cache[key] = p.array;
+ return p.array;
+ }
+
+ /* "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);
+ }
+ /* "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);
+ }
+ /* "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);
+ }
+ /* "ECC200" fills an nrow x ncol array with appropriate values for ECC200 */
+ private void Ecc200(){
+ int row, col, chr;
+ /* First, fill the array[] with invalid entries */
+ for (int k = 0; k < array.Length; ++k)
+ array[k] = (short)0;
+ /* Starting in the correct location for character #1, bit 8,... */
+ chr = 1; row = 4; col = 0;
+ 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++);
+ /* sweep upward diagonally, inserting successive characters,... */
+ do {
+ 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++);
+ 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;
+ }
+ }
+ }
+
+ 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,
+ 5, 219, 196, 96, 40, 222, 115, 103, 228, 78, 107, 125, 135, 8, 29, 162,
+ 244, 186, 141, 180, 45, 99, 24, 49, 56, 13, 119, 153, 212, 199, 235, 91,
+ 6, 76, 220, 217, 197, 11, 97, 184, 41, 36, 223, 253, 116, 138, 104, 193,
+ 229, 86, 79, 171, 108, 165, 126, 145, 136, 34, 9, 74, 30, 32, 163, 84,
+ 245, 173, 187, 204, 142, 81, 181, 190, 46, 88, 100, 159, 25, 231, 50, 207,
+ 57, 147, 14, 67, 120, 128, 154, 248, 213, 167, 200, 63, 236, 110, 92, 176,
+ 7, 161, 77, 124, 221, 102, 218, 95, 198, 90, 12, 152, 98, 48, 185, 179,
+ 42, 209, 37, 132, 224, 52, 254, 239, 117, 233, 139, 22, 105, 27, 194, 113,
+ 230, 206, 87, 158, 80, 189, 172, 203, 109, 175, 166, 62, 127, 247, 146, 66,
+ 137, 192, 35, 252, 10, 183, 75, 216, 31, 83, 33, 73, 164, 144, 85, 170,
+ 246, 65, 174, 61, 188, 202, 205, 157, 143, 169, 82, 72, 182, 215, 191, 251,
+ 47, 178, 89, 151, 101, 94, 160, 123, 26, 112, 232, 21, 51, 238, 208, 131,
+ 58, 69, 148, 18, 15, 16, 68, 17, 121, 149, 129, 19, 155, 59, 249, 70,
+ 214, 250, 168, 71, 201, 156, 64, 60, 237, 130, 111, 20, 93, 122, 177, 150
+ };
+
+ private static readonly int[] alog = {
+ 1, 2, 4, 8, 16, 32, 64, 128, 45, 90, 180, 69, 138, 57, 114, 228,
+ 229, 231, 227, 235, 251, 219, 155, 27, 54, 108, 216, 157, 23, 46, 92, 184,
+ 93, 186, 89, 178, 73, 146, 9, 18, 36, 72, 144, 13, 26, 52, 104, 208,
+ 141, 55, 110, 220, 149, 7, 14, 28, 56, 112, 224, 237, 247, 195, 171, 123,
+ 246, 193, 175, 115, 230, 225, 239, 243, 203, 187, 91, 182, 65, 130, 41, 82,
+ 164, 101, 202, 185, 95, 190, 81, 162, 105, 210, 137, 63, 126, 252, 213, 135,
+ 35, 70, 140, 53, 106, 212, 133, 39, 78, 156, 21, 42, 84, 168, 125, 250,
+ 217, 159, 19, 38, 76, 152, 29, 58, 116, 232, 253, 215, 131, 43, 86, 172,
+ 117, 234, 249, 223, 147, 11, 22, 44, 88, 176, 77, 154, 25, 50, 100, 200,
+ 189, 87, 174, 113, 226, 233, 255, 211, 139, 59, 118, 236, 245, 199, 163, 107,
+ 214, 129, 47, 94, 188, 85, 170, 121, 242, 201, 191, 83, 166, 97, 194, 169,
+ 127, 254, 209, 143, 51, 102, 204, 181, 71, 142, 49, 98, 196, 165, 103, 206,
+ 177, 79, 158, 17, 34, 68, 136, 61, 122, 244, 197, 167, 99, 198, 161, 111,
+ 222, 145, 15, 30, 60, 120, 240, 205, 183, 67, 134, 33, 66, 132, 37, 74,
+ 148, 5, 10, 20, 40, 80, 160, 109, 218, 153, 31, 62, 124, 248, 221, 151,
+ 3, 6, 12, 24, 48, 96, 192, 173, 119, 238, 241, 207, 179, 75, 150, 1
+ };
+
+ private static readonly int[] poly5 = {
+ 228, 48, 15, 111, 62
+ };
+
+ private static readonly int[] poly7 = {
+ 23, 68, 144, 134, 240, 92, 254
+ };
+
+ private static readonly int[] poly10 = {
+ 28, 24, 185, 166, 223, 248, 116, 255, 110, 61
+ };
+
+ private static readonly int[] poly11 = {
+ 175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120
+ };
+
+ private static readonly int[] poly12 = {
+ 41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242
+ };
+
+ private static readonly int[] poly14 = {
+ 156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185
+ };
+
+ private static readonly int[] poly18 = {
+ 83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48,
+ 90, 188
+ };
+
+ private static readonly int[] poly20 = {
+ 15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82,
+ 27, 174, 186, 172
+ };
+
+ private static readonly int[] poly24 = {
+ 52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172,
+ 254, 124, 12, 181, 184, 96, 50, 193
+ };
+
+ private static readonly int[] poly28 = {
+ 211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121,
+ 17, 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255
+ };
+
+ private static readonly int[] poly36 = {
+ 245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80, 182,
+ 229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25,
+ 225, 98, 81, 112
+ };
+
+ private static readonly int[] poly42 = {
+ 77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8,
+ 175, 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101,
+ 248, 202, 69, 50, 150, 177, 226, 5, 9, 5
+ };
+
+ private static readonly int[] poly48 = {
+ 245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87,
+ 191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138,
+ 186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19
+ };
+
+ private static readonly int[] poly56 = {
+ 175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235,
+ 150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232,
+ 144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28,
+ 155, 43, 203, 107, 233, 53, 143, 46
+ };
+
+ private static readonly int[] poly62 = {
+ 242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37,
+ 185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, 71,
+ 161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31,
+ 176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204
+ };
+
+ private static readonly int[] poly68 = {
+ 220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127,
+ 213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, 236,
+ 66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, 223, 239,
+ 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;
+ }
+ return null;
+ }
+
+ 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; inull
is returned.
+ * @param text the code to convert. It must have 12 numeric characters
+ * @return the 8 converted digits or null
if the
+ * code could not be converted
+ */
+ static public string ConvertUPCAtoUPCE(string text) {
+ if (text.Length != 12 || !(text.StartsWith("0") || text.StartsWith("1")))
+ return null;
+ if (text.Substring(3, 3).Equals("000") || text.Substring(3, 3).Equals("100")
+ || text.Substring(3, 3).Equals("200")) {
+ if (text.Substring(6, 2).Equals("00"))
+ return text.Substring(0, 1) + text.Substring(1, 2) + text.Substring(8, 3) + text.Substring(3, 1) + text.Substring(11);
+ }
+ else if (text.Substring(4, 2).Equals("00")) {
+ if (text.Substring(6, 3).Equals("000"))
+ return text.Substring(0, 1) + text.Substring(1, 3) + text.Substring(9, 2) + "3" + text.Substring(11);
+ }
+ else if (text.Substring(5, 1).Equals("0")) {
+ if (text.Substring(6, 4).Equals("0000"))
+ return text.Substring(0, 1) + text.Substring(1, 4) + text.Substring(10, 1) + "4" + text.Substring(11);
+ }
+ else if (text[10] >= '5') {
+ if (text.Substring(6, 4).Equals("0000"))
+ return text.Substring(0, 1) + text.Substring(1, 5) + text.Substring(10, 1) + text.Substring(11);
+ }
+ return null;
+ }
+
+ /** Creates the bars for the barcode EAN13 and UPCA.
+ * @param _code the text with 13 digits
+ * @return the barcode
+ */
+ public static byte[] GetBarsEAN13(string _code) {
+ int[] code = new int[_code.Length];
+ for (int k = 0; k < code.Length; ++k)
+ code[k] = _code[k] - '0';
+ byte[] bars = new byte[TOTALBARS_EAN13];
+ int pb = 0;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ byte[] sequence = PARITY13[code[0]];
+ for (int k = 0; k < sequence.Length; ++k) {
+ int c = code[k + 1];
+ byte[] stripes = BARS[c];
+ if (sequence[k] == ODD) {
+ bars[pb++] = stripes[0];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[3];
+ }
+ else {
+ bars[pb++] = stripes[3];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[0];
+ }
+ }
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ for (int k = 7; k < 13; ++k) {
+ int c = code[k];
+ byte[] stripes = BARS[c];
+ bars[pb++] = stripes[0];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[3];
+ }
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ return bars;
+ }
+
+ /** Creates the bars for the barcode EAN8.
+ * @param _code the text with 8 digits
+ * @return the barcode
+ */
+ public static byte[] GetBarsEAN8(string _code) {
+ int[] code = new int[_code.Length];
+ for (int k = 0; k < code.Length; ++k)
+ code[k] = _code[k] - '0';
+ byte[] bars = new byte[TOTALBARS_EAN8];
+ int pb = 0;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ for (int k = 0; k < 4; ++k) {
+ int c = code[k];
+ byte[] stripes = BARS[c];
+ bars[pb++] = stripes[0];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[3];
+ }
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ for (int k = 4; k < 8; ++k) {
+ int c = code[k];
+ byte[] stripes = BARS[c];
+ bars[pb++] = stripes[0];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[3];
+ }
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ return bars;
+ }
+
+ /** Creates the bars for the barcode UPCE.
+ * @param _code the text with 8 digits
+ * @return the barcode
+ */
+ public static byte[] GetBarsUPCE(string _code) {
+ int[] code = new int[_code.Length];
+ for (int k = 0; k < code.Length; ++k)
+ code[k] = _code[k] - '0';
+ byte[] bars = new byte[TOTALBARS_UPCE];
+ bool flip = (code[0] != 0);
+ int pb = 0;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ byte[] sequence = PARITYE[code[code.Length - 1]];
+ for (int k = 1; k < code.Length - 1; ++k) {
+ int c = code[k];
+ byte[] stripes = BARS[c];
+ if (sequence[k - 1] == (flip ? EVEN : ODD)) {
+ bars[pb++] = stripes[0];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[3];
+ }
+ else {
+ bars[pb++] = stripes[3];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[0];
+ }
+ }
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ return bars;
+ }
+
+ /** Creates the bars for the barcode supplemental 2.
+ * @param _code the text with 2 digits
+ * @return the barcode
+ */
+ public static byte[] GetBarsSupplemental2(string _code) {
+ int[] code = new int[2];
+ for (int k = 0; k < code.Length; ++k)
+ code[k] = _code[k] - '0';
+ byte[] bars = new byte[TOTALBARS_SUPP2];
+ int pb = 0;
+ int parity = (code[0] * 10 + code[1]) % 4;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 2;
+ byte[] sequence = PARITY2[parity];
+ for (int k = 0; k < sequence.Length; ++k) {
+ if (k == 1) {
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ }
+ int c = code[k];
+ byte[] stripes = BARS[c];
+ if (sequence[k] == ODD) {
+ bars[pb++] = stripes[0];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[3];
+ }
+ else {
+ bars[pb++] = stripes[3];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[0];
+ }
+ }
+ return bars;
+ }
+
+ /** Creates the bars for the barcode supplemental 5.
+ * @param _code the text with 5 digits
+ * @return the barcode
+ */
+ public static byte[] GetBarsSupplemental5(string _code) {
+ int[] code = new int[5];
+ for (int k = 0; k < code.Length; ++k)
+ code[k] = _code[k] - '0';
+ byte[] bars = new byte[TOTALBARS_SUPP5];
+ int pb = 0;
+ int parity = (((code[0] + code[2] + code[4]) * 3) + ((code[1] + code[3]) * 9)) % 10;
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ bars[pb++] = 2;
+ byte[] sequence = PARITY5[parity];
+ for (int k = 0; k < sequence.Length; ++k) {
+ if (k != 0) {
+ bars[pb++] = 1;
+ bars[pb++] = 1;
+ }
+ int c = code[k];
+ byte[] stripes = BARS[c];
+ if (sequence[k] == ODD) {
+ bars[pb++] = stripes[0];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[3];
+ }
+ else {
+ bars[pb++] = stripes[3];
+ bars[pb++] = stripes[2];
+ bars[pb++] = stripes[1];
+ bars[pb++] = stripes[0];
+ }
+ }
+ return bars;
+ }
+
+ /** Gets the maximum area that the barcode and the text, if
+ * any, will occupy. The lower left corner is always (0, 0).
+ * @return the size the barcode occupies.
+ */
+ public override Rectangle BarcodeSize {
+ get {
+ float width = 0;
+ float height = barHeight;
+ if (font != null) {
+ if (baseline <= 0)
+ height += -baseline + size;
+ else
+ height += baseline - font.GetFontDescriptor(BaseFont.DESCENT, size);
+ }
+ switch (codeType) {
+ case BarcodeEAN.EAN13:
+ width = x * (11 + 12 * 7);
+ if (font != null) {
+ width += font.GetWidthPoint(code[0], size);
+ }
+ break;
+ case EAN8:
+ width = x * (11 + 8 * 7);
+ break;
+ case UPCA:
+ width = x * (11 + 12 * 7);
+ if (font != null) {
+ width += font.GetWidthPoint(code[0], size) + font.GetWidthPoint(code[11], size);
+ }
+ break;
+ case UPCE:
+ width = x * (9 + 6 * 7);
+ if (font != null) {
+ width += font.GetWidthPoint(code[0], size) + font.GetWidthPoint(code[7], size);
+ }
+ break;
+ case SUPP2:
+ width = x * (6 + 2 * 7);
+ break;
+ case SUPP5:
+ width = x * (4 + 5 * 7 + 4 * 2);
+ break;
+ default:
+ throw new ArgumentException("Invalid code type.");
+ }
+ return new Rectangle(width, height);
+ }
+ }
+
+ /** Places the barcode in a PdfContentByte
. The
+ * barcode is always placed at coodinates (0, 0). Use the
+ * translation matrix to move it elsewhere.
+ *
+ * @param cb the
+ *
+ *
+ * barColor
+ * textColor
+ *
+ *
+ *
+ * null
+ * null
+ *
+ *
+ *
+ * barColor
+ * null
+ * barColor
+ *
+ *
+ * null
+ * textColor
+ *
text painted with textColor
+ *
+ *
+ * barColor
+ * textColor
+ * barColor
text painted with textColor
PdfContentByte
where the barcode will be placed
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the dimensions the barcode occupies
+ */
+ public override Rectangle PlaceBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ Rectangle rect = this.BarcodeSize;
+ float barStartX = 0;
+ float barStartY = 0;
+ float textStartY = 0;
+ if (font != null) {
+ if (baseline <= 0)
+ textStartY = barHeight - baseline;
+ else {
+ textStartY = -font.GetFontDescriptor(BaseFont.DESCENT, size);
+ barStartY = textStartY + baseline;
+ }
+ }
+ switch (codeType) {
+ case EAN13:
+ case UPCA:
+ case UPCE:
+ if (font != null)
+ barStartX += font.GetWidthPoint(code[0], size);
+ break;
+ }
+ byte[] bars = null;
+ int[] guard = GUARD_EMPTY;
+ switch (codeType) {
+ case EAN13:
+ bars = GetBarsEAN13(code);
+ guard = GUARD_EAN13;
+ break;
+ case EAN8:
+ bars = GetBarsEAN8(code);
+ guard = GUARD_EAN8;
+ break;
+ case UPCA:
+ bars = GetBarsEAN13("0" + code);
+ guard = GUARD_UPCA;
+ break;
+ case UPCE:
+ bars = GetBarsUPCE(code);
+ guard = GUARD_UPCE;
+ break;
+ case SUPP2:
+ bars = GetBarsSupplemental2(code);
+ break;
+ case SUPP5:
+ bars = GetBarsSupplemental5(code);
+ break;
+ }
+ float keepBarX = barStartX;
+ bool print = true;
+ float gd = 0;
+ if (font != null && baseline > 0 && guardBars) {
+ gd = baseline / 2;
+ }
+ if (barColor != null)
+ cb.SetColorFill(barColor);
+ for (int k = 0; k < bars.Length; ++k) {
+ float w = bars[k] * x;
+ if (print) {
+ if (Array.BinarySearch(guard, k) >= 0)
+ cb.Rectangle(barStartX, barStartY - gd, w - inkSpreading, barHeight + gd);
+ else
+ cb.Rectangle(barStartX, barStartY, w - inkSpreading, barHeight);
+ }
+ print = !print;
+ barStartX += w;
+ }
+ cb.Fill();
+ if (font != null) {
+ if (textColor != null)
+ cb.SetColorFill(textColor);
+ cb.BeginText();
+ cb.SetFontAndSize(font, size);
+ switch (codeType) {
+ case EAN13:
+ cb.SetTextMatrix(0, textStartY);
+ cb.ShowText(code.Substring(0, 1));
+ for (int k = 1; k < 13; ++k) {
+ string c = code.Substring(k, 1);
+ float len = font.GetWidthPoint(c, size);
+ float pX = keepBarX + TEXTPOS_EAN13[k - 1] * x - len / 2;
+ cb.SetTextMatrix(pX, textStartY);
+ cb.ShowText(c);
+ }
+ break;
+ case EAN8:
+ for (int k = 0; k < 8; ++k) {
+ string c = code.Substring(k, 1);
+ float len = font.GetWidthPoint(c, size);
+ float pX = TEXTPOS_EAN8[k] * x - len / 2;
+ cb.SetTextMatrix(pX, textStartY);
+ cb.ShowText(c);
+ }
+ break;
+ case UPCA:
+ cb.SetTextMatrix(0, textStartY);
+ cb.ShowText(code.Substring(0, 1));
+ for (int k = 1; k < 11; ++k) {
+ string c = code.Substring(k, 1);
+ float len = font.GetWidthPoint(c, size);
+ float pX = keepBarX + TEXTPOS_EAN13[k] * x - len / 2;
+ cb.SetTextMatrix(pX, textStartY);
+ cb.ShowText(c);
+ }
+ cb.SetTextMatrix(keepBarX + x * (11 + 12 * 7), textStartY);
+ cb.ShowText(code.Substring(11, 1));
+ break;
+ case UPCE:
+ cb.SetTextMatrix(0, textStartY);
+ cb.ShowText(code.Substring(0, 1));
+ for (int k = 1; k < 7; ++k) {
+ string c = code.Substring(k, 1);
+ float len = font.GetWidthPoint(c, size);
+ float pX = keepBarX + TEXTPOS_EAN13[k - 1] * x - len / 2;
+ cb.SetTextMatrix(pX, textStartY);
+ cb.ShowText(c);
+ }
+ cb.SetTextMatrix(keepBarX + x * (9 + 6 * 7), textStartY);
+ cb.ShowText(code.Substring(7, 1));
+ break;
+ case SUPP2:
+ case SUPP5:
+ for (int k = 0; k < code.Length; ++k) {
+ string c = code.Substring(k, 1);
+ float len = font.GetWidthPoint(c, size);
+ float pX = (7.5f + (9 * k)) * x - len / 2;
+ cb.SetTextMatrix(pX, textStartY);
+ cb.ShowText(c);
+ }
+ break;
+ }
+ cb.EndText();
+ }
+ return rect;
+ }
+
+ public override System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) {
+ int width = 0;
+ byte[] bars = null;
+ switch (codeType) {
+ case EAN13:
+ bars = GetBarsEAN13(code);
+ width = 11 + 12 * 7;
+ break;
+ case EAN8:
+ bars = GetBarsEAN8(code);
+ width = 11 + 8 * 7;
+ break;
+ case UPCA:
+ bars = GetBarsEAN13("0" + code);
+ width = 11 + 12 * 7;
+ break;
+ case UPCE:
+ bars = GetBarsUPCE(code);
+ width = 9 + 6 * 7;
+ break;
+ case SUPP2:
+ bars = GetBarsSupplemental2(code);
+ width = 6 + 2 * 7;
+ break;
+ case SUPP5:
+ bars = GetBarsSupplemental5(code);
+ width = 4 + 5 * 7 + 4 * 2;
+ break;
+ default:
+ throw new InvalidOperationException("Invalid code type.");
+ }
+ int height = (int)barHeight;
+ System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
+ for (int h = 0; h < height; ++h) {
+ bool print = true;
+ int ptr = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ int w = bars[k];
+ System.Drawing.Color c = background;
+ if (print)
+ c = foreground;
+ print = !print;
+ for (int j = 0; j < w; ++j)
+ bmp.SetPixel(ptr++, h, c);
+ }
+ }
+ return bmp;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BarcodeEANSUPP.cs b/iTechSharp/iTextSharp/text/pdf/BarcodeEANSUPP.cs
new file mode 100644
index 0000000..0f15fb0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BarcodeEANSUPP.cs
@@ -0,0 +1,150 @@
+using System;
+using iTextSharp.text;
+
+/*
+ * Copyright 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /** This class takes 2 barcodes, an EAN/UPC and a supplemental
+ * and creates a single barcode with both combined in the
+ * expected layout. The UPC/EAN should have a positive text
+ * baseline and the supplemental a negative one (in the supplemental
+ * the text is on the top of the barcode.
+ *n = 8; // horizontal distance between the two barcodes
+ *
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class BarcodeEANSUPP : Barcode {
+
+ /** The barcode with the EAN/UPC.
+ */
+ protected Barcode ean;
+ /** The barcode with the supplemental.
+ */
+ protected Barcode supp;
+
+ /** Creates new combined barcode.
+ * @param ean the EAN/UPC barcode
+ * @param supp the supplemental barcode
+ */
+ public BarcodeEANSUPP(Barcode ean, Barcode supp) {
+ n = 8; // horizontal distance between the two barcodes
+ this.ean = ean;
+ this.supp = supp;
+ }
+
+ /** Gets the maximum area that the barcode and the text, if
+ * any, will occupy. The lower left corner is always (0, 0).
+ * @return the size the barcode occupies.
+ */
+ public override Rectangle BarcodeSize {
+ get {
+ Rectangle rect = ean.BarcodeSize;
+ rect.Right = rect.Width + supp.BarcodeSize.Width + n;
+ return rect;
+ }
+ }
+
+ /** Places the barcode in a PdfContentByte
. The
+ * barcode is always placed at coodinates (0, 0). Use the
+ * translation matrix to move it elsewhere.
+ *
+ * @param cb the
+ *
+ *
+ * barColor
+ * textColor
+ *
+ *
+ *
+ * null
+ * null
+ *
+ *
+ *
+ * barColor
+ * null
+ * barColor
+ *
+ *
+ * null
+ * textColor
+ *
text painted with textColor
+ *
+ *
+ * barColor
+ * textColor
+ * barColor
text painted with textColor
PdfContentByte
where the barcode will be placed
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the dimensions the barcode occupies
+ */
+ public override Rectangle PlaceBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ if (supp.Font != null)
+ supp.BarHeight = ean.BarHeight + supp.Baseline - supp.Font.GetFontDescriptor(BaseFont.CAPHEIGHT, supp.Size);
+ else
+ supp.BarHeight = ean.BarHeight;
+ Rectangle eanR = ean.BarcodeSize;
+ cb.SaveState();
+ ean.PlaceBarcode(cb, barColor, textColor);
+ cb.RestoreState();
+ cb.SaveState();
+ cb.ConcatCTM(1, 0, 0, 1, eanR.Width + n, eanR.Height - ean.BarHeight);
+ supp.PlaceBarcode(cb, barColor, textColor);
+ cb.RestoreState();
+ return this.BarcodeSize;
+ }
+
+ public override System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) {
+ throw new InvalidOperationException("The two barcodes must be composed externally.");
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BarcodeInter25.cs b/iTechSharp/iTextSharp/text/pdf/BarcodeInter25.cs
new file mode 100644
index 0000000..cc1479b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BarcodeInter25.cs
@@ -0,0 +1,317 @@
+using System;
+using System.Text;
+using iTextSharp.text;
+
+/*
+ * $Id: BarcodeInter25.cs,v 1.5 2006/09/17 15:58:51 psoares33 Exp $
+ *
+ * Copyright 2002-2006 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /** Implements the code interleaved 2 of 5. The text can include
+ * non numeric characters that are printed but do not generate bars.
+ * The default parameters are:
+ *
+ *x = 0.8f;
+ *n = 2;
+ *font = BaseFont.CreateFont("Helvetica", "winansi", false);
+ *size = 8;
+ *baseline = size;
+ *barHeight = size * 3;
+ *textint= Element.ALIGN_CENTER;
+ *generateChecksum = false;
+ *checksumText = false;
+ *
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class BarcodeInter25 : Barcode {
+
+ /** The bars to generate the code.
+ */
+ private static readonly byte[][] BARS = {
+ new byte[] {0,0,1,1,0},
+ new byte[] {1,0,0,0,1},
+ new byte[] {0,1,0,0,1},
+ new byte[] {1,1,0,0,0},
+ new byte[] {0,0,1,0,1},
+ new byte[] {1,0,1,0,0},
+ new byte[] {0,1,1,0,0},
+ new byte[] {0,0,0,1,1},
+ new byte[] {1,0,0,1,0},
+ new byte[] {0,1,0,1,0}
+ };
+
+ /** Creates new BarcodeInter25 */
+ public BarcodeInter25() {
+ x = 0.8f;
+ n = 2;
+ font = BaseFont.CreateFont("Helvetica", "winansi", false);
+ size = 8;
+ baseline = size;
+ barHeight = size * 3;
+ textAlignment = Element.ALIGN_CENTER;
+ generateChecksum = false;
+ checksumText = false;
+ }
+
+ /** Deletes all the non numeric characters from text
.
+ * @param text the text
+ * @return a string
with only numeric characters
+ */
+ public static string KeepNumbers(string text) {
+ StringBuilder sb = new StringBuilder();
+ for (int k = 0; k < text.Length; ++k) {
+ char c = text[k];
+ if (c >= '0' && c <= '9')
+ sb.Append(c);
+ }
+ return sb.ToString();
+ }
+
+ /** Calculates the checksum.
+ * @param text the numeric text
+ * @return the checksum
+ */
+ public static char GetChecksum(string text) {
+ int mul = 3;
+ int total = 0;
+ for (int k = text.Length - 1; k >= 0; --k) {
+ int n = text[k] - '0';
+ total += mul * n;
+ mul ^= 2;
+ }
+ return (char)(((10 - (total % 10)) % 10) + '0');
+ }
+
+ /** Creates the bars for the barcode.
+ * @param text the text. It can contain non numeric characters
+ * @return the barcode
+ */
+ public static byte[] GetBarsInter25(string text) {
+ text = KeepNumbers(text);
+ if ((text.Length & 1) != 0)
+ throw new ArgumentException("The text length must be even.");
+ byte[] bars = new byte[text.Length * 5 + 7];
+ int pb = 0;
+ bars[pb++] = 0;
+ bars[pb++] = 0;
+ bars[pb++] = 0;
+ bars[pb++] = 0;
+ int len = text.Length / 2;
+ for (int k = 0; k < len; ++k) {
+ int c1 = text[k * 2] - '0';
+ int c2 = text[k * 2 + 1] - '0';
+ byte[] b1 = BARS[c1];
+ byte[] b2 = BARS[c2];
+ for (int j = 0; j < 5; ++j) {
+ bars[pb++] = b1[j];
+ bars[pb++] = b2[j];
+ }
+ }
+ bars[pb++] = 1;
+ bars[pb++] = 0;
+ bars[pb++] = 0;
+ return bars;
+ }
+
+ /** Gets the maximum area that the barcode and the text, if
+ * any, will occupy. The lower left corner is always (0, 0).
+ * @return the size the barcode occupies.
+ */
+ public override Rectangle BarcodeSize {
+ get {
+ float fontX = 0;
+ float fontY = 0;
+ if (font != null) {
+ if (baseline > 0)
+ fontY = baseline - font.GetFontDescriptor(BaseFont.DESCENT, size);
+ else
+ fontY = -baseline + size;
+ string fullCode = code;
+ if (generateChecksum && checksumText)
+ fullCode += GetChecksum(fullCode);
+ fontX = font.GetWidthPoint(altText != null ? altText : fullCode, size);
+ }
+ string fCode = KeepNumbers(code);
+ int len = fCode.Length;
+ if (generateChecksum)
+ ++len;
+ float fullWidth = len * (3 * x + 2 * x * n) + (6 + n ) * x;
+ fullWidth = Math.Max(fullWidth, fontX);
+ float fullHeight = barHeight + fontY;
+ return new Rectangle(fullWidth, fullHeight);
+ }
+ }
+
+ /** Places the barcode in a PdfContentByte
. The
+ * barcode is always placed at coodinates (0, 0). Use the
+ * translation matrix to move it elsewhere.
+ *
+ * @param cb the
+ *
+ *
+ * barColor
+ * textColor
+ *
+ *
+ *
+ * null
+ * null
+ *
+ *
+ *
+ * barColor
+ * null
+ * barColor
+ *
+ *
+ * null
+ * textColor
+ *
text painted with textColor
+ *
+ *
+ * barColor
+ * textColor
+ * barColor
text painted with textColor
PdfContentByte
where the barcode will be placed
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the dimensions the barcode occupies
+ */
+ public override Rectangle PlaceBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ string fullCode = code;
+ float fontX = 0;
+ if (font != null) {
+ if (generateChecksum && checksumText)
+ fullCode += GetChecksum(fullCode);
+ fontX = font.GetWidthPoint(fullCode = altText != null ? altText : fullCode, size);
+ }
+ string bCode = KeepNumbers(code);
+ if (generateChecksum)
+ bCode += GetChecksum(bCode);
+ int len = bCode.Length;
+ float fullWidth = len * (3 * x + 2 * x * n) + (6 + n ) * x;
+ float barStartX = 0;
+ float textStartX = 0;
+ switch (textAlignment) {
+ case Element.ALIGN_LEFT:
+ break;
+ case Element.ALIGN_RIGHT:
+ if (fontX > fullWidth)
+ barStartX = fontX - fullWidth;
+ else
+ textStartX = fullWidth - fontX;
+ break;
+ default:
+ if (fontX > fullWidth)
+ barStartX = (fontX - fullWidth) / 2;
+ else
+ textStartX = (fullWidth - fontX) / 2;
+ break;
+ }
+ float barStartY = 0;
+ float textStartY = 0;
+ if (font != null) {
+ if (baseline <= 0)
+ textStartY = barHeight - baseline;
+ else {
+ textStartY = -font.GetFontDescriptor(BaseFont.DESCENT, size);
+ barStartY = textStartY + baseline;
+ }
+ }
+ byte[] bars = GetBarsInter25(bCode);
+ bool print = true;
+ if (barColor != null)
+ cb.SetColorFill(barColor);
+ for (int k = 0; k < bars.Length; ++k) {
+ float w = (bars[k] == 0 ? x : x * n);
+ if (print)
+ cb.Rectangle(barStartX, barStartY, w - inkSpreading, barHeight);
+ print = !print;
+ barStartX += w;
+ }
+ cb.Fill();
+ if (font != null) {
+ if (textColor != null)
+ cb.SetColorFill(textColor);
+ cb.BeginText();
+ cb.SetFontAndSize(font, size);
+ cb.SetTextMatrix(textStartX, textStartY);
+ cb.ShowText(fullCode);
+ cb.EndText();
+ }
+ return this.BarcodeSize;
+ }
+
+ public override System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) {
+ String bCode = KeepNumbers(code);
+ if (generateChecksum)
+ bCode += GetChecksum(bCode);
+ int len = bCode.Length;
+ int nn = (int)n;
+ int fullWidth = len * (3 + 2 * nn) + (6 + nn );
+ byte[] bars = GetBarsInter25(bCode);
+ int height = (int)barHeight;
+ System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(fullWidth, height);
+ for (int h = 0; h < height; ++h) {
+ bool print = true;
+ int ptr = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ int w = (bars[k] == 0 ? 1 : nn);
+ System.Drawing.Color c = background;
+ if (print)
+ c = foreground;
+ print = !print;
+ for (int j = 0; j < w; ++j)
+ bmp.SetPixel(ptr++, h, c);
+ }
+ }
+ return bmp;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BarcodePDF417.cs b/iTechSharp/iTextSharp/text/pdf/BarcodePDF417.cs
new file mode 100644
index 0000000..94cf499
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BarcodePDF417.cs
@@ -0,0 +1,1551 @@
+using System;
+using iTextSharp.text;
+using iTextSharp.text.pdf.codec;
+using System.Collections;
+using System.Text;
+
+namespace iTextSharp.text.pdf {
+ /** Generates the 2D barcode PDF417. Supports dimensioning auto-sizing, fixed
+ * and variable sizes, automatic and manual error levels, raw codeword input,
+ * codeword size optimization and bitmap inversion. The output can
+ * be a CCITT G4 Image
or a raw bitmap.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class BarcodePDF417 {
+
+ /** Auto-size is made based on aspectRatio
and yHeight
. */
+ public const int PDF417_USE_ASPECT_RATIO = 0;
+ /** The size of the barcode will be at least codeColumns*codeRows
. */
+ public const int PDF417_FIXED_RECTANGLE = 1;
+ /** The size will be at least codeColumns
+ * with a variable number of codeRows
.
+ */
+ public const int PDF417_FIXED_COLUMNS = 2;
+ /** The size will be at least codeRows
+ * with a variable number of codeColumns
.
+ */
+ public const int PDF417_FIXED_ROWS = 4;
+ /** The error level correction is set automatically according
+ * to ISO 15438 recomendations.
+ */
+ public const int PDF417_AUTO_ERROR_LEVEL = 0;
+ /** The error level correction is set by the user. It can be 0 to 8. */
+ public const int PDF417_USE_ERROR_LEVEL = 16;
+ /**
+ * One single binary segment is used
+ */
+ public const int PDF417_FORCE_BINARY = 32;
+ /** No text
interpretation is done and the content of codewords
+ * is used directly.
+ */
+ public const int PDF417_USE_RAW_CODEWORDS = 64;
+ /** Inverts the output bits of the raw bitmap that is normally
+ * bit one for black. It has only effect for the raw bitmap.
+ */
+ public const int PDF417_INVERT_BITMAP = 128;
+ /** Use Macro PDF417 Encoding
+ * @see #setMacroFileId(String)
+ * @see #setMacroSegmentId(int)
+ * @see #setMacroSegmentCount(int)
+ */
+ public const int PDF417_USE_MACRO = 256;
+
+
+ private int macroSegmentCount=0;
+ private int macroSegmentId=-1;
+ private String macroFileId;
+ private int macroIndex;
+
+ protected int bitPtr;
+ protected int cwPtr;
+ protected SegmentList segmentList;
+
+ /** Creates a new BarcodePDF417
with the default settings. */
+ public BarcodePDF417() {
+ SetDefaultParameters();
+ }
+
+ /**
+ * Sets the segment id for macro PDF417 encoding
+ * @param id the id (starting at 0)
+ * @see #setMacroSegmentCount(int)
+ */
+ public int MacroSegmentId {
+ set {
+ this.macroSegmentId = value;
+ }
+ }
+
+ /**
+ * Sets the segment count for macro PDF417 encoding
+ * @param cnt the number of macro segments
+ * @see #setMacroSegmentId(int)
+ */
+ public int MacroSegmentCount {
+ set {
+ this.macroSegmentCount = value;
+ }
+ }
+
+ /**
+ * Sets the File ID for macro PDF417 encoding
+ * @param id the file id
+ */
+ public String MacroFileId {
+ set {
+ this.macroFileId = value;
+ }
+ }
+
+ protected bool CheckSegmentType(Segment segment, char type) {
+ if (segment == null)
+ return false;
+ return segment.type == type;
+ }
+
+ protected int GetSegmentLength(Segment segment) {
+ if (segment == null)
+ return 0;
+ return segment.end - segment.start;
+ }
+
+ /** Set the default settings that correspond to PDF417_USE_ASPECT_RATIO
+ * and PDF417_AUTO_ERROR_LEVEL
.
+ */
+ public void SetDefaultParameters() {
+ options = 0;
+ outBits = null;
+ text = new byte[0];
+ yHeight = 3;
+ aspectRatio = 0.5f;
+ }
+
+ protected void OutCodeword17(int codeword) {
+ int bytePtr = bitPtr / 8;
+ int bit = bitPtr - bytePtr * 8;
+ outBits[bytePtr++] |= (byte)(codeword >> (9 + bit));
+ outBits[bytePtr++] |= (byte)(codeword >> (1 + bit));
+ codeword <<= 8;
+ outBits[bytePtr] |= (byte)(codeword >> (1 + bit));
+ bitPtr += 17;
+ }
+
+ protected void OutCodeword18(int codeword) {
+ int bytePtr = bitPtr / 8;
+ int bit = bitPtr - bytePtr * 8;
+ outBits[bytePtr++] |= (byte)(codeword >> (10 + bit));
+ outBits[bytePtr++] |= (byte)(codeword >> (2 + bit));
+ codeword <<= 8;
+ outBits[bytePtr] |= (byte)(codeword >> (2 + bit));
+ if (bit == 7)
+ outBits[++bytePtr] |= 0x80;
+ bitPtr += 18;
+ }
+
+ protected void OutCodeword(int codeword) {
+ OutCodeword17(codeword);
+ }
+
+ protected void OutStopPattern() {
+ OutCodeword18(STOP_PATTERN);
+ }
+
+ protected void OutStartPattern() {
+ OutCodeword17(START_PATTERN);
+ }
+
+ protected void OutPaintCode() {
+ int codePtr = 0;
+ bitColumns = START_CODE_SIZE * (codeColumns + 3) + STOP_SIZE;
+ int lenBits = ((bitColumns - 1) / 8 + 1) * codeRows;
+ outBits = new byte[lenBits];
+ for (int row = 0; row < codeRows; ++row) {
+ bitPtr = ((bitColumns - 1) / 8 + 1) * 8 * row;
+ int rowMod = row % 3;
+ int[] cluster = CLUSTERS[rowMod];
+ OutStartPattern();
+ int edge = 0;
+ switch (rowMod) {
+ case 0:
+ edge = 30 * (row / 3) + ((codeRows - 1) / 3);
+ break;
+ case 1:
+ edge = 30 * (row / 3) + errorLevel * 3 + ((codeRows - 1) % 3);
+ break;
+ default:
+ edge = 30 * (row / 3) + codeColumns - 1;
+ break;
+ }
+ OutCodeword(cluster[edge]);
+
+ for (int column = 0; column < codeColumns; ++column) {
+ OutCodeword(cluster[codewords[codePtr++]]);
+ }
+
+ switch (rowMod) {
+ case 0:
+ edge = 30 * (row / 3) + codeColumns - 1;
+ break;
+ case 1:
+ edge = 30 * (row / 3) + ((codeRows - 1) / 3);
+ break;
+ default:
+ edge = 30 * (row / 3) + errorLevel * 3 + ((codeRows - 1) % 3);
+ break;
+ }
+ OutCodeword(cluster[edge]);
+ OutStopPattern();
+ }
+ if ((options & PDF417_INVERT_BITMAP) != 0) {
+ for (int k = 0; k < outBits.Length; ++k)
+ outBits[k] ^= 0xff;
+ }
+ }
+
+ protected void CalculateErrorCorrection(int dest) {
+ if (errorLevel < 0 || errorLevel > 8)
+ errorLevel = 0;
+ int[] A = ERROR_LEVEL[errorLevel];
+ int Alength = 2 << errorLevel;
+ for (int k = 0; k < Alength; ++k)
+ codewords[dest + k] = 0;
+ int lastE = Alength - 1;
+ for (int k = 0; k < lenCodewords; ++k) {
+ int t1 = codewords[k] + codewords[dest];
+ for (int e = 0; e <= lastE; ++e) {
+ int t2 = (t1 * A[lastE - e]) % MOD;
+ int t3 = MOD - t2;
+ codewords[dest + e] = ((e == lastE ? 0 : codewords[dest + e + 1]) + t3) % MOD;
+ }
+ }
+ for (int k = 0; k < Alength; ++k)
+ codewords[dest + k] = (MOD - codewords[dest + k]) % MOD;
+ }
+
+ private static int GetTextTypeAndValue(byte[] input, int maxLength, int idx) {
+ if (idx >= maxLength)
+ return 0;
+ char c = (char)(input[idx] & 0xff);
+ if (c >= 'A' && c <= 'Z')
+ return (ALPHA + c - 'A');
+ if (c >= 'a' && c <= 'z')
+ return (LOWER + c - 'a');
+ if (c == ' ')
+ return (ALPHA + LOWER + MIXED + SPACE);
+ int ms = MIXED_SET.IndexOf(c);
+ int ps = PUNCTUATION_SET.IndexOf(c);
+ if (ms < 0 && ps < 0)
+ return (ISBYTE + c);
+ if (ms == ps)
+ return (MIXED + PUNCTUATION + ms);
+ if (ms >= 0)
+ return (MIXED + ms);
+ return (PUNCTUATION + ps);
+ }
+
+ protected int GetTextTypeAndValue(int maxLength, int idx) {
+ return GetTextTypeAndValue(text, maxLength,idx);
+ }
+
+ private void TextCompaction(byte[] input, int start, int length) {
+ int[] dest = new int[ABSOLUTE_MAX_TEXT_SIZE * 2];
+ int mode = ALPHA;
+ int ptr = 0;
+ int fullBytes = 0;
+ int v = 0;
+ int k;
+ int size;
+ length += start;
+ for (k = start; k < length; ++k) {
+ v = GetTextTypeAndValue(input, length, k);
+ if ((v & mode) != 0) {
+ dest[ptr++] = v & 0xff;
+ continue;
+ }
+ if ((v & ISBYTE) != 0) {
+ if ((ptr & 1) != 0) {
+ //add a padding word
+ dest[ptr++] = PAL;
+ mode = (mode & PUNCTUATION) != 0 ? ALPHA : mode;
+ }
+ dest[ptr++] = BYTESHIFT;
+ dest[ptr++] = v & 0xff;
+ fullBytes += 2;
+ continue;
+ }
+ switch (mode) {
+ case ALPHA:
+ if ((v & LOWER) != 0) {
+ dest[ptr++] = LL;
+ dest[ptr++] = v & 0xff;
+ mode = LOWER;
+ }
+ else if ((v & MIXED) != 0) {
+ dest[ptr++] = ML;
+ dest[ptr++] = v & 0xff;
+ mode = MIXED;
+ }
+ else if ((GetTextTypeAndValue(input, length, k + 1) & GetTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) {
+ dest[ptr++] = ML;
+ dest[ptr++] = PL;
+ dest[ptr++] = v & 0xff;
+ mode = PUNCTUATION;
+ }
+ else {
+ dest[ptr++] = PS;
+ dest[ptr++] = v & 0xff;
+ }
+ break;
+ case LOWER:
+ if ((v & ALPHA) != 0) {
+ if ((GetTextTypeAndValue(length, k + 1) & GetTextTypeAndValue(length, k + 2) & ALPHA) != 0) {
+ dest[ptr++] = ML;
+ dest[ptr++] = AL;
+ mode = ALPHA;
+ }
+ else {
+ dest[ptr++] = AS;
+ }
+ dest[ptr++] = v & 0xff;
+ }
+ else if ((v & MIXED) != 0) {
+ dest[ptr++] = ML;
+ dest[ptr++] = v & 0xff;
+ mode = MIXED;
+ }
+ else if ((GetTextTypeAndValue(input, length, k + 1) & GetTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) {
+ dest[ptr++] = ML;
+ dest[ptr++] = PL;
+ dest[ptr++] = v & 0xff;
+ mode = PUNCTUATION;
+ }
+ else {
+ dest[ptr++] = PS;
+ dest[ptr++] = v & 0xff;
+ }
+ break;
+ case MIXED:
+ if ((v & LOWER) != 0) {
+ dest[ptr++] = LL;
+ dest[ptr++] = v & 0xff;
+ mode = LOWER;
+ }
+ else if ((v & ALPHA) != 0) {
+ dest[ptr++] = AL;
+ dest[ptr++] = v & 0xff;
+ mode = ALPHA;
+ }
+ else if ((GetTextTypeAndValue(input, length, k + 1) & GetTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) {
+ dest[ptr++] = PL;
+ dest[ptr++] = v & 0xff;
+ mode = PUNCTUATION;
+ }
+ else {
+ dest[ptr++] = PS;
+ dest[ptr++] = v & 0xff;
+ }
+ break;
+ case PUNCTUATION:
+ dest[ptr++] = PAL;
+ mode = ALPHA;
+ --k;
+ break;
+ }
+ }
+ if ((ptr & 1) != 0)
+ dest[ptr++] = PS;
+ size = (ptr + fullBytes) / 2;
+ if (size + cwPtr > MAX_DATA_CODEWORDS) {
+ throw new ArgumentOutOfRangeException("The text is too big.");
+ }
+ length = ptr;
+ ptr = 0;
+ while (ptr < length) {
+ v = dest[ptr++];
+ if (v >= 30) {
+ codewords[cwPtr++] = v;
+ codewords[cwPtr++] = dest[ptr++];
+ }
+ else
+ codewords[cwPtr++] = v * 30 + dest[ptr++];
+ }
+ }
+
+ protected void TextCompaction(int start, int length) {
+ TextCompaction(text, start, length);
+ }
+
+ protected void BasicNumberCompaction(int start, int length) {
+ BasicNumberCompaction(text, start, length);
+ }
+
+ private void BasicNumberCompaction(byte[] input, int start, int length) {
+ int ret = cwPtr;
+ int retLast = length / 3;
+ int ni, k;
+ cwPtr += retLast + 1;
+ for (k = 0; k <= retLast; ++k)
+ codewords[ret + k] = 0;
+ codewords[ret + retLast] = 1;
+ length += start;
+ for (ni = start; ni < length; ++ni) {
+ // multiply by 10
+ for (k = retLast; k >= 0; --k)
+ codewords[ret + k] *= 10;
+ // add the digit
+ codewords[ret + retLast] += input[ni] - '0';
+ // propagate carry
+ for (k = retLast; k > 0; --k) {
+ codewords[ret + k - 1] += codewords[ret + k] / 900;
+ codewords[ret + k] %= 900;
+ }
+ }
+ }
+
+ private void NumberCompaction(byte[] input, int start, int length) {
+ int full = (length / 44) * 15;
+ int size = length % 44;
+ int k;
+ if (size == 0)
+ size = full;
+ else
+ size = full + size / 3 + 1;
+ if (size + cwPtr > MAX_DATA_CODEWORDS) {
+ throw new ArgumentOutOfRangeException("The text is too big.");
+ }
+ length += start;
+ for (k = start; k < length; k += 44) {
+ size = length - k < 44 ? length - k : 44;
+ BasicNumberCompaction(input, k, size);
+ }
+ }
+
+ protected void NumberCompaction(int start, int length) {
+ NumberCompaction(text, start, length);
+ }
+
+ protected void ByteCompaction6(int start) {
+ int length = 6;
+ int ret = cwPtr;
+ int retLast = 4;
+ int ni, k;
+ cwPtr += retLast + 1;
+ for (k = 0; k <= retLast ; ++k)
+ codewords[ret + k] = 0;
+ length += start;
+ for (ni = start; ni < length; ++ni) {
+ // multiply by 256
+ for (k = retLast; k >= 0; --k)
+ codewords[ret + k] *= 256;
+ // add the digit
+ codewords[ret + retLast] += (int)text[ni] & 0xff;
+ // propagate carry
+ for (k = retLast; k > 0; --k) {
+ codewords[ret + k - 1] += codewords[ret + k] / 900;
+ codewords[ret + k] %= 900;
+ }
+ }
+ }
+
+ internal void ByteCompaction(int start, int length) {
+ int k, j;
+ int size = (length / 6) * 5 + (length % 6);
+ if (size + cwPtr > MAX_DATA_CODEWORDS) {
+ throw new ArgumentOutOfRangeException("The text is too big.");
+ }
+ length += start;
+ for (k = start; k < length; k += 6) {
+ size = length - k < 44 ? length - k : 6;
+ if (size < 6) {
+ for (j = 0; j < size; ++j)
+ codewords[cwPtr++] = (int)text[k + j] & 0xff;
+ }
+ else {
+ ByteCompaction6(k);
+ }
+ }
+ }
+
+ internal void BreakString() {
+ int textLength = text.Length;
+ int lastP = 0;
+ int startN = 0;
+ int nd = 0;
+ char c = (char)0;
+ int k, j;
+ bool lastTxt, txt;
+ Segment v;
+ Segment vp;
+ Segment vn;
+
+ if ((options & PDF417_FORCE_BINARY) != 0) {
+ segmentList.Add('B', 0, textLength);
+ return;
+ }
+ for (k = 0; k < textLength; ++k) {
+ c = (char)(text[k] & 0xff);
+ if (c >= '0' && c <= '9') {
+ if (nd == 0)
+ startN = k;
+ ++nd;
+ continue;
+ }
+ if (nd >= 13) {
+ if (lastP != startN) {
+ c = (char)(text[lastP] & 0xff);
+ lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t';
+ for (j = lastP; j < startN; ++j) {
+ c = (char)(text[j] & 0xff);
+ txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t';
+ if (txt != lastTxt) {
+ segmentList.Add(lastTxt ? 'T' : 'B', lastP, j);
+ lastP = j;
+ lastTxt = txt;
+ }
+ }
+ segmentList.Add(lastTxt ? 'T' : 'B', lastP, startN);
+ }
+ segmentList.Add('N', startN, k);
+ lastP = k;
+ }
+ nd = 0;
+ }
+ if (nd < 13)
+ startN = textLength;
+ if (lastP != startN) {
+ c = (char)(text[lastP] & 0xff);
+ lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t';
+ for (j = lastP; j < startN; ++j) {
+ c = (char)(text[j] & 0xff);
+ txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t';
+ if (txt != lastTxt) {
+ segmentList.Add(lastTxt ? 'T' : 'B', lastP, j);
+ lastP = j;
+ lastTxt = txt;
+ }
+ }
+ segmentList.Add(lastTxt ? 'T' : 'B', lastP, startN);
+ }
+ if (nd >= 13)
+ segmentList.Add('N', startN, textLength);
+ //optimize
+ //merge short binary
+ for (k = 0; k < segmentList.Size; ++k) {
+ v = segmentList.Get(k);
+ vp = segmentList.Get(k - 1);
+ vn = segmentList.Get(k + 1);
+ if (CheckSegmentType(v, 'B') && GetSegmentLength(v) == 1) {
+ if (CheckSegmentType(vp, 'T') && CheckSegmentType(vn, 'T')
+ && GetSegmentLength(vp) + GetSegmentLength(vn) >= 3) {
+ vp.end = vn.end;
+ segmentList.Remove(k);
+ segmentList.Remove(k);
+ k = -1;
+ continue;
+ }
+ }
+ }
+ //merge text sections
+ for (k = 0; k < segmentList.Size; ++k) {
+ v = segmentList.Get(k);
+ vp = segmentList.Get(k - 1);
+ vn = segmentList.Get(k + 1);
+ if (CheckSegmentType(v, 'T') && GetSegmentLength(v) >= 5) {
+ bool redo = false;
+ if ((CheckSegmentType(vp, 'B') && GetSegmentLength(vp) == 1) || CheckSegmentType(vp, 'T')) {
+ redo = true;
+ v.start = vp.start;
+ segmentList.Remove(k - 1);
+ --k;
+ }
+ if ((CheckSegmentType(vn, 'B') && GetSegmentLength(vn) == 1) || CheckSegmentType(vn, 'T')) {
+ redo = true;
+ v.end = vn.end;
+ segmentList.Remove(k + 1);
+ }
+ if (redo) {
+ k = -1;
+ continue;
+ }
+ }
+ }
+ //merge binary sections
+ for (k = 0; k < segmentList.Size; ++k) {
+ v = segmentList.Get(k);
+ vp = segmentList.Get(k - 1);
+ vn = segmentList.Get(k + 1);
+ if (CheckSegmentType(v, 'B')) {
+ bool redo = false;
+ if ((CheckSegmentType(vp, 'T') && GetSegmentLength(vp) < 5) || CheckSegmentType(vp, 'B')) {
+ redo = true;
+ v.start = vp.start;
+ segmentList.Remove(k - 1);
+ --k;
+ }
+ if ((CheckSegmentType(vn, 'T') && GetSegmentLength(vn) < 5) || CheckSegmentType(vn, 'B')) {
+ redo = true;
+ v.end = vn.end;
+ segmentList.Remove(k + 1);
+ }
+ if (redo) {
+ k = -1;
+ continue;
+ }
+ }
+ }
+ // check if all numbers
+ if (segmentList.Size == 1 && (v = segmentList.Get(0)).type == 'T' && GetSegmentLength(v) >= 8) {
+ for (k = v.start; k < v.end; ++k) {
+ c = (char)(text[k] & 0xff);
+ if (c < '0' || c > '9')
+ break;
+ }
+ if (k == v.end)
+ v.type = 'N';
+ }
+ }
+
+ protected void Assemble() {
+ int k;
+ if (segmentList.Size == 0)
+ return;
+ cwPtr = 1;
+ for (k = 0; k < segmentList.Size; ++k) {
+ Segment v = segmentList.Get(k);
+ switch (v.type) {
+ case 'T':
+ if (k != 0)
+ codewords[cwPtr++] = TEXT_MODE;
+ TextCompaction(v.start, GetSegmentLength(v));
+ break;
+ case 'N':
+ codewords[cwPtr++] = NUMERIC_MODE;
+ NumberCompaction(v.start, GetSegmentLength(v));
+ break;
+ case 'B':
+ codewords[cwPtr++] = (GetSegmentLength(v) % 6) != 0 ? BYTE_MODE : BYTE_MODE_6;
+ ByteCompaction(v.start, GetSegmentLength(v));
+ break;
+ }
+ }
+ if ((options & PDF417_USE_MACRO) != 0) {
+ MacroCodes();
+ }
+
+ }
+
+ private void MacroCodes() {
+ if (macroSegmentId < 0) {
+ throw new InvalidOperationException("macroSegmentId must be >=0");
+ }
+ if (macroSegmentId >= macroSegmentCount) {
+ throw new InvalidOperationException("macroSegmentId must be < macroSemgentCount");
+ }
+ if (macroSegmentCount < 1) {
+ throw new InvalidOperationException("macroSemgentCount must be > 0");
+ }
+
+ macroIndex = cwPtr;
+ codewords[cwPtr++] = MACRO_SEGMENT_ID;
+ Append(macroSegmentId, 5);
+
+ if (macroFileId != null) {
+ Append(macroFileId);
+ }
+
+ if (macroSegmentId >= macroSegmentCount-1) {
+ codewords[cwPtr++] = MACRO_LAST_SEGMENT;
+ }
+
+ }
+
+ private void Append(int inp, int len) {
+ StringBuilder sb = new StringBuilder(len+1);
+ sb.Append(inp);
+ for(int i = sb.Length; i < len; i++) {
+ sb.Insert(0, "0");
+ }
+
+ byte[] bytes = PdfEncodings.ConvertToBytes(sb.ToString(), "cp437");
+ NumberCompaction(bytes, 0, bytes.Length);
+ }
+
+ private void Append(String s) {
+ byte[] bytes = PdfEncodings.ConvertToBytes(s, "cp437");
+ TextCompaction(bytes, 0, bytes.Length);
+ }
+
+ protected static int MaxPossibleErrorLevel(int remain) {
+ int level = 8;
+ int size = 512;
+ while (level > 0) {
+ if (remain >= size)
+ return level;
+ --level;
+ size >>= 1;
+ }
+ return 0;
+ }
+
+ protected void DumpList() {
+ if (segmentList.Size == 0)
+ return;
+ for (int k = 0; k < segmentList.Size; ++k) {
+ Segment v = segmentList.Get(k);
+ int len = GetSegmentLength(v);
+ char[] c = new char[len];
+ for (int j = 0; j < len; ++j) {
+ c[j] = (char)(text[v.start + j] & 0xff);
+ if (c[j] == '\r')
+ c[j] = '\n';
+ }
+ Console.WriteLine("" + v.type + new String(c));
+ }
+ }
+
+ protected int GetMaxSquare() {
+ if (codeColumns > 21) {
+ codeColumns = 29;
+ codeRows = 32;
+ }
+ else {
+ codeColumns = 16;
+ codeRows = 58;
+ }
+ return MAX_DATA_CODEWORDS + 2;
+ }
+
+ /** Paints the barcode. If no exception was thrown a valid barcode is available. */
+ public void PaintCode() {
+ int maxErr, lenErr, tot, pad;
+ if ((options & PDF417_USE_RAW_CODEWORDS) != 0) {
+ if (lenCodewords > MAX_DATA_CODEWORDS || lenCodewords < 1 || lenCodewords != codewords[0]) {
+ throw new ArgumentException("Invalid codeword size.");
+ }
+ }
+ else {
+ if (text == null)
+ throw new ArgumentNullException("Text cannot be null.");
+ if (text.Length > ABSOLUTE_MAX_TEXT_SIZE) {
+ throw new ArgumentOutOfRangeException("The text is too big.");
+ }
+ segmentList = new SegmentList();
+ BreakString();
+ //dumpList();
+ Assemble();
+ segmentList = null;
+ codewords[0] = lenCodewords = cwPtr;
+ }
+ maxErr = MaxPossibleErrorLevel(MAX_DATA_CODEWORDS + 2 - lenCodewords);
+ if ((options & PDF417_USE_ERROR_LEVEL) == 0) {
+ if (lenCodewords < 41)
+ errorLevel = 2;
+ else if (lenCodewords < 161)
+ errorLevel = 3;
+ else if (lenCodewords < 321)
+ errorLevel = 4;
+ else
+ errorLevel = 5;
+ }
+ if (errorLevel < 0)
+ errorLevel = 0;
+ else if (errorLevel > maxErr)
+ errorLevel = maxErr;
+ if (codeColumns < 1)
+ codeColumns = 1;
+ else if (codeColumns > 30)
+ codeColumns = 30;
+ if (codeRows < 3)
+ codeRows = 3;
+ else if (codeRows > 90)
+ codeRows = 90;
+ lenErr = 2 << errorLevel;
+ bool fixedColumn = (options & PDF417_FIXED_ROWS) == 0;
+ bool skipRowColAdjust = false;
+ tot = lenCodewords + lenErr;
+ if ((options & PDF417_FIXED_RECTANGLE) != 0) {
+ tot = codeColumns * codeRows;
+ if (tot > MAX_DATA_CODEWORDS + 2) {
+ tot = GetMaxSquare();
+ }
+ if (tot < lenCodewords + lenErr)
+ tot = lenCodewords + lenErr;
+ else
+ skipRowColAdjust = true;
+ }
+ else if ((options & (PDF417_FIXED_COLUMNS | PDF417_FIXED_ROWS)) == 0) {
+ double c, b;
+ fixedColumn = true;
+ if (aspectRatio < 0.001)
+ aspectRatio = 0.001f;
+ else if (aspectRatio > 1000)
+ aspectRatio = 1000;
+ b = 73 * aspectRatio - 4;
+ c = (-b + Math.Sqrt(b * b + 4 * 17 * aspectRatio * (lenCodewords + lenErr) * yHeight)) / (2 * 17 * aspectRatio);
+ codeColumns = (int)(c + 0.5);
+ if (codeColumns < 1)
+ codeColumns = 1;
+ else if (codeColumns > 30)
+ codeColumns = 30;
+ }
+ if (!skipRowColAdjust) {
+ if (fixedColumn) {
+ codeRows = (tot - 1) / codeColumns + 1;
+ if (codeRows < 3)
+ codeRows = 3;
+ else if (codeRows > 90) {
+ codeRows = 90;
+ codeColumns = (tot - 1) / 90 + 1;
+ }
+ }
+ else {
+ codeColumns = (tot - 1) / codeRows + 1;
+ if (codeColumns > 30) {
+ codeColumns = 30;
+ codeRows = (tot - 1) / 30 + 1;
+ }
+ }
+ tot = codeRows * codeColumns;
+ }
+ if (tot > MAX_DATA_CODEWORDS + 2) {
+ tot = GetMaxSquare();
+ }
+ errorLevel = MaxPossibleErrorLevel(tot - lenCodewords);
+ lenErr = 2 << errorLevel;
+ pad = tot - lenErr - lenCodewords;
+ if ((options & PDF417_USE_MACRO) != 0) {
+ // the padding comes before the control block
+ System.Array.Copy(codewords, macroIndex, codewords, macroIndex + pad, pad);
+ cwPtr = lenCodewords + pad;
+ while (pad-- != 0)
+ codewords[macroIndex++] = TEXT_MODE;
+ }
+ else {
+ cwPtr = lenCodewords;
+ while (pad-- != 0)
+ codewords[cwPtr++] = TEXT_MODE;
+ }
+ codewords[0] = lenCodewords = cwPtr;
+ CalculateErrorCorrection(lenCodewords);
+ lenCodewords = tot;
+ OutPaintCode();
+ }
+
+ /** Gets an Image
with the barcode. The image will have to be
+ * scaled in the Y direction by yHeight
for the barcode
+ * to have the right printing aspect.
+ * @return the barcode Image
+ * @throws BadElementException on error
+ */
+ public Image GetImage() {
+ PaintCode();
+ byte[] g4 = CCITTG4Encoder.Compress(outBits, bitColumns, codeRows);
+ return Image.GetInstance(bitColumns, codeRows, false, Element.CCITTG4, (options & PDF417_INVERT_BITMAP) == 0 ? 0 : Element.CCITT_BLACKIS1, g4, null);
+ }
+
+ public virtual System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) {
+ PaintCode();
+ int h = (int)yHeight;
+ int stride = (bitColumns + 7) / 8;
+ System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(bitColumns, codeRows * h);
+ int y = 0;
+ for (int k = 0; k < codeRows; ++k) {
+ for (int hh = 0; hh < h; ++hh) {
+ int p = k * stride;
+ for (int j = 0; j < bitColumns; ++j) {
+ int b = outBits[p + (j / 8)] & 0xff;
+ b <<= j % 8;
+ bmp.SetPixel(j, y, (b & 0x80) == 0 ? background : foreground);
+ }
+ ++y;
+ }
+ }
+ return bmp;
+ }
+
+ /** Gets the raw image bits of the barcode. The image will have to
+ * be scaled in the Y direction by yHeight
.
+ * @return The raw barcode image
+ */
+ public byte[] OutBits {
+ get {
+ return this.outBits;
+ }
+ }
+
+ /** Gets the number of X pixels of outBits
.
+ * @return the number of X pixels of outBits
+ */
+ public int BitColumns {
+ get {
+ return this.bitColumns;
+ }
+ }
+
+ /** Gets the number of Y pixels of outBits
.
+ * It is also the number of rows in the barcode.
+ * @return the number of Y pixels of outBits
+ */
+ /** Sets the number of barcode rows. This number may be changed
+ * to keep the barcode valid.
+ * @param codeRows the number of barcode rows
+ */
+ public int CodeRows {
+ set {
+ this.codeRows = value;
+ }
+ get {
+ return codeRows;
+ }
+ }
+
+ /** Sets the number of barcode data columns.
+ * This number may be changed to keep the barcode valid.
+ * @param codeColumns the number of barcode data columns
+ */
+ public int CodeColumns {
+ set {
+ this.codeColumns = value;
+ }
+ get {
+ return codeColumns;
+ }
+ }
+
+ /** Gets the codeword array. This array is always 928 elements long.
+ * It can be writen to if the option PDF417_USE_RAW_CODEWORDS
+ * is set.
+ * @return the codeword array
+ */
+ public int[] Codewords {
+ get {
+ return this.codewords;
+ }
+ }
+
+ /** Sets the length of the codewords.
+ * @param lenCodewords the length of the codewords
+ */
+ public int LenCodewords {
+ set {
+ this.lenCodewords = value;
+ }
+ get {
+ return lenCodewords;
+ }
+ }
+
+ /** Gets the error level correction used for the barcode. It may different
+ * from the previously set value.
+ * @return the error level correction used for the barcode
+ */
+ /** Sets the error level correction for the barcode.
+ * @param errorLevel the error level correction for the barcode
+ */
+ public int ErrorLevel {
+ set {
+ this.errorLevel = value;
+ }
+ get {
+ return errorLevel;
+ }
+ }
+
+ /** Sets the bytes that form the barcode. This bytes should
+ * be interpreted in the codepage Cp437.
+ * @param text the bytes that form the barcode
+ */
+ public byte[] Text {
+ set {
+ this.text = value;
+ }
+ get {
+ return text;
+ }
+ }
+
+ /** Sets the text that will form the barcode. This text is converted
+ * to bytes using the encoding Cp437.
+ * @param s the text that will form the barcode
+ * @throws UnsupportedEncodingException if the encoding Cp437 is not supported
+ */
+ public void SetText(String s) {
+ this.text = PdfEncodings.ConvertToBytes(s, "cp437");
+ }
+
+ /** Sets the options to generate the barcode. This can be all
+ * the PDF417_*
constants.
+ * @param options the options to generate the barcode
+ */
+ public int Options {
+ set {
+ this.options = value;
+ }
+ get {
+ return options;
+ }
+ }
+
+ /** Sets the barcode aspect ratio. A ratio or 0.5 will make the
+ * barcode width twice as large as the height.
+ * @param aspectRatio the barcode aspect ratio
+ */
+ public float AspectRatio {
+ set {
+ this.aspectRatio = value;
+ }
+ get {
+ return aspectRatio;
+ }
+ }
+
+ /** Sets the Y pixel height relative to X. It is usually 3.
+ * @param yHeight the Y pixel height relative to X
+ */
+ public float YHeight {
+ set {
+ this.yHeight = value;
+ }
+ get {
+ return yHeight;
+ }
+ }
+
+ protected const int START_PATTERN = 0x1fea8;
+ protected const int STOP_PATTERN = 0x3fa29;
+ protected const int START_CODE_SIZE = 17;
+ protected const int STOP_SIZE = 18;
+ protected const int MOD = 929;
+ protected const int ALPHA = 0x10000;
+ protected const int LOWER = 0x20000;
+ protected const int MIXED = 0x40000;
+ protected const int PUNCTUATION = 0x80000;
+ protected const int ISBYTE = 0x100000;
+ protected const int BYTESHIFT = 913;
+ protected const int PL = 25;
+ protected const int LL = 27;
+ protected const int AS = 27;
+ protected const int ML = 28;
+ protected const int AL = 28;
+ protected const int PS = 29;
+ protected const int PAL = 29;
+ protected const int SPACE = 26;
+ protected const int TEXT_MODE = 900;
+ protected const int BYTE_MODE_6 = 924;
+ protected const int BYTE_MODE = 901;
+ protected const int NUMERIC_MODE = 902;
+ protected const int ABSOLUTE_MAX_TEXT_SIZE = 5420;
+ protected const int MAX_DATA_CODEWORDS = 926;
+ protected const int MACRO_SEGMENT_ID=928;
+ protected const int MACRO_LAST_SEGMENT=922;
+
+ private const string MIXED_SET = "0123456789&\r\t,:#-.$/+%*=^";
+ private const string PUNCTUATION_SET = ";<>@[\\]_`~!\r\t,:\n-.$/\"|*()?{}'";
+
+ private static readonly int[][] CLUSTERS = new int[][]
+ {new int[]{
+ 0x1d5c0, 0x1eaf0, 0x1f57c, 0x1d4e0, 0x1ea78, 0x1f53e, 0x1a8c0, 0x1d470,
+ 0x1a860, 0x15040, 0x1a830, 0x15020, 0x1adc0, 0x1d6f0, 0x1eb7c, 0x1ace0,
+ 0x1d678, 0x1eb3e, 0x158c0, 0x1ac70, 0x15860, 0x15dc0, 0x1aef0, 0x1d77c,
+ 0x15ce0, 0x1ae78, 0x1d73e, 0x15c70, 0x1ae3c, 0x15ef0, 0x1af7c, 0x15e78,
+ 0x1af3e, 0x15f7c, 0x1f5fa, 0x1d2e0, 0x1e978, 0x1f4be, 0x1a4c0, 0x1d270,
+ 0x1e93c, 0x1a460, 0x1d238, 0x14840, 0x1a430, 0x1d21c, 0x14820, 0x1a418,
+ 0x14810, 0x1a6e0, 0x1d378, 0x1e9be, 0x14cc0, 0x1a670, 0x1d33c, 0x14c60,
+ 0x1a638, 0x1d31e, 0x14c30, 0x1a61c, 0x14ee0, 0x1a778, 0x1d3be, 0x14e70,
+ 0x1a73c, 0x14e38, 0x1a71e, 0x14f78, 0x1a7be, 0x14f3c, 0x14f1e, 0x1a2c0,
+ 0x1d170, 0x1e8bc, 0x1a260, 0x1d138, 0x1e89e, 0x14440, 0x1a230, 0x1d11c,
+ 0x14420, 0x1a218, 0x14410, 0x14408, 0x146c0, 0x1a370, 0x1d1bc, 0x14660,
+ 0x1a338, 0x1d19e, 0x14630, 0x1a31c, 0x14618, 0x1460c, 0x14770, 0x1a3bc,
+ 0x14738, 0x1a39e, 0x1471c, 0x147bc, 0x1a160, 0x1d0b8, 0x1e85e, 0x14240,
+ 0x1a130, 0x1d09c, 0x14220, 0x1a118, 0x1d08e, 0x14210, 0x1a10c, 0x14208,
+ 0x1a106, 0x14360, 0x1a1b8, 0x1d0de, 0x14330, 0x1a19c, 0x14318, 0x1a18e,
+ 0x1430c, 0x14306, 0x1a1de, 0x1438e, 0x14140, 0x1a0b0, 0x1d05c, 0x14120,
+ 0x1a098, 0x1d04e, 0x14110, 0x1a08c, 0x14108, 0x1a086, 0x14104, 0x141b0,
+ 0x14198, 0x1418c, 0x140a0, 0x1d02e, 0x1a04c, 0x1a046, 0x14082, 0x1cae0,
+ 0x1e578, 0x1f2be, 0x194c0, 0x1ca70, 0x1e53c, 0x19460, 0x1ca38, 0x1e51e,
+ 0x12840, 0x19430, 0x12820, 0x196e0, 0x1cb78, 0x1e5be, 0x12cc0, 0x19670,
+ 0x1cb3c, 0x12c60, 0x19638, 0x12c30, 0x12c18, 0x12ee0, 0x19778, 0x1cbbe,
+ 0x12e70, 0x1973c, 0x12e38, 0x12e1c, 0x12f78, 0x197be, 0x12f3c, 0x12fbe,
+ 0x1dac0, 0x1ed70, 0x1f6bc, 0x1da60, 0x1ed38, 0x1f69e, 0x1b440, 0x1da30,
+ 0x1ed1c, 0x1b420, 0x1da18, 0x1ed0e, 0x1b410, 0x1da0c, 0x192c0, 0x1c970,
+ 0x1e4bc, 0x1b6c0, 0x19260, 0x1c938, 0x1e49e, 0x1b660, 0x1db38, 0x1ed9e,
+ 0x16c40, 0x12420, 0x19218, 0x1c90e, 0x16c20, 0x1b618, 0x16c10, 0x126c0,
+ 0x19370, 0x1c9bc, 0x16ec0, 0x12660, 0x19338, 0x1c99e, 0x16e60, 0x1b738,
+ 0x1db9e, 0x16e30, 0x12618, 0x16e18, 0x12770, 0x193bc, 0x16f70, 0x12738,
+ 0x1939e, 0x16f38, 0x1b79e, 0x16f1c, 0x127bc, 0x16fbc, 0x1279e, 0x16f9e,
+ 0x1d960, 0x1ecb8, 0x1f65e, 0x1b240, 0x1d930, 0x1ec9c, 0x1b220, 0x1d918,
+ 0x1ec8e, 0x1b210, 0x1d90c, 0x1b208, 0x1b204, 0x19160, 0x1c8b8, 0x1e45e,
+ 0x1b360, 0x19130, 0x1c89c, 0x16640, 0x12220, 0x1d99c, 0x1c88e, 0x16620,
+ 0x12210, 0x1910c, 0x16610, 0x1b30c, 0x19106, 0x12204, 0x12360, 0x191b8,
+ 0x1c8de, 0x16760, 0x12330, 0x1919c, 0x16730, 0x1b39c, 0x1918e, 0x16718,
+ 0x1230c, 0x12306, 0x123b8, 0x191de, 0x167b8, 0x1239c, 0x1679c, 0x1238e,
+ 0x1678e, 0x167de, 0x1b140, 0x1d8b0, 0x1ec5c, 0x1b120, 0x1d898, 0x1ec4e,
+ 0x1b110, 0x1d88c, 0x1b108, 0x1d886, 0x1b104, 0x1b102, 0x12140, 0x190b0,
+ 0x1c85c, 0x16340, 0x12120, 0x19098, 0x1c84e, 0x16320, 0x1b198, 0x1d8ce,
+ 0x16310, 0x12108, 0x19086, 0x16308, 0x1b186, 0x16304, 0x121b0, 0x190dc,
+ 0x163b0, 0x12198, 0x190ce, 0x16398, 0x1b1ce, 0x1638c, 0x12186, 0x16386,
+ 0x163dc, 0x163ce, 0x1b0a0, 0x1d858, 0x1ec2e, 0x1b090, 0x1d84c, 0x1b088,
+ 0x1d846, 0x1b084, 0x1b082, 0x120a0, 0x19058, 0x1c82e, 0x161a0, 0x12090,
+ 0x1904c, 0x16190, 0x1b0cc, 0x19046, 0x16188, 0x12084, 0x16184, 0x12082,
+ 0x120d8, 0x161d8, 0x161cc, 0x161c6, 0x1d82c, 0x1d826, 0x1b042, 0x1902c,
+ 0x12048, 0x160c8, 0x160c4, 0x160c2, 0x18ac0, 0x1c570, 0x1e2bc, 0x18a60,
+ 0x1c538, 0x11440, 0x18a30, 0x1c51c, 0x11420, 0x18a18, 0x11410, 0x11408,
+ 0x116c0, 0x18b70, 0x1c5bc, 0x11660, 0x18b38, 0x1c59e, 0x11630, 0x18b1c,
+ 0x11618, 0x1160c, 0x11770, 0x18bbc, 0x11738, 0x18b9e, 0x1171c, 0x117bc,
+ 0x1179e, 0x1cd60, 0x1e6b8, 0x1f35e, 0x19a40, 0x1cd30, 0x1e69c, 0x19a20,
+ 0x1cd18, 0x1e68e, 0x19a10, 0x1cd0c, 0x19a08, 0x1cd06, 0x18960, 0x1c4b8,
+ 0x1e25e, 0x19b60, 0x18930, 0x1c49c, 0x13640, 0x11220, 0x1cd9c, 0x1c48e,
+ 0x13620, 0x19b18, 0x1890c, 0x13610, 0x11208, 0x13608, 0x11360, 0x189b8,
+ 0x1c4de, 0x13760, 0x11330, 0x1cdde, 0x13730, 0x19b9c, 0x1898e, 0x13718,
+ 0x1130c, 0x1370c, 0x113b8, 0x189de, 0x137b8, 0x1139c, 0x1379c, 0x1138e,
+ 0x113de, 0x137de, 0x1dd40, 0x1eeb0, 0x1f75c, 0x1dd20, 0x1ee98, 0x1f74e,
+ 0x1dd10, 0x1ee8c, 0x1dd08, 0x1ee86, 0x1dd04, 0x19940, 0x1ccb0, 0x1e65c,
+ 0x1bb40, 0x19920, 0x1eedc, 0x1e64e, 0x1bb20, 0x1dd98, 0x1eece, 0x1bb10,
+ 0x19908, 0x1cc86, 0x1bb08, 0x1dd86, 0x19902, 0x11140, 0x188b0, 0x1c45c,
+ 0x13340, 0x11120, 0x18898, 0x1c44e, 0x17740, 0x13320, 0x19998, 0x1ccce,
+ 0x17720, 0x1bb98, 0x1ddce, 0x18886, 0x17710, 0x13308, 0x19986, 0x17708,
+ 0x11102, 0x111b0, 0x188dc, 0x133b0, 0x11198, 0x188ce, 0x177b0, 0x13398,
+ 0x199ce, 0x17798, 0x1bbce, 0x11186, 0x13386, 0x111dc, 0x133dc, 0x111ce,
+ 0x177dc, 0x133ce, 0x1dca0, 0x1ee58, 0x1f72e, 0x1dc90, 0x1ee4c, 0x1dc88,
+ 0x1ee46, 0x1dc84, 0x1dc82, 0x198a0, 0x1cc58, 0x1e62e, 0x1b9a0, 0x19890,
+ 0x1ee6e, 0x1b990, 0x1dccc, 0x1cc46, 0x1b988, 0x19884, 0x1b984, 0x19882,
+ 0x1b982, 0x110a0, 0x18858, 0x1c42e, 0x131a0, 0x11090, 0x1884c, 0x173a0,
+ 0x13190, 0x198cc, 0x18846, 0x17390, 0x1b9cc, 0x11084, 0x17388, 0x13184,
+ 0x11082, 0x13182, 0x110d8, 0x1886e, 0x131d8, 0x110cc, 0x173d8, 0x131cc,
+ 0x110c6, 0x173cc, 0x131c6, 0x110ee, 0x173ee, 0x1dc50, 0x1ee2c, 0x1dc48,
+ 0x1ee26, 0x1dc44, 0x1dc42, 0x19850, 0x1cc2c, 0x1b8d0, 0x19848, 0x1cc26,
+ 0x1b8c8, 0x1dc66, 0x1b8c4, 0x19842, 0x1b8c2, 0x11050, 0x1882c, 0x130d0,
+ 0x11048, 0x18826, 0x171d0, 0x130c8, 0x19866, 0x171c8, 0x1b8e6, 0x11042,
+ 0x171c4, 0x130c2, 0x171c2, 0x130ec, 0x171ec, 0x171e6, 0x1ee16, 0x1dc22,
+ 0x1cc16, 0x19824, 0x19822, 0x11028, 0x13068, 0x170e8, 0x11022, 0x13062,
+ 0x18560, 0x10a40, 0x18530, 0x10a20, 0x18518, 0x1c28e, 0x10a10, 0x1850c,
+ 0x10a08, 0x18506, 0x10b60, 0x185b8, 0x1c2de, 0x10b30, 0x1859c, 0x10b18,
+ 0x1858e, 0x10b0c, 0x10b06, 0x10bb8, 0x185de, 0x10b9c, 0x10b8e, 0x10bde,
+ 0x18d40, 0x1c6b0, 0x1e35c, 0x18d20, 0x1c698, 0x18d10, 0x1c68c, 0x18d08,
+ 0x1c686, 0x18d04, 0x10940, 0x184b0, 0x1c25c, 0x11b40, 0x10920, 0x1c6dc,
+ 0x1c24e, 0x11b20, 0x18d98, 0x1c6ce, 0x11b10, 0x10908, 0x18486, 0x11b08,
+ 0x18d86, 0x10902, 0x109b0, 0x184dc, 0x11bb0, 0x10998, 0x184ce, 0x11b98,
+ 0x18dce, 0x11b8c, 0x10986, 0x109dc, 0x11bdc, 0x109ce, 0x11bce, 0x1cea0,
+ 0x1e758, 0x1f3ae, 0x1ce90, 0x1e74c, 0x1ce88, 0x1e746, 0x1ce84, 0x1ce82,
+ 0x18ca0, 0x1c658, 0x19da0, 0x18c90, 0x1c64c, 0x19d90, 0x1cecc, 0x1c646,
+ 0x19d88, 0x18c84, 0x19d84, 0x18c82, 0x19d82, 0x108a0, 0x18458, 0x119a0,
+ 0x10890, 0x1c66e, 0x13ba0, 0x11990, 0x18ccc, 0x18446, 0x13b90, 0x19dcc,
+ 0x10884, 0x13b88, 0x11984, 0x10882, 0x11982, 0x108d8, 0x1846e, 0x119d8,
+ 0x108cc, 0x13bd8, 0x119cc, 0x108c6, 0x13bcc, 0x119c6, 0x108ee, 0x119ee,
+ 0x13bee, 0x1ef50, 0x1f7ac, 0x1ef48, 0x1f7a6, 0x1ef44, 0x1ef42, 0x1ce50,
+ 0x1e72c, 0x1ded0, 0x1ef6c, 0x1e726, 0x1dec8, 0x1ef66, 0x1dec4, 0x1ce42,
+ 0x1dec2, 0x18c50, 0x1c62c, 0x19cd0, 0x18c48, 0x1c626, 0x1bdd0, 0x19cc8,
+ 0x1ce66, 0x1bdc8, 0x1dee6, 0x18c42, 0x1bdc4, 0x19cc2, 0x1bdc2, 0x10850,
+ 0x1842c, 0x118d0, 0x10848, 0x18426, 0x139d0, 0x118c8, 0x18c66, 0x17bd0,
+ 0x139c8, 0x19ce6, 0x10842, 0x17bc8, 0x1bde6, 0x118c2, 0x17bc4, 0x1086c,
+ 0x118ec, 0x10866, 0x139ec, 0x118e6, 0x17bec, 0x139e6, 0x17be6, 0x1ef28,
+ 0x1f796, 0x1ef24, 0x1ef22, 0x1ce28, 0x1e716, 0x1de68, 0x1ef36, 0x1de64,
+ 0x1ce22, 0x1de62, 0x18c28, 0x1c616, 0x19c68, 0x18c24, 0x1bce8, 0x19c64,
+ 0x18c22, 0x1bce4, 0x19c62, 0x1bce2, 0x10828, 0x18416, 0x11868, 0x18c36,
+ 0x138e8, 0x11864, 0x10822, 0x179e8, 0x138e4, 0x11862, 0x179e4, 0x138e2,
+ 0x179e2, 0x11876, 0x179f6, 0x1ef12, 0x1de34, 0x1de32, 0x19c34, 0x1bc74,
+ 0x1bc72, 0x11834, 0x13874, 0x178f4, 0x178f2, 0x10540, 0x10520, 0x18298,
+ 0x10510, 0x10508, 0x10504, 0x105b0, 0x10598, 0x1058c, 0x10586, 0x105dc,
+ 0x105ce, 0x186a0, 0x18690, 0x1c34c, 0x18688, 0x1c346, 0x18684, 0x18682,
+ 0x104a0, 0x18258, 0x10da0, 0x186d8, 0x1824c, 0x10d90, 0x186cc, 0x10d88,
+ 0x186c6, 0x10d84, 0x10482, 0x10d82, 0x104d8, 0x1826e, 0x10dd8, 0x186ee,
+ 0x10dcc, 0x104c6, 0x10dc6, 0x104ee, 0x10dee, 0x1c750, 0x1c748, 0x1c744,
+ 0x1c742, 0x18650, 0x18ed0, 0x1c76c, 0x1c326, 0x18ec8, 0x1c766, 0x18ec4,
+ 0x18642, 0x18ec2, 0x10450, 0x10cd0, 0x10448, 0x18226, 0x11dd0, 0x10cc8,
+ 0x10444, 0x11dc8, 0x10cc4, 0x10442, 0x11dc4, 0x10cc2, 0x1046c, 0x10cec,
+ 0x10466, 0x11dec, 0x10ce6, 0x11de6, 0x1e7a8, 0x1e7a4, 0x1e7a2, 0x1c728,
+ 0x1cf68, 0x1e7b6, 0x1cf64, 0x1c722, 0x1cf62, 0x18628, 0x1c316, 0x18e68,
+ 0x1c736, 0x19ee8, 0x18e64, 0x18622, 0x19ee4, 0x18e62, 0x19ee2, 0x10428,
+ 0x18216, 0x10c68, 0x18636, 0x11ce8, 0x10c64, 0x10422, 0x13de8, 0x11ce4,
+ 0x10c62, 0x13de4, 0x11ce2, 0x10436, 0x10c76, 0x11cf6, 0x13df6, 0x1f7d4,
+ 0x1f7d2, 0x1e794, 0x1efb4, 0x1e792, 0x1efb2, 0x1c714, 0x1cf34, 0x1c712,
+ 0x1df74, 0x1cf32, 0x1df72, 0x18614, 0x18e34, 0x18612, 0x19e74, 0x18e32,
+ 0x1bef4
+ }, new int[]{
+ 0x1f560, 0x1fab8, 0x1ea40, 0x1f530, 0x1fa9c, 0x1ea20, 0x1f518, 0x1fa8e,
+ 0x1ea10, 0x1f50c, 0x1ea08, 0x1f506, 0x1ea04, 0x1eb60, 0x1f5b8, 0x1fade,
+ 0x1d640, 0x1eb30, 0x1f59c, 0x1d620, 0x1eb18, 0x1f58e, 0x1d610, 0x1eb0c,
+ 0x1d608, 0x1eb06, 0x1d604, 0x1d760, 0x1ebb8, 0x1f5de, 0x1ae40, 0x1d730,
+ 0x1eb9c, 0x1ae20, 0x1d718, 0x1eb8e, 0x1ae10, 0x1d70c, 0x1ae08, 0x1d706,
+ 0x1ae04, 0x1af60, 0x1d7b8, 0x1ebde, 0x15e40, 0x1af30, 0x1d79c, 0x15e20,
+ 0x1af18, 0x1d78e, 0x15e10, 0x1af0c, 0x15e08, 0x1af06, 0x15f60, 0x1afb8,
+ 0x1d7de, 0x15f30, 0x1af9c, 0x15f18, 0x1af8e, 0x15f0c, 0x15fb8, 0x1afde,
+ 0x15f9c, 0x15f8e, 0x1e940, 0x1f4b0, 0x1fa5c, 0x1e920, 0x1f498, 0x1fa4e,
+ 0x1e910, 0x1f48c, 0x1e908, 0x1f486, 0x1e904, 0x1e902, 0x1d340, 0x1e9b0,
+ 0x1f4dc, 0x1d320, 0x1e998, 0x1f4ce, 0x1d310, 0x1e98c, 0x1d308, 0x1e986,
+ 0x1d304, 0x1d302, 0x1a740, 0x1d3b0, 0x1e9dc, 0x1a720, 0x1d398, 0x1e9ce,
+ 0x1a710, 0x1d38c, 0x1a708, 0x1d386, 0x1a704, 0x1a702, 0x14f40, 0x1a7b0,
+ 0x1d3dc, 0x14f20, 0x1a798, 0x1d3ce, 0x14f10, 0x1a78c, 0x14f08, 0x1a786,
+ 0x14f04, 0x14fb0, 0x1a7dc, 0x14f98, 0x1a7ce, 0x14f8c, 0x14f86, 0x14fdc,
+ 0x14fce, 0x1e8a0, 0x1f458, 0x1fa2e, 0x1e890, 0x1f44c, 0x1e888, 0x1f446,
+ 0x1e884, 0x1e882, 0x1d1a0, 0x1e8d8, 0x1f46e, 0x1d190, 0x1e8cc, 0x1d188,
+ 0x1e8c6, 0x1d184, 0x1d182, 0x1a3a0, 0x1d1d8, 0x1e8ee, 0x1a390, 0x1d1cc,
+ 0x1a388, 0x1d1c6, 0x1a384, 0x1a382, 0x147a0, 0x1a3d8, 0x1d1ee, 0x14790,
+ 0x1a3cc, 0x14788, 0x1a3c6, 0x14784, 0x14782, 0x147d8, 0x1a3ee, 0x147cc,
+ 0x147c6, 0x147ee, 0x1e850, 0x1f42c, 0x1e848, 0x1f426, 0x1e844, 0x1e842,
+ 0x1d0d0, 0x1e86c, 0x1d0c8, 0x1e866, 0x1d0c4, 0x1d0c2, 0x1a1d0, 0x1d0ec,
+ 0x1a1c8, 0x1d0e6, 0x1a1c4, 0x1a1c2, 0x143d0, 0x1a1ec, 0x143c8, 0x1a1e6,
+ 0x143c4, 0x143c2, 0x143ec, 0x143e6, 0x1e828, 0x1f416, 0x1e824, 0x1e822,
+ 0x1d068, 0x1e836, 0x1d064, 0x1d062, 0x1a0e8, 0x1d076, 0x1a0e4, 0x1a0e2,
+ 0x141e8, 0x1a0f6, 0x141e4, 0x141e2, 0x1e814, 0x1e812, 0x1d034, 0x1d032,
+ 0x1a074, 0x1a072, 0x1e540, 0x1f2b0, 0x1f95c, 0x1e520, 0x1f298, 0x1f94e,
+ 0x1e510, 0x1f28c, 0x1e508, 0x1f286, 0x1e504, 0x1e502, 0x1cb40, 0x1e5b0,
+ 0x1f2dc, 0x1cb20, 0x1e598, 0x1f2ce, 0x1cb10, 0x1e58c, 0x1cb08, 0x1e586,
+ 0x1cb04, 0x1cb02, 0x19740, 0x1cbb0, 0x1e5dc, 0x19720, 0x1cb98, 0x1e5ce,
+ 0x19710, 0x1cb8c, 0x19708, 0x1cb86, 0x19704, 0x19702, 0x12f40, 0x197b0,
+ 0x1cbdc, 0x12f20, 0x19798, 0x1cbce, 0x12f10, 0x1978c, 0x12f08, 0x19786,
+ 0x12f04, 0x12fb0, 0x197dc, 0x12f98, 0x197ce, 0x12f8c, 0x12f86, 0x12fdc,
+ 0x12fce, 0x1f6a0, 0x1fb58, 0x16bf0, 0x1f690, 0x1fb4c, 0x169f8, 0x1f688,
+ 0x1fb46, 0x168fc, 0x1f684, 0x1f682, 0x1e4a0, 0x1f258, 0x1f92e, 0x1eda0,
+ 0x1e490, 0x1fb6e, 0x1ed90, 0x1f6cc, 0x1f246, 0x1ed88, 0x1e484, 0x1ed84,
+ 0x1e482, 0x1ed82, 0x1c9a0, 0x1e4d8, 0x1f26e, 0x1dba0, 0x1c990, 0x1e4cc,
+ 0x1db90, 0x1edcc, 0x1e4c6, 0x1db88, 0x1c984, 0x1db84, 0x1c982, 0x1db82,
+ 0x193a0, 0x1c9d8, 0x1e4ee, 0x1b7a0, 0x19390, 0x1c9cc, 0x1b790, 0x1dbcc,
+ 0x1c9c6, 0x1b788, 0x19384, 0x1b784, 0x19382, 0x1b782, 0x127a0, 0x193d8,
+ 0x1c9ee, 0x16fa0, 0x12790, 0x193cc, 0x16f90, 0x1b7cc, 0x193c6, 0x16f88,
+ 0x12784, 0x16f84, 0x12782, 0x127d8, 0x193ee, 0x16fd8, 0x127cc, 0x16fcc,
+ 0x127c6, 0x16fc6, 0x127ee, 0x1f650, 0x1fb2c, 0x165f8, 0x1f648, 0x1fb26,
+ 0x164fc, 0x1f644, 0x1647e, 0x1f642, 0x1e450, 0x1f22c, 0x1ecd0, 0x1e448,
+ 0x1f226, 0x1ecc8, 0x1f666, 0x1ecc4, 0x1e442, 0x1ecc2, 0x1c8d0, 0x1e46c,
+ 0x1d9d0, 0x1c8c8, 0x1e466, 0x1d9c8, 0x1ece6, 0x1d9c4, 0x1c8c2, 0x1d9c2,
+ 0x191d0, 0x1c8ec, 0x1b3d0, 0x191c8, 0x1c8e6, 0x1b3c8, 0x1d9e6, 0x1b3c4,
+ 0x191c2, 0x1b3c2, 0x123d0, 0x191ec, 0x167d0, 0x123c8, 0x191e6, 0x167c8,
+ 0x1b3e6, 0x167c4, 0x123c2, 0x167c2, 0x123ec, 0x167ec, 0x123e6, 0x167e6,
+ 0x1f628, 0x1fb16, 0x162fc, 0x1f624, 0x1627e, 0x1f622, 0x1e428, 0x1f216,
+ 0x1ec68, 0x1f636, 0x1ec64, 0x1e422, 0x1ec62, 0x1c868, 0x1e436, 0x1d8e8,
+ 0x1c864, 0x1d8e4, 0x1c862, 0x1d8e2, 0x190e8, 0x1c876, 0x1b1e8, 0x1d8f6,
+ 0x1b1e4, 0x190e2, 0x1b1e2, 0x121e8, 0x190f6, 0x163e8, 0x121e4, 0x163e4,
+ 0x121e2, 0x163e2, 0x121f6, 0x163f6, 0x1f614, 0x1617e, 0x1f612, 0x1e414,
+ 0x1ec34, 0x1e412, 0x1ec32, 0x1c834, 0x1d874, 0x1c832, 0x1d872, 0x19074,
+ 0x1b0f4, 0x19072, 0x1b0f2, 0x120f4, 0x161f4, 0x120f2, 0x161f2, 0x1f60a,
+ 0x1e40a, 0x1ec1a, 0x1c81a, 0x1d83a, 0x1903a, 0x1b07a, 0x1e2a0, 0x1f158,
+ 0x1f8ae, 0x1e290, 0x1f14c, 0x1e288, 0x1f146, 0x1e284, 0x1e282, 0x1c5a0,
+ 0x1e2d8, 0x1f16e, 0x1c590, 0x1e2cc, 0x1c588, 0x1e2c6, 0x1c584, 0x1c582,
+ 0x18ba0, 0x1c5d8, 0x1e2ee, 0x18b90, 0x1c5cc, 0x18b88, 0x1c5c6, 0x18b84,
+ 0x18b82, 0x117a0, 0x18bd8, 0x1c5ee, 0x11790, 0x18bcc, 0x11788, 0x18bc6,
+ 0x11784, 0x11782, 0x117d8, 0x18bee, 0x117cc, 0x117c6, 0x117ee, 0x1f350,
+ 0x1f9ac, 0x135f8, 0x1f348, 0x1f9a6, 0x134fc, 0x1f344, 0x1347e, 0x1f342,
+ 0x1e250, 0x1f12c, 0x1e6d0, 0x1e248, 0x1f126, 0x1e6c8, 0x1f366, 0x1e6c4,
+ 0x1e242, 0x1e6c2, 0x1c4d0, 0x1e26c, 0x1cdd0, 0x1c4c8, 0x1e266, 0x1cdc8,
+ 0x1e6e6, 0x1cdc4, 0x1c4c2, 0x1cdc2, 0x189d0, 0x1c4ec, 0x19bd0, 0x189c8,
+ 0x1c4e6, 0x19bc8, 0x1cde6, 0x19bc4, 0x189c2, 0x19bc2, 0x113d0, 0x189ec,
+ 0x137d0, 0x113c8, 0x189e6, 0x137c8, 0x19be6, 0x137c4, 0x113c2, 0x137c2,
+ 0x113ec, 0x137ec, 0x113e6, 0x137e6, 0x1fba8, 0x175f0, 0x1bafc, 0x1fba4,
+ 0x174f8, 0x1ba7e, 0x1fba2, 0x1747c, 0x1743e, 0x1f328, 0x1f996, 0x132fc,
+ 0x1f768, 0x1fbb6, 0x176fc, 0x1327e, 0x1f764, 0x1f322, 0x1767e, 0x1f762,
+ 0x1e228, 0x1f116, 0x1e668, 0x1e224, 0x1eee8, 0x1f776, 0x1e222, 0x1eee4,
+ 0x1e662, 0x1eee2, 0x1c468, 0x1e236, 0x1cce8, 0x1c464, 0x1dde8, 0x1cce4,
+ 0x1c462, 0x1dde4, 0x1cce2, 0x1dde2, 0x188e8, 0x1c476, 0x199e8, 0x188e4,
+ 0x1bbe8, 0x199e4, 0x188e2, 0x1bbe4, 0x199e2, 0x1bbe2, 0x111e8, 0x188f6,
+ 0x133e8, 0x111e4, 0x177e8, 0x133e4, 0x111e2, 0x177e4, 0x133e2, 0x177e2,
+ 0x111f6, 0x133f6, 0x1fb94, 0x172f8, 0x1b97e, 0x1fb92, 0x1727c, 0x1723e,
+ 0x1f314, 0x1317e, 0x1f734, 0x1f312, 0x1737e, 0x1f732, 0x1e214, 0x1e634,
+ 0x1e212, 0x1ee74, 0x1e632, 0x1ee72, 0x1c434, 0x1cc74, 0x1c432, 0x1dcf4,
+ 0x1cc72, 0x1dcf2, 0x18874, 0x198f4, 0x18872, 0x1b9f4, 0x198f2, 0x1b9f2,
+ 0x110f4, 0x131f4, 0x110f2, 0x173f4, 0x131f2, 0x173f2, 0x1fb8a, 0x1717c,
+ 0x1713e, 0x1f30a, 0x1f71a, 0x1e20a, 0x1e61a, 0x1ee3a, 0x1c41a, 0x1cc3a,
+ 0x1dc7a, 0x1883a, 0x1987a, 0x1b8fa, 0x1107a, 0x130fa, 0x171fa, 0x170be,
+ 0x1e150, 0x1f0ac, 0x1e148, 0x1f0a6, 0x1e144, 0x1e142, 0x1c2d0, 0x1e16c,
+ 0x1c2c8, 0x1e166, 0x1c2c4, 0x1c2c2, 0x185d0, 0x1c2ec, 0x185c8, 0x1c2e6,
+ 0x185c4, 0x185c2, 0x10bd0, 0x185ec, 0x10bc8, 0x185e6, 0x10bc4, 0x10bc2,
+ 0x10bec, 0x10be6, 0x1f1a8, 0x1f8d6, 0x11afc, 0x1f1a4, 0x11a7e, 0x1f1a2,
+ 0x1e128, 0x1f096, 0x1e368, 0x1e124, 0x1e364, 0x1e122, 0x1e362, 0x1c268,
+ 0x1e136, 0x1c6e8, 0x1c264, 0x1c6e4, 0x1c262, 0x1c6e2, 0x184e8, 0x1c276,
+ 0x18de8, 0x184e4, 0x18de4, 0x184e2, 0x18de2, 0x109e8, 0x184f6, 0x11be8,
+ 0x109e4, 0x11be4, 0x109e2, 0x11be2, 0x109f6, 0x11bf6, 0x1f9d4, 0x13af8,
+ 0x19d7e, 0x1f9d2, 0x13a7c, 0x13a3e, 0x1f194, 0x1197e, 0x1f3b4, 0x1f192,
+ 0x13b7e, 0x1f3b2, 0x1e114, 0x1e334, 0x1e112, 0x1e774, 0x1e332, 0x1e772,
+ 0x1c234, 0x1c674, 0x1c232, 0x1cef4, 0x1c672, 0x1cef2, 0x18474, 0x18cf4,
+ 0x18472, 0x19df4, 0x18cf2, 0x19df2, 0x108f4, 0x119f4, 0x108f2, 0x13bf4,
+ 0x119f2, 0x13bf2, 0x17af0, 0x1bd7c, 0x17a78, 0x1bd3e, 0x17a3c, 0x17a1e,
+ 0x1f9ca, 0x1397c, 0x1fbda, 0x17b7c, 0x1393e, 0x17b3e, 0x1f18a, 0x1f39a,
+ 0x1f7ba, 0x1e10a, 0x1e31a, 0x1e73a, 0x1ef7a, 0x1c21a, 0x1c63a, 0x1ce7a,
+ 0x1defa, 0x1843a, 0x18c7a, 0x19cfa, 0x1bdfa, 0x1087a, 0x118fa, 0x139fa,
+ 0x17978, 0x1bcbe, 0x1793c, 0x1791e, 0x138be, 0x179be, 0x178bc, 0x1789e,
+ 0x1785e, 0x1e0a8, 0x1e0a4, 0x1e0a2, 0x1c168, 0x1e0b6, 0x1c164, 0x1c162,
+ 0x182e8, 0x1c176, 0x182e4, 0x182e2, 0x105e8, 0x182f6, 0x105e4, 0x105e2,
+ 0x105f6, 0x1f0d4, 0x10d7e, 0x1f0d2, 0x1e094, 0x1e1b4, 0x1e092, 0x1e1b2,
+ 0x1c134, 0x1c374, 0x1c132, 0x1c372, 0x18274, 0x186f4, 0x18272, 0x186f2,
+ 0x104f4, 0x10df4, 0x104f2, 0x10df2, 0x1f8ea, 0x11d7c, 0x11d3e, 0x1f0ca,
+ 0x1f1da, 0x1e08a, 0x1e19a, 0x1e3ba, 0x1c11a, 0x1c33a, 0x1c77a, 0x1823a,
+ 0x1867a, 0x18efa, 0x1047a, 0x10cfa, 0x11dfa, 0x13d78, 0x19ebe, 0x13d3c,
+ 0x13d1e, 0x11cbe, 0x13dbe, 0x17d70, 0x1bebc, 0x17d38, 0x1be9e, 0x17d1c,
+ 0x17d0e, 0x13cbc, 0x17dbc, 0x13c9e, 0x17d9e, 0x17cb8, 0x1be5e, 0x17c9c,
+ 0x17c8e, 0x13c5e, 0x17cde, 0x17c5c, 0x17c4e, 0x17c2e, 0x1c0b4, 0x1c0b2,
+ 0x18174, 0x18172, 0x102f4, 0x102f2, 0x1e0da, 0x1c09a, 0x1c1ba, 0x1813a,
+ 0x1837a, 0x1027a, 0x106fa, 0x10ebe, 0x11ebc, 0x11e9e, 0x13eb8, 0x19f5e,
+ 0x13e9c, 0x13e8e, 0x11e5e, 0x13ede, 0x17eb0, 0x1bf5c, 0x17e98, 0x1bf4e,
+ 0x17e8c, 0x17e86, 0x13e5c, 0x17edc, 0x13e4e, 0x17ece, 0x17e58, 0x1bf2e,
+ 0x17e4c, 0x17e46, 0x13e2e, 0x17e6e, 0x17e2c, 0x17e26, 0x10f5e, 0x11f5c,
+ 0x11f4e, 0x13f58, 0x19fae, 0x13f4c, 0x13f46, 0x11f2e, 0x13f6e, 0x13f2c,
+ 0x13f26
+ }, new int[]{
+ 0x1abe0, 0x1d5f8, 0x153c0, 0x1a9f0, 0x1d4fc, 0x151e0, 0x1a8f8, 0x1d47e,
+ 0x150f0, 0x1a87c, 0x15078, 0x1fad0, 0x15be0, 0x1adf8, 0x1fac8, 0x159f0,
+ 0x1acfc, 0x1fac4, 0x158f8, 0x1ac7e, 0x1fac2, 0x1587c, 0x1f5d0, 0x1faec,
+ 0x15df8, 0x1f5c8, 0x1fae6, 0x15cfc, 0x1f5c4, 0x15c7e, 0x1f5c2, 0x1ebd0,
+ 0x1f5ec, 0x1ebc8, 0x1f5e6, 0x1ebc4, 0x1ebc2, 0x1d7d0, 0x1ebec, 0x1d7c8,
+ 0x1ebe6, 0x1d7c4, 0x1d7c2, 0x1afd0, 0x1d7ec, 0x1afc8, 0x1d7e6, 0x1afc4,
+ 0x14bc0, 0x1a5f0, 0x1d2fc, 0x149e0, 0x1a4f8, 0x1d27e, 0x148f0, 0x1a47c,
+ 0x14878, 0x1a43e, 0x1483c, 0x1fa68, 0x14df0, 0x1a6fc, 0x1fa64, 0x14cf8,
+ 0x1a67e, 0x1fa62, 0x14c7c, 0x14c3e, 0x1f4e8, 0x1fa76, 0x14efc, 0x1f4e4,
+ 0x14e7e, 0x1f4e2, 0x1e9e8, 0x1f4f6, 0x1e9e4, 0x1e9e2, 0x1d3e8, 0x1e9f6,
+ 0x1d3e4, 0x1d3e2, 0x1a7e8, 0x1d3f6, 0x1a7e4, 0x1a7e2, 0x145e0, 0x1a2f8,
+ 0x1d17e, 0x144f0, 0x1a27c, 0x14478, 0x1a23e, 0x1443c, 0x1441e, 0x1fa34,
+ 0x146f8, 0x1a37e, 0x1fa32, 0x1467c, 0x1463e, 0x1f474, 0x1477e, 0x1f472,
+ 0x1e8f4, 0x1e8f2, 0x1d1f4, 0x1d1f2, 0x1a3f4, 0x1a3f2, 0x142f0, 0x1a17c,
+ 0x14278, 0x1a13e, 0x1423c, 0x1421e, 0x1fa1a, 0x1437c, 0x1433e, 0x1f43a,
+ 0x1e87a, 0x1d0fa, 0x14178, 0x1a0be, 0x1413c, 0x1411e, 0x141be, 0x140bc,
+ 0x1409e, 0x12bc0, 0x195f0, 0x1cafc, 0x129e0, 0x194f8, 0x1ca7e, 0x128f0,
+ 0x1947c, 0x12878, 0x1943e, 0x1283c, 0x1f968, 0x12df0, 0x196fc, 0x1f964,
+ 0x12cf8, 0x1967e, 0x1f962, 0x12c7c, 0x12c3e, 0x1f2e8, 0x1f976, 0x12efc,
+ 0x1f2e4, 0x12e7e, 0x1f2e2, 0x1e5e8, 0x1f2f6, 0x1e5e4, 0x1e5e2, 0x1cbe8,
+ 0x1e5f6, 0x1cbe4, 0x1cbe2, 0x197e8, 0x1cbf6, 0x197e4, 0x197e2, 0x1b5e0,
+ 0x1daf8, 0x1ed7e, 0x169c0, 0x1b4f0, 0x1da7c, 0x168e0, 0x1b478, 0x1da3e,
+ 0x16870, 0x1b43c, 0x16838, 0x1b41e, 0x1681c, 0x125e0, 0x192f8, 0x1c97e,
+ 0x16de0, 0x124f0, 0x1927c, 0x16cf0, 0x1b67c, 0x1923e, 0x16c78, 0x1243c,
+ 0x16c3c, 0x1241e, 0x16c1e, 0x1f934, 0x126f8, 0x1937e, 0x1fb74, 0x1f932,
+ 0x16ef8, 0x1267c, 0x1fb72, 0x16e7c, 0x1263e, 0x16e3e, 0x1f274, 0x1277e,
+ 0x1f6f4, 0x1f272, 0x16f7e, 0x1f6f2, 0x1e4f4, 0x1edf4, 0x1e4f2, 0x1edf2,
+ 0x1c9f4, 0x1dbf4, 0x1c9f2, 0x1dbf2, 0x193f4, 0x193f2, 0x165c0, 0x1b2f0,
+ 0x1d97c, 0x164e0, 0x1b278, 0x1d93e, 0x16470, 0x1b23c, 0x16438, 0x1b21e,
+ 0x1641c, 0x1640e, 0x122f0, 0x1917c, 0x166f0, 0x12278, 0x1913e, 0x16678,
+ 0x1b33e, 0x1663c, 0x1221e, 0x1661e, 0x1f91a, 0x1237c, 0x1fb3a, 0x1677c,
+ 0x1233e, 0x1673e, 0x1f23a, 0x1f67a, 0x1e47a, 0x1ecfa, 0x1c8fa, 0x1d9fa,
+ 0x191fa, 0x162e0, 0x1b178, 0x1d8be, 0x16270, 0x1b13c, 0x16238, 0x1b11e,
+ 0x1621c, 0x1620e, 0x12178, 0x190be, 0x16378, 0x1213c, 0x1633c, 0x1211e,
+ 0x1631e, 0x121be, 0x163be, 0x16170, 0x1b0bc, 0x16138, 0x1b09e, 0x1611c,
+ 0x1610e, 0x120bc, 0x161bc, 0x1209e, 0x1619e, 0x160b8, 0x1b05e, 0x1609c,
+ 0x1608e, 0x1205e, 0x160de, 0x1605c, 0x1604e, 0x115e0, 0x18af8, 0x1c57e,
+ 0x114f0, 0x18a7c, 0x11478, 0x18a3e, 0x1143c, 0x1141e, 0x1f8b4, 0x116f8,
+ 0x18b7e, 0x1f8b2, 0x1167c, 0x1163e, 0x1f174, 0x1177e, 0x1f172, 0x1e2f4,
+ 0x1e2f2, 0x1c5f4, 0x1c5f2, 0x18bf4, 0x18bf2, 0x135c0, 0x19af0, 0x1cd7c,
+ 0x134e0, 0x19a78, 0x1cd3e, 0x13470, 0x19a3c, 0x13438, 0x19a1e, 0x1341c,
+ 0x1340e, 0x112f0, 0x1897c, 0x136f0, 0x11278, 0x1893e, 0x13678, 0x19b3e,
+ 0x1363c, 0x1121e, 0x1361e, 0x1f89a, 0x1137c, 0x1f9ba, 0x1377c, 0x1133e,
+ 0x1373e, 0x1f13a, 0x1f37a, 0x1e27a, 0x1e6fa, 0x1c4fa, 0x1cdfa, 0x189fa,
+ 0x1bae0, 0x1dd78, 0x1eebe, 0x174c0, 0x1ba70, 0x1dd3c, 0x17460, 0x1ba38,
+ 0x1dd1e, 0x17430, 0x1ba1c, 0x17418, 0x1ba0e, 0x1740c, 0x132e0, 0x19978,
+ 0x1ccbe, 0x176e0, 0x13270, 0x1993c, 0x17670, 0x1bb3c, 0x1991e, 0x17638,
+ 0x1321c, 0x1761c, 0x1320e, 0x1760e, 0x11178, 0x188be, 0x13378, 0x1113c,
+ 0x17778, 0x1333c, 0x1111e, 0x1773c, 0x1331e, 0x1771e, 0x111be, 0x133be,
+ 0x177be, 0x172c0, 0x1b970, 0x1dcbc, 0x17260, 0x1b938, 0x1dc9e, 0x17230,
+ 0x1b91c, 0x17218, 0x1b90e, 0x1720c, 0x17206, 0x13170, 0x198bc, 0x17370,
+ 0x13138, 0x1989e, 0x17338, 0x1b99e, 0x1731c, 0x1310e, 0x1730e, 0x110bc,
+ 0x131bc, 0x1109e, 0x173bc, 0x1319e, 0x1739e, 0x17160, 0x1b8b8, 0x1dc5e,
+ 0x17130, 0x1b89c, 0x17118, 0x1b88e, 0x1710c, 0x17106, 0x130b8, 0x1985e,
+ 0x171b8, 0x1309c, 0x1719c, 0x1308e, 0x1718e, 0x1105e, 0x130de, 0x171de,
+ 0x170b0, 0x1b85c, 0x17098, 0x1b84e, 0x1708c, 0x17086, 0x1305c, 0x170dc,
+ 0x1304e, 0x170ce, 0x17058, 0x1b82e, 0x1704c, 0x17046, 0x1302e, 0x1706e,
+ 0x1702c, 0x17026, 0x10af0, 0x1857c, 0x10a78, 0x1853e, 0x10a3c, 0x10a1e,
+ 0x10b7c, 0x10b3e, 0x1f0ba, 0x1e17a, 0x1c2fa, 0x185fa, 0x11ae0, 0x18d78,
+ 0x1c6be, 0x11a70, 0x18d3c, 0x11a38, 0x18d1e, 0x11a1c, 0x11a0e, 0x10978,
+ 0x184be, 0x11b78, 0x1093c, 0x11b3c, 0x1091e, 0x11b1e, 0x109be, 0x11bbe,
+ 0x13ac0, 0x19d70, 0x1cebc, 0x13a60, 0x19d38, 0x1ce9e, 0x13a30, 0x19d1c,
+ 0x13a18, 0x19d0e, 0x13a0c, 0x13a06, 0x11970, 0x18cbc, 0x13b70, 0x11938,
+ 0x18c9e, 0x13b38, 0x1191c, 0x13b1c, 0x1190e, 0x13b0e, 0x108bc, 0x119bc,
+ 0x1089e, 0x13bbc, 0x1199e, 0x13b9e, 0x1bd60, 0x1deb8, 0x1ef5e, 0x17a40,
+ 0x1bd30, 0x1de9c, 0x17a20, 0x1bd18, 0x1de8e, 0x17a10, 0x1bd0c, 0x17a08,
+ 0x1bd06, 0x17a04, 0x13960, 0x19cb8, 0x1ce5e, 0x17b60, 0x13930, 0x19c9c,
+ 0x17b30, 0x1bd9c, 0x19c8e, 0x17b18, 0x1390c, 0x17b0c, 0x13906, 0x17b06,
+ 0x118b8, 0x18c5e, 0x139b8, 0x1189c, 0x17bb8, 0x1399c, 0x1188e, 0x17b9c,
+ 0x1398e, 0x17b8e, 0x1085e, 0x118de, 0x139de, 0x17bde, 0x17940, 0x1bcb0,
+ 0x1de5c, 0x17920, 0x1bc98, 0x1de4e, 0x17910, 0x1bc8c, 0x17908, 0x1bc86,
+ 0x17904, 0x17902, 0x138b0, 0x19c5c, 0x179b0, 0x13898, 0x19c4e, 0x17998,
+ 0x1bcce, 0x1798c, 0x13886, 0x17986, 0x1185c, 0x138dc, 0x1184e, 0x179dc,
+ 0x138ce, 0x179ce, 0x178a0, 0x1bc58, 0x1de2e, 0x17890, 0x1bc4c, 0x17888,
+ 0x1bc46, 0x17884, 0x17882, 0x13858, 0x19c2e, 0x178d8, 0x1384c, 0x178cc,
+ 0x13846, 0x178c6, 0x1182e, 0x1386e, 0x178ee, 0x17850, 0x1bc2c, 0x17848,
+ 0x1bc26, 0x17844, 0x17842, 0x1382c, 0x1786c, 0x13826, 0x17866, 0x17828,
+ 0x1bc16, 0x17824, 0x17822, 0x13816, 0x17836, 0x10578, 0x182be, 0x1053c,
+ 0x1051e, 0x105be, 0x10d70, 0x186bc, 0x10d38, 0x1869e, 0x10d1c, 0x10d0e,
+ 0x104bc, 0x10dbc, 0x1049e, 0x10d9e, 0x11d60, 0x18eb8, 0x1c75e, 0x11d30,
+ 0x18e9c, 0x11d18, 0x18e8e, 0x11d0c, 0x11d06, 0x10cb8, 0x1865e, 0x11db8,
+ 0x10c9c, 0x11d9c, 0x10c8e, 0x11d8e, 0x1045e, 0x10cde, 0x11dde, 0x13d40,
+ 0x19eb0, 0x1cf5c, 0x13d20, 0x19e98, 0x1cf4e, 0x13d10, 0x19e8c, 0x13d08,
+ 0x19e86, 0x13d04, 0x13d02, 0x11cb0, 0x18e5c, 0x13db0, 0x11c98, 0x18e4e,
+ 0x13d98, 0x19ece, 0x13d8c, 0x11c86, 0x13d86, 0x10c5c, 0x11cdc, 0x10c4e,
+ 0x13ddc, 0x11cce, 0x13dce, 0x1bea0, 0x1df58, 0x1efae, 0x1be90, 0x1df4c,
+ 0x1be88, 0x1df46, 0x1be84, 0x1be82, 0x13ca0, 0x19e58, 0x1cf2e, 0x17da0,
+ 0x13c90, 0x19e4c, 0x17d90, 0x1becc, 0x19e46, 0x17d88, 0x13c84, 0x17d84,
+ 0x13c82, 0x17d82, 0x11c58, 0x18e2e, 0x13cd8, 0x11c4c, 0x17dd8, 0x13ccc,
+ 0x11c46, 0x17dcc, 0x13cc6, 0x17dc6, 0x10c2e, 0x11c6e, 0x13cee, 0x17dee,
+ 0x1be50, 0x1df2c, 0x1be48, 0x1df26, 0x1be44, 0x1be42, 0x13c50, 0x19e2c,
+ 0x17cd0, 0x13c48, 0x19e26, 0x17cc8, 0x1be66, 0x17cc4, 0x13c42, 0x17cc2,
+ 0x11c2c, 0x13c6c, 0x11c26, 0x17cec, 0x13c66, 0x17ce6, 0x1be28, 0x1df16,
+ 0x1be24, 0x1be22, 0x13c28, 0x19e16, 0x17c68, 0x13c24, 0x17c64, 0x13c22,
+ 0x17c62, 0x11c16, 0x13c36, 0x17c76, 0x1be14, 0x1be12, 0x13c14, 0x17c34,
+ 0x13c12, 0x17c32, 0x102bc, 0x1029e, 0x106b8, 0x1835e, 0x1069c, 0x1068e,
+ 0x1025e, 0x106de, 0x10eb0, 0x1875c, 0x10e98, 0x1874e, 0x10e8c, 0x10e86,
+ 0x1065c, 0x10edc, 0x1064e, 0x10ece, 0x11ea0, 0x18f58, 0x1c7ae, 0x11e90,
+ 0x18f4c, 0x11e88, 0x18f46, 0x11e84, 0x11e82, 0x10e58, 0x1872e, 0x11ed8,
+ 0x18f6e, 0x11ecc, 0x10e46, 0x11ec6, 0x1062e, 0x10e6e, 0x11eee, 0x19f50,
+ 0x1cfac, 0x19f48, 0x1cfa6, 0x19f44, 0x19f42, 0x11e50, 0x18f2c, 0x13ed0,
+ 0x19f6c, 0x18f26, 0x13ec8, 0x11e44, 0x13ec4, 0x11e42, 0x13ec2, 0x10e2c,
+ 0x11e6c, 0x10e26, 0x13eec, 0x11e66, 0x13ee6, 0x1dfa8, 0x1efd6, 0x1dfa4,
+ 0x1dfa2, 0x19f28, 0x1cf96, 0x1bf68, 0x19f24, 0x1bf64, 0x19f22, 0x1bf62,
+ 0x11e28, 0x18f16, 0x13e68, 0x11e24, 0x17ee8, 0x13e64, 0x11e22, 0x17ee4,
+ 0x13e62, 0x17ee2, 0x10e16, 0x11e36, 0x13e76, 0x17ef6, 0x1df94, 0x1df92,
+ 0x19f14, 0x1bf34, 0x19f12, 0x1bf32, 0x11e14, 0x13e34, 0x11e12, 0x17e74,
+ 0x13e32, 0x17e72, 0x1df8a, 0x19f0a, 0x1bf1a, 0x11e0a, 0x13e1a, 0x17e3a,
+ 0x1035c, 0x1034e, 0x10758, 0x183ae, 0x1074c, 0x10746, 0x1032e, 0x1076e,
+ 0x10f50, 0x187ac, 0x10f48, 0x187a6, 0x10f44, 0x10f42, 0x1072c, 0x10f6c,
+ 0x10726, 0x10f66, 0x18fa8, 0x1c7d6, 0x18fa4, 0x18fa2, 0x10f28, 0x18796,
+ 0x11f68, 0x18fb6, 0x11f64, 0x10f22, 0x11f62, 0x10716, 0x10f36, 0x11f76,
+ 0x1cfd4, 0x1cfd2, 0x18f94, 0x19fb4, 0x18f92, 0x19fb2, 0x10f14, 0x11f34,
+ 0x10f12, 0x13f74, 0x11f32, 0x13f72, 0x1cfca, 0x18f8a, 0x19f9a, 0x10f0a,
+ 0x11f1a, 0x13f3a, 0x103ac, 0x103a6, 0x107a8, 0x183d6, 0x107a4, 0x107a2,
+ 0x10396, 0x107b6, 0x187d4, 0x187d2, 0x10794, 0x10fb4, 0x10792, 0x10fb2,
+ 0x1c7ea
+ }};
+
+ private static readonly int[][] ERROR_LEVEL = new int[][]
+ {new int[]{
+ 27, 917
+ }, new int[]{
+ 522, 568, 723, 809
+ }, new int[]{
+ 237, 308, 436, 284, 646, 653, 428, 379
+ }, new int[]{
+ 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65
+ }, new int[]{
+ 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517,
+ 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410
+ }, new int[]{
+ 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612,
+ 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184,
+ 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502,
+ 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543
+ }, new int[]{
+ 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415,
+ 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704,
+ 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569,
+ 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776,
+ 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898,
+ 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616,
+ 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34,
+ 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539
+ }, new int[]{
+ 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720,
+ 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757,
+ 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137,
+ 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884,
+ 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521,
+ 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470,
+ 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90,
+ 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134,
+ 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234,
+ 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621,
+ 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528,
+ 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550,
+ 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754,
+ 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532,
+ 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173,
+ 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10
+ }, new int[]{
+ 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492,
+ 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781,
+ 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534,
+ 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41,
+ 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741,
+ 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142,
+ 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258,
+ 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303,
+ 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402,
+ 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785,
+ 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543,
+ 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820,
+ 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578,
+ 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911,
+ 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408,
+ 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729,
+ 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772,
+ 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777,
+ 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45,
+ 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905,
+ 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341,
+ 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808,
+ 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249,
+ 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791,
+ 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437,
+ 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842,
+ 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316,
+ 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656,
+ 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433,
+ 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780,
+ 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647,
+ 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263
+ }};
+
+ /** Holds value of property outBits. */
+ private byte[] outBits;
+
+ /** Holds value of property bitColumns. */
+ private int bitColumns;
+
+ /** Holds value of property codeRows. */
+ private int codeRows;
+
+ /** Holds value of property codeColumns. */
+ private int codeColumns;
+
+ /** Holds value of property codewords. */
+ private int[] codewords = new int[MAX_DATA_CODEWORDS + 2];
+
+ /** Holds value of property lenCodewords. */
+ private int lenCodewords;
+
+ /** Holds value of property errorLevel. */
+ private int errorLevel;
+
+ /** Holds value of property text. */
+ private byte[] text;
+
+ /** Holds value of property options. */
+ private int options;
+
+ /** Holds value of property aspectRatio. */
+ private float aspectRatio;
+
+ /** Holds value of property yHeight. */
+ private float yHeight;
+
+ protected class Segment {
+ public char type;
+ public int start;
+ public int end;
+
+ public Segment(char type, int start, int end) {
+ this.type = type;
+ this.start = start;
+ this.end = end;
+ }
+ }
+
+ protected class SegmentList {
+ protected ArrayList list = new ArrayList();
+
+ public void Add(char type, int start, int end) {
+ list.Add(new Segment(type, start, end));
+ }
+
+ public Segment Get(int idx) {
+ if (idx < 0 || idx >= list.Count)
+ return null;
+ return (Segment)list[idx];
+ }
+
+ public void Remove(int idx) {
+ if (idx < 0 || idx >= list.Count)
+ return;
+ list.RemoveAt(idx);
+ }
+
+ public int Size {
+ get {
+ return list.Count;
+ }
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BarcodePostnet.cs b/iTechSharp/iTextSharp/text/pdf/BarcodePostnet.cs
new file mode 100644
index 0000000..0aa745f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BarcodePostnet.cs
@@ -0,0 +1,219 @@
+using System;
+using iTextSharp.text;
+
+/*
+ * Copyright 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /** Implements the Postnet and Planet barcodes. The default parameters are:
+ *
+ *n = 72f / 22f; // distance between bars
+ *x = 0.02f * 72f; // bar width
+ *barHeight = 0.125f * 72f; // height of the tall bars
+ *size = 0.05f * 72f; // height of the short bars
+ *codeType = POSTNET; // type of code
+ *
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class BarcodePostnet : Barcode{
+
+ /** The bars for each character.
+ */
+ private static readonly byte[][] BARS = {
+ new byte[] {1,1,0,0,0},
+ new byte[] {0,0,0,1,1},
+ new byte[] {0,0,1,0,1},
+ new byte[] {0,0,1,1,0},
+ new byte[] {0,1,0,0,1},
+ new byte[] {0,1,0,1,0},
+ new byte[] {0,1,1,0,0},
+ new byte[] {1,0,0,0,1},
+ new byte[] {1,0,0,1,0},
+ new byte[] {1,0,1,0,0}
+ };
+
+ /** Creates new BarcodePostnet */
+ public BarcodePostnet() {
+ n = 72f / 22f; // distance between bars
+ x = 0.02f * 72f; // bar width
+ barHeight = 0.125f * 72f; // height of the tall bars
+ size = 0.05f * 72f; // height of the short bars
+ codeType = POSTNET; // type of code
+ }
+
+ /** Creates the bars for Postnet.
+ * @param text the code to be created without checksum
+ * @return the bars
+ */
+ public static byte[] GetBarsPostnet(string text) {
+ int total = 0;
+ for (int k = text.Length - 1; k >= 0; --k) {
+ int n = text[k] - '0';
+ total += n;
+ }
+ text += (char)(((10 - (total % 10)) % 10) + '0');
+ byte[] bars = new byte[text.Length * 5 + 2];
+ bars[0] = 1;
+ bars[bars.Length - 1] = 1;
+ for (int k = 0; k < text.Length; ++k) {
+ int c = text[k] - '0';
+ Array.Copy(BARS[c], 0, bars, k * 5 + 1, 5);
+ }
+ return bars;
+ }
+
+ /** Gets the maximum area that the barcode and the text, if
+ * any, will occupy. The lower left corner is always (0, 0).
+ * @return the size the barcode occupies.
+ */
+ public override Rectangle BarcodeSize {
+ get {
+ float width = ((code.Length + 1) * 5 + 1) * n + x;
+ return new Rectangle(width, barHeight);
+ }
+ }
+
+ /** Places the barcode in a PdfContentByte
. The
+ * barcode is always placed at coodinates (0, 0). Use the
+ * translation matrix to move it elsewhere.
+ *
+ * @param cb the
+ *
+ *
+ * barColor
+ * textColor
+ *
+ *
+ *
+ * null
+ * null
+ *
+ *
+ *
+ * barColor
+ * null
+ * barColor
+ *
+ *
+ * null
+ * textColor
+ *
text painted with textColor
+ *
+ *
+ * barColor
+ * textColor
+ * barColor
text painted with textColor
PdfContentByte
where the barcode will be placed
+ * @param barColor the color of the bars. It can be null
+ * @param textColor the color of the text. It can be null
+ * @return the dimensions the barcode occupies
+ */
+ public override Rectangle PlaceBarcode(PdfContentByte cb, Color barColor, Color textColor) {
+ if (barColor != null)
+ cb.SetColorFill(barColor);
+ byte[] bars = GetBarsPostnet(code);
+ byte flip = 1;
+ if (codeType == PLANET) {
+ flip = 0;
+ bars[0] = 0;
+ bars[bars.Length - 1] = 0;
+ }
+ float startX = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ cb.Rectangle(startX, 0, x - inkSpreading, bars[k] == flip ? barHeight : size);
+ startX += n;
+ }
+ cb.Fill();
+ return this.BarcodeSize;
+ }
+
+ public override System.Drawing.Image CreateDrawingImage(System.Drawing.Color foreground, System.Drawing.Color background) {
+ int barWidth = (int)x;
+ if (barWidth <= 0)
+ barWidth = 1;
+ int barDistance = (int)n;
+ if (barDistance <= barWidth)
+ barDistance = barWidth + 1;
+ int barShort = (int)size;
+ if (barShort <= 0)
+ barShort = 1;
+ int barTall = (int)barHeight;
+ if (barTall <= barShort)
+ barTall = barShort + 1;
+ byte[] bars = GetBarsPostnet(code);
+ int width = bars.Length * barDistance;
+ byte flip = 1;
+ if (codeType == PLANET) {
+ flip = 0;
+ bars[0] = 0;
+ bars[bars.Length - 1] = 0;
+ }
+ System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, barTall);
+ int seg1 = barTall - barShort;
+ for (int i = 0; i < seg1; ++i) {
+ int idx = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ bool dot = (bars[k] == flip);
+ for (int j = 0; j < barDistance; ++j) {
+ bmp.SetPixel(idx++, i, (dot && j < barWidth) ? foreground : background);
+ }
+ }
+ }
+ for (int i = seg1; i < barTall; ++i) {
+ int idx = 0;
+ for (int k = 0; k < bars.Length; ++k) {
+ for (int j = 0; j < barDistance; ++j) {
+ bmp.SetPixel(idx++, i, (j < barWidth) ? foreground : background);
+ }
+ }
+ }
+ return bmp;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BaseField.cs b/iTechSharp/iTextSharp/text/pdf/BaseField.cs
new file mode 100644
index 0000000..9d73757
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BaseField.cs
@@ -0,0 +1,630 @@
+using System;
+using System.Collections;
+using System.Text;
+/*
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf
+{
+ public abstract class BaseField {
+
+ /** A thin border with 1 point width. */
+ public const float BORDER_WIDTH_THIN = 1;
+ /** A medium border with 2 point width. */
+ public const float BORDER_WIDTH_MEDIUM = 2;
+ /** A thick border with 3 point width. */
+ public const float BORDER_WIDTH_THICK = 3;
+ /** The field is visible. */
+ public const int VISIBLE = 0;
+ /** The field is hidden. */
+ public const int HIDDEN = 1;
+ /** The field is visible but does not print. */
+ public const int VISIBLE_BUT_DOES_NOT_PRINT = 2;
+ /** The field is hidden but is printable. */
+ public const int HIDDEN_BUT_PRINTABLE = 3;
+ /** The user may not change the value of the field. */
+ public const int READ_ONLY = PdfFormField.FF_READ_ONLY;
+ /** The field must have a value at the time it is exported by a submit-form
+ * action.
+ */
+ public const int REQUIRED = PdfFormField.FF_REQUIRED;
+ /** The field may contain multiple lines of text.
+ * This flag is only meaningful with text fields.
+ */
+ public const int MULTILINE = PdfFormField.FF_MULTILINE;
+ /** The field will not scroll (horizontally for single-line
+ * fields, vertically for multiple-line fields) to accommodate more text
+ * than will fit within its annotation rectangle. Once the field is full, no
+ * further text will be accepted.
+ */
+ public const int DO_NOT_SCROLL = PdfFormField.FF_DONOTSCROLL;
+ /** The field is intended for entering a secure password that should
+ * not be echoed visibly to the screen.
+ */
+ public const int PASSWORD = PdfFormField.FF_PASSWORD;
+ /** The text entered in the field represents the pathname of
+ * a file whose contents are to be submitted as the value of the field.
+ */
+ public const int FILE_SELECTION = PdfFormField.FF_FILESELECT;
+ /** The text entered in the field will not be spell-checked.
+ * This flag is meaningful only in text fields and in combo
+ * fields with the EDIT
flag set.
+ */
+ public const int DO_NOT_SPELL_CHECK = PdfFormField.FF_DONOTSPELLCHECK;
+ /** If set the combo box includes an editable text box as well as a drop list; if
+ * clear, it includes only a drop list.
+ * This flag is only meaningful with combo fields.
+ */
+ public const int EDIT = PdfFormField.FF_EDIT;
+
+ /**
+ * combo box flag.
+ */
+ public const int COMB = PdfFormField.FF_COMB;
+
+ protected float borderWidth = BORDER_WIDTH_THIN;
+ protected int borderStyle = PdfBorderDictionary.STYLE_SOLID;
+ protected Color borderColor;
+ protected Color backgroundColor;
+ protected Color textColor;
+ protected BaseFont font;
+ protected float fontSize = 0;
+ protected int alignment = Element.ALIGN_LEFT;
+ protected PdfWriter writer;
+ protected String text;
+ protected Rectangle box;
+
+ /** Holds value of property rotation. */
+ protected int rotation = 0;
+
+ /** Holds value of property visibility. */
+ protected int visibility;
+
+ /** Holds value of property fieldName. */
+ protected String fieldName;
+
+ /** Holds value of property options. */
+ protected int options;
+
+ /** Holds value of property maxCharacterLength. */
+ protected int maxCharacterLength;
+
+ private static Hashtable fieldKeys = new Hashtable();
+
+ static BaseField() {
+ foreach (DictionaryEntry entry in PdfCopyFieldsImp.fieldKeys)
+ fieldKeys[entry.Key] = entry.Value;
+ fieldKeys[PdfName.T] = 1;
+ }
+ /** Creates a new TextField
.
+ * @param writer the document PdfWriter
+ * @param box the field location and dimensions
+ * @param fieldName the field name. If null
only the widget keys
+ * will be included in the field allowing it to be used as a kid field.
+ */
+ public BaseField(PdfWriter writer, Rectangle box, String fieldName) {
+ this.writer = writer;
+ Box = box;
+ this.fieldName = fieldName;
+ }
+
+ protected BaseFont RealFont {
+ get {
+ if (font == null)
+ return BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, false);
+ else
+ return font;
+ }
+ }
+
+ protected PdfAppearance GetBorderAppearance() {
+ PdfAppearance app = PdfAppearance.CreateAppearance(writer, box.Width, box.Height);
+ switch (rotation) {
+ case 90:
+ app.SetMatrix(0, 1, -1, 0, box.Height, 0);
+ break;
+ case 180:
+ app.SetMatrix(-1, 0, 0, -1, box.Width, box.Height);
+ break;
+ case 270:
+ app.SetMatrix(0, -1, 1, 0, 0, box.Width);
+ break;
+ }
+ app.SaveState();
+ // background
+ if (backgroundColor != null) {
+ app.SetColorFill(backgroundColor);
+ app.Rectangle(0, 0, box.Width, box.Height);
+ app.Fill();
+ }
+ // border
+ if (borderStyle == PdfBorderDictionary.STYLE_UNDERLINE) {
+ if (borderWidth != 0 && borderColor != null) {
+ app.SetColorStroke(borderColor);
+ app.SetLineWidth(borderWidth);
+ app.MoveTo(0, borderWidth / 2);
+ app.LineTo(box.Width, borderWidth / 2);
+ app.Stroke();
+ }
+ }
+ else if (borderStyle == PdfBorderDictionary.STYLE_BEVELED) {
+ if (borderWidth != 0 && borderColor != null) {
+ app.SetColorStroke(borderColor);
+ app.SetLineWidth(borderWidth);
+ app.Rectangle(borderWidth / 2, borderWidth / 2, box.Width - borderWidth, box.Height - borderWidth);
+ app.Stroke();
+ }
+ // beveled
+ Color actual = backgroundColor;
+ if (actual == null)
+ actual = Color.WHITE;
+ app.SetGrayFill(1);
+ DrawTopFrame(app);
+ app.SetColorFill(actual.Darker());
+ DrawBottomFrame(app);
+ }
+ else if (borderStyle == PdfBorderDictionary.STYLE_INSET) {
+ if (borderWidth != 0 && borderColor != null) {
+ app.SetColorStroke(borderColor);
+ app.SetLineWidth(borderWidth);
+ app.Rectangle(borderWidth / 2, borderWidth / 2, box.Width - borderWidth, box.Height - borderWidth);
+ app.Stroke();
+ }
+ // inset
+ app.SetGrayFill(0.5f);
+ DrawTopFrame(app);
+ app.SetGrayFill(0.75f);
+ DrawBottomFrame(app);
+ }
+ else {
+ if (borderWidth != 0 && borderColor != null) {
+ if (borderStyle == PdfBorderDictionary.STYLE_DASHED)
+ app.SetLineDash(3, 0);
+ app.SetColorStroke(borderColor);
+ app.SetLineWidth(borderWidth);
+ app.Rectangle(borderWidth / 2, borderWidth / 2, box.Width - borderWidth, box.Height - borderWidth);
+ app.Stroke();
+ if ((options & COMB) != 0 && maxCharacterLength > 1) {
+ float step = box.Width / maxCharacterLength;
+ float yb = borderWidth / 2;
+ float yt = box.Height - borderWidth / 2;
+ for (int k = 1; k < maxCharacterLength; ++k) {
+ float x = step * k;
+ app.MoveTo(x, yb);
+ app.LineTo(x, yt);
+ }
+ app.Stroke();
+ }
+ }
+ }
+ app.RestoreState();
+ return app;
+ }
+
+ protected static ArrayList GetHardBreaks(String text) {
+ ArrayList arr = new ArrayList();
+ char[] cs = text.ToCharArray();
+ int len = cs.Length;
+ StringBuilder buf = new StringBuilder();
+ for (int k = 0; k < len; ++k) {
+ char c = cs[k];
+ if (c == '\r') {
+ if (k + 1 < len && cs[k + 1] == '\n')
+ ++k;
+ arr.Add(buf.ToString());
+ buf = new StringBuilder();
+ }
+ else if (c == '\n') {
+ arr.Add(buf.ToString());
+ buf = new StringBuilder();
+ }
+ else
+ buf.Append(c);
+ }
+ arr.Add(buf.ToString());
+ return arr;
+ }
+
+ protected static void TrimRight(StringBuilder buf) {
+ int len = buf.Length;
+ while (true) {
+ if (len == 0)
+ return;
+ if (buf[--len] != ' ')
+ return;
+ buf.Length = len;
+ }
+ }
+
+ protected static ArrayList BreakLines(ArrayList breaks, BaseFont font, float fontSize, float width) {
+ ArrayList lines = new ArrayList();
+ StringBuilder buf = new StringBuilder();
+ for (int ck = 0; ck < breaks.Count; ++ck) {
+ buf.Length = 0;
+ float w = 0;
+ char[] cs = ((String)breaks[ck]).ToCharArray();
+ int len = cs.Length;
+ // 0 inline first, 1 inline, 2 spaces
+ int state = 0;
+ int lastspace = -1;
+ char c = (char)0;
+ int refk = 0;
+ for (int k = 0; k < len; ++k) {
+ c = cs[k];
+ switch (state) {
+ case 0:
+ w += font.GetWidthPoint(c, fontSize);
+ buf.Append(c);
+ if (w > width) {
+ w = 0;
+ if (buf.Length > 1) {
+ --k;
+ buf.Length = buf.Length - 1;
+ }
+ lines.Add(buf.ToString());
+ buf.Length = 0;
+ refk = k;
+ if (c == ' ')
+ state = 2;
+ else
+ state = 1;
+ }
+ else {
+ if (c != ' ')
+ state = 1;
+ }
+ break;
+ case 1:
+ w += font.GetWidthPoint(c, fontSize);
+ buf.Append(c);
+ if (c == ' ')
+ lastspace = k;
+ if (w > width) {
+ w = 0;
+ if (lastspace >= 0) {
+ k = lastspace;
+ buf.Length = lastspace - refk;
+ TrimRight(buf);
+ lines.Add(buf.ToString());
+ buf.Length = 0;
+ refk = k;
+ lastspace = -1;
+ state = 2;
+ }
+ else {
+ if (buf.Length > 1) {
+ --k;
+ buf.Length = buf.Length - 1;
+ }
+ lines.Add(buf.ToString());
+ buf.Length = 0;
+ refk = k;
+ if (c == ' ')
+ state = 2;
+ }
+ }
+ break;
+ case 2:
+ if (c != ' ') {
+ w = 0;
+ --k;
+ state = 1;
+ }
+ break;
+ }
+ }
+ TrimRight(buf);
+ lines.Add(buf.ToString());
+ }
+ return lines;
+ }
+
+ private void DrawTopFrame(PdfAppearance app) {
+ app.MoveTo(borderWidth, borderWidth);
+ app.LineTo(borderWidth, box.Height - borderWidth);
+ app.LineTo(box.Width - borderWidth, box.Height - borderWidth);
+ app.LineTo(box.Width - 2 * borderWidth, box.Height - 2 * borderWidth);
+ app.LineTo(2 * borderWidth, box.Height - 2 * borderWidth);
+ app.LineTo(2 * borderWidth, 2 * borderWidth);
+ app.LineTo(borderWidth, borderWidth);
+ app.Fill();
+ }
+
+ private void DrawBottomFrame(PdfAppearance app) {
+ app.MoveTo(borderWidth, borderWidth);
+ app.LineTo(box.Width - borderWidth, borderWidth);
+ app.LineTo(box.Width - borderWidth, box.Height - borderWidth);
+ app.LineTo(box.Width - 2 * borderWidth, box.Height - 2 * borderWidth);
+ app.LineTo(box.Width - 2 * borderWidth, 2 * borderWidth);
+ app.LineTo(2 * borderWidth, 2 * borderWidth);
+ app.LineTo(borderWidth, borderWidth);
+ app.Fill();
+ }
+
+ /** Sets the border width in points. To eliminate the border
+ * set the border color to null
.
+ * @param borderWidth the border width in points
+ */
+ public float BorderWidth {
+ set {
+ this.borderWidth = value;
+ }
+ get {
+ return borderWidth;
+ }
+ }
+
+ /** Sets the border style. The styles are found in PdfBorderDictionary
+ * and can be STYLE_SOLID
, STYLE_DASHED
,
+ * STYLE_BEVELED
, STYLE_INSET
and
+ * STYLE_UNDERLINE
.
+ * @param borderStyle the border style
+ */
+ public int BorderStyle {
+ set {
+ this.borderStyle = value;
+ }
+ get {
+ return borderStyle;
+ }
+ }
+
+ /** Sets the border color. Set to null
to remove
+ * the border.
+ * @param borderColor the border color
+ */
+ public Color BorderColor {
+ set {
+ this.borderColor = value;
+ }
+ get {
+ return borderColor;
+ }
+ }
+
+ /** Sets the background color. Set to null
for
+ * transparent background.
+ * @param backgroundColor the background color
+ */
+ public Color BackgroundColor {
+ set {
+ this.backgroundColor = value;
+ }
+ get {
+ return backgroundColor;
+ }
+ }
+
+ /** Sets the text color. If null
the color used
+ * will be black.
+ * @param textColor the text color
+ */
+ public Color TextColor {
+ set {
+ this.textColor = value;
+ }
+ get {
+ return textColor;
+ }
+ }
+
+ /** Sets the text font. If null
then Helvetica
+ * will be used.
+ * @param font the text font
+ */
+ public BaseFont Font {
+ set {
+ this.font = value;
+ }
+ get {
+ return font;
+ }
+ }
+
+ /** Sets the font size. If 0 then auto-sizing will be used but
+ * only for text fields.
+ * @param fontSize the font size
+ */
+ public float FontSize {
+ set {
+ this.fontSize = value;
+ }
+ get {
+ return fontSize;
+ }
+ }
+
+ /** Sets the text horizontal alignment. It can be Element.ALIGN_LEFT
,
+ * Element.ALIGN_CENTER
and Element.ALIGN_RIGHT
.
+ * @param alignment the text horizontal alignment
+ */
+ public int Alignment {
+ set {
+ this.alignment = value;
+ }
+ get {
+ return alignment;
+ }
+ }
+
+ /** Sets the text for text fields.
+ * @param text the text
+ */
+ public string Text {
+ set {
+ this.text = value;
+ }
+ get {
+ return text;
+ }
+ }
+
+ /** Sets the field dimension and position.
+ * @param box the field dimension and position
+ */
+ public Rectangle Box {
+ set {
+ if (value == null)
+ box = null;
+ else {
+ box = new Rectangle(value);
+ box.Normalize();
+ }
+ }
+ get {
+ return box;
+ }
+ }
+
+ /** Sets the field rotation. This value should be the same as
+ * the page rotation where the field will be shown.
+ * @param rotation the field rotation
+ */
+ public int Rotation {
+ set {
+ if (value % 90 != 0)
+ throw new ArgumentException("Rotation must be a multiple of 90.");
+ rotation = (value % 360);
+ if (rotation < 0)
+ rotation += 360;
+ }
+ get {
+ return rotation;
+ }
+ }
+
+ /** Convenience method to set the field rotation the same as the
+ * page rotation.
+ * @param page the page
+ */
+ public void SetRotationFromPage(Rectangle page) {
+ Rotation = page.Rotation;
+ }
+
+ /** Sets the field visibility flag. This flags can be one of
+ * VISIBLE
, HIDDEN
, VISIBLE_BUT_DOES_NOT_PRINT
+ * and HIDDEN_BUT_PRINTABLE
.
+ * @param visibility field visibility flag
+ */
+ public int Visibility {
+ set {
+ this.visibility = value;
+ }
+ get {
+ return visibility;
+ }
+ }
+
+ /** Sets the field name.
+ * @param fieldName the field name. If null
only the widget keys
+ * will be included in the field allowing it to be used as a kid field.
+ */
+ public string FieldName {
+ set {
+ this.fieldName = value;
+ }
+ get {
+ return fieldName;
+ }
+ }
+
+ /** Sets the option flags. The option flags can be a combination by oring of
+ * READ_ONLY
, REQUIRED
,
+ * MULTILINE
, DO_NOT_SCROLL
,
+ * PASSWORD
, FILE_SELECTION
,
+ * DO_NOT_SPELL_CHECK
and EDIT
.
+ * @param options the option flags
+ */
+ public int Options {
+ set {
+ this.options = value;
+ }
+ get {
+ return options;
+ }
+ }
+
+ /** Sets the maximum length of the field’s text, in characters.
+ * It is only meaningful for text fields.
+ * @param maxCharacterLength the maximum length of the field’s text, in characters
+ */
+ public int MaxCharacterLength {
+ set {
+ this.maxCharacterLength = value;
+ }
+ get {
+ return maxCharacterLength;
+ }
+ }
+
+ public PdfWriter Writer {
+ get {
+ return writer;
+ }
+ set {
+ writer = value;
+ }
+ }
+
+ /**
+ * Moves the field keys from from
to to
. The moved keys
+ * are removed from from
.
+ * @param from the source
+ * @param to the destination. It may be null
+ */
+ public static void MoveFields(PdfDictionary from, PdfDictionary to) {
+ PdfName[] keys = new PdfName[from.Size];
+ foreach (PdfName key in keys) {
+ if (fieldKeys.ContainsKey(key)) {
+ if (to != null)
+ to.Put(key, from.Get(key));
+ from.Remove(key);
+ }
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/BaseFont.cs b/iTechSharp/iTextSharp/text/pdf/BaseFont.cs
new file mode 100644
index 0000000..c2b27ca
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BaseFont.cs
@@ -0,0 +1,1433 @@
+using System;
+using System.Globalization;
+using System.Reflection;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.util;
+using iTextSharp.text.xml.simpleparser;
+
+/*
+ * $Id: BaseFont.cs,v 1.17 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2000-2006 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /// encoding
is only used to map a char to the position inside
+ * the font, not to the expected char name.
+ */
+ protected bool fontSpecific = true;
+
+ /** cache for the fonts already used. */
+ protected static Hashtable fontCache = new Hashtable();
+
+ /** list of the 14 built in fonts. */
+ protected static Hashtable BuiltinFonts14 = new Hashtable();
+
+ /** Forces the output of the width array. Only matters for the 14
+ * built-in fonts.
+ */
+ protected bool forceWidthsOutput = false;
+
+ /** Converts char
directly to byte
+ * by casting.
+ */
+ protected bool directTextToByte = false;
+
+ /** Indicates if all the glyphs and widths for that particular
+ * encoding should be included in the document.
+ */
+ protected bool subset = true;
+
+ protected bool fastWinansi = false;
+
+ /**
+ * Custom encodings use this map to key the Unicode character
+ * to the single byte code.
+ */
+ protected IntHashtable specialMap;
+
+ protected static internal ArrayList resourceSearch = ArrayList.Synchronized(new ArrayList());
+
+ private static Random random = new Random();
+
+ static BaseFont() {
+ BuiltinFonts14.Add(COURIER, PdfName.COURIER);
+ BuiltinFonts14.Add(COURIER_BOLD, PdfName.COURIER_BOLD);
+ BuiltinFonts14.Add(COURIER_BOLDOBLIQUE, PdfName.COURIER_BOLDOBLIQUE);
+ BuiltinFonts14.Add(COURIER_OBLIQUE, PdfName.COURIER_OBLIQUE);
+ BuiltinFonts14.Add(HELVETICA, PdfName.HELVETICA);
+ BuiltinFonts14.Add(HELVETICA_BOLD, PdfName.HELVETICA_BOLD);
+ BuiltinFonts14.Add(HELVETICA_BOLDOBLIQUE, PdfName.HELVETICA_BOLDOBLIQUE);
+ BuiltinFonts14.Add(HELVETICA_OBLIQUE, PdfName.HELVETICA_OBLIQUE);
+ BuiltinFonts14.Add(SYMBOL, PdfName.SYMBOL);
+ BuiltinFonts14.Add(TIMES_ROMAN, PdfName.TIMES_ROMAN);
+ BuiltinFonts14.Add(TIMES_BOLD, PdfName.TIMES_BOLD);
+ BuiltinFonts14.Add(TIMES_BOLDITALIC, PdfName.TIMES_BOLDITALIC);
+ BuiltinFonts14.Add(TIMES_ITALIC, PdfName.TIMES_ITALIC);
+ BuiltinFonts14.Add(ZAPFDINGBATS, PdfName.ZAPFDINGBATS);
+ }
+
+ /** Generates the PDF stream with the Type1 and Truetype fonts returning
+ * a PdfStream.
+ */
+ internal class StreamFont : PdfStream {
+
+ /** Generates the PDF stream with the Type1 and Truetype fonts returning
+ * a PdfStream.
+ * @param contents the content of the stream
+ * @param lengths an array of int that describes the several lengths of each part of the font
+ */
+ internal StreamFont(byte[] contents, int[] lengths) {
+ bytes = contents;
+ Put(PdfName.LENGTH, new PdfNumber(bytes.Length));
+ for (int k = 0; k < lengths.Length; ++k) {
+ Put(new PdfName("Length" + (k + 1)), new PdfNumber(lengths[k]));
+ }
+ FlateCompress();
+ }
+
+ internal StreamFont(byte[] contents, string subType) {
+ bytes = contents;
+ Put(PdfName.LENGTH, new PdfNumber(bytes.Length));
+ if (subType != null)
+ Put(PdfName.SUBTYPE, new PdfName(subType));
+ FlateCompress();
+ }
+ }
+
+ /**
+ *Creates new BaseFont
+ */
+ protected BaseFont() {
+ }
+
+ /**
+ * Creates a new font. This will always be the default Helvetica font (not embedded).
+ * This method is introduced because Helvetica is used in many examples.
+ * @return a BaseFont object (Helvetica, Winansi, not embedded)
+ * @throws IOException This shouldn't occur ever
+ * @throws DocumentException This shouldn't occur ever
+ * @since 2.1.1
+ */
+ public static BaseFont CreateFont() {
+ return CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
+ }
+ /**
+ * Creates a new font. This font can be one of the 14 built in types,
+ * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the
+ * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier
+ * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An
+ * example would be "STSong-Light,Bold". Note that this modifiers do not work if
+ * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1".
+ * This would get the second font (indexes start at 0), in this case "MS PGothic".
+ *
+ * The "simple" encoding is recommended for TrueType fonts
+ * as the "full" encoding risks not matching the character with the right glyph
+ * if not done with care.
+ * The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be
+ * described by non standard names like the Tex math fonts. Each group of three elements
+ * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character
+ * used to access the glyph. The space must be assigned to character position 32 otherwise
+ * text justification will not work.
+ *
+ * "# simple 32 0020 0041 0042 0454"
+ *
+ *
+ * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
+ *
+ *
+ *
+ * createFont(name, encoding, embedded, true, null, null);
+ *
+ * @param name the name of the font or it's location on file
+ * @param encoding the encoding to be applied to this font
+ * @param embedded true if the font is to be embedded in the PDF
+ * @return returns a new font. This font may come from the cache
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ public static BaseFont CreateFont(string name, string encoding, bool embedded) {
+ return CreateFont(name, encoding, embedded, true, null, null);
+ }
+
+ /** Creates a new font. This font can be one of the 14 built in types,
+ * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the
+ * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier
+ * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An
+ * example would be "STSong-Light,Bold". Note that this modifiers do not work if
+ * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1".
+ * This would get the second font (indexes start at 0), in this case "MS PGothic".
+ * cached
.
+ * If the byte
arrays are present the font will be
+ * read from them instead of the name. A name is still required to identify
+ * the font type.
+ *
+ * The "simple" encoding is recommended for TrueType fonts
+ * as the "full" encoding risks not matching the character with the right glyph
+ * if not done with care.
+ * The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be
+ * described by non standard names like the Tex math fonts. Each group of three elements
+ * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character
+ * used to access the glyph. The space must be assigned to character position 32 otherwise
+ * text justification will not work.
+ *
+ * "# simple 32 0020 0041 0042 0454"
+ *
+ *
+ * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
+ *
+ * @param name the name of the font or it's location on file
+ * @param encoding the encoding to be applied to this font
+ * @param embedded true if the font is to be embedded in the PDF
+ * @param cached true if the font comes from the cache or is added to
+ * the cache if new, false if the font is always created new
+ * @param ttfAfm the true type font or the afm in a byte array
+ * @param pfb the pfb in a byte array
+ * @return returns a new font. This font may come from the cache but only if cached
+ * is true, otherwise it will always be created new
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ public static BaseFont CreateFont(string name, string encoding, bool embedded, bool cached, byte[] ttfAfm, byte[] pfb) {
+ return CreateFont(name, encoding, embedded, cached, ttfAfm, pfb, false);
+ }
+
+ /** Creates a new font. This font can be one of the 14 built in types,
+ * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the
+ * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier
+ * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An
+ * example would be "STSong-Light,Bold". Note that this modifiers do not work if
+ * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1".
+ * This would get the second font (indexes start at 0), in this case "MS PGothic".
+ * cached
.
+ * If the byte
arrays are present the font will be
+ * read from them instead of the name. A name is still required to identify
+ * the font type.
+ *
+ * The "simple" encoding is recommended for TrueType fonts
+ * as the "full" encoding risks not matching the character with the right glyph
+ * if not done with care.
+ * The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be
+ * described by non standard names like the Tex math fonts. Each group of three elements
+ * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character
+ * used to access the glyph. The space must be assigned to character position 32 otherwise
+ * text justification will not work.
+ *
+ * "# simple 32 0020 0041 0042 0454"
+ *
+ *
+ * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
+ *
+ * @param name the name of the font or it's location on file
+ * @param encoding the encoding to be applied to this font
+ * @param embedded true if the font is to be embedded in the PDF
+ * @param cached true if the font comes from the cache or is added to
+ * the cache if new, false if the font is always created new
+ * @param ttfAfm the true type font or the afm in a byte array
+ * @param pfb the pfb in a byte array
+ * @param noThrow if true will not throw an exception if the font is not recognized and will return null, if false will throw
+ * an exception if the font is not recognized. Note that even if true an exception may be thrown in some circumstances.
+ * This parameter is useful for FontFactory that may have to check many invalid font names before finding the right one
+ * @return returns a new font. This font may come from the cache but only if cached
+ * is true, otherwise it will always be created new
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ public static BaseFont CreateFont(string name, string encoding, bool embedded, bool cached, byte[] ttfAfm, byte[] pfb, bool noThrow) {
+ string nameBase = GetBaseName(name);
+ encoding = NormalizeEncoding(encoding);
+ bool isBuiltinFonts14 = BuiltinFonts14.ContainsKey(name);
+ bool isCJKFont = isBuiltinFonts14 ? false : CJKFont.IsCJKFont(nameBase, encoding);
+ if (isBuiltinFonts14 || isCJKFont)
+ embedded = false;
+ else if (encoding.Equals(IDENTITY_H) || encoding.Equals(IDENTITY_V))
+ embedded = true;
+ BaseFont fontFound = null;
+ BaseFont fontBuilt = null;
+ string key = name + "\n" + encoding + "\n" + embedded;
+ if (cached) {
+ lock (fontCache) {
+ fontFound = (BaseFont)fontCache[key];
+ }
+ if (fontFound != null)
+ return fontFound;
+ }
+ if (isBuiltinFonts14 || name.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".afm") || name.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".pfm")) {
+ fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb);
+ fontBuilt.fastWinansi = encoding.Equals(CP1252);
+ }
+ else if (nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf(".ttc,") > 0) {
+ if (encoding.Equals(IDENTITY_H) || encoding.Equals(IDENTITY_V))
+ fontBuilt = new TrueTypeFontUnicode(name, encoding, embedded, ttfAfm);
+ else {
+ fontBuilt = new TrueTypeFont(name, encoding, embedded, ttfAfm);
+ fontBuilt.fastWinansi = encoding.Equals(CP1252);
+ }
+ }
+ else if (isCJKFont)
+ fontBuilt = new CJKFont(name, encoding, embedded);
+ else if (noThrow)
+ return null;
+ else
+ throw new DocumentException("Font '" + name + "' with '" + encoding + "' is not recognized.");
+ if (cached) {
+ lock (fontCache) {
+ fontFound = (BaseFont)fontCache[key];
+ if (fontFound != null)
+ return fontFound;
+ fontCache.Add(key, fontBuilt);
+ }
+ }
+ return fontBuilt;
+ }
+
+ /**
+ * Creates a font based on an existing document font. The created font font may not
+ * behave as expected, depending on the encoding or subset.
+ * @param fontRef the reference to the document font
+ * @return the font
+ */
+ public static BaseFont CreateFont(PRIndirectReference fontRef) {
+ return new DocumentFont(fontRef);
+ }
+
+ /**
+ * Gets the name without the modifiers Bold, Italic or BoldItalic.
+ * @param name the full name of the font
+ * @return the name without the modifiers Bold, Italic or BoldItalic
+ */
+ protected static string GetBaseName(string name) {
+ if (name.EndsWith(",Bold"))
+ return name.Substring(0, name.Length - 5);
+ else if (name.EndsWith(",Italic"))
+ return name.Substring(0, name.Length - 7);
+ else if (name.EndsWith(",BoldItalic"))
+ return name.Substring(0, name.Length - 11);
+ else
+ return name;
+ }
+
+ /**
+ * Normalize the encoding names. "winansi" is changed to "Cp1252" and
+ * "macroman" is changed to "MacRoman".
+ * @param enc the encoding to be normalized
+ * @return the normalized encoding
+ */
+ protected static string NormalizeEncoding(string enc) {
+ if (enc.Equals("winansi") || enc.Equals(""))
+ return CP1252;
+ else if (enc.Equals("macroman"))
+ return MACROMAN;
+ int n = IanaEncodings.GetEncodingNumber(enc);
+ if (n == 1252)
+ return CP1252;
+ if (n == 10000)
+ return MACROMAN;
+ return enc;
+ }
+
+ /**
+ * Creates the widths
and the differences
arrays
+ * @throws UnsupportedEncodingException the encoding is not supported
+ */
+ protected void CreateEncoding() {
+ if (encoding.StartsWith("#")) {
+ specialMap = new IntHashtable();
+ StringTokenizer tok = new StringTokenizer(encoding.Substring(1), " ,\t\n\r\f");
+ if (tok.NextToken().Equals("full")) {
+ while (tok.HasMoreTokens()) {
+ String order = tok.NextToken();
+ String name = tok.NextToken();
+ char uni = (char)int.Parse(tok.NextToken(), NumberStyles.HexNumber);
+ int orderK;
+ if (order.StartsWith("'"))
+ orderK = (int)order[1];
+ else
+ orderK = int.Parse(order);
+ orderK %= 256;
+ specialMap[(int)uni] = orderK;
+ differences[orderK] = name;
+ unicodeDifferences[orderK] = uni;
+ widths[orderK] = GetRawWidth((int)uni, name);
+ charBBoxes[orderK] = GetRawCharBBox((int)uni, name);
+ }
+ }
+ else {
+ int k = 0;
+ if (tok.HasMoreTokens())
+ k = int.Parse(tok.NextToken());
+ while (tok.HasMoreTokens() && k < 256) {
+ String hex = tok.NextToken();
+ int uni = int.Parse(hex, NumberStyles.HexNumber) % 0x10000;
+ String name = GlyphList.UnicodeToName(uni);
+ if (name != null) {
+ specialMap[uni] = k;
+ differences[k] = name;
+ unicodeDifferences[k] = (char)uni;
+ widths[k] = GetRawWidth(uni, name);
+ charBBoxes[k] = GetRawCharBBox(uni, name);
+ ++k;
+ }
+ }
+ }
+ for (int k = 0; k < 256; ++k) {
+ if (differences[k] == null) {
+ differences[k] = notdef;
+ }
+ }
+ }
+ else if (fontSpecific) {
+ for (int k = 0; k < 256; ++k) {
+ widths[k] = GetRawWidth(k, null);
+ charBBoxes[k] = GetRawCharBBox(k, null);
+ }
+ }
+ else {
+ string s;
+ string name;
+ char c;
+ byte[] b = new byte[1];
+ for (int k = 0; k < 256; ++k) {
+ b[0] = (byte)k;
+ s = PdfEncodings.ConvertToString(b, encoding);
+ if (s.Length > 0) {
+ c = s[0];
+ }
+ else {
+ c = '?';
+ }
+ name = GlyphList.UnicodeToName((int)c);
+ if (name == null)
+ name = notdef;
+ differences[k] = name;
+ this.UnicodeDifferences[k] = c;
+ widths[k] = GetRawWidth((int)c, name);
+ charBBoxes[k] = GetRawCharBBox((int)c, name);
+ }
+ }
+ }
+
+ /**
+ * Gets the width from the font according to the Unicode char c
+ * or the name
. If the name
is null it's a symbolic font.
+ * @param c the unicode char
+ * @param name the glyph name
+ * @return the width of the char
+ */
+ internal abstract int GetRawWidth(int c, string name);
+
+ /**
+ * Gets the kerning between two Unicode chars.
+ * @param char1 the first char
+ * @param char2 the second char
+ * @return the kerning to be applied
+ */
+ public abstract int GetKerning(int char1, int char2);
+
+ /**
+ * Sets the kerning between two Unicode chars.
+ * @param char1 the first char
+ * @param char2 the second char
+ * @param kern the kerning to apply in normalized 1000 units
+ * @return true
if the kerning was applied, false
otherwise
+ */
+ public abstract bool SetKerning(int char1, int char2, int kern);
+
+ /**
+ * Gets the width of a char
in normalized 1000 units.
+ * @param char1 the unicode char
to get the width of
+ * @return the width in normalized 1000 units
+ */
+ public virtual int GetWidth(int char1) {
+ if (fastWinansi) {
+ if (char1 < 128 || (char1 >= 160 && char1 <= 255))
+ return widths[char1];
+ else
+ return widths[PdfEncodings.winansi[char1]];
+ }
+ else {
+ int total = 0;
+ byte[] mbytes = ConvertToBytes((char)char1);
+ for (int k = 0; k < mbytes.Length; ++k)
+ total += widths[0xff & mbytes[k]];
+ return total;
+ }
+ }
+
+ /**
+ * Gets the width of a string
in normalized 1000 units.
+ * @param text the string
to get the witdth of
+ * @return the width in normalized 1000 units
+ */
+ public virtual int GetWidth(string text) {
+ int total = 0;
+ if (fastWinansi) {
+ int len = text.Length;
+ for (int k = 0; k < len; ++k) {
+ char char1 = text[k];
+ if (char1 < 128 || (char1 >= 160 && char1 <= 255))
+ total += widths[char1];
+ else
+ total += widths[PdfEncodings.winansi[char1]];
+ }
+ return total;
+ }
+ else {
+ byte[] mbytes = ConvertToBytes(text);
+ for (int k = 0; k < mbytes.Length; ++k)
+ total += widths[0xff & mbytes[k]];
+ }
+ return total;
+ }
+
+ /**
+ * Gets the descent of a String
in normalized 1000 units. The descent will always be
+ * less than or equal to zero even if all the characters have an higher descent.
+ * @param text the String
to get the descent of
+ * @return the dexcent in normalized 1000 units
+ */
+ public int GetDescent(String text) {
+ int min = 0;
+ char[] chars = text.ToCharArray();
+ for (int k = 0; k < chars.Length; ++k) {
+ int[] bbox = GetCharBBox(chars[k]);
+ if (bbox != null && bbox[1] < min)
+ min = bbox[1];
+ }
+ return min;
+ }
+
+ /**
+ * Gets the ascent of a String
in normalized 1000 units. The ascent will always be
+ * greater than or equal to zero even if all the characters have a lower ascent.
+ * @param text the String
to get the ascent of
+ * @return the ascent in normalized 1000 units
+ */
+ public int GetAscent(String text) {
+ int max = 0;
+ char[] chars = text.ToCharArray();
+ for (int k = 0; k < chars.Length; ++k) {
+ int[] bbox = GetCharBBox(chars[k]);
+ if (bbox != null && bbox[3] > max)
+ max = bbox[3];
+ }
+ return max;
+ }
+
+ /**
+ * Gets the descent of a String
in points. The descent will always be
+ * less than or equal to zero even if all the characters have an higher descent.
+ * @param text the String
to get the descent of
+ * @param fontSize the size of the font
+ * @return the dexcent in points
+ */
+ public float GetDescentPoint(String text, float fontSize)
+ {
+ return (float)GetDescent(text) * 0.001f * fontSize;
+ }
+
+ /**
+ * Gets the ascent of a String
in points. The ascent will always be
+ * greater than or equal to zero even if all the characters have a lower ascent.
+ * @param text the String
to get the ascent of
+ * @param fontSize the size of the font
+ * @return the ascent in points
+ */
+ public float GetAscentPoint(String text, float fontSize)
+ {
+ return (float)GetAscent(text) * 0.001f * fontSize;
+ }
+
+ /**
+ * Gets the width of a String
in points taking kerning
+ * into account.
+ * @param text the String
to get the witdth of
+ * @param fontSize the font size
+ * @return the width in points
+ */
+ public float GetWidthPointKerned(String text, float fontSize) {
+ float size = (float)GetWidth(text) * 0.001f * fontSize;
+ if (!HasKernPairs())
+ return size;
+ int len = text.Length - 1;
+ int kern = 0;
+ char[] c = text.ToCharArray();
+ for (int k = 0; k < len; ++k) {
+ kern += GetKerning(c[k], c[k + 1]);
+ }
+ return size + kern * 0.001f * fontSize;
+ }
+
+ /**
+ * Gets the width of a string
in points.
+ * @param text the string
to get the witdth of
+ * @param fontSize the font size
+ * @return the width in points
+ */
+ public float GetWidthPoint(string text, float fontSize) {
+ return (float)GetWidth(text) * 0.001f * fontSize;
+ }
+
+ /**
+ * Gets the width of a char
in points.
+ * @param char1 the char
to get the witdth of
+ * @param fontSize the font size
+ * @return the width in points
+ */
+ public float GetWidthPoint(int char1, float fontSize) {
+ return GetWidth(char1) * 0.001f * fontSize;
+ }
+
+ /**
+ * Converts a string
to a byte array according
+ * to the font's encoding.
+ * @param text the string
to be converted
+ * @return an array of byte
representing the conversion according to the font's encoding
+ */
+ internal virtual byte[] ConvertToBytes(string text) {
+ if (directTextToByte)
+ return PdfEncodings.ConvertToBytes(text, null);
+ if (specialMap != null) {
+ byte[] b = new byte[text.Length];
+ int ptr = 0;
+ int length = text.Length;
+ for (int k = 0; k < length; ++k) {
+ char c = text[k];
+ if (specialMap.ContainsKey((int)c))
+ b[ptr++] = (byte)specialMap[(int)c];
+ }
+ if (ptr < length) {
+ byte[] b2 = new byte[ptr];
+ System.Array.Copy(b, 0, b2, 0, ptr);
+ return b2;
+ }
+ else
+ return b;
+ }
+ return PdfEncodings.ConvertToBytes(text, encoding);
+ }
+
+ /**
+ * Converts a char
to a byte array according
+ * to the font's encoding.
+ * @param text the String
to be converted
+ * @return an array of byte
representing the conversion according to the font's encoding
+ */
+ internal virtual byte[] ConvertToBytes(int char1) {
+ if (directTextToByte)
+ return PdfEncodings.ConvertToBytes((char)char1, null);
+ if (specialMap != null) {
+ if (specialMap.ContainsKey(char1))
+ return new byte[]{(byte)specialMap[(int)char1]};
+ else
+ return new byte[0];
+ }
+ return PdfEncodings.ConvertToBytes((char)char1, encoding);
+ }
+
+ /** Outputs to the writer the font dictionaries and streams.
+ * @param writer the writer for this document
+ * @param ref the font indirect reference
+ * @param params several parameters that depend on the font type
+ * @throws IOException on error
+ * @throws DocumentException error in generating the object
+ */
+ internal abstract void WriteFont(PdfWriter writer, PdfIndirectReference piRef, Object[] oParams);
+
+ /** Gets the encoding used to convert string
into byte[]
.
+ * @return the encoding name
+ */
+ public string Encoding {
+ get {
+ return encoding;
+ }
+ }
+
+ /** Gets the font parameter identified by key
. Valid values
+ * for key
are ASCENT
, CAPHEIGHT
, DESCENT
,
+ * ITALICANGLE
, BBOXLLX
, BBOXLLY
, BBOXURX
+ * and BBOXURY
.
+ * @param key the parameter to be extracted
+ * @param fontSize the font size in points
+ * @return the parameter in points
+ */
+ public abstract float GetFontDescriptor(int key, float fontSize);
+
+ /** Gets the font type. The font types can be: FONT_TYPE_T1,
+ * FONT_TYPE_TT, FONT_TYPE_CJK and FONT_TYPE_TTUNI.
+ * @return the font type
+ */
+ public int FontType {
+ get {
+ return fontType;
+ }
+
+ set {
+ fontType = value;
+ }
+ }
+
+ /** Gets the embedded flag.
+ * @return true
if the font is embedded.
+ */
+ public bool IsEmbedded() {
+ return embedded;
+ }
+
+ /** Gets the symbolic flag of the font.
+ * @return true
if the font is symbolic
+ */
+ public bool IsFontSpecific() {
+ return fontSpecific;
+ }
+
+ /** Creates a unique subset prefix to be added to the font name when the font is embedded and subset.
+ * @return the subset prefix
+ */
+ internal static string CreateSubsetPrefix() {
+ char[] s = new char[7];
+ lock (random) {
+ for (int k = 0; k < 6; ++k)
+ s[k] = (char)(random.Next('A', 'Z' + 1));
+ }
+ s[6] = '+';
+ return new String(s);
+ }
+
+ /** Gets the Unicode character corresponding to the byte output to the pdf stream.
+ * @param index the byte index
+ * @return the Unicode character
+ */
+ internal char GetUnicodeDifferences(int index) {
+ return unicodeDifferences[index];
+ }
+
+ /** Gets the postscript font name.
+ * @return the postscript font name
+ */
+ public abstract string PostscriptFontName {
+ get;
+ set;
+ }
+
+ /** Gets the full name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public abstract string[][] FullFontName {
+ get;
+ }
+
+ /** Gets all the entries of the names-table. If it is a True Type font
+ * each array element will have {Name ID, Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"4", "", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public abstract string[][] AllNameEntries{
+ get;
+ }
+
+ /** Gets the full name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @param name the name of the font
+ * @param encoding the encoding of the font
+ * @param ttfAfm the true type font or the afm in a byte array
+ * @throws DocumentException on error
+ * @throws IOException on error
+ * @return the full name of the font
+ */
+ public static string[][] GetFullFontName(string name, string encoding, byte[] ttfAfm) {
+ string nameBase = GetBaseName(name);
+ BaseFont fontBuilt = null;
+ if (nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf(".ttc,") > 0)
+ fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true);
+ else
+ fontBuilt = CreateFont(name, encoding, false, false, ttfAfm, null);
+ return fontBuilt.FullFontName;
+ }
+
+ /** Gets all the names from the font. Only the required tables are read.
+ * @param name the name of the font
+ * @param encoding the encoding of the font
+ * @param ttfAfm the true type font or the afm in a byte array
+ * @throws DocumentException on error
+ * @throws IOException on error
+ * @return an array of Object[] built with {getPostscriptFontName(), GetFamilyFontName(), GetFullFontName()}
+ */
+ public static Object[] GetAllFontNames(String name, String encoding, byte[] ttfAfm) {
+ String nameBase = GetBaseName(name);
+ BaseFont fontBuilt = null;
+ if (nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf(".ttc,") > 0)
+ fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true);
+ else
+ fontBuilt = CreateFont(name, encoding, false, false, ttfAfm, null);
+ return new Object[]{fontBuilt.PostscriptFontName, fontBuilt.FamilyFontName, fontBuilt.FullFontName};
+ }
+
+ /** Gets all the entries of the namestable from the font. Only the required tables are read.
+ * @param name the name of the font
+ * @param encoding the encoding of the font
+ * @param ttfAfm the true type font or the afm in a byte array
+ * @throws DocumentException on error
+ * @throws IOException on error
+ * @return an array of Object[] built with {getPostscriptFontName(), getFamilyFontName(), getFullFontName()}
+ */
+ public static String[][] GetAllNameEntries(String name, String encoding, byte[] ttfAfm) {
+ String nameBase = GetBaseName(name);
+ BaseFont fontBuilt = null;
+ if (nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf(".ttc,") > 0)
+ fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true);
+ else
+ fontBuilt = CreateFont(name, encoding, false, false, ttfAfm, null);
+ return fontBuilt.AllNameEntries;
+ }
+
+ /** Gets the family name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the family name of the font
+ */
+ public abstract string[][] FamilyFontName {
+ get;
+ }
+
+ /** Gets the code pages supported by the font. This has only meaning
+ * with True Type fonts.
+ * @return the code pages supported by the font
+ */
+ public virtual string[] CodePagesSupported {
+ get {
+ return new string[0];
+ }
+ }
+
+ /** Enumerates the postscript font names present inside a
+ * True Type Collection.
+ * @param ttcFile the file name of the font
+ * @throws DocumentException on error
+ * @throws IOException on error
+ * @return the postscript font names
+ */
+ public static string[] EnumerateTTCNames(string ttcFile) {
+ return new EnumerateTTC(ttcFile).Names;
+ }
+
+ /** Enumerates the postscript font names present inside a
+ * True Type Collection.
+ * @param ttcArray the font as a byte
array
+ * @throws DocumentException on error
+ * @throws IOException on error
+ * @return the postscript font names
+ */
+ public static string[] EnumerateTTCNames(byte[] ttcArray) {
+ return new EnumerateTTC(ttcArray).Names;
+ }
+
+ /** Gets the font width array.
+ * @return the font width array
+ */
+ public int[] Widths {
+ get {
+ return widths;
+ }
+ }
+
+ /** Gets the array with the names of the characters.
+ * @return the array with the names of the characters
+ */
+ public string[] Differences {
+ get {
+ return differences;
+ }
+ }
+
+ /** Gets the array with the unicode characters.
+ * @return the array with the unicode characters
+ */
+ public char[] UnicodeDifferences {
+ get {
+ return unicodeDifferences;
+ }
+ }
+
+ /** Set to true
to force the generation of the
+ * widths array.
+ * @param forceWidthsOutput true
to force the generation of the
+ * widths array
+ */
+ public bool ForceWidthsOutput {
+ set {
+ this.forceWidthsOutput = value;
+ }
+ get {
+ return forceWidthsOutput;
+ }
+ }
+
+ /** Sets the conversion of char
directly to byte
+ * by casting. This is a low level feature to put the bytes directly in
+ * the content stream without passing through string.GetBytes().
+ * @param directTextToByte New value of property directTextToByte.
+ */
+ public bool DirectTextToByte {
+ set {
+ this.directTextToByte = value;
+ }
+ get {
+ return directTextToByte;
+ }
+ }
+
+ /** Indicates if all the glyphs and widths for that particular
+ * encoding should be included in the document. When set to true
+ * only the glyphs used will be included in the font. When set to false
+ * and {@link #addSubsetRange(int[])} was not called the full font will be included
+ * otherwise just the characters ranges will be included.
+ * @param subset new value of property subset
+ */
+ public bool Subset {
+ set {
+ this.subset = value;
+ }
+ get {
+ return subset;
+ }
+ }
+
+ public static void AddToResourceSearch (object obj) {
+ if (obj is Assembly) {
+ resourceSearch.Add(obj);
+ }
+ else if (obj is string) {
+ string f = (string)obj;
+ if (Directory.Exists(f) || File.Exists(f))
+ resourceSearch.Add(obj);
+ }
+ }
+
+ /** Gets the font resources.
+ * @param key the name of the resource
+ * @return the Stream
to get the resource or
+ * null
if not found
+ */
+ public static Stream GetResourceStream(string key) {
+ Stream istr = null;
+ // Try to use resource loader to load the properties file.
+ try {
+ Assembly assm = Assembly.GetExecutingAssembly();
+ istr = assm.GetManifestResourceStream(key);
+ }
+ catch {
+ }
+ if (istr != null)
+ return istr;
+ for (int k = 0; k < resourceSearch.Count; ++k) {
+ object obj = resourceSearch[k];
+ try {
+ if (obj is Assembly) {
+ istr = ((Assembly)obj).GetManifestResourceStream(key);
+ if (istr != null)
+ return istr;
+ }
+ else if (obj is string) {
+ string dir = (string)obj;
+ try {
+ istr = Assembly.LoadFrom(dir).GetManifestResourceStream(key);
+ }
+ catch {
+ }
+ if (istr != null)
+ return istr;
+ string modkey = key.Replace('.', '/');
+ string fullPath = Path.Combine(dir, modkey);
+ if (File.Exists(fullPath)) {
+ return new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ }
+ int idx = modkey.LastIndexOf('/');
+ if (idx >= 0) {
+ modkey = modkey.Substring(0, idx) + "." + modkey.Substring(idx + 1);
+ fullPath = Path.Combine(dir, modkey);
+ if (File.Exists(fullPath))
+ return new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ }
+ }
+ }
+ catch {
+ }
+ }
+
+ return istr;
+ }
+
+ /** Gets the Unicode equivalent to a CID.
+ * The (inexistent) CID true
if the font has any kerning pairs
+ */
+ public abstract bool HasKernPairs();
+
+ /**
+ * Checks if a character exists in this font.
+ * @param c the character to check
+ * @return true
if the character has a glyph,
+ * false
otherwise
+ */
+ public virtual bool CharExists(int c) {
+ byte[] b = ConvertToBytes(c);
+ return b.Length > 0;
+ }
+
+ /**
+ * Sets the character advance.
+ * @param c the character
+ * @param advance the character advance normalized to 1000 units
+ * @return true
if the advance was set,
+ * false
otherwise
+ */
+ public virtual bool SetCharAdvance(int c, int advance) {
+ byte[] b = ConvertToBytes(c);
+ if (b.Length == 0)
+ return false;
+ widths[0xff & b[0]] = advance;
+ return true;
+ }
+
+ private static void AddFont(PRIndirectReference fontRef, IntHashtable hits, ArrayList fonts) {
+ PdfObject obj = PdfReader.GetPdfObject(fontRef);
+ if (obj == null || !obj.IsDictionary())
+ return;
+ PdfDictionary font = (PdfDictionary)obj;
+ PdfName subtype = (PdfName)PdfReader.GetPdfObject(font.Get(PdfName.SUBTYPE));
+ if (!PdfName.TYPE1.Equals(subtype) && !PdfName.TRUETYPE.Equals(subtype))
+ return;
+ PdfName name = (PdfName)PdfReader.GetPdfObject(font.Get(PdfName.BASEFONT));
+ fonts.Add(new Object[]{PdfName.DecodeName(name.ToString()), fontRef});
+ hits[fontRef.Number] = 1;
+ }
+
+ private static void RecourseFonts(PdfDictionary page, IntHashtable hits, ArrayList fonts, int level) {
+ ++level;
+ if (level > 50) // in case we have an endless loop
+ return;
+ PdfDictionary resources = (PdfDictionary)PdfReader.GetPdfObject(page.Get(PdfName.RESOURCES));
+ if (resources == null)
+ return;
+ PdfDictionary font = (PdfDictionary)PdfReader.GetPdfObject(resources.Get(PdfName.FONT));
+ if (font != null) {
+ foreach (PdfName key in font.Keys) {
+ PdfObject ft = font.Get(key);
+ if (ft == null || !ft.IsIndirect())
+ continue;
+ int hit = ((PRIndirectReference)ft).Number;
+ if (hits.ContainsKey(hit))
+ continue;
+ AddFont((PRIndirectReference)ft, hits, fonts);
+ }
+ }
+ PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(resources.Get(PdfName.XOBJECT));
+ if (xobj != null) {
+ foreach (PdfName key in xobj.Keys) {
+ RecourseFonts((PdfDictionary)PdfReader.GetPdfObject(xobj.Get(key)), hits, fonts, level);
+ }
+ }
+ }
+
+ /**
+ * Gets a list of all document fonts. Each element of the ArrayList
+ * contains a Object[]{String,PRIndirectReference}
with the font name
+ * and the indirect reference to it.
+ * @param reader the document where the fonts are to be listed from
+ * @return the list of fonts and references
+ */
+ public static ArrayList GetDocumentFonts(PdfReader reader) {
+ IntHashtable hits = new IntHashtable();
+ ArrayList fonts = new ArrayList();
+ int npages = reader.NumberOfPages;
+ for (int k = 1; k <= npages; ++k)
+ RecourseFonts(reader.GetPageN(k), hits, fonts, 1);
+ return fonts;
+ }
+
+ /**
+ * Gets a list of the document fonts in a particular page. Each element of the ArrayList
+ * contains a Object[]{String,PRIndirectReference}
with the font name
+ * and the indirect reference to it.
+ * @param reader the document where the fonts are to be listed from
+ * @param page the page to list the fonts from
+ * @return the list of fonts and references
+ */
+ public static ArrayList GetDocumentFonts(PdfReader reader, int page) {
+ IntHashtable hits = new IntHashtable();
+ ArrayList fonts = new ArrayList();
+ RecourseFonts(reader.GetPageN(page), hits, fonts, 1);
+ return fonts;
+ }
+
+ /**
+ * Gets the smallest box enclosing the character contours. It will return
+ * null
if the font has not the information or the character has no
+ * contours, as in the case of the space, for example. Characters with no contours may
+ * also return [0,0,0,0].
+ * @param c the character to get the contour bounding box from
+ * @return an array of four floats with the bounding box in the format [llx,lly,urx,ury] or
+ * null
+ */
+ public virtual int[] GetCharBBox(int c) {
+ byte[] b = ConvertToBytes(c);
+ if (b.Length == 0)
+ return null;
+ else
+ return charBBoxes[b[0] & 0xff];
+ }
+
+ protected abstract int[] GetRawCharBBox(int c, String name);
+
+ /**
+ * iText expects Arabic Diactrics (tashkeel) to have zero advance but some fonts,
+ * most notably those that come with Windows, like times.ttf, have non-zero
+ * advance for those characters. This method makes those character to have zero
+ * width advance and work correctly in the iText Arabic shaping and reordering
+ * context.
+ */
+ public void CorrectArabicAdvance() {
+ for (char c = '\u064b'; c <= '\u0658'; ++c)
+ SetCharAdvance(c, 0);
+ SetCharAdvance('\u0670', 0);
+ for (char c = '\u06d6'; c <= '\u06dc'; ++c)
+ SetCharAdvance(c, 0);
+ for (char c = '\u06df'; c <= '\u06e4'; ++c)
+ SetCharAdvance(c, 0);
+ for (char c = '\u06e7'; c <= '\u06e8'; ++c)
+ SetCharAdvance(c, 0);
+ for (char c = '\u06ea'; c <= '\u06ed'; ++c)
+ SetCharAdvance(c, 0);
+ }
+
+ /**
+ * Adds a character range when subsetting. The range is an int
array
+ * where the first element is the start range inclusive and the second element is the
+ * end range inclusive. Several ranges are allowed in the same array.
+ * @param range the character range
+ */
+ public void AddSubsetRange(int[] range) {
+ if (subsetRanges == null)
+ subsetRanges = new ArrayList();
+ subsetRanges.Add(range);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/BidiLine.cs b/iTechSharp/iTextSharp/text/pdf/BidiLine.cs
new file mode 100644
index 0000000..239e921
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BidiLine.cs
@@ -0,0 +1,946 @@
+using System;
+using System.Collections;
+using System.Text;
+
+/*
+ *
+ * Copyright 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Does all the line bidirectional processing with PdfChunk assembly.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class BidiLine {
+ private const int pieceSizeStart = 256;
+
+ protected int runDirection;
+ protected int pieceSize = pieceSizeStart;
+ protected char[] text = new char[pieceSizeStart];
+ protected PdfChunk[] detailChunks = new PdfChunk[pieceSizeStart];
+ protected int totalTextLength = 0;
+
+ protected byte[] orderLevels = new byte[pieceSizeStart];
+ protected int[] indexChars = new int[pieceSizeStart];
+
+ protected ArrayList chunks = new ArrayList();
+ protected int indexChunk = 0;
+ protected int indexChunkChar = 0;
+ protected int currentChar = 0;
+
+ protected int storedRunDirection;
+ protected char[] storedText = new char[0];
+ protected PdfChunk[] storedDetailChunks = new PdfChunk[0];
+ protected int storedTotalTextLength = 0;
+
+ protected byte[] storedOrderLevels = new byte[0];
+ protected int[] storedIndexChars = new int[0];
+
+ protected int storedIndexChunk = 0;
+ protected int storedIndexChunkChar = 0;
+ protected int storedCurrentChar = 0;
+
+ protected bool shortStore;
+ protected static IntHashtable mirrorChars = new IntHashtable();
+ protected int arabicOptions;
+
+ /** Creates new BidiLine */
+ public BidiLine() {
+ }
+
+ public BidiLine(BidiLine org) {
+ runDirection = org.runDirection;
+ pieceSize = org.pieceSize;
+ text = (char[])org.text.Clone();
+ detailChunks = (PdfChunk[])org.detailChunks.Clone();
+ totalTextLength = org.totalTextLength;
+
+ orderLevels = (byte[])org.orderLevels.Clone();
+ indexChars = (int[])org.indexChars.Clone();
+
+ chunks = new ArrayList(org.chunks);
+ indexChunk = org.indexChunk;
+ indexChunkChar = org.indexChunkChar;
+ currentChar = org.currentChar;
+
+ storedRunDirection = org.storedRunDirection;
+ storedText = (char[])org.storedText.Clone();
+ storedDetailChunks = (PdfChunk[])org.storedDetailChunks.Clone();
+ storedTotalTextLength = org.storedTotalTextLength;
+
+ storedOrderLevels = (byte[])org.storedOrderLevels.Clone();
+ storedIndexChars = (int[])org.storedIndexChars.Clone();
+
+ storedIndexChunk = org.storedIndexChunk;
+ storedIndexChunkChar = org.storedIndexChunkChar;
+ storedCurrentChar = org.storedCurrentChar;
+
+ shortStore = org.shortStore;
+ arabicOptions = org.arabicOptions;
+ }
+
+ public bool IsEmpty() {
+ return (currentChar >= totalTextLength && indexChunk >= chunks.Count);
+ }
+
+ public void ClearChunks() {
+ chunks.Clear();
+ totalTextLength = 0;
+ currentChar = 0;
+ }
+
+ public bool GetParagraph(int runDirection) {
+ this.runDirection = runDirection;
+ currentChar = 0;
+ totalTextLength = 0;
+ bool hasText = false;
+ char c;
+ char uniC;
+ BaseFont bf;
+ for (; indexChunk < chunks.Count; ++indexChunk) {
+ PdfChunk ck = (PdfChunk)chunks[indexChunk];
+ bf = ck.Font.Font;
+ string s = ck.ToString();
+ int len = s.Length;
+ for (; indexChunkChar < len; ++indexChunkChar) {
+ c = s[indexChunkChar];
+ uniC = (char)bf.GetUnicodeEquivalent(c);
+ if (uniC == '\r' || uniC == '\n') {
+ // next condition is never true for CID
+ if (uniC == '\r' && indexChunkChar + 1 < len && s[indexChunkChar + 1] == '\n')
+ ++indexChunkChar;
+ ++indexChunkChar;
+ if (indexChunkChar >= len) {
+ indexChunkChar = 0;
+ ++indexChunk;
+ }
+ hasText = true;
+ if (totalTextLength == 0)
+ detailChunks[0] = ck;
+ break;
+ }
+ AddPiece(c, ck);
+ }
+ if (hasText)
+ break;
+ indexChunkChar = 0;
+ }
+ if (totalTextLength == 0)
+ return hasText;
+
+ // remove trailing WS
+ totalTextLength = TrimRight(0, totalTextLength - 1) + 1;
+ if (totalTextLength == 0)
+ return true;
+
+ if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) {
+ if (orderLevels.Length < totalTextLength) {
+ orderLevels = new byte[pieceSize];
+ indexChars = new int[pieceSize];
+ }
+
+ ArabicLigaturizer.ProcessNumbers(text, 0, totalTextLength, arabicOptions);
+ BidiOrder order = new BidiOrder(text, 0, totalTextLength, (sbyte)(runDirection == PdfWriter.RUN_DIRECTION_RTL ? 1 : 0));
+ byte[] od = order.GetLevels();
+ for (int k = 0; k < totalTextLength; ++k) {
+ orderLevels[k] = od[k];
+ indexChars[k] = k;
+ }
+ DoArabicShapping();
+ MirrorGlyphs();
+ }
+ totalTextLength = TrimRightEx(0, totalTextLength - 1) + 1;
+ return true;
+ }
+
+ public void AddChunk(PdfChunk chunk) {
+ chunks.Add(chunk);
+ }
+
+ public void AddChunks(ArrayList chunks) {
+ this.chunks.AddRange(chunks);
+ }
+
+ public void AddPiece(char c, PdfChunk chunk) {
+ if (totalTextLength >= pieceSize) {
+ char[] tempText = text;
+ PdfChunk[] tempDetailChunks = detailChunks;
+ pieceSize *= 2;
+ text = new char[pieceSize];
+ detailChunks = new PdfChunk[pieceSize];
+ Array.Copy(tempText, 0, text, 0, totalTextLength);
+ Array.Copy(tempDetailChunks, 0, detailChunks, 0, totalTextLength);
+ }
+ text[totalTextLength] = c;
+ detailChunks[totalTextLength++] = chunk;
+ }
+
+ public void Save() {
+ if (indexChunk > 0) {
+ if (indexChunk >= chunks.Count)
+ chunks.Clear();
+ else {
+ for (--indexChunk; indexChunk >= 0; --indexChunk)
+ chunks.RemoveAt(indexChunk);
+ }
+ indexChunk = 0;
+ }
+ storedRunDirection = runDirection;
+ storedTotalTextLength = totalTextLength;
+ storedIndexChunk = indexChunk;
+ storedIndexChunkChar = indexChunkChar;
+ storedCurrentChar = currentChar;
+ shortStore = (currentChar < totalTextLength);
+ if (!shortStore) {
+ // long save
+ if (storedText.Length < totalTextLength) {
+ storedText = new char[totalTextLength];
+ storedDetailChunks = new PdfChunk[totalTextLength];
+ }
+ Array.Copy(text, 0, storedText, 0, totalTextLength);
+ Array.Copy(detailChunks, 0, storedDetailChunks, 0, totalTextLength);
+ }
+ if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) {
+ if (storedOrderLevels.Length < totalTextLength) {
+ storedOrderLevels = new byte[totalTextLength];
+ storedIndexChars = new int[totalTextLength];
+ }
+ Array.Copy(orderLevels, currentChar, storedOrderLevels, currentChar, totalTextLength - currentChar);
+ Array.Copy(indexChars, currentChar, storedIndexChars, currentChar, totalTextLength - currentChar);
+ }
+ }
+
+ public void Restore() {
+ runDirection = storedRunDirection;
+ totalTextLength = storedTotalTextLength;
+ indexChunk = storedIndexChunk;
+ indexChunkChar = storedIndexChunkChar;
+ currentChar = storedCurrentChar;
+ if (!shortStore) {
+ // long restore
+ Array.Copy(storedText, 0, text, 0, totalTextLength);
+ Array.Copy(storedDetailChunks, 0, detailChunks, 0, totalTextLength);
+ }
+ if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) {
+ Array.Copy(storedOrderLevels, currentChar, orderLevels, currentChar, totalTextLength - currentChar);
+ Array.Copy(storedIndexChars, currentChar, indexChars, currentChar, totalTextLength - currentChar);
+ }
+ }
+
+ public void MirrorGlyphs() {
+ for (int k = 0; k < totalTextLength; ++k) {
+ if ((orderLevels[k] & 1) == 1) {
+ int mirror = mirrorChars[text[k]];
+ if (mirror != 0)
+ text[k] = (char)mirror;
+ }
+ }
+ }
+
+ public void DoArabicShapping() {
+ int src = 0;
+ int dest = 0;
+ for (;;) {
+ while (src < totalTextLength) {
+ char c = text[src];
+ if (c >= 0x0600 && c <= 0x06ff)
+ break;
+ if (src != dest) {
+ text[dest] = text[src];
+ detailChunks[dest] = detailChunks[src];
+ orderLevels[dest] = orderLevels[src];
+ }
+ ++src;
+ ++dest;
+ }
+ if (src >= totalTextLength) {
+ totalTextLength = dest;
+ return;
+ }
+ int startArabicIdx = src;
+ ++src;
+ while (src < totalTextLength) {
+ char c = text[src];
+ if (c < 0x0600 || c > 0x06ff)
+ break;
+ ++src;
+ }
+ int arabicWordSize = src - startArabicIdx;
+ int size = ArabicLigaturizer.Arabic_shape(text, startArabicIdx, arabicWordSize, text, dest, arabicWordSize, arabicOptions);
+ if (startArabicIdx != dest) {
+ for (int k = 0; k < size; ++k) {
+ detailChunks[dest] = detailChunks[startArabicIdx];
+ orderLevels[dest++] = orderLevels[startArabicIdx++];
+ }
+ }
+ else
+ dest += size;
+ }
+ }
+
+ public PdfLine ProcessLine(float leftX, float width, int alignment, int runDirection, int arabicOptions) {
+ this.arabicOptions = arabicOptions;
+ Save();
+ bool isRTL = (runDirection == PdfWriter.RUN_DIRECTION_RTL);
+ if (currentChar >= totalTextLength) {
+ bool hasText = GetParagraph(runDirection);
+ if (!hasText)
+ return null;
+ if (totalTextLength == 0) {
+ ArrayList ar = new ArrayList();
+ PdfChunk ckx = new PdfChunk("", detailChunks[0]);
+ ar.Add(ckx);
+ return new PdfLine(0, 0, 0, alignment, true, ar, isRTL);
+ }
+ }
+ float originalWidth = width;
+ int lastSplit = -1;
+ if (currentChar != 0)
+ currentChar = TrimLeftEx(currentChar, totalTextLength - 1);
+ int oldCurrentChar = currentChar;
+ int uniC = 0;
+ PdfChunk ck = null;
+ float charWidth = 0;
+ PdfChunk lastValidChunk = null;
+ bool splitChar = false;
+ bool surrogate = false;
+ for (; currentChar < totalTextLength; ++currentChar) {
+ ck = detailChunks[currentChar];
+ surrogate = Utilities.IsSurrogatePair(text, currentChar);
+ if (surrogate)
+ uniC = ck.GetUnicodeEquivalent(Utilities.ConvertToUtf32(text, currentChar));
+ else
+ uniC = ck.GetUnicodeEquivalent(text[currentChar]);
+ if (PdfChunk.NoPrint(uniC))
+ continue;
+ if (surrogate)
+ charWidth = ck.GetCharWidth(uniC);
+ else
+ charWidth = ck.GetCharWidth(text[currentChar]);
+ splitChar = ck.IsExtSplitCharacter(oldCurrentChar, currentChar, totalTextLength, text, detailChunks);
+ if (splitChar && Char.IsWhiteSpace((char)uniC))
+ lastSplit = currentChar;
+ if (width - charWidth < 0)
+ break;
+ if (splitChar)
+ lastSplit = currentChar;
+ width -= charWidth;
+ lastValidChunk = ck;
+ if (surrogate)
+ ++currentChar;
+ if (ck.IsTab()) {
+ Object[] tab = (Object[])ck.GetAttribute(Chunk.TAB);
+ float tabPosition = (float)tab[1];
+ bool newLine = (bool)tab[2];
+ if (newLine && tabPosition < originalWidth - width) {
+ return new PdfLine(0, originalWidth, width, alignment, true, CreateArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL);
+ }
+ detailChunks[currentChar].AdjustLeft(leftX);
+ width = originalWidth - tabPosition;
+ }
+ }
+ if (lastValidChunk == null) {
+ // not even a single char fit; must output the first char
+ ++currentChar;
+ if (surrogate)
+ ++currentChar;
+ return new PdfLine(0, originalWidth, 0, alignment, false, CreateArrayOfPdfChunks(currentChar - 1, currentChar - 1), isRTL);
+ }
+ if (currentChar >= totalTextLength) {
+ // there was more line than text
+ return new PdfLine(0, originalWidth, width, alignment, true, CreateArrayOfPdfChunks(oldCurrentChar, totalTextLength - 1), isRTL);
+ }
+ int newCurrentChar = TrimRightEx(oldCurrentChar, currentChar - 1);
+ if (newCurrentChar < oldCurrentChar) {
+ // only WS
+ return new PdfLine(0, originalWidth, width, alignment, false, CreateArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL);
+ }
+ if (newCurrentChar == currentChar - 1) { // middle of word
+ IHyphenationEvent he = (IHyphenationEvent)lastValidChunk.GetAttribute(Chunk.HYPHENATION);
+ if (he != null) {
+ int[] word = GetWord(oldCurrentChar, newCurrentChar);
+ if (word != null) {
+ float testWidth = width + GetWidth(word[0], currentChar - 1);
+ String pre = he.GetHyphenatedWordPre(new String(text, word[0], word[1] - word[0]), lastValidChunk.Font.Font, lastValidChunk.Font.Size, testWidth);
+ String post = he.HyphenatedWordPost;
+ if (pre.Length > 0) {
+ PdfChunk extra = new PdfChunk(pre, lastValidChunk);
+ currentChar = word[1] - post.Length;
+ return new PdfLine(0, originalWidth, testWidth - lastValidChunk.Font.Width(pre), alignment, false, CreateArrayOfPdfChunks(oldCurrentChar, word[0] - 1, extra), isRTL);
+ }
+ }
+ }
+ }
+ if (lastSplit == -1 || lastSplit >= newCurrentChar) {
+ // no split point or split point ahead of end
+ return new PdfLine(0, originalWidth, width + GetWidth(newCurrentChar + 1, currentChar - 1), alignment, false, CreateArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL);
+ }
+ // standard split
+ currentChar = lastSplit + 1;
+ newCurrentChar = TrimRightEx(oldCurrentChar, lastSplit);
+ if (newCurrentChar < oldCurrentChar) {
+ // only WS again
+ newCurrentChar = currentChar - 1;
+ }
+ return new PdfLine(0, originalWidth, originalWidth - GetWidth(oldCurrentChar, newCurrentChar), alignment, false, CreateArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL);
+ }
+
+ /** Gets the width of a range of characters.
+ * @param startIdx the first index to calculate
+ * @param lastIdx the last inclusive index to calculate
+ * @return the sum of all widths
+ */
+ public float GetWidth(int startIdx, int lastIdx) {
+ char c = (char)0;
+ PdfChunk ck = null;
+ float width = 0;
+ for (; startIdx <= lastIdx; ++startIdx) {
+ bool surrogate = Utilities.IsSurrogatePair(text, startIdx);
+ if (surrogate) {
+ width += detailChunks[startIdx].GetCharWidth(Utilities.ConvertToUtf32(text, startIdx));
+ ++startIdx;
+ }
+ else {
+ c = text[startIdx];
+ ck = detailChunks[startIdx];
+ if (PdfChunk.NoPrint(ck.GetUnicodeEquivalent(c)))
+ continue;
+ width += detailChunks[startIdx].GetCharWidth(c);
+ }
+ }
+ return width;
+ }
+
+ public ArrayList CreateArrayOfPdfChunks(int startIdx, int endIdx) {
+ return CreateArrayOfPdfChunks(startIdx, endIdx, null);
+ }
+
+ public ArrayList CreateArrayOfPdfChunks(int startIdx, int endIdx, PdfChunk extraPdfChunk) {
+ bool bidi = (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL);
+ if (bidi)
+ Reorder(startIdx, endIdx);
+ ArrayList ar = new ArrayList();
+ PdfChunk refCk = detailChunks[startIdx];
+ PdfChunk ck = null;
+ StringBuilder buf = new StringBuilder();
+ char c;
+ int idx = 0;
+ for (; startIdx <= endIdx; ++startIdx) {
+ idx = bidi ? indexChars[startIdx] : startIdx;
+ c = text[idx];
+ ck = detailChunks[idx];
+ if (PdfChunk.NoPrint(ck.GetUnicodeEquivalent(c)))
+ continue;
+ if (ck.IsImage() || ck.IsSeparator() || ck.IsTab()) {
+ if (buf.Length > 0) {
+ ar.Add(new PdfChunk(buf.ToString(), refCk));
+ buf = new StringBuilder();
+ }
+ ar.Add(ck);
+ }
+ else if (ck == refCk) {
+ buf.Append(c);
+ }
+ else {
+ if (buf.Length > 0) {
+ ar.Add(new PdfChunk(buf.ToString(), refCk));
+ buf = new StringBuilder();
+ }
+ if (!ck.IsImage() && !ck.IsSeparator() && !ck.IsTab())
+ buf.Append(c);
+ refCk = ck;
+ }
+ }
+ if (buf.Length > 0) {
+ ar.Add(new PdfChunk(buf.ToString(), refCk));
+ }
+ if (extraPdfChunk != null)
+ ar.Add(extraPdfChunk);
+ return ar;
+ }
+
+ public int[] GetWord(int startIdx, int idx) {
+ int last = idx;
+ int first = idx;
+ // forward
+ for (; last < totalTextLength; ++last) {
+ if (!char.IsLetter(text[last]))
+ break;
+ }
+ if (last == idx)
+ return null;
+ // backward
+ for (; first >= startIdx; --first) {
+ if (!char.IsLetter(text[first]))
+ break;
+ }
+ ++first;
+ return new int[]{first, last};
+ }
+
+ public int TrimRight(int startIdx, int endIdx) {
+ int idx = endIdx;
+ char c;
+ for (; idx >= startIdx; --idx) {
+ c = (char)detailChunks[idx].GetUnicodeEquivalent(text[idx]);
+ if (!IsWS(c))
+ break;
+ }
+ return idx;
+ }
+
+ public int TrimLeft(int startIdx, int endIdx) {
+ int idx = startIdx;
+ char c;
+ for (; idx <= endIdx; ++idx) {
+ c = (char)detailChunks[idx].GetUnicodeEquivalent(text[idx]);
+ if (!IsWS(c))
+ break;
+ }
+ return idx;
+ }
+
+ public int TrimRightEx(int startIdx, int endIdx) {
+ int idx = endIdx;
+ char c = (char)0;
+ for (; idx >= startIdx; --idx) {
+ c = (char)detailChunks[idx].GetUnicodeEquivalent(text[idx]);
+ if (!IsWS(c) && !PdfChunk.NoPrint(c))
+ break;
+ }
+ return idx;
+ }
+
+ public int TrimLeftEx(int startIdx, int endIdx) {
+ int idx = startIdx;
+ char c = (char)0;
+ for (; idx <= endIdx; ++idx) {
+ c = (char)detailChunks[idx].GetUnicodeEquivalent(text[idx]);
+ if (!IsWS(c) && !PdfChunk.NoPrint(c))
+ break;
+ }
+ return idx;
+ }
+
+ public void Reorder(int start, int end) {
+ byte maxLevel = orderLevels[start];
+ byte minLevel = maxLevel;
+ byte onlyOddLevels = maxLevel;
+ byte onlyEvenLevels = maxLevel;
+ for (int k = start + 1; k <= end; ++k) {
+ byte b = orderLevels[k];
+ if (b > maxLevel)
+ maxLevel = b;
+ else if (b < minLevel)
+ minLevel = b;
+ onlyOddLevels &= b;
+ onlyEvenLevels |= b;
+ }
+ if ((onlyEvenLevels & 1) == 0) // nothing to do
+ return;
+ if ((onlyOddLevels & 1) == 1) { // single inversion
+ Flip(start, end + 1);
+ return;
+ }
+ minLevel |= 1;
+ for (; maxLevel >= minLevel; --maxLevel) {
+ int pstart = start;
+ for (;;) {
+ for (;pstart <= end; ++pstart) {
+ if (orderLevels[pstart] >= maxLevel)
+ break;
+ }
+ if (pstart > end)
+ break;
+ int pend = pstart + 1;
+ for (; pend <= end; ++pend) {
+ if (orderLevels[pend] < maxLevel)
+ break;
+ }
+ Flip(pstart, pend);
+ pstart = pend + 1;
+ }
+ }
+ }
+
+ public void Flip(int start, int end) {
+ int mid = (start + end) / 2;
+ --end;
+ for (; start < mid; ++start, --end) {
+ int temp = indexChars[start];
+ indexChars[start] = indexChars[end];
+ indexChars[end] = temp;
+ }
+ }
+
+ public static bool IsWS(char c) {
+ return (c <= ' ');
+ }
+
+ static BidiLine() {
+ mirrorChars[0x0028] = 0x0029; // LEFT PARENTHESIS
+ mirrorChars[0x0029] = 0x0028; // RIGHT PARENTHESIS
+ mirrorChars[0x003C] = 0x003E; // LESS-THAN SIGN
+ mirrorChars[0x003E] = 0x003C; // GREATER-THAN SIGN
+ mirrorChars[0x005B] = 0x005D; // LEFT SQUARE BRACKET
+ mirrorChars[0x005D] = 0x005B; // RIGHT SQUARE BRACKET
+ mirrorChars[0x007B] = 0x007D; // LEFT CURLY BRACKET
+ mirrorChars[0x007D] = 0x007B; // RIGHT CURLY BRACKET
+ mirrorChars[0x00AB] = 0x00BB; // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ mirrorChars[0x00BB] = 0x00AB; // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ mirrorChars[0x2039] = 0x203A; // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ mirrorChars[0x203A] = 0x2039; // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ mirrorChars[0x2045] = 0x2046; // LEFT SQUARE BRACKET WITH QUILL
+ mirrorChars[0x2046] = 0x2045; // RIGHT SQUARE BRACKET WITH QUILL
+ mirrorChars[0x207D] = 0x207E; // SUPERSCRIPT LEFT PARENTHESIS
+ mirrorChars[0x207E] = 0x207D; // SUPERSCRIPT RIGHT PARENTHESIS
+ mirrorChars[0x208D] = 0x208E; // SUBSCRIPT LEFT PARENTHESIS
+ mirrorChars[0x208E] = 0x208D; // SUBSCRIPT RIGHT PARENTHESIS
+ mirrorChars[0x2208] = 0x220B; // ELEMENT OF
+ mirrorChars[0x2209] = 0x220C; // NOT AN ELEMENT OF
+ mirrorChars[0x220A] = 0x220D; // SMALL ELEMENT OF
+ mirrorChars[0x220B] = 0x2208; // CONTAINS AS MEMBER
+ mirrorChars[0x220C] = 0x2209; // DOES NOT CONTAIN AS MEMBER
+ mirrorChars[0x220D] = 0x220A; // SMALL CONTAINS AS MEMBER
+ mirrorChars[0x2215] = 0x29F5; // DIVISION SLASH
+ mirrorChars[0x223C] = 0x223D; // TILDE OPERATOR
+ mirrorChars[0x223D] = 0x223C; // REVERSED TILDE
+ mirrorChars[0x2243] = 0x22CD; // ASYMPTOTICALLY EQUAL TO
+ mirrorChars[0x2252] = 0x2253; // APPROXIMATELY EQUAL TO OR THE IMAGE OF
+ mirrorChars[0x2253] = 0x2252; // IMAGE OF OR APPROXIMATELY EQUAL TO
+ mirrorChars[0x2254] = 0x2255; // COLON EQUALS
+ mirrorChars[0x2255] = 0x2254; // EQUALS COLON
+ mirrorChars[0x2264] = 0x2265; // LESS-THAN OR EQUAL TO
+ mirrorChars[0x2265] = 0x2264; // GREATER-THAN OR EQUAL TO
+ mirrorChars[0x2266] = 0x2267; // LESS-THAN OVER EQUAL TO
+ mirrorChars[0x2267] = 0x2266; // GREATER-THAN OVER EQUAL TO
+ mirrorChars[0x2268] = 0x2269; // [BEST FIT] LESS-THAN BUT NOT EQUAL TO
+ mirrorChars[0x2269] = 0x2268; // [BEST FIT] GREATER-THAN BUT NOT EQUAL TO
+ mirrorChars[0x226A] = 0x226B; // MUCH LESS-THAN
+ mirrorChars[0x226B] = 0x226A; // MUCH GREATER-THAN
+ mirrorChars[0x226E] = 0x226F; // [BEST FIT] NOT LESS-THAN
+ mirrorChars[0x226F] = 0x226E; // [BEST FIT] NOT GREATER-THAN
+ mirrorChars[0x2270] = 0x2271; // [BEST FIT] NEITHER LESS-THAN NOR EQUAL TO
+ mirrorChars[0x2271] = 0x2270; // [BEST FIT] NEITHER GREATER-THAN NOR EQUAL TO
+ mirrorChars[0x2272] = 0x2273; // [BEST FIT] LESS-THAN OR EQUIVALENT TO
+ mirrorChars[0x2273] = 0x2272; // [BEST FIT] GREATER-THAN OR EQUIVALENT TO
+ mirrorChars[0x2274] = 0x2275; // [BEST FIT] NEITHER LESS-THAN NOR EQUIVALENT TO
+ mirrorChars[0x2275] = 0x2274; // [BEST FIT] NEITHER GREATER-THAN NOR EQUIVALENT TO
+ mirrorChars[0x2276] = 0x2277; // LESS-THAN OR GREATER-THAN
+ mirrorChars[0x2277] = 0x2276; // GREATER-THAN OR LESS-THAN
+ mirrorChars[0x2278] = 0x2279; // NEITHER LESS-THAN NOR GREATER-THAN
+ mirrorChars[0x2279] = 0x2278; // NEITHER GREATER-THAN NOR LESS-THAN
+ mirrorChars[0x227A] = 0x227B; // PRECEDES
+ mirrorChars[0x227B] = 0x227A; // SUCCEEDS
+ mirrorChars[0x227C] = 0x227D; // PRECEDES OR EQUAL TO
+ mirrorChars[0x227D] = 0x227C; // SUCCEEDS OR EQUAL TO
+ mirrorChars[0x227E] = 0x227F; // [BEST FIT] PRECEDES OR EQUIVALENT TO
+ mirrorChars[0x227F] = 0x227E; // [BEST FIT] SUCCEEDS OR EQUIVALENT TO
+ mirrorChars[0x2280] = 0x2281; // [BEST FIT] DOES NOT PRECEDE
+ mirrorChars[0x2281] = 0x2280; // [BEST FIT] DOES NOT SUCCEED
+ mirrorChars[0x2282] = 0x2283; // SUBSET OF
+ mirrorChars[0x2283] = 0x2282; // SUPERSET OF
+ mirrorChars[0x2284] = 0x2285; // [BEST FIT] NOT A SUBSET OF
+ mirrorChars[0x2285] = 0x2284; // [BEST FIT] NOT A SUPERSET OF
+ mirrorChars[0x2286] = 0x2287; // SUBSET OF OR EQUAL TO
+ mirrorChars[0x2287] = 0x2286; // SUPERSET OF OR EQUAL TO
+ mirrorChars[0x2288] = 0x2289; // [BEST FIT] NEITHER A SUBSET OF NOR EQUAL TO
+ mirrorChars[0x2289] = 0x2288; // [BEST FIT] NEITHER A SUPERSET OF NOR EQUAL TO
+ mirrorChars[0x228A] = 0x228B; // [BEST FIT] SUBSET OF WITH NOT EQUAL TO
+ mirrorChars[0x228B] = 0x228A; // [BEST FIT] SUPERSET OF WITH NOT EQUAL TO
+ mirrorChars[0x228F] = 0x2290; // SQUARE IMAGE OF
+ mirrorChars[0x2290] = 0x228F; // SQUARE ORIGINAL OF
+ mirrorChars[0x2291] = 0x2292; // SQUARE IMAGE OF OR EQUAL TO
+ mirrorChars[0x2292] = 0x2291; // SQUARE ORIGINAL OF OR EQUAL TO
+ mirrorChars[0x2298] = 0x29B8; // CIRCLED DIVISION SLASH
+ mirrorChars[0x22A2] = 0x22A3; // RIGHT TACK
+ mirrorChars[0x22A3] = 0x22A2; // LEFT TACK
+ mirrorChars[0x22A6] = 0x2ADE; // ASSERTION
+ mirrorChars[0x22A8] = 0x2AE4; // TRUE
+ mirrorChars[0x22A9] = 0x2AE3; // FORCES
+ mirrorChars[0x22AB] = 0x2AE5; // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
+ mirrorChars[0x22B0] = 0x22B1; // PRECEDES UNDER RELATION
+ mirrorChars[0x22B1] = 0x22B0; // SUCCEEDS UNDER RELATION
+ mirrorChars[0x22B2] = 0x22B3; // NORMAL SUBGROUP OF
+ mirrorChars[0x22B3] = 0x22B2; // CONTAINS AS NORMAL SUBGROUP
+ mirrorChars[0x22B4] = 0x22B5; // NORMAL SUBGROUP OF OR EQUAL TO
+ mirrorChars[0x22B5] = 0x22B4; // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO
+ mirrorChars[0x22B6] = 0x22B7; // ORIGINAL OF
+ mirrorChars[0x22B7] = 0x22B6; // IMAGE OF
+ mirrorChars[0x22C9] = 0x22CA; // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT
+ mirrorChars[0x22CA] = 0x22C9; // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT
+ mirrorChars[0x22CB] = 0x22CC; // LEFT SEMIDIRECT PRODUCT
+ mirrorChars[0x22CC] = 0x22CB; // RIGHT SEMIDIRECT PRODUCT
+ mirrorChars[0x22CD] = 0x2243; // REVERSED TILDE EQUALS
+ mirrorChars[0x22D0] = 0x22D1; // DOUBLE SUBSET
+ mirrorChars[0x22D1] = 0x22D0; // DOUBLE SUPERSET
+ mirrorChars[0x22D6] = 0x22D7; // LESS-THAN WITH DOT
+ mirrorChars[0x22D7] = 0x22D6; // GREATER-THAN WITH DOT
+ mirrorChars[0x22D8] = 0x22D9; // VERY MUCH LESS-THAN
+ mirrorChars[0x22D9] = 0x22D8; // VERY MUCH GREATER-THAN
+ mirrorChars[0x22DA] = 0x22DB; // LESS-THAN EQUAL TO OR GREATER-THAN
+ mirrorChars[0x22DB] = 0x22DA; // GREATER-THAN EQUAL TO OR LESS-THAN
+ mirrorChars[0x22DC] = 0x22DD; // EQUAL TO OR LESS-THAN
+ mirrorChars[0x22DD] = 0x22DC; // EQUAL TO OR GREATER-THAN
+ mirrorChars[0x22DE] = 0x22DF; // EQUAL TO OR PRECEDES
+ mirrorChars[0x22DF] = 0x22DE; // EQUAL TO OR SUCCEEDS
+ mirrorChars[0x22E0] = 0x22E1; // [BEST FIT] DOES NOT PRECEDE OR EQUAL
+ mirrorChars[0x22E1] = 0x22E0; // [BEST FIT] DOES NOT SUCCEED OR EQUAL
+ mirrorChars[0x22E2] = 0x22E3; // [BEST FIT] NOT SQUARE IMAGE OF OR EQUAL TO
+ mirrorChars[0x22E3] = 0x22E2; // [BEST FIT] NOT SQUARE ORIGINAL OF OR EQUAL TO
+ mirrorChars[0x22E4] = 0x22E5; // [BEST FIT] SQUARE IMAGE OF OR NOT EQUAL TO
+ mirrorChars[0x22E5] = 0x22E4; // [BEST FIT] SQUARE ORIGINAL OF OR NOT EQUAL TO
+ mirrorChars[0x22E6] = 0x22E7; // [BEST FIT] LESS-THAN BUT NOT EQUIVALENT TO
+ mirrorChars[0x22E7] = 0x22E6; // [BEST FIT] GREATER-THAN BUT NOT EQUIVALENT TO
+ mirrorChars[0x22E8] = 0x22E9; // [BEST FIT] PRECEDES BUT NOT EQUIVALENT TO
+ mirrorChars[0x22E9] = 0x22E8; // [BEST FIT] SUCCEEDS BUT NOT EQUIVALENT TO
+ mirrorChars[0x22EA] = 0x22EB; // [BEST FIT] NOT NORMAL SUBGROUP OF
+ mirrorChars[0x22EB] = 0x22EA; // [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP
+ mirrorChars[0x22EC] = 0x22ED; // [BEST FIT] NOT NORMAL SUBGROUP OF OR EQUAL TO
+ mirrorChars[0x22ED] = 0x22EC; // [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL
+ mirrorChars[0x22F0] = 0x22F1; // UP RIGHT DIAGONAL ELLIPSIS
+ mirrorChars[0x22F1] = 0x22F0; // DOWN RIGHT DIAGONAL ELLIPSIS
+ mirrorChars[0x22F2] = 0x22FA; // ELEMENT OF WITH LONG HORIZONTAL STROKE
+ mirrorChars[0x22F3] = 0x22FB; // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
+ mirrorChars[0x22F4] = 0x22FC; // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
+ mirrorChars[0x22F6] = 0x22FD; // ELEMENT OF WITH OVERBAR
+ mirrorChars[0x22F7] = 0x22FE; // SMALL ELEMENT OF WITH OVERBAR
+ mirrorChars[0x22FA] = 0x22F2; // CONTAINS WITH LONG HORIZONTAL STROKE
+ mirrorChars[0x22FB] = 0x22F3; // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
+ mirrorChars[0x22FC] = 0x22F4; // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
+ mirrorChars[0x22FD] = 0x22F6; // CONTAINS WITH OVERBAR
+ mirrorChars[0x22FE] = 0x22F7; // SMALL CONTAINS WITH OVERBAR
+ mirrorChars[0x2308] = 0x2309; // LEFT CEILING
+ mirrorChars[0x2309] = 0x2308; // RIGHT CEILING
+ mirrorChars[0x230A] = 0x230B; // LEFT FLOOR
+ mirrorChars[0x230B] = 0x230A; // RIGHT FLOOR
+ mirrorChars[0x2329] = 0x232A; // LEFT-POINTING ANGLE BRACKET
+ mirrorChars[0x232A] = 0x2329; // RIGHT-POINTING ANGLE BRACKET
+ mirrorChars[0x2768] = 0x2769; // MEDIUM LEFT PARENTHESIS ORNAMENT
+ mirrorChars[0x2769] = 0x2768; // MEDIUM RIGHT PARENTHESIS ORNAMENT
+ mirrorChars[0x276A] = 0x276B; // MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
+ mirrorChars[0x276B] = 0x276A; // MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
+ mirrorChars[0x276C] = 0x276D; // MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
+ mirrorChars[0x276D] = 0x276C; // MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
+ mirrorChars[0x276E] = 0x276F; // HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
+ mirrorChars[0x276F] = 0x276E; // HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
+ mirrorChars[0x2770] = 0x2771; // HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
+ mirrorChars[0x2771] = 0x2770; // HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
+ mirrorChars[0x2772] = 0x2773; // LIGHT LEFT TORTOISE SHELL BRACKET
+ mirrorChars[0x2773] = 0x2772; // LIGHT RIGHT TORTOISE SHELL BRACKET
+ mirrorChars[0x2774] = 0x2775; // MEDIUM LEFT CURLY BRACKET ORNAMENT
+ mirrorChars[0x2775] = 0x2774; // MEDIUM RIGHT CURLY BRACKET ORNAMENT
+ mirrorChars[0x27D5] = 0x27D6; // LEFT OUTER JOIN
+ mirrorChars[0x27D6] = 0x27D5; // RIGHT OUTER JOIN
+ mirrorChars[0x27DD] = 0x27DE; // LONG RIGHT TACK
+ mirrorChars[0x27DE] = 0x27DD; // LONG LEFT TACK
+ mirrorChars[0x27E2] = 0x27E3; // WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK
+ mirrorChars[0x27E3] = 0x27E2; // WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK
+ mirrorChars[0x27E4] = 0x27E5; // WHITE SQUARE WITH LEFTWARDS TICK
+ mirrorChars[0x27E5] = 0x27E4; // WHITE SQUARE WITH RIGHTWARDS TICK
+ mirrorChars[0x27E6] = 0x27E7; // MATHEMATICAL LEFT WHITE SQUARE BRACKET
+ mirrorChars[0x27E7] = 0x27E6; // MATHEMATICAL RIGHT WHITE SQUARE BRACKET
+ mirrorChars[0x27E8] = 0x27E9; // MATHEMATICAL LEFT ANGLE BRACKET
+ mirrorChars[0x27E9] = 0x27E8; // MATHEMATICAL RIGHT ANGLE BRACKET
+ mirrorChars[0x27EA] = 0x27EB; // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
+ mirrorChars[0x27EB] = 0x27EA; // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
+ mirrorChars[0x2983] = 0x2984; // LEFT WHITE CURLY BRACKET
+ mirrorChars[0x2984] = 0x2983; // RIGHT WHITE CURLY BRACKET
+ mirrorChars[0x2985] = 0x2986; // LEFT WHITE PARENTHESIS
+ mirrorChars[0x2986] = 0x2985; // RIGHT WHITE PARENTHESIS
+ mirrorChars[0x2987] = 0x2988; // Z NOTATION LEFT IMAGE BRACKET
+ mirrorChars[0x2988] = 0x2987; // Z NOTATION RIGHT IMAGE BRACKET
+ mirrorChars[0x2989] = 0x298A; // Z NOTATION LEFT BINDING BRACKET
+ mirrorChars[0x298A] = 0x2989; // Z NOTATION RIGHT BINDING BRACKET
+ mirrorChars[0x298B] = 0x298C; // LEFT SQUARE BRACKET WITH UNDERBAR
+ mirrorChars[0x298C] = 0x298B; // RIGHT SQUARE BRACKET WITH UNDERBAR
+ mirrorChars[0x298D] = 0x2990; // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
+ mirrorChars[0x298E] = 0x298F; // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+ mirrorChars[0x298F] = 0x298E; // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+ mirrorChars[0x2990] = 0x298D; // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
+ mirrorChars[0x2991] = 0x2992; // LEFT ANGLE BRACKET WITH DOT
+ mirrorChars[0x2992] = 0x2991; // RIGHT ANGLE BRACKET WITH DOT
+ mirrorChars[0x2993] = 0x2994; // LEFT ARC LESS-THAN BRACKET
+ mirrorChars[0x2994] = 0x2993; // RIGHT ARC GREATER-THAN BRACKET
+ mirrorChars[0x2995] = 0x2996; // DOUBLE LEFT ARC GREATER-THAN BRACKET
+ mirrorChars[0x2996] = 0x2995; // DOUBLE RIGHT ARC LESS-THAN BRACKET
+ mirrorChars[0x2997] = 0x2998; // LEFT BLACK TORTOISE SHELL BRACKET
+ mirrorChars[0x2998] = 0x2997; // RIGHT BLACK TORTOISE SHELL BRACKET
+ mirrorChars[0x29B8] = 0x2298; // CIRCLED REVERSE SOLIDUS
+ mirrorChars[0x29C0] = 0x29C1; // CIRCLED LESS-THAN
+ mirrorChars[0x29C1] = 0x29C0; // CIRCLED GREATER-THAN
+ mirrorChars[0x29C4] = 0x29C5; // SQUARED RISING DIAGONAL SLASH
+ mirrorChars[0x29C5] = 0x29C4; // SQUARED FALLING DIAGONAL SLASH
+ mirrorChars[0x29CF] = 0x29D0; // LEFT TRIANGLE BESIDE VERTICAL BAR
+ mirrorChars[0x29D0] = 0x29CF; // VERTICAL BAR BESIDE RIGHT TRIANGLE
+ mirrorChars[0x29D1] = 0x29D2; // BOWTIE WITH LEFT HALF BLACK
+ mirrorChars[0x29D2] = 0x29D1; // BOWTIE WITH RIGHT HALF BLACK
+ mirrorChars[0x29D4] = 0x29D5; // TIMES WITH LEFT HALF BLACK
+ mirrorChars[0x29D5] = 0x29D4; // TIMES WITH RIGHT HALF BLACK
+ mirrorChars[0x29D8] = 0x29D9; // LEFT WIGGLY FENCE
+ mirrorChars[0x29D9] = 0x29D8; // RIGHT WIGGLY FENCE
+ mirrorChars[0x29DA] = 0x29DB; // LEFT DOUBLE WIGGLY FENCE
+ mirrorChars[0x29DB] = 0x29DA; // RIGHT DOUBLE WIGGLY FENCE
+ mirrorChars[0x29F5] = 0x2215; // REVERSE SOLIDUS OPERATOR
+ mirrorChars[0x29F8] = 0x29F9; // BIG SOLIDUS
+ mirrorChars[0x29F9] = 0x29F8; // BIG REVERSE SOLIDUS
+ mirrorChars[0x29FC] = 0x29FD; // LEFT-POINTING CURVED ANGLE BRACKET
+ mirrorChars[0x29FD] = 0x29FC; // RIGHT-POINTING CURVED ANGLE BRACKET
+ mirrorChars[0x2A2B] = 0x2A2C; // MINUS SIGN WITH FALLING DOTS
+ mirrorChars[0x2A2C] = 0x2A2B; // MINUS SIGN WITH RISING DOTS
+ mirrorChars[0x2A2D] = 0x2A2C; // PLUS SIGN IN LEFT HALF CIRCLE
+ mirrorChars[0x2A2E] = 0x2A2D; // PLUS SIGN IN RIGHT HALF CIRCLE
+ mirrorChars[0x2A34] = 0x2A35; // MULTIPLICATION SIGN IN LEFT HALF CIRCLE
+ mirrorChars[0x2A35] = 0x2A34; // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE
+ mirrorChars[0x2A3C] = 0x2A3D; // INTERIOR PRODUCT
+ mirrorChars[0x2A3D] = 0x2A3C; // RIGHTHAND INTERIOR PRODUCT
+ mirrorChars[0x2A64] = 0x2A65; // Z NOTATION DOMAIN ANTIRESTRICTION
+ mirrorChars[0x2A65] = 0x2A64; // Z NOTATION RANGE ANTIRESTRICTION
+ mirrorChars[0x2A79] = 0x2A7A; // LESS-THAN WITH CIRCLE INSIDE
+ mirrorChars[0x2A7A] = 0x2A79; // GREATER-THAN WITH CIRCLE INSIDE
+ mirrorChars[0x2A7D] = 0x2A7E; // LESS-THAN OR SLANTED EQUAL TO
+ mirrorChars[0x2A7E] = 0x2A7D; // GREATER-THAN OR SLANTED EQUAL TO
+ mirrorChars[0x2A7F] = 0x2A80; // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
+ mirrorChars[0x2A80] = 0x2A7F; // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
+ mirrorChars[0x2A81] = 0x2A82; // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
+ mirrorChars[0x2A82] = 0x2A81; // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
+ mirrorChars[0x2A83] = 0x2A84; // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT
+ mirrorChars[0x2A84] = 0x2A83; // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT
+ mirrorChars[0x2A8B] = 0x2A8C; // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
+ mirrorChars[0x2A8C] = 0x2A8B; // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN
+ mirrorChars[0x2A91] = 0x2A92; // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL
+ mirrorChars[0x2A92] = 0x2A91; // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL
+ mirrorChars[0x2A93] = 0x2A94; // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL
+ mirrorChars[0x2A94] = 0x2A93; // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL
+ mirrorChars[0x2A95] = 0x2A96; // SLANTED EQUAL TO OR LESS-THAN
+ mirrorChars[0x2A96] = 0x2A95; // SLANTED EQUAL TO OR GREATER-THAN
+ mirrorChars[0x2A97] = 0x2A98; // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE
+ mirrorChars[0x2A98] = 0x2A97; // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE
+ mirrorChars[0x2A99] = 0x2A9A; // DOUBLE-LINE EQUAL TO OR LESS-THAN
+ mirrorChars[0x2A9A] = 0x2A99; // DOUBLE-LINE EQUAL TO OR GREATER-THAN
+ mirrorChars[0x2A9B] = 0x2A9C; // DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN
+ mirrorChars[0x2A9C] = 0x2A9B; // DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN
+ mirrorChars[0x2AA1] = 0x2AA2; // DOUBLE NESTED LESS-THAN
+ mirrorChars[0x2AA2] = 0x2AA1; // DOUBLE NESTED GREATER-THAN
+ mirrorChars[0x2AA6] = 0x2AA7; // LESS-THAN CLOSED BY CURVE
+ mirrorChars[0x2AA7] = 0x2AA6; // GREATER-THAN CLOSED BY CURVE
+ mirrorChars[0x2AA8] = 0x2AA9; // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
+ mirrorChars[0x2AA9] = 0x2AA8; // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
+ mirrorChars[0x2AAA] = 0x2AAB; // SMALLER THAN
+ mirrorChars[0x2AAB] = 0x2AAA; // LARGER THAN
+ mirrorChars[0x2AAC] = 0x2AAD; // SMALLER THAN OR EQUAL TO
+ mirrorChars[0x2AAD] = 0x2AAC; // LARGER THAN OR EQUAL TO
+ mirrorChars[0x2AAF] = 0x2AB0; // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN
+ mirrorChars[0x2AB0] = 0x2AAF; // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN
+ mirrorChars[0x2AB3] = 0x2AB4; // PRECEDES ABOVE EQUALS SIGN
+ mirrorChars[0x2AB4] = 0x2AB3; // SUCCEEDS ABOVE EQUALS SIGN
+ mirrorChars[0x2ABB] = 0x2ABC; // DOUBLE PRECEDES
+ mirrorChars[0x2ABC] = 0x2ABB; // DOUBLE SUCCEEDS
+ mirrorChars[0x2ABD] = 0x2ABE; // SUBSET WITH DOT
+ mirrorChars[0x2ABE] = 0x2ABD; // SUPERSET WITH DOT
+ mirrorChars[0x2ABF] = 0x2AC0; // SUBSET WITH PLUS SIGN BELOW
+ mirrorChars[0x2AC0] = 0x2ABF; // SUPERSET WITH PLUS SIGN BELOW
+ mirrorChars[0x2AC1] = 0x2AC2; // SUBSET WITH MULTIPLICATION SIGN BELOW
+ mirrorChars[0x2AC2] = 0x2AC1; // SUPERSET WITH MULTIPLICATION SIGN BELOW
+ mirrorChars[0x2AC3] = 0x2AC4; // SUBSET OF OR EQUAL TO WITH DOT ABOVE
+ mirrorChars[0x2AC4] = 0x2AC3; // SUPERSET OF OR EQUAL TO WITH DOT ABOVE
+ mirrorChars[0x2AC5] = 0x2AC6; // SUBSET OF ABOVE EQUALS SIGN
+ mirrorChars[0x2AC6] = 0x2AC5; // SUPERSET OF ABOVE EQUALS SIGN
+ mirrorChars[0x2ACD] = 0x2ACE; // SQUARE LEFT OPEN BOX OPERATOR
+ mirrorChars[0x2ACE] = 0x2ACD; // SQUARE RIGHT OPEN BOX OPERATOR
+ mirrorChars[0x2ACF] = 0x2AD0; // CLOSED SUBSET
+ mirrorChars[0x2AD0] = 0x2ACF; // CLOSED SUPERSET
+ mirrorChars[0x2AD1] = 0x2AD2; // CLOSED SUBSET OR EQUAL TO
+ mirrorChars[0x2AD2] = 0x2AD1; // CLOSED SUPERSET OR EQUAL TO
+ mirrorChars[0x2AD3] = 0x2AD4; // SUBSET ABOVE SUPERSET
+ mirrorChars[0x2AD4] = 0x2AD3; // SUPERSET ABOVE SUBSET
+ mirrorChars[0x2AD5] = 0x2AD6; // SUBSET ABOVE SUBSET
+ mirrorChars[0x2AD6] = 0x2AD5; // SUPERSET ABOVE SUPERSET
+ mirrorChars[0x2ADE] = 0x22A6; // SHORT LEFT TACK
+ mirrorChars[0x2AE3] = 0x22A9; // DOUBLE VERTICAL BAR LEFT TURNSTILE
+ mirrorChars[0x2AE4] = 0x22A8; // VERTICAL BAR DOUBLE LEFT TURNSTILE
+ mirrorChars[0x2AE5] = 0x22AB; // DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE
+ mirrorChars[0x2AEC] = 0x2AED; // DOUBLE STROKE NOT SIGN
+ mirrorChars[0x2AED] = 0x2AEC; // REVERSED DOUBLE STROKE NOT SIGN
+ mirrorChars[0x2AF7] = 0x2AF8; // TRIPLE NESTED LESS-THAN
+ mirrorChars[0x2AF8] = 0x2AF7; // TRIPLE NESTED GREATER-THAN
+ mirrorChars[0x2AF9] = 0x2AFA; // DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO
+ mirrorChars[0x2AFA] = 0x2AF9; // DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO
+ mirrorChars[0x3008] = 0x3009; // LEFT ANGLE BRACKET
+ mirrorChars[0x3009] = 0x3008; // RIGHT ANGLE BRACKET
+ mirrorChars[0x300A] = 0x300B; // LEFT DOUBLE ANGLE BRACKET
+ mirrorChars[0x300B] = 0x300A; // RIGHT DOUBLE ANGLE BRACKET
+ mirrorChars[0x300C] = 0x300D; // [BEST FIT] LEFT CORNER BRACKET
+ mirrorChars[0x300D] = 0x300C; // [BEST FIT] RIGHT CORNER BRACKET
+ mirrorChars[0x300E] = 0x300F; // [BEST FIT] LEFT WHITE CORNER BRACKET
+ mirrorChars[0x300F] = 0x300E; // [BEST FIT] RIGHT WHITE CORNER BRACKET
+ mirrorChars[0x3010] = 0x3011; // LEFT BLACK LENTICULAR BRACKET
+ mirrorChars[0x3011] = 0x3010; // RIGHT BLACK LENTICULAR BRACKET
+ mirrorChars[0x3014] = 0x3015; // LEFT TORTOISE SHELL BRACKET
+ mirrorChars[0x3015] = 0x3014; // RIGHT TORTOISE SHELL BRACKET
+ mirrorChars[0x3016] = 0x3017; // LEFT WHITE LENTICULAR BRACKET
+ mirrorChars[0x3017] = 0x3016; // RIGHT WHITE LENTICULAR BRACKET
+ mirrorChars[0x3018] = 0x3019; // LEFT WHITE TORTOISE SHELL BRACKET
+ mirrorChars[0x3019] = 0x3018; // RIGHT WHITE TORTOISE SHELL BRACKET
+ mirrorChars[0x301A] = 0x301B; // LEFT WHITE SQUARE BRACKET
+ mirrorChars[0x301B] = 0x301A; // RIGHT WHITE SQUARE BRACKET
+ mirrorChars[0xFF08] = 0xFF09; // FULLWIDTH LEFT PARENTHESIS
+ mirrorChars[0xFF09] = 0xFF08; // FULLWIDTH RIGHT PARENTHESIS
+ mirrorChars[0xFF1C] = 0xFF1E; // FULLWIDTH LESS-THAN SIGN
+ mirrorChars[0xFF1E] = 0xFF1C; // FULLWIDTH GREATER-THAN SIGN
+ mirrorChars[0xFF3B] = 0xFF3D; // FULLWIDTH LEFT SQUARE BRACKET
+ mirrorChars[0xFF3D] = 0xFF3B; // FULLWIDTH RIGHT SQUARE BRACKET
+ mirrorChars[0xFF5B] = 0xFF5D; // FULLWIDTH LEFT CURLY BRACKET
+ mirrorChars[0xFF5D] = 0xFF5B; // FULLWIDTH RIGHT CURLY BRACKET
+ mirrorChars[0xFF5F] = 0xFF60; // FULLWIDTH LEFT WHITE PARENTHESIS
+ mirrorChars[0xFF60] = 0xFF5F; // FULLWIDTH RIGHT WHITE PARENTHESIS
+ mirrorChars[0xFF62] = 0xFF63; // [BEST FIT] HALFWIDTH LEFT CORNER BRACKET
+ mirrorChars[0xFF63] = 0xFF62; // [BEST FIT] HALFWIDTH RIGHT CORNER BRACKET
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/BidiOrder.cs b/iTechSharp/iTextSharp/text/pdf/BidiOrder.cs
new file mode 100644
index 0000000..08f4be6
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/BidiOrder.cs
@@ -0,0 +1,1296 @@
+using System;
+/*
+ * Copyright 2003 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+/*
+ * (C) Copyright IBM Corp. 1999, All Rights Reserved
+ *
+ * version 1.1
+ */
+
+/*
+ * As stated in the Javadoc comments below, materials from Unicode.org
+ * are used in this class. The following license applies to these materials:
+ * http://www.unicode.org/copyright.html#Exhibit1
+ *
+ * EXHIBIT 1
+ * UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+ *
+ * Unicode Data Files include all data files under the directories
+ * http://www.unicode.org/Public/, http://www.unicode.org/reports/,
+ * and http://www.unicode.org/cldr/data/ .
+ * Unicode Software includes any source code published in the Unicode Standard
+ * or under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/,
+ * and http://www.unicode.org/cldr/data/.
+ *
+ * NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING,
+ * INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"),
+ * AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY,
+ * ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
+ * DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
+ *
+ * COPYRIGHT AND PERMISSION NOTICE
+ * Copyright © 1991-2007 Unicode, Inc. All rights reserved. Distributed under
+ * the Terms of Use in http://www.unicode.org/copyright.html.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of the Unicode data files and any associated documentation (the "Data Files")
+ * or Unicode software and any associated documentation (the "Software") to deal
+ * in the Data Files or Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, and/or sell copies
+ * of the Data Files or Software, and to permit persons to whom the Data Files
+ * or Software are furnished to do so, provided that (a) the above copyright
+ * notice(s) and this permission notice appear with all copies of the Data Files
+ * or Software, (b) both the above copyright notice(s) and this permission notice
+ * appear in associated documentation, and (c) there is clear notice in each
+ * modified Data File or in the Software as well as in the documentation associated
+ * with the Data File(s) or Software that the data or software has been modified.
+ *
+ * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
+ * LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall not
+ * be used in advertising or otherwise to promote the sale, use or other dealings
+ * in these Data Files or Software without prior written authorization of the
+ * copyright holder.
+ */
+
+/**
+ * Reference implementation of the Unicode 3.0 Bidi algorithm.
+ *
+ *
+ * There are two levels of input to the algorithm, since clients may prefer
+ * to supply some information from out-of-band sources rather than relying on
+ * the default behavior.
+ *
+ *
+ *
+ * Output is separated into several stages as well, to better enable clients
+ * to evaluate various aspects of implementation conformance.
+ *
+ *
+ * Note that for conformance, algorithms are only required to generate correct
+ * reordering and character directionality (odd or even levels) over a line.
+ * Generating identical level arrays over a line is not required. Bidi
+ * explicit format codes (LRE, RLE, LRO, RLO, PDF) and BN can be assigned
+ * arbitrary levels and positions as long as the other text matches.
+ *
+ * Rule L1.
+ * GetReordering(linebreaks)[linebreaks[1] + 4]
+ * (linebreaks[1] is the position after the last character of the
+ * second line, which is also the index of the first character on the
+ * third line, and adding four gets the fifth character from the left).
+ * StringBuilder
but works with byte
arrays.
+ * floating point is converted to a format suitable to the PDF.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+
+ public class ByteBuffer : Stream {
+ /** The count of bytes in the buffer. */
+ protected int count;
+
+ /** The buffer where the bytes are stored. */
+ protected byte[] buf;
+
+ private static int byteCacheSize = 0;
+
+ private static byte[][] byteCache = new byte[byteCacheSize][];
+ public const byte ZERO = (byte)'0';
+ private static char[] chars = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+ private static byte[] bytes = new byte[] {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102};
+ /**
+ * If true
always output floating point numbers with 6 decimal digits.
+ * If false
uses the faster, although less precise, representation.
+ */
+ public static bool HIGH_PRECISION = false;
+
+ /** Creates new ByteBuffer with capacity 128 */
+ public ByteBuffer() : this(128) {}
+
+ /**
+ * Creates a byte buffer with a certain capacity.
+ * @param size the initial capacity
+ */
+ public ByteBuffer(int size) {
+ if (size < 1)
+ size = 128;
+ buf = new byte[size];
+ }
+
+ /**
+ * Sets the cache size.
+ * int
. The size of the array will grow by one.
+ * @param b the int to be appended
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append_i(int b) {
+ int newcount = count + 1;
+ if (newcount > buf.Length) {
+ byte[] newbuf = new byte[Math.Max(buf.Length << 1, newcount)];
+ Array.Copy(buf, 0, newbuf, 0, count);
+ buf = newbuf;
+ }
+ buf[count] = (byte)b;
+ count = newcount;
+ return this;
+ }
+
+ /**
+ * Appends the subarray of the byte
array. The buffer will grow by
+ * len
bytes.
+ * @param b the array to be appended
+ * @param off the offset to the start of the array
+ * @param len the length of bytes to Append
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append(byte[] b, int off, int len) {
+ if ((off < 0) || (off > b.Length) || (len < 0) ||
+ ((off + len) > b.Length) || ((off + len) < 0) || len == 0)
+ return this;
+ int newcount = count + len;
+ if (newcount > buf.Length) {
+ byte[] newbuf = new byte[Math.Max(buf.Length << 1, newcount)];
+ Array.Copy(buf, 0, newbuf, 0, count);
+ buf = newbuf;
+ }
+ Array.Copy(b, off, buf, count, len);
+ count = newcount;
+ return this;
+ }
+
+ /**
+ * Appends an array of bytes.
+ * @param b the array to be appended
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append(byte[] b) {
+ return Append(b, 0, b.Length);
+ }
+
+ /**
+ * Appends a string
to the buffer. The string
is
+ * converted according to the encoding ISO-8859-1.
+ * @param str the string
to be appended
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append(string str) {
+ if (str != null)
+ return Append(DocWriter.GetISOBytes(str));
+ return this;
+ }
+
+ /**
+ * Appends a char
to the buffer. The char
is
+ * converted according to the encoding ISO-8859-1.
+ * @param c the char
to be appended
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append(char c) {
+ return Append_i(c);
+ }
+
+ /**
+ * Appends another ByteBuffer
to this buffer.
+ * @param buf the ByteBuffer
to be appended
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append(ByteBuffer buf) {
+ return Append(buf.buf, 0, buf.count);
+ }
+
+ /**
+ * Appends the string representation of an int
.
+ * @param i the int
to be appended
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append(int i) {
+ return Append((double)i);
+ }
+
+ public ByteBuffer Append(byte b) {
+ return Append_i(b);
+ }
+
+ public ByteBuffer AppendHex(byte b) {
+ Append(bytes[(b >> 4) & 0x0f]);
+ return Append(bytes[b & 0x0f]);
+ }
+
+ /**
+ * Appends a string representation of a float
according
+ * to the Pdf conventions.
+ * @param i the float
to be appended
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append(float i) {
+ return Append((double)i);
+ }
+
+ /**
+ * Appends a string representation of a double
according
+ * to the Pdf conventions.
+ * @param d the double
to be appended
+ * @return a reference to this ByteBuffer
object
+ */
+ public ByteBuffer Append(double d) {
+ Append(FormatDouble(d, this));
+ return this;
+ }
+
+ /**
+ * Outputs a double
into a format suitable for the PDF.
+ * @param d a double
+ * @return the string
representation of the double
+ */
+ public static string FormatDouble(double d) {
+ return FormatDouble(d, null);
+ }
+
+ /**
+ * Outputs a double
into a format suitable for the PDF.
+ * @param d a double
+ * @param buf a ByteBuffer
+ * @return the String
representation of the double
if
+ * buf
is null
. If buf
is not null
,
+ * then the double is appended directly to the buffer and this methods returns null
.
+ */
+ public static string FormatDouble(double d, ByteBuffer buf) {
+ if (HIGH_PRECISION) {
+ String sform = d.ToString("0.######", CultureInfo.InvariantCulture);
+ if (buf == null)
+ return sform;
+ else {
+ buf.Append(sform);
+ return null;
+ }
+ }
+ bool negative = false;
+ if (Math.Abs(d) < 0.000015) {
+ if (buf != null) {
+ buf.Append(ZERO);
+ return null;
+ } else {
+ return "0";
+ }
+ }
+ if (d < 0) {
+ negative = true;
+ d = -d;
+ }
+ if (d < 1.0) {
+ d += 0.000005;
+ if (d >= 1) {
+ if (negative) {
+ if (buf != null) {
+ buf.Append((byte)'-');
+ buf.Append((byte)'1');
+ return null;
+ } else {
+ return "-1";
+ }
+ } else {
+ if (buf != null) {
+ buf.Append((byte)'1');
+ return null;
+ } else {
+ return "1";
+ }
+ }
+ }
+ if (buf != null) {
+ int v = (int) (d * 100000);
+
+ if (negative) buf.Append((byte)'-');
+ buf.Append((byte)'0');
+ buf.Append((byte)'.');
+
+ buf.Append( (byte)(v / 10000 + ZERO) );
+ if (v % 10000 != 0) {
+ buf.Append( (byte)((v / 1000) % 10 + ZERO) );
+ if (v % 1000 != 0) {
+ buf.Append( (byte)((v / 100) % 10 + ZERO) );
+ if (v % 100 != 0) {
+ buf.Append((byte)((v / 10) % 10 + ZERO) );
+ if (v % 10 != 0) {
+ buf.Append((byte)((v) % 10 + ZERO) );
+ }
+ }
+ }
+ }
+ return null;
+ } else {
+ int x = 100000;
+ int v = (int) (d * x);
+
+ StringBuilder res = new StringBuilder();
+ if (negative) res.Append('-');
+ res.Append("0.");
+
+ while ( v < x/10 ) {
+ res.Append('0');
+ x /= 10;
+ }
+ res.Append(v);
+ int cut = res.Length - 1;
+ while (res[cut] == '0') {
+ --cut;
+ }
+ res.Length = cut + 1;
+ return res.ToString();
+ }
+ } else if (d <= 32767) {
+ d += 0.005;
+ int v = (int) (d * 100);
+
+ if (v < byteCacheSize && byteCache[v] != null) {
+ if (buf != null) {
+ if (negative) buf.Append((byte)'-');
+ buf.Append(byteCache[v]);
+ return null;
+ } else {
+ string tmp = PdfEncodings.ConvertToString(byteCache[v], null);
+ if (negative) tmp = "-" + tmp;
+ return tmp;
+ }
+ }
+ if (buf != null) {
+ if (v < byteCacheSize) {
+ //create the cachebyte[]
+ byte[] cache;
+ int size = 0;
+ if (v >= 1000000) {
+ //the original number is >=10000, we need 5 more bytes
+ size += 5;
+ } else if (v >= 100000) {
+ //the original number is >=1000, we need 4 more bytes
+ size += 4;
+ } else if (v >= 10000) {
+ //the original number is >=100, we need 3 more bytes
+ size += 3;
+ } else if (v >= 1000) {
+ //the original number is >=10, we need 2 more bytes
+ size += 2;
+ } else if (v >= 100) {
+ //the original number is >=1, we need 1 more bytes
+ size += 1;
+ }
+
+ //now we must check if we have a decimal number
+ if (v % 100 != 0) {
+ //yes, do not forget the "."
+ size += 2;
+ }
+ if (v % 10 != 0) {
+ size++;
+ }
+ cache = new byte[size];
+ int add = 0;
+ if (v >= 1000000) {
+ cache[add++] = bytes[(v / 1000000)];
+ }
+ if (v >= 100000) {
+ cache[add++] = bytes[(v / 100000) % 10];
+ }
+ if (v >= 10000) {
+ cache[add++] = bytes[(v / 10000) % 10];
+ }
+ if (v >= 1000) {
+ cache[add++] = bytes[(v / 1000) % 10];
+ }
+ if (v >= 100) {
+ cache[add++] = bytes[(v / 100) % 10];
+ }
+
+ if (v % 100 != 0) {
+ cache[add++] = (byte)'.';
+ cache[add++] = bytes[(v / 10) % 10];
+ if (v % 10 != 0) {
+ cache[add++] = bytes[v % 10];
+ }
+ }
+ byteCache[v] = cache;
+ }
+
+ if (negative) buf.Append((byte)'-');
+ if (v >= 1000000) {
+ buf.Append( bytes[(v / 1000000)] );
+ }
+ if (v >= 100000) {
+ buf.Append( bytes[(v / 100000) % 10] );
+ }
+ if (v >= 10000) {
+ buf.Append( bytes[(v / 10000) % 10] );
+ }
+ if (v >= 1000) {
+ buf.Append( bytes[(v / 1000) % 10] );
+ }
+ if (v >= 100) {
+ buf.Append( bytes[(v / 100) % 10] );
+ }
+
+ if (v % 100 != 0) {
+ buf.Append((byte)'.');
+ buf.Append( bytes[(v / 10) % 10] );
+ if (v % 10 != 0) {
+ buf.Append( bytes[v % 10] );
+ }
+ }
+ return null;
+ } else {
+ StringBuilder res = new StringBuilder();
+ if (negative) res.Append('-');
+ if (v >= 1000000) {
+ res.Append( chars[(v / 1000000)] );
+ }
+ if (v >= 100000) {
+ res.Append( chars[(v / 100000) % 10] );
+ }
+ if (v >= 10000) {
+ res.Append( chars[(v / 10000) % 10] );
+ }
+ if (v >= 1000) {
+ res.Append( chars[(v / 1000) % 10] );
+ }
+ if (v >= 100) {
+ res.Append( chars[(v / 100) % 10] );
+ }
+
+ if (v % 100 != 0) {
+ res.Append('.');
+ res.Append( chars[(v / 10) % 10] );
+ if (v % 10 != 0) {
+ res.Append( chars[v % 10] );
+ }
+ }
+ return res.ToString();
+ }
+ } else {
+ StringBuilder res = new StringBuilder();
+ if (negative) res.Append('-');
+ d += 0.5;
+ long v = (long) d;
+ return res.Append(v).ToString();
+ }
+ }
+
+ /**
+ * Sets the size to zero.
+ */
+ public void Reset() {
+ count = 0;
+ }
+
+ /**
+ * Creates a newly allocated byte array. Its size is the current
+ * size of this output stream and the valid contents of the buffer
+ * have been copied into it.
+ *
+ * @return the current contents of this output stream, as a byte array.
+ */
+ public byte[] ToByteArray() {
+ byte[] newbuf = new byte[count];
+ Array.Copy(buf, 0, newbuf, 0, count);
+ return newbuf;
+ }
+
+ /**
+ * Returns the current size of the buffer.
+ *
+ * @return the value of the count
field, which is the number of valid bytes in this byte buffer.
+ */
+ public int Size {
+ get {
+ return count;
+ }
+ set {
+ if (value > count || value < 0)
+ throw new ArgumentOutOfRangeException("The new size must be positive and <= of the current size");
+ count = value;
+ }
+ }
+
+ /**
+ * Converts the buffer's contents into a string, translating bytes into
+ * characters according to the platform's default character encoding.
+ *
+ * @return string translated from the buffer's contents.
+ */
+ public override string ToString() {
+ char[] tmp = this.ConvertToChar(buf);
+ return new String(tmp, 0, count);
+ }
+
+ /**
+ * Converts the buffer's contents into a string, translating bytes into
+ * characters according to the specified character encoding.
+ *
+ * @param enc a character-encoding name.
+ * @return string translated from the buffer's contents.
+ * @throws UnsupportedEncodingException
+ * If the named encoding is not supported.
+ */
+// public string ToString(System.Text.Encoding enc) {
+// return new String(ref buf, 0, count, enc);
+// }
+
+ /**
+ * Writes the complete contents of this byte buffer output to
+ * the specified output stream argument, as if by calling the output
+ * stream's write method using out.Write(buf, 0, count)
.
+ *
+ * @param out the output stream to which to write the data.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void WriteTo(Stream str) {
+ str.Write(buf, 0, count);
+ }
+
+ private char[] ConvertToChar(byte[] buf) {
+ char[] retVal = new char[count + 1];
+ for (int i = 0; i <= count; i++) {
+ retVal[i] = (char)buf[i];
+ }
+ return retVal;
+ }
+
+ public byte[] Buffer {
+ get {
+ return buf;
+ }
+ }
+
+ public override bool CanRead {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanSeek {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanWrite {
+ get {
+ return true;
+ }
+ }
+
+ public override long Length {
+ get {
+ return count;
+ }
+ }
+
+ public override long Position {
+ get {
+ return count;
+ }
+ set {
+ }
+ }
+
+ public override void Flush() {
+ }
+
+ public override int Read(byte[] buffer, int offset, int count) {
+ return 0;
+ }
+
+ public override long Seek(long offset, SeekOrigin origin) {
+ return 0;
+ }
+
+ public override void SetLength(long value) {
+ }
+
+ public override void Write(byte[] buffer, int offset, int count) {
+ Append(buffer, offset, count);
+ }
+
+ public override void WriteByte(byte value) {
+ Append(value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/CFFFont.cs b/iTechSharp/iTextSharp/text/pdf/CFFFont.cs
new file mode 100644
index 0000000..4062617
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/CFFFont.cs
@@ -0,0 +1,1111 @@
+using System;
+using System.Text;
+using System.Collections;
+/*
+ *
+ * Copyright 2003 Sivan Toledo
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ */
+
+namespace iTextSharp.text.pdf {
+ public class CFFFont {
+
+ internal static String[] operatorNames = {
+ "version", "Notice", "FullName", "FamilyName",
+ "Weight", "FontBBox", "BlueValues", "OtherBlues",
+ "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW",
+ "UNKNOWN_12", "UniqueID", "XUID", "charset",
+ "Encoding", "CharStrings", "Private", "Subrs",
+ "defaultWidthX", "nominalWidthX", "UNKNOWN_22", "UNKNOWN_23",
+ "UNKNOWN_24", "UNKNOWN_25", "UNKNOWN_26", "UNKNOWN_27",
+ "UNKNOWN_28", "UNKNOWN_29", "UNKNOWN_30", "UNKNOWN_31",
+ "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition",
+ "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix",
+ "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz",
+ "StemSnapH", "StemSnapV", "ForceBold", "UNKNOWN_12_15",
+ "UNKNOWN_12_16", "LanguageGroup", "ExpansionFactor", "initialRandomSeed",
+ "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend",
+ "UNKNOWN_12_24", "UNKNOWN_12_25", "UNKNOWN_12_26", "UNKNOWN_12_27",
+ "UNKNOWN_12_28", "UNKNOWN_12_29", "ROS", "CIDFontVersion",
+ "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase",
+ "FDArray", "FDSelect", "FontName"
+ };
+
+ internal static String[] standardStrings = {
+ // Automatically generated from Appendix A of the CFF specification; do
+ // not edit. Size should be 391.
+ ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar",
+ "percent", "ampersand", "quoteright", "parenleft", "parenright",
+ "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one",
+ "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon",
+ "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C",
+ "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
+ "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash",
+ "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c",
+ "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
+ "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright",
+ "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen",
+ "florin", "section", "currency", "quotesingle", "quotedblleft",
+ "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash",
+ "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet",
+ "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
+ "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex",
+ "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla",
+ "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash",
+ "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe",
+ "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth",
+ "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar",
+ "degree", "thorn", "threequarters", "twosuperior", "registered", "minus",
+ "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex",
+ "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute",
+ "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
+ "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve",
+ "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave",
+ "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis",
+ "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex",
+ "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave",
+ "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde",
+ "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute",
+ "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall",
+ "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall",
+ "parenleftsuperior", "parenrightsuperior", "twodotenleader",
+ "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle",
+ "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle",
+ "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior",
+ "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
+ "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior",
+ "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior",
+ "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
+ "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
+ "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall",
+ "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall",
+ "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
+ "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary",
+ "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle",
+ "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall",
+ "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
+ "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
+ "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths",
+ "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior",
+ "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior",
+ "ninesuperior", "zeroinferior", "oneinferior", "twoinferior",
+ "threeinferior", "fourinferior", "fiveinferior", "sixinferior",
+ "seveninferior", "eightinferior", "nineinferior", "centinferior",
+ "dollarinferior", "periodinferior", "commainferior", "Agravesmall",
+ "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall",
+ "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall",
+ "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall",
+ "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall",
+ "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
+ "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall",
+ "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall",
+ "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black",
+ "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold"
+ };
+
+ //private String[] strings;
+ public String GetString(char sid) {
+ if (sid < standardStrings.Length) return standardStrings[sid];
+ if (sid >= standardStrings.Length+(stringOffsets.Length-1)) return null;
+ int j = sid - standardStrings.Length;
+ int p = GetPosition();
+ Seek(stringOffsets[j]);
+ StringBuilder s = new StringBuilder();
+ for (int k=stringOffsets[j]; kfalse
. CJK font and not embedded
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ internal CJKFont(string fontName, string enc, bool emb) {
+ LoadProperties();
+ this.FontType = FONT_TYPE_CJK;
+ string nameBase = GetBaseName(fontName);
+ if (!IsCJKFont(nameBase, enc))
+ throw new DocumentException("Font '" + fontName + "' with '" + enc + "' encoding is not a CJK font.");
+ if (nameBase.Length < fontName.Length) {
+ style = fontName.Substring(nameBase.Length);
+ fontName = nameBase;
+ }
+ this.fontName = fontName;
+ encoding = CJK_ENCODING;
+ vertical = enc.EndsWith("V");
+ CMap = enc;
+ if (enc.StartsWith("Identity-")) {
+ cidDirect = true;
+ string s = cjkFonts[fontName];
+ s = s.Substring(0, s.IndexOf('_'));
+ char[] c = (char[])allCMaps[s];
+ if (c == null) {
+ c = ReadCMap(s);
+ if (c == null)
+ throw new DocumentException("The cmap " + s + " does not exist as a resource.");
+ c[CID_NEWLINE] = '\n';
+ allCMaps.Add(s, c);
+ }
+ translationMap = c;
+ }
+ else {
+ char[] c = (char[])allCMaps[enc];
+ if (c == null) {
+ string s = cjkEncodings[enc];
+ if (s == null)
+ throw new DocumentException("The resource cjkencodings.properties does not contain the encoding " + enc);
+ StringTokenizer tk = new StringTokenizer(s);
+ string nt = tk.NextToken();
+ c = (char[])allCMaps[nt];
+ if (c == null) {
+ c = ReadCMap(nt);
+ allCMaps.Add(nt, c);
+ }
+ if (tk.HasMoreTokens()) {
+ string nt2 = tk.NextToken();
+ char[] m2 = ReadCMap(nt2);
+ for (int k = 0; k < 0x10000; ++k) {
+ if (m2[k] == 0)
+ m2[k] = c[k];
+ }
+ allCMaps.Add(enc, m2);
+ c = m2;
+ }
+ }
+ translationMap = c;
+ }
+ fontDesc = (Hashtable)allFonts[fontName];
+ if (fontDesc == null) {
+ fontDesc = ReadFontProperties(fontName);
+ allFonts.Add(fontName, fontDesc);
+ }
+ hMetrics = (IntHashtable)fontDesc["W"];
+ vMetrics = (IntHashtable)fontDesc["W2"];
+ }
+
+ /** Checks if its a valid CJK font.
+ * @param fontName the font name
+ * @param enc the encoding
+ * @return true
if it is CJK font
+ */
+ public static bool IsCJKFont(string fontName, string enc) {
+ LoadProperties();
+ string encodings = cjkFonts[fontName];
+ return (encodings != null && (enc.Equals("Identity-H") || enc.Equals("Identity-V") || encodings.IndexOf("_" + enc + "_") >= 0));
+ }
+
+ /**
+ * Gets the width of a char
in normalized 1000 units.
+ * @param char1 the unicode char
to get the width of
+ * @return the width in normalized 1000 units
+ */
+ public override int GetWidth(int char1) {
+ int c = (int)char1;
+ if (!cidDirect)
+ c = translationMap[c];
+ int v;
+ if (vertical)
+ v = vMetrics[c];
+ else
+ v = hMetrics[c];
+ if (v > 0)
+ return v;
+ else
+ return 1000;
+ }
+
+ public override int GetWidth(string text) {
+ int total = 0;
+ for (int k = 0; k < text.Length; ++k) {
+ int c = text[k];
+ if (!cidDirect)
+ c = translationMap[c];
+ int v;
+ if (vertical)
+ v = vMetrics[c];
+ else
+ v = hMetrics[c];
+ if (v > 0)
+ total += v;
+ else
+ total += 1000;
+ }
+ return total;
+ }
+
+ internal override int GetRawWidth(int c, string name) {
+ return 0;
+ }
+ public override int GetKerning(int char1, int char2) {
+ return 0;
+ }
+
+ private PdfDictionary GetFontDescriptor() {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR);
+ dic.Put(PdfName.ASCENT, new PdfLiteral((String)fontDesc["Ascent"]));
+ dic.Put(PdfName.CAPHEIGHT, new PdfLiteral((String)fontDesc["CapHeight"]));
+ dic.Put(PdfName.DESCENT, new PdfLiteral((String)fontDesc["Descent"]));
+ dic.Put(PdfName.FLAGS, new PdfLiteral((String)fontDesc["Flags"]));
+ dic.Put(PdfName.FONTBBOX, new PdfLiteral((String)fontDesc["FontBBox"]));
+ dic.Put(PdfName.FONTNAME, new PdfName(fontName + style));
+ dic.Put(PdfName.ITALICANGLE, new PdfLiteral((String)fontDesc["ItalicAngle"]));
+ dic.Put(PdfName.STEMV, new PdfLiteral((String)fontDesc["StemV"]));
+ PdfDictionary pdic = new PdfDictionary();
+ pdic.Put(PdfName.PANOSE, new PdfString((String)fontDesc["Panose"], null));
+ dic.Put(PdfName.STYLE, pdic);
+ return dic;
+ }
+
+ private PdfDictionary GetCIDFont(PdfIndirectReference fontDescriptor, IntHashtable cjkTag) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONT);
+ dic.Put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE0);
+ dic.Put(PdfName.BASEFONT, new PdfName(fontName + style));
+ dic.Put(PdfName.FONTDESCRIPTOR, fontDescriptor);
+ int[] keys = cjkTag.ToOrderedKeys();
+ string w = ConvertToHCIDMetrics(keys, hMetrics);
+ if (w != null)
+ dic.Put(PdfName.W, new PdfLiteral(w));
+ if (vertical) {
+ w = ConvertToVCIDMetrics(keys, vMetrics, hMetrics);
+ if (w != null)
+ dic.Put(PdfName.W2, new PdfLiteral(w));
+ }
+ else
+ dic.Put(PdfName.DW, new PdfNumber(1000));
+ PdfDictionary cdic = new PdfDictionary();
+ cdic.Put(PdfName.REGISTRY, new PdfString((string)fontDesc["Registry"], null));
+ cdic.Put(PdfName.ORDERING, new PdfString((string)fontDesc["Ordering"], null));
+ cdic.Put(PdfName.SUPPLEMENT, new PdfLiteral((string)fontDesc["Supplement"]));
+ dic.Put(PdfName.CIDSYSTEMINFO, cdic);
+ return dic;
+ }
+
+ private PdfDictionary GetFontBaseType(PdfIndirectReference CIDFont) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONT);
+ dic.Put(PdfName.SUBTYPE, PdfName.TYPE0);
+ string name = fontName;
+ if (style.Length > 0)
+ name += "-" + style.Substring(1);
+ name += "-" + CMap;
+ dic.Put(PdfName.BASEFONT, new PdfName(name));
+ dic.Put(PdfName.ENCODING, new PdfName(CMap));
+ dic.Put(PdfName.DESCENDANTFONTS, new PdfArray(CIDFont));
+ return dic;
+ }
+
+ internal override void WriteFont(PdfWriter writer, PdfIndirectReference piref, Object[] parms) {
+ IntHashtable cjkTag = (IntHashtable)parms[0];
+ PdfIndirectReference ind_font = null;
+ PdfObject pobj = null;
+ PdfIndirectObject obj = null;
+ pobj = GetFontDescriptor();
+ if (pobj != null){
+ obj = writer.AddToBody(pobj);
+ ind_font = obj.IndirectReference;
+ }
+ pobj = GetCIDFont(ind_font, cjkTag);
+ if (pobj != null){
+ obj = writer.AddToBody(pobj);
+ ind_font = obj.IndirectReference;
+ }
+ pobj = GetFontBaseType(ind_font);
+ writer.AddToBody(pobj, piref);
+ }
+
+ private float GetDescNumber(string name) {
+ return int.Parse((string)fontDesc[name]);
+ }
+
+ private float GetBBox(int idx) {
+ string s = (string)fontDesc["FontBBox"];
+ StringTokenizer tk = new StringTokenizer(s, " []\r\n\t\f");
+ string ret = tk.NextToken();
+ for (int k = 0; k < idx; ++k)
+ ret = tk.NextToken();
+ return int.Parse(ret);
+ }
+
+ /** Gets the font parameter identified by key
. Valid values
+ * for key
are ASCENT
, CAPHEIGHT
, DESCENT
+ * and ITALICANGLE
.
+ * @param key the parameter to be extracted
+ * @param fontSize the font size in points
+ * @return the parameter in points
+ */
+ public override float GetFontDescriptor(int key, float fontSize) {
+ switch (key) {
+ case AWT_ASCENT:
+ case ASCENT:
+ return GetDescNumber("Ascent") * fontSize / 1000;
+ case CAPHEIGHT:
+ return GetDescNumber("CapHeight") * fontSize / 1000;
+ case AWT_DESCENT:
+ case DESCENT:
+ return GetDescNumber("Descent") * fontSize / 1000;
+ case ITALICANGLE:
+ return GetDescNumber("ItalicAngle");
+ case BBOXLLX:
+ return fontSize * GetBBox(0) / 1000;
+ case BBOXLLY:
+ return fontSize * GetBBox(1) / 1000;
+ case BBOXURX:
+ return fontSize * GetBBox(2) / 1000;
+ case BBOXURY:
+ return fontSize * GetBBox(3) / 1000;
+ case AWT_LEADING:
+ return 0;
+ case AWT_MAXADVANCE:
+ return fontSize * (GetBBox(2) - GetBBox(0)) / 1000;
+ }
+ return 0;
+ }
+
+ public override string PostscriptFontName {
+ get {
+ return fontName;
+ }
+ set {
+ fontName = value;
+ }
+ }
+
+ /** Gets the full name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public override string[][] FullFontName {
+ get {
+ return new string[][]{new string[] {"", "", "", fontName}};
+ }
+ }
+
+ /** Gets all the entries of the names-table. If it is a True Type font
+ * each array element will have {Name ID, Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"4", "", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public override string[][] AllNameEntries {
+ get {
+ return new string[][]{new string[]{"4", "", "", "", fontName}};
+ }
+ }
+
+ /** Gets the family name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the family name of the font
+ */
+ public override string[][] FamilyFontName {
+ get {
+ return this.FullFontName;
+ }
+ }
+
+ internal static char[] ReadCMap(string name) {
+ Stream istr = null;
+ try {
+ name = name + ".cmap";
+ istr = GetResourceStream(RESOURCE_PATH + name);
+ char[] c = new char[0x10000];
+ for (int k = 0; k < 0x10000; ++k)
+ c[k] = (char)((istr.ReadByte() << 8) + istr.ReadByte());
+ return c;
+ }
+ catch {
+ // empty on purpose
+ }
+ finally {
+ try{istr.Close();}catch{}
+ }
+
+ return null;
+ }
+
+ internal static IntHashtable CreateMetric(string s) {
+ IntHashtable h = new IntHashtable();
+ StringTokenizer tk = new StringTokenizer(s);
+ while (tk.HasMoreTokens()) {
+ int n1 = int.Parse(tk.NextToken());
+ h[n1] = int.Parse(tk.NextToken());
+ }
+ return h;
+ }
+
+ internal static string ConvertToHCIDMetrics(int[] keys, IntHashtable h) {
+ if (keys.Length == 0)
+ return null;
+ int lastCid = 0;
+ int lastValue = 0;
+ int start;
+ for (start = 0; start < keys.Length; ++start) {
+ lastCid = keys[start];
+ lastValue = h[lastCid];
+ if (lastValue != 0) {
+ ++start;
+ break;
+ }
+ }
+ if (lastValue == 0)
+ return null;
+ StringBuilder buf = new StringBuilder();
+ buf.Append('[');
+ buf.Append(lastCid);
+ int state = FIRST;
+ for (int k = start; k < keys.Length; ++k) {
+ int cid = keys[k];
+ int value = h[cid];
+ if (value == 0)
+ continue;
+ switch (state) {
+ case FIRST: {
+ if (cid == lastCid + 1 && value == lastValue) {
+ state = SERIAL;
+ }
+ else if (cid == lastCid + 1) {
+ state = BRACKET;
+ buf.Append('[').Append(lastValue);
+ }
+ else {
+ buf.Append('[').Append(lastValue).Append(']').Append(cid);
+ }
+ break;
+ }
+ case BRACKET: {
+ if (cid == lastCid + 1 && value == lastValue) {
+ state = SERIAL;
+ buf.Append(']').Append(lastCid);
+ }
+ else if (cid == lastCid + 1) {
+ buf.Append(' ').Append(lastValue);
+ }
+ else {
+ state = FIRST;
+ buf.Append(' ').Append(lastValue).Append(']').Append(cid);
+ }
+ break;
+ }
+ case SERIAL: {
+ if (cid != lastCid + 1 || value != lastValue) {
+ buf.Append(' ').Append(lastCid).Append(' ').Append(lastValue).Append(' ').Append(cid);
+ state = FIRST;
+ }
+ break;
+ }
+ }
+ lastValue = value;
+ lastCid = cid;
+ }
+ switch (state) {
+ case FIRST: {
+ buf.Append('[').Append(lastValue).Append("]]");
+ break;
+ }
+ case BRACKET: {
+ buf.Append(' ').Append(lastValue).Append("]]");
+ break;
+ }
+ case SERIAL: {
+ buf.Append(' ').Append(lastCid).Append(' ').Append(lastValue).Append(']');
+ break;
+ }
+ }
+ return buf.ToString();
+ }
+
+ internal static string ConvertToVCIDMetrics(int[] keys, IntHashtable v, IntHashtable h) {
+ if (keys.Length == 0)
+ return null;
+ int lastCid = 0;
+ int lastValue = 0;
+ int lastHValue = 0;
+ int start;
+ for (start = 0; start < keys.Length; ++start) {
+ lastCid = keys[start];
+ lastValue = v[lastCid];
+ if (lastValue != 0) {
+ ++start;
+ break;
+ }
+ else
+ lastHValue = h[lastCid];
+ }
+ if (lastValue == 0)
+ return null;
+ if (lastHValue == 0)
+ lastHValue = 1000;
+ StringBuilder buf = new StringBuilder();
+ buf.Append('[');
+ buf.Append(lastCid);
+ int state = FIRST;
+ for (int k = start; k < keys.Length; ++k) {
+ int cid = keys[k];
+ int value = v[cid];
+ if (value == 0)
+ continue;
+ int hValue = h[lastCid];
+ if (hValue == 0)
+ hValue = 1000;
+ switch (state) {
+ case FIRST: {
+ if (cid == lastCid + 1 && value == lastValue && hValue == lastHValue) {
+ state = SERIAL;
+ }
+ else {
+ buf.Append(' ').Append(lastCid).Append(' ').Append(-lastValue).Append(' ').Append(lastHValue / 2).Append(' ').Append(V1Y).Append(' ').Append(cid);
+ }
+ break;
+ }
+ case SERIAL: {
+ if (cid != lastCid + 1 || value != lastValue || hValue != lastHValue) {
+ buf.Append(' ').Append(lastCid).Append(' ').Append(-lastValue).Append(' ').Append(lastHValue / 2).Append(' ').Append(V1Y).Append(' ').Append(cid);
+ state = FIRST;
+ }
+ break;
+ }
+ }
+ lastValue = value;
+ lastCid = cid;
+ lastHValue = hValue;
+ }
+ buf.Append(' ').Append(lastCid).Append(' ').Append(-lastValue).Append(' ').Append(lastHValue / 2).Append(' ').Append(V1Y).Append(" ]");
+ return buf.ToString();
+ }
+
+ internal static Hashtable ReadFontProperties(String name) {
+ try {
+ name += ".properties";
+ Stream isp = GetResourceStream(RESOURCE_PATH + name);
+ Properties p = new Properties();
+ p.Load(isp);
+ isp.Close();
+ IntHashtable W = CreateMetric(p["W"]);
+ p.Remove("W");
+ IntHashtable W2 = CreateMetric(p["W2"]);
+ p.Remove("W2");
+ Hashtable map = new Hashtable();
+ foreach (string key in p.Keys) {
+ map[key] = p[key];
+ }
+ map["W"] = W;
+ map["W2"] = W2;
+ return map;
+ }
+ catch {
+ // empty on purpose
+ }
+ return null;
+ }
+
+ public override int GetUnicodeEquivalent(int c) {
+ if (cidDirect)
+ return translationMap[c];
+ return c;
+ }
+
+ public override int GetCidCode(int c) {
+ if (cidDirect)
+ return c;
+ return translationMap[c];
+ }
+
+ public override bool HasKernPairs() {
+ return false;
+ }
+
+ public override bool CharExists(int c) {
+ return translationMap[c] != 0;
+ }
+
+ public override bool SetCharAdvance(int c, int advance) {
+ return false;
+ }
+
+ public override bool SetKerning(int char1, int char2, int kern) {
+ return false;
+ }
+
+ public override int[] GetCharBBox(int c) {
+ return null;
+ }
+
+ protected override int[] GetRawCharBBox(int c, String name) {
+ return null;
+ }
+}
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/CMYKColor.cs b/iTechSharp/iTextSharp/text/pdf/CMYKColor.cs
new file mode 100644
index 0000000..ba718d2
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/CMYKColor.cs
@@ -0,0 +1,112 @@
+using System;
+
+/*
+ * $Id: CMYKColor.cs,v 1.4 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class CMYKColor : ExtendedColor {
+
+ float ccyan;
+ float cmagenta;
+ float cyellow;
+ float cblack;
+
+ public CMYKColor(int intCyan, int intMagenta, int intYellow, int intBlack) :
+ this((float)intCyan / 255f, (float)intMagenta / 255f, (float)intYellow / 255f, (float)intBlack / 255f) {}
+
+ public CMYKColor(float floatCyan, float floatMagenta, float floatYellow, float floatBlack) :
+ base(TYPE_CMYK, 1f - floatCyan - floatBlack, 1f - floatMagenta - floatBlack, 1f - floatYellow - floatBlack) {
+ ccyan = Normalize(floatCyan);
+ cmagenta = Normalize(floatMagenta);
+ cyellow = Normalize(floatYellow);
+ cblack = Normalize(floatBlack);
+ }
+
+ public float Cyan {
+ get {
+ return ccyan;
+ }
+ }
+
+ public float Magenta {
+ get {
+ return cmagenta;
+ }
+ }
+
+ public float Yellow {
+ get {
+ return cyellow;
+ }
+ }
+
+ public float Black {
+ get {
+ return cblack;
+ }
+ }
+
+ public override bool Equals(Object obj) {
+ if (!(obj is CMYKColor))
+ return false;
+ CMYKColor c2 = (CMYKColor)obj;
+ return (ccyan == c2.ccyan && cmagenta == c2.cmagenta && cyellow == c2.cyellow && cblack == c2.cblack);
+ }
+
+ public override int GetHashCode() {
+ return ccyan.GetHashCode() ^ cmagenta.GetHashCode() ^ cyellow.GetHashCode() ^ cblack.GetHashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/CodeFile1.cs b/iTechSharp/iTextSharp/text/pdf/CodeFile1.cs
new file mode 100644
index 0000000..e69de29
diff --git a/iTechSharp/iTextSharp/text/pdf/ColorDetails.cs b/iTechSharp/iTextSharp/text/pdf/ColorDetails.cs
new file mode 100644
index 0000000..86d0636
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/ColorDetails.cs
@@ -0,0 +1,107 @@
+using System;
+
+/*
+ * $Id: ColorDetails.cs,v 1.3 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Each spotcolor in the document will have an instance of this class
+ *
+ * @author Phillip Pan (phillip@formstar.com)
+ */
+ public class ColorDetails {
+
+ /** The indirect reference to this color
+ */
+ PdfIndirectReference indirectReference;
+ /** The color name that appears in the document body stream
+ */
+ PdfName colorName;
+ /** The color
+ */
+ PdfSpotColor spotcolor;
+
+ /** Each spot color used in a document has an instance of this class.
+ * @param colorName the color name
+ * @param indirectReference the indirect reference to the font
+ * @param scolor the PDfSpotColor
+ */
+ internal ColorDetails(PdfName colorName, PdfIndirectReference indirectReference, PdfSpotColor scolor) {
+ this.colorName = colorName;
+ this.indirectReference = indirectReference;
+ this.spotcolor = scolor;
+ }
+
+ /** Gets the indirect reference to this color.
+ * @return the indirect reference to this color
+ */
+ internal PdfIndirectReference IndirectReference {
+ get {
+ return indirectReference;
+ }
+ }
+
+ /** Gets the color name as it appears in the document body.
+ * @return the color name
+ */
+ internal PdfName ColorName {
+ get {
+ return colorName;
+ }
+ }
+
+ /** Gets the SpotColor
object.
+ * @return the PdfSpotColor
+ */
+ internal PdfObject GetSpotColor(PdfWriter writer) {
+ return spotcolor.GetSpotObject(writer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/ColumnText.cs b/iTechSharp/iTextSharp/text/pdf/ColumnText.cs
new file mode 100644
index 0000000..6e72376
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/ColumnText.cs
@@ -0,0 +1,1534 @@
+using System;
+using System.Collections;
+using System.util.collections;
+using iTextSharp.text.pdf.draw;
+
+/*
+ * Copyright 2001-2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+/**
+ * Formats text in a columnwise form. The text is bound
+ * on the left and on the right by a sequence of lines. This allows the column
+ * to have any shape, not only rectangular.
+ * go
will return one of the following
+ * situations: the column ended or the text ended.
+ * setColumns
and the method go
can be called again.
+ * addText
+ * and the method go
can be called again.
+ * The only limitation is that one or more complete paragraphs must be loaded
+ * each time.
+ * PdfWriter.RUN_DIRECTION_RTL
the meaning of the horizontal
+ * alignments and margins is mirrored.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+
+public class ColumnText {
+ /** Eliminate the arabic vowels */
+ public int AR_NOVOWEL = ArabicLigaturizer.ar_novowel;
+ /** Compose the tashkeel in the ligatures. */
+ public const int AR_COMPOSEDTASHKEEL = ArabicLigaturizer.ar_composedtashkeel;
+ /** Do some extra double ligatures. */
+ public const int AR_LIG = ArabicLigaturizer.ar_lig;
+ /**
+ * Digit shaping option: Replace European digits (U+0030...U+0039) by Arabic-Indic digits.
+ */
+ public const int DIGITS_EN2AN = ArabicLigaturizer.DIGITS_EN2AN;
+
+ /**
+ * Digit shaping option: Replace Arabic-Indic digits by European digits (U+0030...U+0039).
+ */
+ public const int DIGITS_AN2EN = ArabicLigaturizer.DIGITS_AN2EN;
+
+ /**
+ * Digit shaping option:
+ * Replace European digits (U+0030...U+0039) by Arabic-Indic digits
+ * if the most recent strongly directional character
+ * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC).
+ * The initial state at the start of the text is assumed to be not an Arabic,
+ * letter, so European digits at the start of the text will not change.
+ * Compare to DIGITS_ALEN2AN_INIT_AL.
+ */
+ public const int DIGITS_EN2AN_INIT_LR = ArabicLigaturizer.DIGITS_EN2AN_INIT_LR;
+
+ /**
+ * Digit shaping option:
+ * Replace European digits (U+0030...U+0039) by Arabic-Indic digits
+ * if the most recent strongly directional character
+ * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC).
+ * The initial state at the start of the text is assumed to be an Arabic,
+ * letter, so European digits at the start of the text will change.
+ * Compare to DIGITS_ALEN2AN_INT_LR.
+ */
+ public const int DIGITS_EN2AN_INIT_AL = ArabicLigaturizer.DIGITS_EN2AN_INIT_AL;
+
+ /**
+ * Digit type option: Use Arabic-Indic digits (U+0660...U+0669).
+ */
+ public const int DIGIT_TYPE_AN = ArabicLigaturizer.DIGIT_TYPE_AN;
+
+ /**
+ * Digit type option: Use Eastern (Extended) Arabic-Indic digits (U+06f0...U+06f9).
+ */
+ public const int DIGIT_TYPE_AN_EXTENDED = ArabicLigaturizer.DIGIT_TYPE_AN_EXTENDED;
+
+ protected int runDirection = PdfWriter.RUN_DIRECTION_DEFAULT;
+ public static float GLOBAL_SPACE_CHAR_RATIO = 0;
+
+ /** Signals that there is no more text available. */
+ public const int NO_MORE_TEXT = 1;
+
+ /** Signals that there is no more column. */
+ public const int NO_MORE_COLUMN = 2;
+
+ /** The column is valid. */
+ protected const int LINE_STATUS_OK = 0;
+
+ /** The line is out the column limits. */
+ protected const int LINE_STATUS_OFFLIMITS = 1;
+
+ /** The line cannot fit this column position. */
+ protected const int LINE_STATUS_NOLINE = 2;
+
+ /** Upper bound of the column. */
+ protected float maxY;
+
+ /** Lower bound of the column. */
+ protected float minY;
+
+ protected float leftX;
+
+ protected float rightX;
+
+ /** The column Element. Default is left Element. */
+ protected int alignment = Element.ALIGN_LEFT;
+
+ /** The left column bound. */
+ protected ArrayList leftWall;
+
+ /** The right column bound. */
+ protected ArrayList rightWall;
+
+ /** The chunks that form the text. */
+// protected ArrayList chunks = new ArrayList();
+ protected BidiLine bidiLine;
+
+ /** The current y line location. Text will be written at this line minus the leading. */
+ protected float yLine;
+
+ /** The leading for the current line. */
+ protected float currentLeading = 16;
+
+ /** The fixed text leading. */
+ protected float fixedLeading = 16;
+
+ /** The text leading that is multiplied by the biggest font size in the line. */
+ protected float multipliedLeading = 0;
+
+ /** The PdfContent
where the text will be written to. */
+ protected PdfContentByte canvas;
+
+ protected PdfContentByte[] canvases;
+
+ /** The line status when trying to fit a line to a column. */
+ protected int lineStatus;
+
+ /** The first paragraph line indent. */
+ protected float indent = 0;
+
+ /** The following paragraph lines indent. */
+ protected float followingIndent = 0;
+
+ /** The right paragraph lines indent. */
+ protected float rightIndent = 0;
+
+ /** The extra space between paragraphs. */
+ protected float extraParagraphSpace = 0;
+
+ /** The width of the line when the column is defined as a simple rectangle. */
+ protected float rectangularWidth = -1;
+
+ protected bool rectangularMode = false;
+
+ /** Holds value of property spaceCharRatio. */
+ private float spaceCharRatio = GLOBAL_SPACE_CHAR_RATIO;
+
+ private bool lastWasNewline = true;
+
+ /** Holds value of property linesWritten. */
+ private int linesWritten;
+
+ private float firstLineY;
+
+ private bool firstLineYDone = false;
+
+ /** Holds value of property arabicOptions. */
+ private int arabicOptions = 0;
+
+ protected float descender;
+
+ protected bool composite = false;
+
+ protected ColumnText compositeColumn;
+
+ protected internal ArrayList compositeElements;
+
+ protected int listIdx = 0;
+
+ private bool splittedRow;
+
+ protected Phrase waitPhrase;
+
+ /** if true, first line height is adjusted so that the max ascender touches the top */
+ private bool useAscender = false;
+
+ /**
+ * Creates a ColumnText
.
+ * @param text the place where the text will be written to. Can
+ * be a template.
+ */
+ public ColumnText(PdfContentByte canvas) {
+ this.canvas = canvas;
+ }
+
+ /** Creates an independent duplicated of the instance org
.
+ * @param org the original ColumnText
+ * @return the duplicated
+ */
+ public static ColumnText Duplicate(ColumnText org) {
+ ColumnText ct = new ColumnText(null);
+ ct.SetACopy(org);
+ return ct;
+ }
+
+ /** Makes this instance an independent copy of org
.
+ * @param org the original ColumnText
+ * @return itself
+ */
+ public ColumnText SetACopy(ColumnText org) {
+ SetSimpleVars(org);
+ if (org.bidiLine != null)
+ bidiLine = new BidiLine(org.bidiLine);
+ return this;
+ }
+
+ protected internal void SetSimpleVars(ColumnText org) {
+ maxY = org.maxY;
+ minY = org.minY;
+ alignment = org.alignment;
+ leftWall = null;
+ if (org.leftWall != null)
+ leftWall = new ArrayList(org.leftWall);
+ rightWall = null;
+ if (org.rightWall != null)
+ rightWall = new ArrayList(org.rightWall);
+ yLine = org.yLine;
+ currentLeading = org.currentLeading;
+ fixedLeading = org.fixedLeading;
+ multipliedLeading = org.multipliedLeading;
+ canvas = org.canvas;
+ canvases = org.canvases;
+ lineStatus = org.lineStatus;
+ indent = org.indent;
+ followingIndent = org.followingIndent;
+ rightIndent = org.rightIndent;
+ extraParagraphSpace = org.extraParagraphSpace;
+ rectangularWidth = org.rectangularWidth;
+ rectangularMode = org.rectangularMode;
+ spaceCharRatio = org.spaceCharRatio;
+ lastWasNewline = org.lastWasNewline;
+ linesWritten = org.linesWritten;
+ arabicOptions = org.arabicOptions;
+ runDirection = org.runDirection;
+ descender = org.descender;
+ composite = org.composite;
+ splittedRow = org.splittedRow;
+ if (org.composite) {
+ compositeElements = new ArrayList(org.compositeElements);
+ if (splittedRow) {
+ PdfPTable table = (PdfPTable)compositeElements[0];
+ compositeElements[0] = new PdfPTable(table);
+ }
+ if (org.compositeColumn != null)
+ compositeColumn = Duplicate(org.compositeColumn);
+ }
+ listIdx = org.listIdx;
+ firstLineY = org.firstLineY;
+ leftX = org.leftX;
+ rightX = org.rightX;
+ firstLineYDone = org.firstLineYDone;
+ waitPhrase = org.waitPhrase;
+ useAscender = org.useAscender;
+ filledWidth = org.filledWidth;
+ adjustFirstLine = org.adjustFirstLine;
+ }
+
+ private void AddWaitingPhrase() {
+ if (bidiLine == null && waitPhrase != null) {
+ bidiLine = new BidiLine();
+ foreach (Chunk ck in waitPhrase.Chunks) {
+ bidiLine.AddChunk(new PdfChunk(ck, null));
+ }
+ waitPhrase = null;
+ }
+ }
+
+ /**
+ * Adds a Phrase
to the current text array.
+ * @param phrase the text
+ */
+ public void AddText(Phrase phrase) {
+ if (phrase == null || composite)
+ return;
+ AddWaitingPhrase();
+ if (bidiLine == null) {
+ waitPhrase = phrase;
+ return;
+ }
+ foreach (Chunk c in phrase.Chunks) {
+ bidiLine.AddChunk(new PdfChunk(c, null));
+ }
+ }
+
+ /**
+ * Replaces the current text array with this Phrase
.
+ * Anything added previously with AddElement() is lost.
+ * @param phrase the text
+ */
+ public void SetText(Phrase phrase) {
+ bidiLine = null;
+ composite = false;
+ compositeColumn = null;
+ compositeElements = null;
+ listIdx = 0;
+ splittedRow = false;
+ waitPhrase = phrase;
+ }
+
+ /**
+ * Adds a Chunk
to the current text array.
+ * Will not have any effect if AddElement() was called before.
+ * @param chunk the text
+ */
+ public void AddText(Chunk chunk) {
+ if (chunk == null || composite)
+ return;
+ AddText(new Phrase(chunk));
+ }
+
+ /**
+ * Adds an element. Elements supported are Paragraph
,
+ * List
, PdfPTable
, Image
and
+ * Graphic
.
+ * addText()
.
+ * @param element the Element
+ */
+ public void AddElement(IElement element) {
+ if (element == null)
+ return;
+ if (element is Image) {
+ Image img = (Image)element;
+ PdfPTable t = new PdfPTable(1);
+ float w = img.WidthPercentage;
+ if (w == 0) {
+ t.TotalWidth = img.ScaledWidth;
+ t.LockedWidth = true;
+ }
+ else
+ t.WidthPercentage = w;
+ t.SpacingAfter = img.SpacingAfter;
+ t.SpacingBefore = img.SpacingBefore;
+ switch (img.Alignment) {
+ case Image.LEFT_ALIGN:
+ t.HorizontalAlignment = Element.ALIGN_LEFT;
+ break;
+ case Image.RIGHT_ALIGN:
+ t.HorizontalAlignment = Element.ALIGN_RIGHT;
+ break;
+ default:
+ t.HorizontalAlignment = Element.ALIGN_CENTER;
+ break;
+ }
+ PdfPCell c = new PdfPCell(img, true);
+ c.Padding = 0;
+ c.Border = img.Border;
+ c.BorderColor = img.BorderColor;
+ c.BorderWidth = img.BorderWidth;
+ c.BackgroundColor = img.BackgroundColor;
+ t.AddCell(c);
+ element = t;
+ }
+ if (element.Type == Element.CHUNK) {
+ element = new Paragraph((Chunk)element);
+ }
+ else if (element.Type == Element.PHRASE) {
+ element = new Paragraph((Phrase)element);
+ }
+ if (element is SimpleTable) {
+ try {
+ element = ((SimpleTable)element).CreatePdfPTable();
+ } catch (DocumentException) {
+ throw new ArgumentException("Element not allowed.");
+ }
+ }
+ else if (element.Type != Element.PARAGRAPH && element.Type != Element.LIST && element.Type != Element.PTABLE && element.Type != Element.YMARK)
+ throw new ArgumentException("Element not allowed.");
+ if (!composite) {
+ composite = true;
+ compositeElements = new ArrayList();
+ bidiLine = null;
+ waitPhrase = null;
+ }
+ compositeElements.Add(element);
+ }
+
+ /**
+ * Converts a sequence of lines representing one of the column bounds into
+ * an internal format.
+ * float[4]
representing
+ * the line x = ax + b.
+ * @param cLine the column array
+ * @return the converted array
+ */
+ protected ArrayList ConvertColumn(float[] cLine) {
+ if (cLine.Length < 4)
+ throw new Exception("No valid column line found.");
+ ArrayList cc = new ArrayList();
+ for (int k = 0; k < cLine.Length - 2; k += 2) {
+ float x1 = cLine[k];
+ float y1 = cLine[k + 1];
+ float x2 = cLine[k + 2];
+ float y2 = cLine[k + 3];
+ if (y1 == y2)
+ continue;
+ // x = ay + b
+ float a = (x1 - x2) / (y1 - y2);
+ float b = x1 - a * y1;
+ float[] r = new float[4];
+ r[0] = Math.Min(y1, y2);
+ r[1] = Math.Max(y1, y2);
+ r[2] = a;
+ r[3] = b;
+ cc.Add(r);
+ maxY = Math.Max(maxY, r[1]);
+ minY = Math.Min(minY, r[0]);
+ }
+ if (cc.Count == 0)
+ throw new Exception("No valid column line found.");
+ return cc;
+ }
+
+ /**
+ * Finds the intersection between the yLine
and the column. It will
+ * set the lineStatus
apropriatly.
+ * @param wall the column to intersect
+ * @return the x coordinate of the intersection
+ */
+ protected float FindLimitsPoint(ArrayList wall) {
+ lineStatus = LINE_STATUS_OK;
+ if (yLine < minY || yLine > maxY) {
+ lineStatus = LINE_STATUS_OFFLIMITS;
+ return 0;
+ }
+ for (int k = 0; k < wall.Count; ++k) {
+ float[] r = (float[])wall[k];
+ if (yLine < r[0] || yLine > r[1])
+ continue;
+ return r[2] * yLine + r[3];
+ }
+ lineStatus = LINE_STATUS_NOLINE;
+ return 0;
+ }
+
+ /**
+ * Finds the intersection between the yLine
and the two
+ * column bounds. It will set the lineStatus
apropriatly.
+ * @return a float[2]
with the x coordinates of the intersection
+ */
+ protected float[] FindLimitsOneLine() {
+ float x1 = FindLimitsPoint(leftWall);
+ if (lineStatus == LINE_STATUS_OFFLIMITS || lineStatus == LINE_STATUS_NOLINE)
+ return null;
+ float x2 = FindLimitsPoint(rightWall);
+ if (lineStatus == LINE_STATUS_NOLINE)
+ return null;
+ return new float[]{x1, x2};
+ }
+
+ /**
+ * Finds the intersection between the yLine
,
+ * the yLine-leading
and the two
+ * column bounds. It will set the lineStatus
apropriatly.
+ * @return a float[4]
with the x coordinates of the intersection
+ */
+ protected float[] FindLimitsTwoLines() {
+ bool repeat = false;
+ for (;;) {
+ if (repeat && currentLeading == 0)
+ return null;
+ repeat = true;
+ float[] x1 = FindLimitsOneLine();
+ if (lineStatus == LINE_STATUS_OFFLIMITS)
+ return null;
+ yLine -= currentLeading;
+ if (lineStatus == LINE_STATUS_NOLINE) {
+ continue;
+ }
+ float[] x2 = FindLimitsOneLine();
+ if (lineStatus == LINE_STATUS_OFFLIMITS)
+ return null;
+ if (lineStatus == LINE_STATUS_NOLINE) {
+ yLine -= currentLeading;
+ continue;
+ }
+ if (x1[0] >= x2[1] || x2[0] >= x1[1])
+ continue;
+ return new float[]{x1[0], x1[1], x2[0], x2[1]};
+ }
+ }
+
+ /**
+ * Sets the columns bounds. Each column bound is described by a
+ * float[]
with the line points [x1,y1,x2,y2,...].
+ * The array must have at least 4 elements.
+ * @param leftLine the left column bound
+ * @param rightLine the right column bound
+ */
+ public void SetColumns(float[] leftLine, float[] rightLine) {
+ maxY = -10e20f;
+ minY = 10e20f;
+ rightWall = ConvertColumn(rightLine);
+ leftWall = ConvertColumn(leftLine);
+ rectangularWidth = -1;
+ rectangularMode = false;
+ }
+
+ /**
+ * Simplified method for rectangular columns.
+ * @param phrase a Phrase
+ * @param llx the lower left x corner
+ * @param lly the lower left y corner
+ * @param urx the upper right x corner
+ * @param ury the upper right y corner
+ * @param leading the leading
+ * @param alignment the column alignment
+ */
+ public void SetSimpleColumn(Phrase phrase, float llx, float lly, float urx, float ury, float leading, int alignment) {
+ AddText(phrase);
+ SetSimpleColumn(llx, lly, urx, ury, leading, alignment);
+ }
+
+ /**
+ * Simplified method for rectangular columns.
+ * @param llx the lower left x corner
+ * @param lly the lower left y corner
+ * @param urx the upper right x corner
+ * @param ury the upper right y corner
+ * @param leading the leading
+ * @param alignment the column alignment
+ */
+ public void SetSimpleColumn(float llx, float lly, float urx, float ury, float leading, int alignment) {
+ Leading = leading;
+ this.alignment = alignment;
+ SetSimpleColumn(llx, lly, urx, ury);
+ }
+
+ /**
+ * Simplified method for rectangular columns.
+ * @param llx
+ * @param lly
+ * @param urx
+ * @param ury
+ */
+ public void SetSimpleColumn(float llx, float lly, float urx, float ury) {
+ leftX = Math.Min(llx, urx);
+ maxY = Math.Max(lly, ury);
+ minY = Math.Min(lly, ury);
+ rightX = Math.Max(llx, urx);
+ yLine = maxY;
+ rectangularWidth = rightX - leftX;
+ if (rectangularWidth < 0)
+ rectangularWidth = 0;
+ rectangularMode = true;
+ }
+
+ /**
+ * Sets the leading fixed and variable. The resultant leading will be
+ * fixedLeading+multipliedLeading*maxFontSize where maxFontSize is the
+ * size of the bigest font in the line.
+ * @param fixedLeading the fixed leading
+ * @param multipliedLeading the variable leading
+ */
+ public void SetLeading(float fixedLeading, float multipliedLeading) {
+ this.fixedLeading = fixedLeading;
+ this.multipliedLeading = multipliedLeading;
+ }
+
+ /**
+ * Gets the fixed leading
+ * @return the leading
+ */
+ public float Leading {
+ get {
+ return fixedLeading;
+ }
+
+ set {
+ this.fixedLeading = value;
+ this.multipliedLeading = 0;
+ }
+ }
+
+ /**
+ * Gets the variable leading
+ * @return the leading
+ */
+ public float MultipliedLeading {
+ get {
+ return multipliedLeading;
+ }
+ }
+
+ /**
+ * Gets the yLine.
+ * @return the yLine
+ */
+ public float YLine {
+ get {
+ return yLine;
+ }
+
+ set {
+ this.yLine = value;
+ }
+ }
+
+ /**
+ * Gets the Element.
+ * @return the alignment
+ */
+ public int Alignment{
+ get {
+ return alignment;
+ }
+
+ set {
+ this.alignment = value;
+ }
+ }
+
+ /**
+ * Gets the first paragraph line indent.
+ * @return the indent
+ */
+ public float Indent {
+ get {
+ return indent;
+ }
+
+ set {
+ this.indent = value;
+ lastWasNewline = true;
+ }
+ }
+
+ /**
+ * Gets the following paragraph lines indent.
+ * @return the indent
+ */
+ public float FollowingIndent {
+ get {
+ return followingIndent;
+ }
+
+ set {
+ this.followingIndent = value;
+ lastWasNewline = true;
+ }
+ }
+
+ /**
+ * Gets the right paragraph lines indent.
+ * @return the indent
+ */
+ public float RightIndent {
+ get {
+ return rightIndent;
+ }
+
+ set {
+ this.rightIndent = value;
+ lastWasNewline = true;
+ }
+ }
+
+ /**
+ * Outputs the lines to the document. It is equivalent to go(false)
.
+ * @return returns the result of the operation. It can be NO_MORE_TEXT
+ * and/or NO_MORE_COLUMN
+ * @throws DocumentException on error
+ */
+ public int Go() {
+ return Go(false);
+ }
+
+ /**
+ * Outputs the lines to the document. The output can be simulated.
+ * @param simulate true
to simulate the writting to the document
+ * @return returns the result of the operation. It can be NO_MORE_TEXT
+ * and/or NO_MORE_COLUMN
+ * @throws DocumentException on error
+ */
+ public int Go(bool simulate) {
+ if (composite)
+ return GoComposite(simulate);
+ AddWaitingPhrase();
+ if (bidiLine == null)
+ return NO_MORE_TEXT;
+ descender = 0;
+ linesWritten = 0;
+ bool dirty = false;
+ float ratio = spaceCharRatio;
+ Object[] currentValues = new Object[2];
+ PdfFont currentFont = null;
+ float lastBaseFactor = 0F;
+ currentValues[1] = lastBaseFactor;
+ PdfDocument pdf = null;
+ PdfContentByte graphics = null;
+ PdfContentByte text = null;
+ firstLineY = float.NaN;
+ int localRunDirection = PdfWriter.RUN_DIRECTION_NO_BIDI;
+ if (runDirection != PdfWriter.RUN_DIRECTION_DEFAULT)
+ localRunDirection = runDirection;
+ if (canvas != null) {
+ graphics = canvas;
+ pdf = canvas.PdfDocument;
+ text = canvas.Duplicate;
+ }
+ else if (!simulate)
+ throw new Exception("ColumnText.go with simulate==false and text==null.");
+ if (!simulate) {
+ if (ratio == GLOBAL_SPACE_CHAR_RATIO)
+ ratio = text.PdfWriter.SpaceCharRatio;
+ else if (ratio < 0.001f)
+ ratio = 0.001f;
+ }
+ float firstIndent = 0;
+
+ int status = 0;
+ if (rectangularMode) {
+ for (;;) {
+ firstIndent = (lastWasNewline ? indent : followingIndent);
+ if (rectangularWidth <= firstIndent + rightIndent) {
+ status = NO_MORE_COLUMN;
+ if (bidiLine.IsEmpty())
+ status |= NO_MORE_TEXT;
+ break;
+ }
+ if (bidiLine.IsEmpty()) {
+ status = NO_MORE_TEXT;
+ break;
+ }
+ PdfLine line = bidiLine.ProcessLine(leftX, rectangularWidth - firstIndent - rightIndent, alignment, localRunDirection, arabicOptions);
+ if (line == null) {
+ status = NO_MORE_TEXT;
+ break;
+ }
+ float maxSize = line.MaxSizeSimple;
+ if (UseAscender && float.IsNaN(firstLineY)) {
+ currentLeading = line.Ascender;
+ }
+ else {
+ currentLeading = fixedLeading + maxSize * multipliedLeading;
+ }
+ if (yLine > maxY || yLine - currentLeading < minY ) {
+ status = NO_MORE_COLUMN;
+ bidiLine.Restore();
+ break;
+ }
+ yLine -= currentLeading;
+ if (!simulate && !dirty) {
+ text.BeginText();
+ dirty = true;
+ }
+ if (float.IsNaN(firstLineY)) {
+ firstLineY = yLine;
+ }
+ UpdateFilledWidth(rectangularWidth - line.WidthLeft);
+ if (!simulate) {
+ currentValues[0] = currentFont;
+ text.SetTextMatrix(leftX + (line.RTL ? rightIndent : firstIndent) + line.IndentLeft, yLine);
+ pdf.WriteLineToContent(line, text, graphics, currentValues, ratio);
+ currentFont = (PdfFont)currentValues[0];
+ }
+ lastWasNewline = line.NewlineSplit;
+ yLine -= line.NewlineSplit ? extraParagraphSpace : 0;
+ ++linesWritten;
+ descender = line.Descender;
+ }
+ }
+ else {
+ currentLeading = fixedLeading;
+ for (;;) {
+ firstIndent = (lastWasNewline ? indent : followingIndent);
+ float yTemp = yLine;
+ float[] xx = FindLimitsTwoLines();
+ if (xx == null) {
+ status = NO_MORE_COLUMN;
+ if (bidiLine.IsEmpty())
+ status |= NO_MORE_TEXT;
+ yLine = yTemp;
+ break;
+ }
+ if (bidiLine.IsEmpty()) {
+ status = NO_MORE_TEXT;
+ yLine = yTemp;
+ break;
+ }
+ float x1 = Math.Max(xx[0], xx[2]);
+ float x2 = Math.Min(xx[1], xx[3]);
+ if (x2 - x1 <= firstIndent + rightIndent)
+ continue;
+ if (!simulate && !dirty) {
+ text.BeginText();
+ dirty = true;
+ }
+ PdfLine line = bidiLine.ProcessLine(x1, x2 - x1 - firstIndent - rightIndent, alignment, localRunDirection, arabicOptions);
+ if (line == null) {
+ status = NO_MORE_TEXT;
+ yLine = yTemp;
+ break;
+ }
+ if (!simulate) {
+ currentValues[0] = currentFont;
+ text.SetTextMatrix(x1 + (line.RTL ? rightIndent : firstIndent) + line.IndentLeft, yLine);
+ pdf.WriteLineToContent(line, text, graphics, currentValues, ratio);
+ currentFont = (PdfFont)currentValues[0];
+ }
+ lastWasNewline = line.NewlineSplit;
+ yLine -= line.NewlineSplit ? extraParagraphSpace : 0;
+ ++linesWritten;
+ descender = line.Descender;
+ }
+ }
+ if (dirty) {
+ text.EndText();
+ canvas.Add(text);
+ }
+ return status;
+ }
+
+ /**
+ * Sets the extra space between paragraphs.
+ * @return the extra space between paragraphs
+ */
+ public float ExtraParagraphSpace {
+ get {
+ return extraParagraphSpace;
+ }
+
+ set {
+ this.extraParagraphSpace = value;
+ }
+ }
+
+ /**
+ * Clears the chunk array. A call to go()
will always return
+ * NO_MORE_TEXT.
+ */
+ public void ClearChunks() {
+ if (bidiLine != null)
+ bidiLine.ClearChunks();
+ }
+
+ /** Gets the space/character extra spacing ratio for
+ * fully justified text.
+ * @return the space/character extra spacing ratio
+ */
+ public float SpaceCharRatio {
+ get {
+ return spaceCharRatio;
+ }
+
+ set {
+ this.spaceCharRatio = value;
+ }
+ }
+
+ /** Gets the run direction.
+ * @return the run direction
+ */
+ public int RunDirection {
+ get {
+ return runDirection;
+ }
+
+ set {
+ if (value < PdfWriter.RUN_DIRECTION_DEFAULT || value > PdfWriter.RUN_DIRECTION_RTL)
+ throw new Exception("Invalid run direction: " + value);
+ this.runDirection = value;
+ }
+ }
+
+ /** Gets the number of lines written.
+ * @return the number of lines written
+ */
+ public int LinesWritten {
+ get {
+ return this.linesWritten;
+ }
+ }
+
+ /** Sets the arabic shaping options. The option can be AR_NOVOWEL,
+ * AR_COMPOSEDTASHKEEL and AR_LIG.
+ * @param arabicOptions the arabic shaping options
+ */
+ public int ArabicOptions {
+ set {
+ this.arabicOptions = value;
+ }
+ get {
+ return arabicOptions;
+ }
+ }
+
+ /** Gets the biggest descender value of the last line written.
+ * @return the biggest descender value of the last line written
+ */
+ public float Descender {
+ get {
+ return descender;
+ }
+ }
+
+ /** Gets the width that the line will occupy after writing.
+ * Only the width of the first line is returned.
+ * @param phrase the Phrase
containing the line
+ * @param runDirection the run direction
+ * @param arabicOptions the options for the arabic shaping
+ * @return the width of the line
+ */
+ public static float GetWidth(Phrase phrase, int runDirection, int arabicOptions) {
+ ColumnText ct = new ColumnText(null);
+ ct.AddText(phrase);
+ ct.AddWaitingPhrase();
+ PdfLine line = ct.bidiLine.ProcessLine(0, 20000, Element.ALIGN_LEFT, runDirection, arabicOptions);
+ if (line == null)
+ return 0;
+ else
+ return 20000 - line.WidthLeft;
+ }
+
+ /** Gets the width that the line will occupy after writing.
+ * Only the width of the first line is returned.
+ * @param phrase the Phrase
containing the line
+ * @return the width of the line
+ */
+ public static float GetWidth(Phrase phrase) {
+ return GetWidth(phrase, PdfWriter.RUN_DIRECTION_NO_BIDI, 0);
+ }
+
+ /** Shows a line of text. Only the first line is written.
+ * @param canvas where the text is to be written to
+ * @param alignment the alignment. It is not influenced by the run direction
+ * @param phrase the Phrase
with the text
+ * @param x the x reference position
+ * @param y the y reference position
+ * @param rotation the rotation to be applied in degrees counterclockwise
+ * @param runDirection the run direction
+ * @param arabicOptions the options for the arabic shaping
+ */
+ public static void ShowTextAligned(PdfContentByte canvas, int alignment, Phrase phrase, float x, float y, float rotation, int runDirection, int arabicOptions) {
+ if (alignment != Element.ALIGN_LEFT && alignment != Element.ALIGN_CENTER
+ && alignment != Element.ALIGN_RIGHT)
+ alignment = Element.ALIGN_LEFT;
+ canvas.SaveState();
+ ColumnText ct = new ColumnText(canvas);
+ if (rotation == 0) {
+ if (alignment == Element.ALIGN_LEFT)
+ ct.SetSimpleColumn(phrase, x, y - 1, 20000 + x, y + 2, 2, alignment);
+ else if (alignment == Element.ALIGN_RIGHT)
+ ct.SetSimpleColumn(phrase, x-20000, y-1, x, y+2, 2, alignment);
+ else
+ ct.SetSimpleColumn(phrase, x-20000, y-1, x+20000, y+2, 2, alignment);
+ }
+ else {
+ double alpha = rotation * Math.PI / 180.0;
+ float cos = (float)Math.Cos(alpha);
+ float sin = (float)Math.Sin(alpha);
+ canvas.ConcatCTM(cos, sin, -sin, cos, x, y);
+ if (alignment == Element.ALIGN_LEFT)
+ ct.SetSimpleColumn(phrase, 0, -1, 20000, 2, 2, alignment);
+ else if (alignment == Element.ALIGN_RIGHT)
+ ct.SetSimpleColumn(phrase, -20000, -1, 0, 2, 2, alignment);
+ else
+ ct.SetSimpleColumn(phrase, -20000, -1, 20000, 2, 2, alignment);
+ }
+ if (runDirection == PdfWriter.RUN_DIRECTION_RTL) {
+ if (alignment == Element.ALIGN_LEFT)
+ alignment = Element.ALIGN_RIGHT;
+ else if (alignment == Element.ALIGN_RIGHT)
+ alignment = Element.ALIGN_LEFT;
+ }
+ ct.Alignment = alignment;
+ ct.ArabicOptions = arabicOptions;
+ ct.RunDirection = runDirection;
+ ct.Go();
+ canvas.RestoreState();
+ }
+
+ /** Shows a line of text. Only the first line is written.
+ * @param canvas where the text is to be written to
+ * @param alignment the alignment
+ * @param phrase the Phrase
with the text
+ * @param x the x reference position
+ * @param y the y reference position
+ * @param rotation the rotation to be applied in degrees counterclockwise
+ */
+ public static void ShowTextAligned(PdfContentByte canvas, int alignment, Phrase phrase, float x, float y, float rotation) {
+ ShowTextAligned(canvas, alignment, phrase, x, y, rotation, PdfWriter.RUN_DIRECTION_NO_BIDI, 0);
+ }
+
+ protected int GoComposite(bool simulate) {
+ if (!rectangularMode)
+ throw new DocumentException("Irregular columns are not supported in composite mode.");
+ linesWritten = 0;
+ descender = 0;
+ bool firstPass = adjustFirstLine;
+ main_loop:
+ while (true) {
+ if (compositeElements.Count == 0)
+ return NO_MORE_TEXT;
+ IElement element = (IElement)compositeElements[0];
+ if (element.Type == Element.PARAGRAPH) {
+ Paragraph para = (Paragraph)element;
+ int status = 0;
+ for (int keep = 0; keep < 2; ++keep) {
+ float lastY = yLine;
+ bool createHere = false;
+ if (compositeColumn == null) {
+ compositeColumn = new ColumnText(canvas);
+ compositeColumn.UseAscender = (firstPass ? useAscender : false);
+ compositeColumn.Alignment = para.Alignment;
+ compositeColumn.Indent = para.IndentationLeft + para.FirstLineIndent;
+ compositeColumn.ExtraParagraphSpace = para.ExtraParagraphSpace;
+ compositeColumn.FollowingIndent = para.IndentationLeft;
+ compositeColumn.RightIndent = para.IndentationRight;
+ compositeColumn.SetLeading(para.Leading, para.MultipliedLeading);
+ compositeColumn.RunDirection = runDirection;
+ compositeColumn.ArabicOptions = arabicOptions;
+ compositeColumn.SpaceCharRatio = spaceCharRatio;
+ compositeColumn.AddText(para);
+ if (!firstPass) {
+ yLine -= para.SpacingBefore;
+ }
+ createHere = true;
+ }
+ compositeColumn.leftX = leftX;
+ compositeColumn.rightX = rightX;
+ compositeColumn.yLine = yLine;
+ compositeColumn.rectangularWidth = rectangularWidth;
+ compositeColumn.rectangularMode = rectangularMode;
+ compositeColumn.minY = minY;
+ compositeColumn.maxY = maxY;
+ bool keepCandidate = (para.KeepTogether && createHere && !firstPass);
+ status = compositeColumn.Go(simulate || (keepCandidate && keep == 0));
+ UpdateFilledWidth(compositeColumn.filledWidth);
+ if ((status & NO_MORE_TEXT) == 0 && keepCandidate) {
+ compositeColumn = null;
+ yLine = lastY;
+ return NO_MORE_COLUMN;
+ }
+ if (simulate || !keepCandidate)
+ break;
+ if (keep == 0) {
+ compositeColumn = null;
+ yLine = lastY;
+ }
+ }
+ firstPass = false;
+ yLine = compositeColumn.yLine;
+ linesWritten += compositeColumn.linesWritten;
+ descender = compositeColumn.descender;
+ if ((status & NO_MORE_TEXT) != 0) {
+ compositeColumn = null;
+ compositeElements.RemoveAt(0);
+ yLine -= para.SpacingAfter;
+ }
+ if ((status & NO_MORE_COLUMN) != 0) {
+ return NO_MORE_COLUMN;
+ }
+ }
+ else if (element.Type == Element.LIST) {
+ List list = (List)element;
+ ArrayList items = list.Items;
+ ListItem item = null;
+ float listIndentation = list.IndentationLeft;
+ int count = 0;
+ Stack stack = new Stack();
+ for (int k = 0; k < items.Count; ++k) {
+ Object obj = items[k];
+ if (obj is ListItem) {
+ if (count == listIdx) {
+ item = (ListItem)obj;
+ break;
+ }
+ else ++count;
+ }
+ else if (obj is List) {
+ stack.Push(new Object[]{list, k, listIndentation});
+ list = (List)obj;
+ items = list.Items;
+ listIndentation += list.IndentationLeft;
+ k = -1;
+ continue;
+ }
+ if (k == items.Count - 1) {
+ if (stack.Count > 0) {
+ Object[] objs = (Object[])stack.Pop();
+ list = (List)objs[0];
+ items = list.Items;
+ k = (int)objs[1];
+ listIndentation = (float)objs[2];
+ }
+ }
+ }
+ int status = 0;
+ for (int keep = 0; keep < 2; ++keep) {
+ float lastY = yLine;
+ bool createHere = false;
+ if (compositeColumn == null) {
+ if (item == null) {
+ listIdx = 0;
+ compositeElements.RemoveAt(0);
+ goto main_loop;
+ }
+ compositeColumn = new ColumnText(canvas);
+
+ compositeColumn.UseAscender = (firstPass ? useAscender : false);
+ compositeColumn.Alignment = item.Alignment;
+ compositeColumn.Indent = item.IndentationLeft + listIndentation + item.FirstLineIndent;
+ compositeColumn.ExtraParagraphSpace = item.ExtraParagraphSpace;
+ compositeColumn.FollowingIndent = compositeColumn.Indent;
+ compositeColumn.RightIndent = item.IndentationRight + list.IndentationRight;
+ compositeColumn.SetLeading(item.Leading, item.MultipliedLeading);
+ compositeColumn.RunDirection = runDirection;
+ compositeColumn.ArabicOptions = arabicOptions;
+ compositeColumn.SpaceCharRatio = spaceCharRatio;
+ compositeColumn.AddText(item);
+ if (!firstPass) {
+ yLine -= item.SpacingBefore;
+ }
+ createHere = true;
+ }
+ compositeColumn.leftX = leftX;
+ compositeColumn.rightX = rightX;
+ compositeColumn.yLine = yLine;
+ compositeColumn.rectangularWidth = rectangularWidth;
+ compositeColumn.rectangularMode = rectangularMode;
+ compositeColumn.minY = minY;
+ compositeColumn.maxY = maxY;
+ bool keepCandidate = (item.KeepTogether && createHere && !firstPass);
+ status = compositeColumn.Go(simulate || (keepCandidate && keep == 0));
+ UpdateFilledWidth(compositeColumn.filledWidth);
+ if ((status & NO_MORE_TEXT) == 0 && keepCandidate) {
+ compositeColumn = null;
+ yLine = lastY;
+ return NO_MORE_COLUMN;
+ }
+ if (simulate || !keepCandidate)
+ break;
+ if (keep == 0) {
+ compositeColumn = null;
+ yLine = lastY;
+ }
+ }
+ firstPass = false;
+ yLine = compositeColumn.yLine;
+ linesWritten += compositeColumn.linesWritten;
+ descender = compositeColumn.descender;
+ if (!float.IsNaN(compositeColumn.firstLineY) && !compositeColumn.firstLineYDone) {
+ if (!simulate)
+ ShowTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(item.ListSymbol), compositeColumn.leftX + listIndentation, compositeColumn.firstLineY, 0);
+ compositeColumn.firstLineYDone = true;
+ }
+ if ((status & NO_MORE_TEXT) != 0) {
+ compositeColumn = null;
+ ++listIdx;
+ yLine -= item.SpacingAfter;
+ }
+ if ((status & NO_MORE_COLUMN) != 0) {
+ return NO_MORE_COLUMN;
+ }
+ }
+ else if (element.Type == Element.PTABLE) {
+ // don't write anything in the current column if there's no more space available
+ if (yLine < minY || yLine > maxY)
+ return NO_MORE_COLUMN;
+
+ // get the PdfPTable element
+ PdfPTable table = (PdfPTable)element;
+
+ // we ignore tables without a body
+ if (table.Size <= table.HeaderRows) {
+ compositeElements.RemoveAt(0);
+ continue;
+ }
+
+ // offsets
+ float yTemp = yLine;
+ if (!firstPass && listIdx == 0) {
+ yTemp -= table.SpacingBefore;
+ }
+ float yLineWrite = yTemp;
+
+ // don't write anything in the current column if there's no more space available
+ if (yTemp < minY || yTemp > maxY) {
+ return NO_MORE_COLUMN;
+ }
+
+ // coordinates
+ currentLeading = 0;
+ float x1 = leftX;
+ float tableWidth;
+ if (table.LockedWidth) {
+ tableWidth = table.TotalWidth;
+ UpdateFilledWidth(tableWidth);
+ }
+ else {
+ tableWidth = rectangularWidth * table.WidthPercentage / 100f;
+ table.TotalWidth = tableWidth;
+ }
+
+ // how many header rows are real header rows; how many are footer rows?
+ int headerRows = table.HeaderRows;
+ int footerRows = table.FooterRows;
+ if (footerRows > headerRows)
+ footerRows = headerRows;
+ int realHeaderRows = headerRows - footerRows;
+ float headerHeight = table.HeaderHeight;
+ float footerHeight = table.FooterHeight;
+
+ // make sure the header and footer fit on the page
+ bool skipHeader = (!firstPass && table.SkipFirstHeader && listIdx <= headerRows);
+ if (!skipHeader) {
+ yTemp -= headerHeight;
+ if (yTemp < minY || yTemp > maxY) {
+ if (firstPass) {
+ compositeElements.RemoveAt(0);
+ continue;
+ }
+ return NO_MORE_COLUMN;
+ }
+ }
+
+ // how many real rows (not header or footer rows) fit on a page?
+ int k;
+ if (listIdx < headerRows) {
+ listIdx = headerRows;
+ }
+ if (!table.ElementComplete) {
+ yTemp -= footerHeight;
+ }
+ for (k = listIdx; k < table.Size; ++k) {
+ float rowHeight = table.GetRowHeight(k);
+ if (yTemp - rowHeight < minY)
+ break;
+ yTemp -= rowHeight;
+ }
+ if (!table.ElementComplete) {
+ yTemp += footerHeight;
+ }
+ // either k is the first row that doesn't fit on the page (break);
+ if (k < table.Size) {
+ if (table.SplitRows && (!table.SplitLate || (k == listIdx && firstPass))) {
+ if (!splittedRow) {
+ splittedRow = true;
+ table = new PdfPTable(table);
+ compositeElements[0] = table;
+ ArrayList rows = table.Rows;
+ for (int i = headerRows; i < listIdx; ++i)
+ rows[i] = null;
+ }
+ float h = yTemp - minY;
+ PdfPRow newRow = table.GetRow(k).SplitRow(h);
+ if (newRow == null) {
+ if (k == listIdx) {
+ return NO_MORE_COLUMN;
+ }
+ }
+ else {
+ yTemp = minY;
+ table.Rows.Insert(++k, newRow);
+ }
+ }
+ else if (!table.SplitRows && k == listIdx && firstPass) {
+ compositeElements.RemoveAt(0);
+ splittedRow = false;
+ continue;
+ }
+ else if (k == listIdx && !firstPass && (!table.SplitRows || table.SplitLate) && (table.FooterRows == 0 || table.ElementComplete)) {
+ return NO_MORE_COLUMN;
+ }
+ }
+ // or k is the number of rows in the table (for loop was done).
+ firstPass = false;
+ // we draw the table (for real now)
+ if (!simulate) {
+ // set the alignment
+ switch (table.HorizontalAlignment) {
+ case Element.ALIGN_LEFT:
+ break;
+ case Element.ALIGN_RIGHT:
+ x1 += rectangularWidth - tableWidth;
+ break;
+ default:
+ x1 += (rectangularWidth - tableWidth) / 2f;
+ break;
+ }
+ // copy the rows that fit on the page in a new table nt
+ PdfPTable nt = PdfPTable.ShallowCopy(table);
+ ArrayList rows = table.Rows;
+ ArrayList sub = nt.Rows;
+
+ // first we add the real header rows (if necessary)
+ if (!skipHeader) {
+ for (int j = 0; j < realHeaderRows; ++j) {
+ PdfPRow headerRow = (PdfPRow)rows[j];
+ sub.Add(headerRow);
+ }
+ }
+ else {
+ nt.HeaderRows = footerRows;
+ }
+ // then we add the real content
+ for (int j = listIdx; j < k; ++j) {
+ sub.Add(rows[j]);
+ }
+ // if k < table.size(), we must indicate that the new table is complete;
+ // otherwise no footers will be added (because iText thinks the table continues on the same page)
+ if (k < table.Size) {
+ nt.ElementComplete = true;
+ }
+ // we add the footer rows if necessary (not for incomplete tables)
+ for (int j = 0; j < footerRows && nt.ElementComplete; ++j) {
+ sub.Add(rows[j + realHeaderRows]);
+ }
+
+ // we need a correction if the last row needs to be extended
+ float rowHeight = 0;
+ if (table.ExtendLastRow) {
+ PdfPRow last = (PdfPRow)sub[sub.Count - 1 - footerRows];
+ rowHeight = last.MaxHeights;
+ last.MaxHeights = yTemp - minY + rowHeight;
+ yTemp = minY;
+ }
+
+ // now we render the rows of the new table
+ if (canvases != null)
+ nt.WriteSelectedRows(0, -1, x1, yLineWrite, canvases);
+ else
+ nt.WriteSelectedRows(0, -1, x1, yLineWrite, canvas);
+ if (table.ExtendLastRow) {
+ PdfPRow last = (PdfPRow)sub[sub.Count - 1 - footerRows];
+ last.MaxHeights = rowHeight;
+ }
+ }
+ else if (table.ExtendLastRow && minY > PdfPRow.BOTTOM_LIMIT) {
+ yTemp = minY;
+ }
+ yLine = yTemp;
+ if (!(skipHeader || table.ElementComplete)) {
+ yLine += footerHeight;
+ }
+ if (k >= table.Size) {
+ yLine -= table.SpacingAfter;
+ compositeElements.RemoveAt(0);
+ splittedRow = false;
+ listIdx = 0;
+ }
+ else {
+ if (splittedRow) {
+ ArrayList rows = table.Rows;
+ for (int i = listIdx; i < k; ++i)
+ rows[i] = null;
+ }
+ listIdx = k;
+ return NO_MORE_COLUMN;
+ }
+ }
+ else if (element.Type == Element.YMARK) {
+ if (!simulate) {
+ IDrawInterface zh = (IDrawInterface)element;
+ zh.Draw(canvas, leftX, minY, rightX, maxY, yLine);
+ }
+ compositeElements.RemoveAt(0);
+ }
+ else
+ compositeElements.RemoveAt(0);
+ }
+ }
+
+ /**
+ * Sets the canvas.
+ * @param canvas
+ */
+ public PdfContentByte Canvas {
+ set {
+ canvas = value;
+ canvases = null;
+ if (compositeColumn != null)
+ compositeColumn.Canvas = value;
+ }
+ get {
+ return canvas;
+ }
+ }
+
+ /**
+ * Sets the canvases.
+ * @param canvas
+ */
+ public PdfContentByte[] Canvases {
+ set {
+ canvases = value;
+ canvas = canvases[PdfPTable.TEXTCANVAS];
+ if (compositeColumn != null)
+ compositeColumn.Canvases = canvases;
+ }
+ get {
+ return canvases;
+ }
+ }
+
+ /**
+ * Checks if the element has a height of 0.
+ * @return true or false
+ * @since 2.1.2
+ */
+ public bool ZeroHeightElement() {
+ return composite && compositeElements.Count != 0 && ((IElement)compositeElements[0]).Type == Element.YMARK;
+ }
+
+ /**
+ * Enables/Disables adjustment of first line height based on max ascender.
+ * @param use enable adjustment if true
+ */
+ public bool UseAscender {
+ set {
+ useAscender = value;
+ }
+ get {
+ return useAscender;
+ }
+ }
+
+ /**
+ * Checks the status variable and looks if there's still some text.
+ */
+ public static bool HasMoreText(int status) {
+ return (status & ColumnText.NO_MORE_TEXT) == 0;
+ }
+ /**
+ * Holds value of property filledWidth.
+ */
+ private float filledWidth;
+
+ /**
+ * Sets the real width used by the largest line. Only used to set it
+ * to zero to start another measurement.
+ * @param filledWidth the real width used by the largest line
+ */
+ public float FilledWidth {
+ set {
+ filledWidth = value;
+ }
+ get {
+ return filledWidth;
+ }
+ }
+
+ /**
+ * Replaces the filledWidth
if greater than the existing one.
+ * @param w the new filledWidth
if greater than the existing one
+ */
+ public void UpdateFilledWidth(float w) {
+ if (w > filledWidth)
+ filledWidth = w;
+ }
+
+ private bool adjustFirstLine = true;
+
+ /**
+ * Sets the first line adjustment. Some objects have properties, like spacing before, that
+ * behave differently if the object is the first to be written after go() or not. The first line adjustment is
+ * true
by default but can be changed if several objects are to be placed one
+ * after the other in the same column calling go() several times.
+ * @param adjustFirstLine true
to adjust the first line, false
otherwise
+ */
+ public bool AdjustFirstLine {
+ set {
+ adjustFirstLine = value;
+ }
+ get {
+ return adjustFirstLine;
+ }
+ }
+}
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/DefaultSplitCharacter.cs b/iTechSharp/iTextSharp/text/pdf/DefaultSplitCharacter.cs
new file mode 100644
index 0000000..d2d8645
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/DefaultSplitCharacter.cs
@@ -0,0 +1,109 @@
+using System;
+using iTextSharp.text;
+
+/*
+ * $Id: DefaultSplitCharacter.cs,v 1.1 2008/05/22 22:11:09 psoares33 Exp $
+ *
+ * Copyright 2008 Bruno Lowagie and Xavier Le Vourch
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * The default class that is used to determine whether or not a character
+ * is a split character. You can subclass this class to define your own
+ * split characters.
+ * @since 2.1.2
+ */
+ public class DefaultSplitCharacter : ISplitCharacter {
+
+ /**
+ * An instance of the default SplitCharacter.
+ */
+ public static readonly ISplitCharacter DEFAULT = new DefaultSplitCharacter();
+
+ /**
+ * Checks if a character can be used to split a PdfString
.
+ * true
if the character can be used to split a string, false
otherwise
+ */
+ public bool IsSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) {
+ char c = GetCurrentCharacter(current, cc, ck);
+ if (c <= ' ' || c == '-' || c == '\u2010') {
+ return true;
+ }
+ if (c < 0x2002)
+ return false;
+ return ((c >= 0x2002 && c <= 0x200b)
+ || (c >= 0x2e80 && c < 0xd7a0)
+ || (c >= 0xf900 && c < 0xfb00)
+ || (c >= 0xfe30 && c < 0xfe50)
+ || (c >= 0xff61 && c < 0xffa0));
+ }
+
+ /**
+ * Returns the current character
+ * @param current current position in the array
+ * @param cc the character array that has to be checked
+ * @param ck chunk array
+ * @return the current character
+ */
+ protected char GetCurrentCharacter(int current, char[] cc, PdfChunk[] ck) {
+ if (ck == null) {
+ return (char)cc[current];
+ }
+ return (char)ck[Math.Min(current, ck.Length - 1)].GetUnicodeEquivalent(cc[current]);
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/DocumentFont.cs b/iTechSharp/iTextSharp/text/pdf/DocumentFont.cs
new file mode 100644
index 0000000..d2dd905
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/DocumentFont.cs
@@ -0,0 +1,633 @@
+using System;
+using System.Collections;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ public class DocumentFont : BaseFont {
+
+ // code, [glyph, width]
+ private Hashtable metrics = new Hashtable();
+ private String fontName;
+ private PRIndirectReference refFont;
+ private PdfDictionary font;
+ private IntHashtable uni2byte = new IntHashtable();
+ private IntHashtable byte2uni = new IntHashtable();
+ private float Ascender = 800;
+ private float CapHeight = 700;
+ private float Descender = -200;
+ private float ItalicAngle = 0;
+ private float llx = -50;
+ private float lly = -200;
+ private float urx = 100;
+ private float ury = 900;
+ private bool isType0 = false;
+
+ private BaseFont cjkMirror;
+
+ private static String[] cjkNames = {"HeiseiMin-W3", "HeiseiKakuGo-W5", "STSong-Light", "MHei-Medium",
+ "MSung-Light", "HYGoThic-Medium", "HYSMyeongJo-Medium", "MSungStd-Light", "STSongStd-Light",
+ "HYSMyeongJoStd-Medium", "KozMinPro-Regular"};
+
+ private static String[] cjkEncs = {"UniJIS-UCS2-H", "UniJIS-UCS2-H", "UniGB-UCS2-H", "UniCNS-UCS2-H",
+ "UniCNS-UCS2-H", "UniKS-UCS2-H", "UniKS-UCS2-H", "UniCNS-UCS2-H", "UniGB-UCS2-H",
+ "UniKS-UCS2-H", "UniJIS-UCS2-H"};
+
+ private static String[] cjkNames2 = {"MSungStd-Light", "STSongStd-Light", "HYSMyeongJoStd-Medium", "KozMinPro-Regular"};
+
+ private static String[] cjkEncs2 = {"UniCNS-UCS2-H", "UniGB-UCS2-H", "UniKS-UCS2-H", "UniJIS-UCS2-H",
+ "UniCNS-UTF16-H", "UniGB-UTF16-H", "UniKS-UTF16-H", "UniJIS-UTF16-H"};
+
+ private static int[] stdEnc = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 32,33,34,35,36,37,38,8217,40,41,42,43,44,45,46,47,
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
+ 8216,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,161,162,163,8260,165,402,167,164,39,8220,171,8249,8250,64257,64258,
+ 0,8211,8224,8225,183,0,182,8226,8218,8222,8221,187,8230,8240,0,191,
+ 0,96,180,710,732,175,728,729,168,0,730,184,0,733,731,711,
+ 8212,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,198,0,170,0,0,0,0,321,216,338,186,0,0,0,0,
+ 0,230,0,0,0,305,0,0,322,248,339,223,0,0,0,0};
+
+ /** Creates a new instance of DocumentFont */
+ internal DocumentFont(PRIndirectReference refFont) {
+ encoding = "";
+ fontSpecific = false;
+ this.refFont = refFont;
+ fontType = FONT_TYPE_DOCUMENT;
+ font = (PdfDictionary)PdfReader.GetPdfObject(refFont);
+ fontName = PdfName.DecodeName(((PdfName)PdfReader.GetPdfObject(font.Get(PdfName.BASEFONT))).ToString());
+ PdfName subType = (PdfName)PdfReader.GetPdfObject(font.Get(PdfName.SUBTYPE));
+ if (PdfName.TYPE1.Equals(subType) || PdfName.TRUETYPE.Equals(subType))
+ DoType1TT();
+ else {
+ for (int k = 0; k < cjkNames.Length; ++k) {
+ if (fontName.StartsWith(cjkNames[k])) {
+ fontName = cjkNames[k];
+ cjkMirror = BaseFont.CreateFont(fontName, cjkEncs[k], false);
+ return;
+ }
+ }
+ String enc = PdfName.DecodeName(((PdfName)PdfReader.GetPdfObject(font.Get(PdfName.ENCODING))).ToString());
+ for (int k = 0; k < cjkEncs2.Length; ++k) {
+ if (enc.StartsWith(cjkEncs2[k])) {
+ if (k > 3)
+ k -= 4;
+ cjkMirror = BaseFont.CreateFont(cjkNames2[k], cjkEncs2[k], false);
+ return;
+ }
+ }
+ if (PdfName.TYPE0.Equals(subType) && enc.Equals("Identity-H")) {
+ ProcessType0(font);
+ isType0 = true;
+ }
+ }
+ }
+
+ private void ProcessType0(PdfDictionary font) {
+ byte[] touni = PdfReader.GetStreamBytes((PRStream)PdfReader.GetPdfObjectRelease(font.Get(PdfName.TOUNICODE)));
+ PdfArray df = (PdfArray)PdfReader.GetPdfObjectRelease(font.Get(PdfName.DESCENDANTFONTS));
+ PdfDictionary cidft = (PdfDictionary)PdfReader.GetPdfObjectRelease((PdfObject)df.ArrayList[0]);
+ PdfNumber dwo = (PdfNumber)PdfReader.GetPdfObjectRelease(cidft.Get(PdfName.DW));
+ int dw = 1000;
+ if (dwo != null)
+ dw = dwo.IntValue;
+ IntHashtable widths = ReadWidths((PdfArray)PdfReader.GetPdfObjectRelease(cidft.Get(PdfName.W)));
+ PdfDictionary fontDesc = (PdfDictionary)PdfReader.GetPdfObjectRelease(cidft.Get(PdfName.FONTDESCRIPTOR));
+ FillFontDesc(fontDesc);
+ FillMetrics(touni, widths, dw);
+ }
+
+ private IntHashtable ReadWidths(PdfArray ws) {
+ IntHashtable hh = new IntHashtable();
+ if (ws == null)
+ return hh;
+ ArrayList ar = ws.ArrayList;
+ for (int k = 0; k < ar.Count; ++k) {
+ int c1 = ((PdfNumber)PdfReader.GetPdfObjectRelease((PdfObject)ar[k])).IntValue;
+ PdfObject obj = PdfReader.GetPdfObjectRelease((PdfObject)ar[++k]);
+ if (obj.IsArray()) {
+ ArrayList ar2 = ((PdfArray)obj).ArrayList;
+ for (int j = 0; j < ar2.Count; ++j) {
+ int c2 = ((PdfNumber)PdfReader.GetPdfObjectRelease((PdfObject)ar2[j])).IntValue;
+ hh[c1++] = c2;
+ }
+ }
+ else {
+ int c2 = ((PdfNumber)obj).IntValue;
+ int w = ((PdfNumber)PdfReader.GetPdfObjectRelease((PdfObject)ar[++k])).IntValue;
+ for (; c1 <= c2; ++c1)
+ hh[c1] = w;
+ }
+ }
+ return hh;
+ }
+
+ private String DecodeString(PdfString ps) {
+ if (ps.IsHexWriting())
+ return PdfEncodings.ConvertToString(ps.GetBytes(), "UnicodeBigUnmarked");
+ else
+ return ps.ToUnicodeString();
+ }
+
+ private void FillMetrics(byte[] touni, IntHashtable widths, int dw) {
+ PdfContentParser ps = new PdfContentParser(new PRTokeniser(touni));
+ PdfObject ob = null;
+ PdfObject last = null;
+ while ((ob = ps.ReadPRObject()) != null) {
+ if (ob.Type == PdfContentParser.COMMAND_TYPE) {
+ if (ob.ToString().Equals("beginbfchar")) {
+ int n = ((PdfNumber)last).IntValue;
+ for (int k = 0; k < n; ++k) {
+ String cid = DecodeString((PdfString)ps.ReadPRObject());
+ String uni = DecodeString((PdfString)ps.ReadPRObject());
+ if (uni.Length == 1) {
+ int cidc = (int)cid[0];
+ int unic = (int)uni[uni.Length - 1];
+ int w = dw;
+ if (widths.ContainsKey(cidc))
+ w = widths[cidc];
+ metrics[unic] = new int[]{cidc, w};
+ }
+ }
+ }
+ else if (ob.ToString().Equals("beginbfrange")) {
+ int n = ((PdfNumber)last).IntValue;
+ for (int k = 0; k < n; ++k) {
+ String cid1 = DecodeString((PdfString)ps.ReadPRObject());
+ String cid2 = DecodeString((PdfString)ps.ReadPRObject());
+ int cid1c = (int)cid1[0];
+ int cid2c = (int)cid2[0];
+ PdfObject ob2 = ps.ReadPRObject();
+ if (ob2.IsString()) {
+ String uni = DecodeString((PdfString)ob2);
+ if (uni.Length == 1) {
+ int unic = (int)uni[uni.Length - 1];
+ for (; cid1c <= cid2c; cid1c++, unic++) {
+ int w = dw;
+ if (widths.ContainsKey(cid1c))
+ w = widths[cid1c];
+ metrics[unic] = new int[]{cid1c, w};
+ }
+ }
+ }
+ else {
+ ArrayList ar = ((PdfArray)ob2).ArrayList;
+ for (int j = 0; j < ar.Count; ++j, ++cid1c) {
+ String uni = DecodeString((PdfString)ar[j]);
+ if (uni.Length == 1) {
+ int unic = (int)uni[uni.Length - 1];
+ int w = dw;
+ if (widths.ContainsKey(cid1c))
+ w = widths[cid1c];
+ metrics[unic] = new int[]{cid1c, w};
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ last = ob;
+ }
+ }
+
+ private void DoType1TT() {
+ PdfObject enc = PdfReader.GetPdfObject(font.Get(PdfName.ENCODING));
+ if (enc == null)
+ FillEncoding(null);
+ else {
+ if (enc.IsName())
+ FillEncoding((PdfName)enc);
+ else {
+ PdfDictionary encDic = (PdfDictionary)enc;
+ enc = PdfReader.GetPdfObject(encDic.Get(PdfName.BASEENCODING));
+ if (enc == null)
+ FillEncoding(null);
+ else
+ FillEncoding((PdfName)enc);
+ PdfArray diffs = (PdfArray)PdfReader.GetPdfObject(encDic.Get(PdfName.DIFFERENCES));
+ if (diffs != null) {
+ ArrayList dif = diffs.ArrayList;
+ int currentNumber = 0;
+ for (int k = 0; k < dif.Count; ++k) {
+ PdfObject obj = (PdfObject)dif[k];
+ if (obj.IsNumber())
+ currentNumber = ((PdfNumber)obj).IntValue;
+ else {
+ int[] c = GlyphList.NameToUnicode(PdfName.DecodeName(((PdfName)obj).ToString()));
+ if (c != null && c.Length > 0) {
+ if (byte2uni.ContainsKey(currentNumber)) {
+ uni2byte.Remove(byte2uni[currentNumber]);
+ }
+ uni2byte[c[0]] = currentNumber;
+ byte2uni[currentNumber] = c[0];
+ }
+ ++currentNumber;
+ }
+ }
+ }
+ }
+ }
+ PdfArray newWidths = (PdfArray)PdfReader.GetPdfObject(font.Get(PdfName.WIDTHS));
+ PdfNumber first = (PdfNumber)PdfReader.GetPdfObject(font.Get(PdfName.FIRSTCHAR));
+ PdfNumber last = (PdfNumber)PdfReader.GetPdfObject(font.Get(PdfName.LASTCHAR));
+ if (BuiltinFonts14.ContainsKey(fontName)) {
+ BaseFont bf;
+ bf = BaseFont.CreateFont(fontName, WINANSI, false);
+ int[] e = uni2byte.ToOrderedKeys();
+ for (int k = 0; k < e.Length; ++k) {
+ int n = uni2byte[e[k]];
+ widths[n] = bf.GetRawWidth(n, GlyphList.UnicodeToName(e[k]));
+ }
+ Ascender = bf.GetFontDescriptor(ASCENT, 1000);
+ CapHeight = bf.GetFontDescriptor(CAPHEIGHT, 1000);
+ Descender = bf.GetFontDescriptor(DESCENT, 1000);
+ ItalicAngle = bf.GetFontDescriptor(ITALICANGLE, 1000);
+ llx = bf.GetFontDescriptor(BBOXLLX, 1000);
+ lly = bf.GetFontDescriptor(BBOXLLY, 1000);
+ urx = bf.GetFontDescriptor(BBOXURX, 1000);
+ ury = bf.GetFontDescriptor(BBOXURY, 1000);
+ }
+ if (first != null && last != null && newWidths != null) {
+ int f = first.IntValue;
+ ArrayList ar = newWidths.ArrayList;
+ for (int k = 0; k < ar.Count; ++k) {
+ widths[f + k] = ((PdfNumber)ar[k]).IntValue;
+ }
+ }
+ FillFontDesc((PdfDictionary)PdfReader.GetPdfObject(font.Get(PdfName.FONTDESCRIPTOR)));
+ }
+
+ private void FillFontDesc(PdfDictionary fontDesc) {
+ if (fontDesc == null)
+ return;
+ PdfNumber v = (PdfNumber)PdfReader.GetPdfObject(fontDesc.Get(PdfName.ASCENT));
+ if (v != null)
+ Ascender = v.FloatValue;
+ v = (PdfNumber)PdfReader.GetPdfObject(fontDesc.Get(PdfName.CAPHEIGHT));
+ if (v != null)
+ CapHeight = v.FloatValue;
+ v = (PdfNumber)PdfReader.GetPdfObject(fontDesc.Get(PdfName.DESCENT));
+ if (v != null)
+ Descender = v.FloatValue;
+ v = (PdfNumber)PdfReader.GetPdfObject(fontDesc.Get(PdfName.ITALICANGLE));
+ if (v != null)
+ ItalicAngle = v.FloatValue;
+ PdfArray bbox = (PdfArray)PdfReader.GetPdfObject(fontDesc.Get(PdfName.FONTBBOX));
+ if (bbox != null) {
+ ArrayList ar = bbox.ArrayList;
+ llx = ((PdfNumber)ar[0]).FloatValue;
+ lly = ((PdfNumber)ar[1]).FloatValue;
+ urx = ((PdfNumber)ar[2]).FloatValue;
+ ury = ((PdfNumber)ar[3]).FloatValue;
+ if (llx > urx) {
+ float t = llx;
+ llx = urx;
+ urx = t;
+ }
+ if (lly > ury) {
+ float t = lly;
+ lly = ury;
+ ury = t;
+ }
+ }
+ }
+
+ private void FillEncoding(PdfName encoding) {
+ if (PdfName.MAC_ROMAN_ENCODING.Equals(encoding) || PdfName.WIN_ANSI_ENCODING.Equals(encoding)) {
+ byte[] b = new byte[256];
+ for (int k = 0; k < 256; ++k)
+ b[k] = (byte)k;
+ String enc = WINANSI;
+ if (PdfName.MAC_ROMAN_ENCODING.Equals(encoding))
+ enc = MACROMAN;
+ String cv = PdfEncodings.ConvertToString(b, enc);
+ char[] arr = cv.ToCharArray();
+ for (int k = 0; k < 256; ++k) {
+ uni2byte[arr[k]] = k;
+ byte2uni[k] = arr[k];
+ }
+ }
+ else {
+ for (int k = 0; k < 256; ++k) {
+ uni2byte[stdEnc[k]] = k;
+ byte2uni[k] = stdEnc[k];
+ }
+ }
+ }
+
+ /** Gets the family name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the family name of the font
+ *
+ */
+ public override string[][] FamilyFontName {
+ get {
+ return FullFontName;
+ }
+ }
+
+ /** Gets the font parameter identified by key
. Valid values
+ * for key
are ASCENT
, CAPHEIGHT
, DESCENT
,
+ * ITALICANGLE
, BBOXLLX
, BBOXLLY
, BBOXURX
+ * and BBOXURY
.
+ * @param key the parameter to be extracted
+ * @param fontSize the font size in points
+ * @return the parameter in points
+ *
+ */
+ public override float GetFontDescriptor(int key, float fontSize) {
+ if (cjkMirror != null)
+ return cjkMirror.GetFontDescriptor(key, fontSize);
+ switch (key) {
+ case AWT_ASCENT:
+ case ASCENT:
+ return Ascender * fontSize / 1000;
+ case CAPHEIGHT:
+ return CapHeight * fontSize / 1000;
+ case AWT_DESCENT:
+ case DESCENT:
+ return Descender * fontSize / 1000;
+ case ITALICANGLE:
+ return ItalicAngle;
+ case BBOXLLX:
+ return llx * fontSize / 1000;
+ case BBOXLLY:
+ return lly * fontSize / 1000;
+ case BBOXURX:
+ return urx * fontSize / 1000;
+ case BBOXURY:
+ return ury * fontSize / 1000;
+ case AWT_LEADING:
+ return 0;
+ case AWT_MAXADVANCE:
+ return (urx - llx) * fontSize / 1000;
+ }
+ return 0;
+ }
+
+ /** Gets the full name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the full name of the font
+ *
+ */
+ public override string[][] FullFontName {
+ get {
+ return new string[][]{new string[]{"", "", "", fontName}};
+ }
+ }
+
+ /** Gets all the entries of the names-table. If it is a True Type font
+ * each array element will have {Name ID, Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"4", "", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public override string[][] AllNameEntries {
+ get {
+ return new string[][]{new string[]{"4", "", "", "", fontName}};
+ }
+ }
+
+ /** Gets the kerning between two Unicode chars.
+ * @param char1 the first char
+ * @param char2 the second char
+ * @return the kerning to be applied
+ *
+ */
+ public override int GetKerning(int char1, int char2) {
+ return 0;
+ }
+
+ /** Gets the postscript font name.
+ * @return the postscript font name
+ *
+ */
+ public override string PostscriptFontName {
+ get {
+ return fontName;
+ }
+ set {
+ }
+ }
+
+ /** Gets the width from the font according to the Unicode char c
+ * or the name
. If the name
is null it's a symbolic font.
+ * @param c the unicode char
+ * @param name the glyph name
+ * @return the width of the char
+ *
+ */
+ internal override int GetRawWidth(int c, String name) {
+ return 0;
+ }
+
+ /** Checks if the font has any kerning pairs.
+ * @return true
if the font has any kerning pairs
+ *
+ */
+ public override bool HasKernPairs() {
+ return false;
+ }
+
+ /** Outputs to the writer the font dictionaries and streams.
+ * @param writer the writer for this document
+ * @param ref the font indirect reference
+ * @param params several parameters that depend on the font type
+ * @throws IOException on error
+ * @throws DocumentException error in generating the object
+ *
+ */
+ internal override void WriteFont(PdfWriter writer, PdfIndirectReference refi, Object[] param) {
+ }
+
+ /**
+ * Gets the width of a char
in normalized 1000 units.
+ * @param char1 the unicode char
to get the width of
+ * @return the width in normalized 1000 units
+ */
+ public override int GetWidth(int char1) {
+ if (cjkMirror != null)
+ return cjkMirror.GetWidth(char1);
+ else if (isType0) {
+ int[] ws = (int[])metrics[(int)char1];
+ if (ws != null)
+ return ws[1];
+ else
+ return 0;
+ }
+ else
+ return base.GetWidth(char1);
+ }
+
+ public override int GetWidth(String text) {
+ if (cjkMirror != null)
+ return cjkMirror.GetWidth(text);
+ else if (isType0) {
+ char[] chars = text.ToCharArray();
+ int len = chars.Length;
+ int total = 0;
+ for (int k = 0; k < len; ++k) {
+ int[] ws = (int[])metrics[(int)chars[k]];
+ if (ws != null)
+ total += ws[1];
+ }
+ return total;
+ }
+ else
+ return base.GetWidth(text);
+ }
+
+ internal override byte[] ConvertToBytes(String text) {
+ if (cjkMirror != null)
+ return PdfEncodings.ConvertToBytes(text, CJKFont.CJK_ENCODING);
+ else if (isType0) {
+ char[] chars = text.ToCharArray();
+ int len = chars.Length;
+ byte[] b = new byte[len * 2];
+ int bptr = 0;
+ for (int k = 0; k < len; ++k) {
+ int[] ws = (int[])metrics[(int)chars[k]];
+ if (ws != null) {
+ int g = ws[0];
+ b[bptr++] = (byte)(g / 256);
+ b[bptr++] = (byte)(g);
+ }
+ }
+ if (bptr == b.Length)
+ return b;
+ else {
+ byte[] nb = new byte[bptr];
+ System.Array.Copy(b, 0, nb, 0, bptr);
+ return nb;
+ }
+ }
+ else {
+ char[] cc = text.ToCharArray();
+ byte[] b = new byte[cc.Length];
+ int ptr = 0;
+ for (int k = 0; k < cc.Length; ++k) {
+ if (uni2byte.ContainsKey(cc[k]))
+ b[ptr++] = (byte)uni2byte[cc[k]];
+ }
+ if (ptr == b.Length)
+ return b;
+ else {
+ byte[] b2 = new byte[ptr];
+ System.Array.Copy(b, 0, b2, 0, ptr);
+ return b2;
+ }
+ }
+ }
+
+ internal override byte[] ConvertToBytes(int char1) {
+ if (cjkMirror != null)
+ return PdfEncodings.ConvertToBytes((char)char1, CJKFont.CJK_ENCODING);
+ else if (isType0) {
+ int[] ws = (int[])metrics[(int)char1];
+ if (ws != null) {
+ int g = ws[0];
+ return new byte[]{(byte)(g / 256), (byte)(g)};
+ }
+ else
+ return new byte[0];
+ }
+ else {
+ if (uni2byte.ContainsKey(char1))
+ return new byte[]{(byte)uni2byte[char1]};
+ else
+ return new byte[0];
+ }
+ }
+
+ internal PdfIndirectReference IndirectReference {
+ get {
+ return refFont;
+ }
+ }
+
+ public override bool CharExists(int c) {
+ if (cjkMirror != null)
+ return cjkMirror.CharExists(c);
+ else if (isType0) {
+ return metrics.ContainsKey((int)c);
+ }
+ else
+ return base.CharExists(c);
+ }
+
+ public override bool SetKerning(int char1, int char2, int kern) {
+ return false;
+ }
+
+ public override int[] GetCharBBox(int c) {
+ return null;
+ }
+
+ protected override int[] GetRawCharBBox(int c, String name) {
+ return null;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/EnumerateTTC.cs b/iTechSharp/iTextSharp/text/pdf/EnumerateTTC.cs
new file mode 100644
index 0000000..88398fe
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/EnumerateTTC.cs
@@ -0,0 +1,123 @@
+using System;
+using System.IO;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * $Id: EnumerateTTC.cs,v 1.3 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Enumerates all the fonts inside a True Type Collection.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ internal class EnumerateTTC : TrueTypeFont {
+
+ protected String[] names;
+
+ internal EnumerateTTC(String ttcFile) {
+ fileName = ttcFile;
+ rf = new RandomAccessFileOrArray(ttcFile);
+ FindNames();
+ }
+
+ internal EnumerateTTC(byte[] ttcArray) {
+ fileName = "Byte array TTC";
+ rf = new RandomAccessFileOrArray(ttcArray);
+ FindNames();
+ }
+
+ internal void FindNames() {
+ tables = new Hashtable();
+
+ try {
+ String mainTag = ReadStandardString(4);
+ if (!mainTag.Equals("ttcf"))
+ throw new DocumentException(fileName + " is not a valid TTC file.");
+ rf.SkipBytes(4);
+ int dirCount = rf.ReadInt();
+ names = new String[dirCount];
+ int dirPos = rf.FilePointer;
+ for (int dirIdx = 0; dirIdx < dirCount; ++dirIdx) {
+ tables.Clear();
+ rf.Seek(dirPos);
+ rf.SkipBytes(dirIdx * 4);
+ directoryOffset = rf.ReadInt();
+ rf.Seek(directoryOffset);
+ if (rf.ReadInt() != 0x00010000)
+ throw new DocumentException(fileName + " is not a valid TTF file.");
+ int num_tables = rf.ReadUnsignedShort();
+ rf.SkipBytes(6);
+ for (int k = 0; k < num_tables; ++k) {
+ String tag = ReadStandardString(4);
+ rf.SkipBytes(4);
+ int[] table_location = new int[2];
+ table_location[0] = rf.ReadInt();
+ table_location[1] = rf.ReadInt();
+ tables[tag] = table_location;
+ }
+ names[dirIdx] = this.BaseFont;
+ }
+ }
+ finally {
+ if (rf != null)
+ rf.Close();
+ }
+ }
+
+ internal String[] Names {
+ get {
+ return names;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/ExtendedColor.cs b/iTechSharp/iTextSharp/text/pdf/ExtendedColor.cs
new file mode 100644
index 0000000..b12e3c9
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/ExtendedColor.cs
@@ -0,0 +1,101 @@
+using System;
+
+using iTextSharp.text;
+
+/*
+ * $Id: ExtendedColor.cs,v 1.4 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ //public class ExtendedColor : Color {
+ public abstract class ExtendedColor : Color {
+
+ internal const int TYPE_RGB = 0;
+ internal const int TYPE_GRAY = 1;
+ internal const int TYPE_CMYK = 2;
+ internal const int TYPE_SEPARATION = 3;
+ internal const int TYPE_PATTERN = 4;
+ internal const int TYPE_SHADING = 5;
+
+ protected int type;
+
+ public ExtendedColor(int type) : base(0, 0, 0) {
+ this.type = type;
+ }
+
+ public ExtendedColor(int type, float red, float green, float blue) : base(Normalize(red), Normalize(green), Normalize(blue)) {
+ this.type = type;
+ }
+
+ public int Type {
+ get {
+ return type;
+ }
+ }
+
+ public static int GetType(object color) {
+ if (color is ExtendedColor)
+ return ((ExtendedColor)color).Type;
+ return TYPE_RGB;
+ }
+
+ internal static float Normalize(float value) {
+ if (value < 0)
+ return 0;
+ if (value > 1)
+ return 1;
+ return (float)value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/FdfReader.cs b/iTechSharp/iTextSharp/text/pdf/FdfReader.cs
new file mode 100644
index 0000000..cb7e23b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/FdfReader.cs
@@ -0,0 +1,218 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Net;
+using System.IO;
+
+/*
+ * Copyright 2003 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /** Reads an FDF form and makes the fields available
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class FdfReader : PdfReader {
+
+ internal Hashtable fields;
+ internal String fileSpec;
+ internal PdfName encoding;
+
+ /** Reads an FDF form.
+ * @param filename the file name of the form
+ * @throws IOException on error
+ */
+ public FdfReader(String filename) : base(filename) {
+ }
+
+ /** Reads an FDF form.
+ * @param pdfIn the byte array with the form
+ * @throws IOException on error
+ */
+ public FdfReader(byte[] pdfIn) : base(pdfIn) {
+ }
+
+ /** Reads an FDF form.
+ * @param url the URL of the document
+ * @throws IOException on error
+ */
+ public FdfReader(Uri url) : base(url) {
+ }
+
+ /** Reads an FDF form.
+ * @param is the InputStream
containing the document. The stream is read to the
+ * end but is not closed
+ * @throws IOException on error
+ */
+ public FdfReader(Stream isp) : base(isp) {
+ }
+
+ protected internal override void ReadPdf() {
+ fields = new Hashtable();
+ try {
+ tokens.CheckFdfHeader();
+ RebuildXref();
+ ReadDocObj();
+ }
+ finally {
+ try {
+ tokens.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ ReadFields();
+ }
+
+ protected virtual void KidNode(PdfDictionary merged, String name) {
+ PdfArray kids = (PdfArray)GetPdfObject(merged.Get(PdfName.KIDS));
+ if (kids == null || kids.ArrayList.Count == 0) {
+ if (name.Length > 0)
+ name = name.Substring(1);
+ fields[name] = merged;
+ }
+ else {
+ merged.Remove(PdfName.KIDS);
+ ArrayList ar = kids.ArrayList;
+ for (int k = 0; k < ar.Count; ++k) {
+ PdfDictionary dic = new PdfDictionary();
+ dic.Merge(merged);
+ PdfDictionary newDic = (PdfDictionary)GetPdfObject((PdfObject)ar[k]);
+ PdfString t = (PdfString)GetPdfObject(newDic.Get(PdfName.T));
+ String newName = name;
+ if (t != null)
+ newName += "." + t.ToUnicodeString();
+ dic.Merge(newDic);
+ dic.Remove(PdfName.T);
+ KidNode(dic, newName);
+ }
+ }
+ }
+
+ protected virtual void ReadFields() {
+ catalog = (PdfDictionary)GetPdfObject(trailer.Get(PdfName.ROOT));
+ PdfDictionary fdf = (PdfDictionary)GetPdfObject(catalog.Get(PdfName.FDF));
+ if (fdf == null)
+ return;
+ PdfString fs = (PdfString)GetPdfObject(fdf.Get(PdfName.F));
+ if (fs != null)
+ fileSpec = fs.ToUnicodeString();
+ PdfArray fld = (PdfArray)GetPdfObject(fdf.Get(PdfName.FIELDS));
+ if (fld == null)
+ return;
+ encoding = (PdfName)GetPdfObject(fdf.Get(PdfName.ENCODING));
+ PdfDictionary merged = new PdfDictionary();
+ merged.Put(PdfName.KIDS, fld);
+ KidNode(merged, "");
+ }
+
+ /** Gets all the fields. The map is keyed by the fully qualified
+ * field name and the value is a merged PdfDictionary
+ * with the field content.
+ * @return all the fields
+ */
+ public Hashtable Fields {
+ get {
+ return fields;
+ }
+ }
+
+ /** Gets the field dictionary.
+ * @param name the fully qualified field name
+ * @return the field dictionary
+ */
+ public PdfDictionary GetField(String name) {
+ return (PdfDictionary)fields[name];
+ }
+
+ /** Gets the field value or null
if the field does not
+ * exist or has no value defined.
+ * @param name the fully qualified field name
+ * @return the field value or null
+ */
+ public String GetFieldValue(String name) {
+ PdfDictionary field = (PdfDictionary)fields[name];
+ if (field == null)
+ return null;
+ PdfObject v = GetPdfObject(field.Get(PdfName.V));
+ if (v == null)
+ return null;
+ if (v.IsName())
+ return PdfName.DecodeName(((PdfName)v).ToString());
+ else if (v.IsString()) {
+ PdfString vs = (PdfString)v;
+ if (encoding == null || vs.Encoding != null)
+ return vs.ToUnicodeString();
+ byte[] b = vs.GetBytes();
+ if (b.Length >= 2 && b[0] == (byte)254 && b[1] == (byte)255)
+ return vs.ToUnicodeString();
+ try {
+ if (encoding.Equals(PdfName.SHIFT_JIS))
+ return Encoding.GetEncoding(932).GetString(b);
+ else if (encoding.Equals(PdfName.UHC))
+ return Encoding.GetEncoding(949).GetString(b);
+ else if (encoding.Equals(PdfName.GBK))
+ return Encoding.GetEncoding(936).GetString(b);
+ else if (encoding.Equals(PdfName.BIGFIVE))
+ return Encoding.GetEncoding(950).GetString(b);
+ }
+ catch {
+ }
+ return vs.ToUnicodeString();
+ }
+ return null;
+ }
+
+ /** Gets the PDF file specification contained in the FDF.
+ * @return the PDF file specification contained in the FDF
+ */
+ public String FileSpec {
+ get {
+ return fileSpec;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/FdfWriter.cs b/iTechSharp/iTextSharp/text/pdf/FdfWriter.cs
new file mode 100644
index 0000000..864a217
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/FdfWriter.cs
@@ -0,0 +1,324 @@
+using System;
+using System.util;
+using System.IO;
+using System.Collections;
+
+/*
+ * Copyright 2003 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /** Writes an FDF form.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class FdfWriter {
+ private static readonly byte[] HEADER_FDF = DocWriter.GetISOBytes("%FDF-1.2\n%\u00e2\u00e3\u00cf\u00d3\n");
+ Hashtable fields = new Hashtable();
+
+ /** The PDF file associated with the FDF. */
+ private String file;
+
+ /** Creates a new FdfWriter. */
+ public FdfWriter() {
+ }
+
+ /** Writes the content to a stream.
+ * @param os the stream
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public void WriteTo(Stream os) {
+ Wrt wrt = new Wrt(os, this);
+ wrt.WriteTo();
+ }
+
+ internal bool SetField(String field, PdfObject value) {
+ Hashtable map = fields;
+ StringTokenizer tk = new StringTokenizer(field, ".");
+ if (!tk.HasMoreTokens())
+ return false;
+ while (true) {
+ String s = tk.NextToken();
+ Object obj = map[s];
+ if (tk.HasMoreTokens()) {
+ if (obj == null) {
+ obj = new Hashtable();
+ map[s] = obj;
+ map = (Hashtable)obj;
+ continue;
+ }
+ else if (obj is Hashtable)
+ map = (Hashtable)obj;
+ else
+ return false;
+ }
+ else {
+ if (!(obj is Hashtable)) {
+ map[s] = value;
+ return true;
+ }
+ else
+ return false;
+ }
+ }
+ }
+
+ internal void IterateFields(Hashtable values, Hashtable map, String name) {
+ foreach (DictionaryEntry entry in map) {
+ String s = (String)entry.Key;
+ Object obj = entry.Value;
+ if (obj is Hashtable)
+ IterateFields(values, (Hashtable)obj, name + "." + s);
+ else
+ values[(name + "." + s).Substring(1)] = obj;
+ }
+ }
+
+ /** Removes the field value.
+ * @param field the field name
+ * @return true
if the field was found and removed,
+ * false
otherwise
+ */
+ public bool RemoveField(String field) {
+ Hashtable map = fields;
+ StringTokenizer tk = new StringTokenizer(field, ".");
+ if (!tk.HasMoreTokens())
+ return false;
+ ArrayList hist = new ArrayList();
+ while (true) {
+ String s = tk.NextToken();
+ Object obj = map[s];
+ if (obj == null)
+ return false;
+ hist.Add(map);
+ hist.Add(s);
+ if (tk.HasMoreTokens()) {
+ if (obj is Hashtable)
+ map = (Hashtable)obj;
+ else
+ return false;
+ }
+ else {
+ if (obj is Hashtable)
+ return false;
+ else
+ break;
+ }
+ }
+ for (int k = hist.Count - 2; k >= 0; k -= 2) {
+ map = (Hashtable)hist[k];
+ String s = (String)hist[k + 1];
+ map.Remove(s);
+ if (map.Count > 0)
+ break;
+ }
+ return true;
+ }
+
+ /** Gets all the fields. The map is keyed by the fully qualified
+ * field name and the values are PdfObject
.
+ * @return a map with all the fields
+ */
+ public Hashtable GetFields() {
+ Hashtable values = new Hashtable();
+ IterateFields(values, fields, "");
+ return values;
+ }
+
+ /** Gets the field value.
+ * @param field the field name
+ * @return the field value or null
if not found
+ */
+ public String GetField(String field) {
+ Hashtable map = fields;
+ StringTokenizer tk = new StringTokenizer(field, ".");
+ if (!tk.HasMoreTokens())
+ return null;
+ while (true) {
+ String s = tk.NextToken();
+ Object obj = map[s];
+ if (obj == null)
+ return null;
+ if (tk.HasMoreTokens()) {
+ if (obj is Hashtable)
+ map = (Hashtable)obj;
+ else
+ return null;
+ }
+ else {
+ if (obj is Hashtable)
+ return null;
+ else {
+ if (((PdfObject)obj).IsString())
+ return ((PdfString)obj).ToUnicodeString();
+ else
+ return PdfName.DecodeName(obj.ToString());
+ }
+ }
+ }
+ }
+
+ /** Sets the field value as a name.
+ * @param field the fully qualified field name
+ * @param value the value
+ * @return true
if the value was inserted,
+ * false
if the name is incompatible with
+ * an existing field
+ */
+ public bool SetFieldAsName(String field, String value) {
+ return SetField(field, new PdfName(value));
+ }
+
+ /** Sets the field value as a string.
+ * @param field the fully qualified field name
+ * @param value the value
+ * @return true
if the value was inserted,
+ * false
if the name is incompatible with
+ * an existing field
+ */
+ public bool SetFieldAsString(String field, String value) {
+ return SetField(field, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+
+ /** Sets all the fields from this FdfReader
+ * @param fdf the FdfReader
+ */
+ public void SetFields(FdfReader fdf) {
+ Hashtable map = fdf.Fields;
+ foreach (DictionaryEntry entry in map) {
+ String key = (String)entry.Key;
+ PdfDictionary dic = (PdfDictionary)entry.Value;
+ PdfObject v = dic.Get(PdfName.V);
+ if (v != null) {
+ SetField(key, v);
+ }
+ }
+ }
+
+ /** Sets all the fields from this PdfReader
+ * @param pdf the PdfReader
+ */
+ public void SetFields(PdfReader pdf) {
+ SetFields(pdf.AcroFields);
+ }
+
+ /** Sets all the fields from this AcroFields
+ * @param acro the AcroFields
+ */
+ public void SetFields(AcroFields af) {
+ foreach (DictionaryEntry entry in af.Fields) {
+ String fn = (String)entry.Key;
+ AcroFields.Item item = (AcroFields.Item)entry.Value;
+ PdfDictionary dic = (PdfDictionary)item.merged[0];
+ PdfObject v = PdfReader.GetPdfObjectRelease(dic.Get(PdfName.V));
+ if (v == null)
+ continue;
+ PdfObject ft = PdfReader.GetPdfObjectRelease(dic.Get(PdfName.FT));
+ if (ft == null || PdfName.SIG.Equals(ft))
+ continue;
+ SetField(fn, v);
+ }
+ }
+
+ /** Gets the PDF file name associated with the FDF.
+ * @return the PDF file name associated with the FDF
+ */
+ public String File {
+ get {
+ return this.file;
+ }
+ set {
+ file = value;
+ }
+ }
+
+ internal class Wrt : PdfWriter {
+ private FdfWriter fdf;
+
+ internal Wrt(Stream os, FdfWriter fdf) : base(new PdfDocument(), os) {
+ this.fdf = fdf;
+ this.os.Write(HEADER_FDF, 0, HEADER_FDF.Length);
+ body = new PdfBody(this);
+ }
+
+ internal void WriteTo() {
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.FIELDS, Calculate(fdf.fields));
+ if (fdf.file != null)
+ dic.Put(PdfName.F, new PdfString(fdf.file, PdfObject.TEXT_UNICODE));
+ PdfDictionary fd = new PdfDictionary();
+ fd.Put(PdfName.FDF, dic);
+ PdfIndirectReference refi = AddToBody(fd).IndirectReference;
+ byte[] b = GetISOBytes("trailer\n");
+ os.Write(b, 0, b.Length);
+ PdfDictionary trailer = new PdfDictionary();
+ trailer.Put(PdfName.ROOT, refi);
+ trailer.ToPdf(null, os);
+ b = GetISOBytes("\n%%EOF\n");
+ os.Write(b, 0, b.Length);
+ os.Close();
+ }
+
+
+ internal PdfArray Calculate(Hashtable map) {
+ PdfArray ar = new PdfArray();
+ foreach (DictionaryEntry entry in map) {
+ String key = (String)entry.Key;
+ Object v = entry.Value;
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.T, new PdfString(key, PdfObject.TEXT_UNICODE));
+ if (v is Hashtable) {
+ dic.Put(PdfName.KIDS, Calculate((Hashtable)v));
+ }
+ else {
+ dic.Put(PdfName.V, (PdfObject)v);
+ }
+ ar.Add(dic);
+ }
+ return ar;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/FontDetails.cs b/iTechSharp/iTextSharp/text/pdf/FontDetails.cs
new file mode 100644
index 0000000..8e56bb1
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/FontDetails.cs
@@ -0,0 +1,278 @@
+using System;
+using System.Collections;
+using System.util;
+using iTextSharp.text;
+
+/*
+ * $Id: FontDetails.cs,v 1.7 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Each font in the document will have an instance of this class
+ * where the characters used will be represented.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ internal class FontDetails {
+
+ /** The indirect reference to this font
+ */
+ PdfIndirectReference indirectReference;
+ /** The font name that appears in the document body stream
+ */
+ PdfName fontName;
+ /** The font
+ */
+ BaseFont baseFont;
+ /** The font if its an instance of TrueTypeFontUnicode
+ */
+ TrueTypeFontUnicode ttu;
+
+ CJKFont cjkFont;
+ /** The array used with single byte encodings
+ */
+ byte[] shortTag;
+ /** The map used with double byte encodings. The key is Int(glyph) and the
+ * value is int[]{glyph, width, Unicode code}
+ */
+ Hashtable longTag;
+
+ IntHashtable cjkTag;
+ /** The font type
+ */
+ int fontType;
+ /** true
if the font is symbolic
+ */
+ bool symbolic;
+ /** Indicates if all the glyphs and widths for that particular
+ * encoding should be included in the document.
+ */
+ protected bool subset = true;
+ /** Each font used in a document has an instance of this class.
+ * This class stores the characters used in the document and other
+ * specifics unique to the current working document.
+ * @param fontName the font name
+ * @param indirectReference the indirect reference to the font
+ * @param baseFont the BaseFont
+ */
+ internal FontDetails(PdfName fontName, PdfIndirectReference indirectReference, BaseFont baseFont) {
+ this.fontName = fontName;
+ this.indirectReference = indirectReference;
+ this.baseFont = baseFont;
+ fontType = baseFont.FontType;
+ switch (fontType) {
+ case BaseFont.FONT_TYPE_T1:
+ case BaseFont.FONT_TYPE_TT:
+ shortTag = new byte[256];
+ break;
+ case BaseFont.FONT_TYPE_CJK:
+ cjkTag = new IntHashtable();
+ cjkFont = (CJKFont)baseFont;
+ break;
+ case BaseFont.FONT_TYPE_TTUNI:
+ longTag = new Hashtable();
+ ttu = (TrueTypeFontUnicode)baseFont;
+ symbolic = baseFont.IsFontSpecific();
+ break;
+ }
+ }
+
+ /** Gets the indirect reference to this font.
+ * @return the indirect reference to this font
+ */
+ internal PdfIndirectReference IndirectReference {
+ get {
+ return indirectReference;
+ }
+ }
+
+ /** Gets the font name as it appears in the document body.
+ * @return the font name
+ */
+ internal PdfName FontName {
+ get {
+ return fontName;
+ }
+ }
+
+ /** Gets the BaseFont
of this font.
+ * @return the BaseFont
of this font
+ */
+ internal BaseFont BaseFont {
+ get {
+ return baseFont;
+ }
+ }
+
+ /** Converts the text into bytes to be placed in the document.
+ * The conversion is done according to the font and the encoding and the characters
+ * used are stored.
+ * @param text the text to convert
+ * @return the conversion
+ */
+ internal byte[] ConvertToBytes(string text) {
+ byte[] b = null;
+ switch (fontType) {
+ case BaseFont.FONT_TYPE_T3:
+ return baseFont.ConvertToBytes(text);
+ case BaseFont.FONT_TYPE_T1:
+ case BaseFont.FONT_TYPE_TT: {
+ b = baseFont.ConvertToBytes(text);
+ int len = b.Length;
+ for (int k = 0; k < len; ++k)
+ shortTag[((int)b[k]) & 0xff] = 1;
+ break;
+ }
+ case BaseFont.FONT_TYPE_CJK: {
+ int len = text.Length;
+ for (int k = 0; k < len; ++k)
+ cjkTag[cjkFont.GetCidCode(text[k])] = 0;
+ b = baseFont.ConvertToBytes(text);
+ break;
+ }
+ case BaseFont.FONT_TYPE_DOCUMENT: {
+ b = baseFont.ConvertToBytes(text);
+ break;
+ }
+ case BaseFont.FONT_TYPE_TTUNI: {
+ int len = text.Length;
+ int[] metrics = null;
+ char[] glyph = new char[len];
+ int i = 0;
+ if (symbolic) {
+ b = PdfEncodings.ConvertToBytes(text, "symboltt");
+ len = b.Length;
+ for (int k = 0; k < len; ++k) {
+ metrics = ttu.GetMetricsTT(b[k] & 0xff);
+ if (metrics == null)
+ continue;
+ longTag[metrics[0]] = new int[]{metrics[0], metrics[1], ttu.GetUnicodeDifferences(b[k] & 0xff)};
+ glyph[i++] = (char)metrics[0];
+ }
+ }
+ else {
+ for (int k = 0; k < len; ++k) {
+ int val;
+ if (Utilities.IsSurrogatePair(text, k)) {
+ val = Utilities.ConvertToUtf32(text, k);
+ k++;
+ }
+ else {
+ val = (int)text[k];
+ }
+ metrics = ttu.GetMetricsTT(val);
+ if (metrics == null)
+ continue;
+ int m0 = metrics[0];
+ int gl = m0;
+ if (!longTag.ContainsKey(gl))
+ longTag[gl] = new int[]{m0, metrics[1], val};
+ glyph[i++] = (char)m0;
+ }
+ }
+ string s = new String(glyph, 0, i);
+ b = PdfEncodings.ConvertToBytes(s, CJKFont.CJK_ENCODING);
+ break;
+ }
+ }
+ return b;
+ }
+
+ /** Writes the font definition to the document.
+ * @param writer the PdfWriter
of this document
+ */
+ internal void WriteFont(PdfWriter writer) {
+ switch (fontType) {
+ case BaseFont.FONT_TYPE_T3:
+ baseFont.WriteFont(writer, indirectReference, null);
+ break;
+ case BaseFont.FONT_TYPE_T1:
+ case BaseFont.FONT_TYPE_TT: {
+ int firstChar;
+ int lastChar;
+ for (firstChar = 0; firstChar < 256; ++firstChar) {
+ if (shortTag[firstChar] != 0)
+ break;
+ }
+ for (lastChar = 255; lastChar >= firstChar; --lastChar) {
+ if (shortTag[lastChar] != 0)
+ break;
+ }
+ if (firstChar > 255) {
+ firstChar = 255;
+ lastChar = 255;
+ }
+ baseFont.WriteFont(writer, indirectReference, new Object[]{firstChar, lastChar, shortTag, subset});
+ break;
+ }
+ case BaseFont.FONT_TYPE_CJK:
+ baseFont.WriteFont(writer, indirectReference, new Object[]{cjkTag});
+ break;
+ case BaseFont.FONT_TYPE_TTUNI:
+ baseFont.WriteFont(writer, indirectReference, new Object[]{longTag, subset});
+ break;
+ }
+ }
+
+ /** Indicates if all the glyphs and widths for that particular
+ * encoding should be included in the document. Set to false
+ * to include all.
+ * @param subset new value of property subset
+ */
+ public bool Subset {
+ set {
+ this.subset = value;
+ }
+ get {
+ return subset;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/FontSelector.cs b/iTechSharp/iTextSharp/text/pdf/FontSelector.cs
new file mode 100644
index 0000000..41cb9f3
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/FontSelector.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections;
+using System.Text;
+using iTextSharp.text;
+/*
+ * Copyright 2003 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** Selects the appropriate fonts that contain the glyphs needed to
+ * render text correctly. The fonts are checked in order until the
+ * character is found.
+ * Font
to be searched for valid characters.
+ * @param font the Font
+ */
+ public void AddFont(Font font) {
+ if (font.BaseFont != null) {
+ fonts.Add(font);
+ return;
+ }
+ BaseFont bf = font.GetCalculatedBaseFont(true);
+ Font f2 = new Font(bf, font.Size, font.CalculatedStyle, font.Color);
+ fonts.Add(f2);
+ }
+
+ /**
+ * Process the text so that it will render with a combination of fonts
+ * if needed.
+ * @param text the text
+ * @return a Phrase
with one or more chunks
+ */
+ public Phrase Process(String text) {
+ int fsize = fonts.Count;
+ if (fsize == 0)
+ throw new ArgumentException("No font is defined.");
+ char[] cc = text.ToCharArray();
+ int len = cc.Length;
+ StringBuilder sb = new StringBuilder();
+ Font font = null;
+ int lastidx = -1;
+ Phrase ret = new Phrase();
+ for (int k = 0; k < len; ++k) {
+ char c = cc[k];
+ if (c == '\n' || c == '\r') {
+ sb.Append(c);
+ continue;
+ }
+ if (Utilities.IsSurrogatePair(cc, k)) {
+ int u = Utilities.ConvertToUtf32(cc, k);
+ for (int f = 0; f < fsize; ++f) {
+ font = (Font)fonts[f];
+ if (font.BaseFont.CharExists(u)) {
+ if (lastidx != f) {
+ if (sb.Length > 0 && lastidx != -1) {
+ Chunk ck = new Chunk(sb.ToString(), (Font)fonts[lastidx]);
+ ret.Add(ck);
+ sb.Length = 0;
+ }
+ lastidx = f;
+ }
+ sb.Append(c);
+ sb.Append(cc[++k]);
+ break;
+ }
+ }
+ }
+ else {
+ for (int f = 0; f < fsize; ++f) {
+ font = (Font)fonts[f];
+ if (font.BaseFont.CharExists(c)) {
+ if (lastidx != f) {
+ if (sb.Length > 0 && lastidx != -1) {
+ Chunk ck = new Chunk(sb.ToString(), (Font)fonts[lastidx]);
+ ret.Add(ck);
+ sb.Length = 0;
+ }
+ lastidx = f;
+ }
+ sb.Append(c);
+ break;
+ }
+ }
+ }
+ }
+ if (sb.Length > 0) {
+ Chunk ck = new Chunk(sb.ToString(), (Font)fonts[lastidx == -1 ? 0 : lastidx]);
+ ret.Add(ck);
+ }
+ return ret;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/GlyphList.cs b/iTechSharp/iTextSharp/text/pdf/GlyphList.cs
new file mode 100644
index 0000000..9ba1c7a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/GlyphList.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Globalization;
+using System.util;
+
+/*
+ * $Id: GlyphList.cs,v 1.7 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ public class GlyphList {
+ private static Hashtable unicode2names = new Hashtable();
+ private static Hashtable names2unicode = new Hashtable();
+
+ static GlyphList() {
+ Stream istr = null;
+ try {
+ istr = BaseFont.GetResourceStream(BaseFont.RESOURCE_PATH + "glyphlist.txt");
+ if (istr == null) {
+ String msg = "glyphlist.txt not found as resource.";
+ throw new Exception(msg);
+ }
+ byte[] buf = new byte[1024];
+ MemoryStream outp = new MemoryStream();
+ while (true) {
+ int size = istr.Read(buf, 0, buf.Length);
+ if (size == 0)
+ break;
+ outp.Write(buf, 0, size);
+ }
+ istr.Close();
+ istr = null;
+ String s = PdfEncodings.ConvertToString(outp.ToArray(), null);
+ StringTokenizer tk = new StringTokenizer(s, "\r\n");
+ while (tk.HasMoreTokens()) {
+ String line = tk.NextToken();
+ if (line.StartsWith("#"))
+ continue;
+ StringTokenizer t2 = new StringTokenizer(line, " ;\r\n\t\f");
+ String name = null;
+ String hex = null;
+ if (!t2.HasMoreTokens())
+ continue;
+ name = t2.NextToken();
+ if (!t2.HasMoreTokens())
+ continue;
+ hex = t2.NextToken();
+ int num = int.Parse(hex, NumberStyles.HexNumber);
+ unicode2names[num] = name;
+ names2unicode[name] = new int[]{num};
+ }
+ }
+ catch (Exception e) {
+ Console.Error.WriteLine("glyphlist.txt loading error: " + e.Message);
+ }
+ finally {
+ if (istr != null) {
+ try {
+ istr.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+ }
+
+ public static int[] NameToUnicode(string name) {
+ return (int[])names2unicode[name];
+ }
+
+ public static string UnicodeToName(int num) {
+ return (string)unicode2names[num];
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/GrayColor.cs b/iTechSharp/iTextSharp/text/pdf/GrayColor.cs
new file mode 100644
index 0000000..ea3c9c8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/GrayColor.cs
@@ -0,0 +1,86 @@
+using System;
+
+/*
+ * $Id: GrayColor.cs,v 1.5 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class GrayColor : ExtendedColor {
+
+ private float cgray;
+
+ public static readonly GrayColor GRAYBLACK = new GrayColor(0f);
+ public static readonly GrayColor GRAYWHITE = new GrayColor(1f);
+
+ public GrayColor(int intGray) : this((float)intGray / 255f) {}
+
+ public GrayColor(float floatGray) : base(TYPE_GRAY, floatGray, floatGray, floatGray) {
+ cgray = Normalize(floatGray);
+ }
+
+ public float Gray {
+ get {
+ return cgray;
+ }
+ }
+
+ public override bool Equals(Object obj) {
+ return (obj is GrayColor) && ((GrayColor)obj).cgray == this.cgray;
+ }
+
+ public override int GetHashCode() {
+ return cgray.GetHashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/HyphenationAuto.cs b/iTechSharp/iTextSharp/text/pdf/HyphenationAuto.cs
new file mode 100644
index 0000000..1d665c3
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/HyphenationAuto.cs
@@ -0,0 +1,130 @@
+using System;
+
+using iTextSharp.text.pdf.hyphenation;
+
+/*
+ * Copyright 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Hyphenates words automatically accordingly to the language and country.
+ * The hyphenator engine was taken from FOP and uses the TEX patterns. If a language
+ * is not provided and a TEX pattern for it exists, it can be easily adapted.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class HyphenationAuto : IHyphenationEvent {
+
+ /** The hyphenator engine.
+ */
+ protected Hyphenator hyphenator;
+ /** The second part of the hyphenated word.
+ */
+ protected string post;
+
+ /** Creates a new hyphenation instance usable in Chunk
.
+ * @param lang the language ("en" for english, for example)
+ * @param country the country ("GB" for Great-Britain or "none" for no country, for example)
+ * @param leftMin the minimun number of letters before the hyphen
+ * @param rightMin the minimun number of letters after the hyphen
+ */
+ public HyphenationAuto(string lang, string country, int leftMin, int rightMin) {
+ hyphenator = new Hyphenator(lang, country, leftMin, rightMin);
+ }
+
+ /** Gets the hyphen symbol.
+ * @return the hyphen symbol
+ */
+ public string HyphenSymbol {
+ get {
+ return "-";
+ }
+ }
+
+ /** Hyphenates a word and returns the first part of it. To get
+ * the second part of the hyphenated word call getHyphenatedWordPost()
.
+ * @param word the word to hyphenate
+ * @param font the font used by this word
+ * @param fontSize the font size used by this word
+ * @param remainingWidth the width available to fit this word in
+ * @return the first part of the hyphenated word including
+ * the hyphen symbol, if any
+ */
+ public string GetHyphenatedWordPre(string word, BaseFont font, float fontSize, float remainingWidth) {
+ post = word;
+ string hyphen = this.HyphenSymbol;
+ float hyphenWidth = font.GetWidthPoint(hyphen, fontSize);
+ if (hyphenWidth > remainingWidth)
+ return "";
+ Hyphenation hyphenation = hyphenator.Hyphenate(word);
+ if (hyphenation == null) {
+ return "";
+ }
+ int len = hyphenation.Length;
+ int k;
+ for (k = 0; k < len; ++k) {
+ if (font.GetWidthPoint(hyphenation.GetPreHyphenText(k), fontSize) + hyphenWidth > remainingWidth)
+ break;
+ }
+ --k;
+ if (k < 0)
+ return "";
+ post = hyphenation.GetPostHyphenText(k);
+ return hyphenation.GetPreHyphenText(k) + hyphen;
+ }
+
+ /** Gets the second part of the hyphenated word. Must be called
+ * after getHyphenatedWordPre()
.
+ * @return the second part of the hyphenated word
+ */
+ public string HyphenatedWordPost {
+ get {
+ return post;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/ICC_Profile.cs b/iTechSharp/iTextSharp/text/pdf/ICC_Profile.cs
new file mode 100644
index 0000000..d2337e8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/ICC_Profile.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.IO;
+
+namespace iTextSharp.text.pdf
+{
+ /// PdfEncoding
.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public interface IExtraEncoding {
+
+ /**
+ * Converts an Unicode string to a byte array according to some encoding.
+ * @param text the Unicode string
+ * @param encoding the requested encoding. It's mainly of use if the same class
+ * supports more than one encoding.
+ * @return the conversion or null
if no conversion is supported
+ */
+ byte[] CharToByte(String text, String encoding);
+
+ /**
+ * Converts an Unicode char to a byte array according to some encoding.
+ * @param char1 the Unicode char
+ * @param encoding the requested encoding. It's mainly of use if the same class
+ * supports more than one encoding.
+ * @return the conversion or null
if no conversion is supported
+ */
+ byte[] CharToByte(char char1, String encoding);
+
+ /**
+ * Converts a byte array to an Unicode string according to some encoding.
+ * @param b the input byte array
+ * @param encoding the requested encoding. It's mainly of use if the same class
+ * supports more than one encoding.
+ * @return the conversion or null
if no conversion is supported
+ */
+ String ByteToChar(byte[] b, String encoding);
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/IHyphenationEvent.cs b/iTechSharp/iTextSharp/text/pdf/IHyphenationEvent.cs
new file mode 100644
index 0000000..5369ab8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/IHyphenationEvent.cs
@@ -0,0 +1,83 @@
+using System;
+
+/*
+ * Copyright 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** Called by Chunk
to hyphenate a word.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public interface IHyphenationEvent {
+
+ /** Gets the hyphen symbol.
+ * @return the hyphen symbol
+ */
+ string HyphenSymbol {
+ get;
+ }
+
+ /** Hyphenates a word and returns the first part of it. To get
+ * the second part of the hyphenated word call getHyphenatedWordPost()
.
+ * @param word the word to hyphenate
+ * @param font the font used by this word
+ * @param fontSize the font size used by this word
+ * @param remainingWidth the width available to fit this word in
+ * @return the first part of the hyphenated word including
+ * the hyphen symbol, if any
+ */
+ string GetHyphenatedWordPre(string word, BaseFont font, float fontSize, float remainingWidth);
+
+ /** Gets the second part of the hyphenated word. Must be called
+ * after getHyphenatedWordPre()
.
+ * @return the second part of the hyphenated word
+ */
+ string HyphenatedWordPost {
+ get;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/IPdfOCG.cs b/iTechSharp/iTextSharp/text/pdf/IPdfOCG.cs
new file mode 100644
index 0000000..1a6d4bf
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/IPdfOCG.cs
@@ -0,0 +1,73 @@
+using System;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * The interface common to all layer types.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public interface IPdfOCG {
+
+ /**
+ * Gets the PdfIndirectReference
that represents this layer.
+ * @return the PdfIndirectReference
that represents this layer
+ */
+ PdfIndirectReference Ref {
+ get;
+ }
+
+ /**
+ * Gets the object representing the layer.
+ * @return the object representing the layer
+ */
+ PdfObject PdfObject {
+ get;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/IPdfPCellEvent.cs b/iTechSharp/iTextSharp/text/pdf/IPdfPCellEvent.cs
new file mode 100644
index 0000000..bf4e680
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/IPdfPCellEvent.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace iTextSharp.text.pdf
+{
+ /// PdfContentByte
contained in
+ * canvases
.
+ * The indexes to canvases
are:
+ *
+ * The layers are placed in sequence on top of each other.
+ * PdfPTable.BASECANVAS
- the original PdfContentByte
. Anything placed here
+ * will be under the cell.
+ * PdfPTable.BACKGROUNDCANVAS
- the layer where the background goes to.
+ * PdfPTable.LINECANVAS
- the layer where the lines go to.
+ * PdfPTable.TEXTCANVAS
- the layer where the text go to. Anything placed here
+ * will be over the cell.
+ * PdfContentByte
+ */
+ void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases);
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/IPdfPTableEvent.cs b/iTechSharp/iTextSharp/text/pdf/IPdfPTableEvent.cs
new file mode 100644
index 0000000..0762633
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/IPdfPTableEvent.cs
@@ -0,0 +1,96 @@
+using System;
+
+/*
+ * $Id: IPdfPTableEvent.cs,v 1.3 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** An interface that can be used to retrieve the position of cells in PdfPTable
.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public interface IPdfPTableEvent {
+
+ /** This method is called at the end of the table rendering. The text or graphics are added to
+ * one of the 4 PdfContentByte
contained in
+ * canvases
.
+ * The indexes to canvases
are:
+ *
+ * The layers are placed in sequence on top of each other.
+ * PdfPTable.BASECANVAS
- the original PdfContentByte
. Anything placed here
+ * will be under the table.
+ * PdfPTable.BACKGROUNDCANVAS
- the layer where the background goes to.
+ * PdfPTable.LINECANVAS
- the layer where the lines go to.
+ * PdfPTable.TEXTCANVAS
- the layer where the text go to. Anything placed here
+ * will be over the table.
+ * widths
and heights
have the coordinates of the cells.
+ * The size of the widths
array is the number of rows.
+ * Each sub-array in widths
corresponds to the x column border positions where
+ * the first element is the x coordinate of the left table border and the last
+ * element is the x coordinate of the right table border.
+ * If colspan is not used all the sub-arrays in widths
+ * are the same.
+ * For the heights
the first element is the y coordinate of the top table border and the last
+ * element is the y coordinate of the bottom table border.
+ * @param table the PdfPTable
in use
+ * @param widths an array of arrays with the cells' x positions. It has the length of the number
+ * of rows
+ * @param heights an array with the cells' y positions. It has a length of the number
+ * of rows + 1
+ * @param headerRows the number of rows defined for the header.
+ * @param rowStart the first row number after the header
+ * @param canvases an array of PdfContentByte
+ */
+ void TableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases);
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/IPdfPageEvent.cs b/iTechSharp/iTextSharp/text/pdf/IPdfPageEvent.cs
new file mode 100644
index 0000000..b441107
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/IPdfPageEvent.cs
@@ -0,0 +1,189 @@
+using System;
+
+using iTextSharp.text;
+
+/*
+ * $Id: IPdfPageEvent.cs,v 1.3 2008/05/13 11:25:17 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * Allows a class to catch several document events.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+
+ public interface IPdfPageEvent {
+
+ /**
+ * Called when the document is opened.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ */
+ void OnOpenDocument(PdfWriter writer, Document document);
+
+ /**
+ * Called when a page is initialized.
+ * onEndPage
to avoid
+ * infinite loops.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ */
+ void OnStartPage(PdfWriter writer, Document document);
+
+ /**
+ * Called when a page is finished, just before being written to the document.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ */
+ void OnEndPage(PdfWriter writer, Document document);
+
+ /**
+ * Called when the document is closed.
+ * PdfWriter
for this document
+ * @param document the document
+ */
+ void OnCloseDocument(PdfWriter writer, Document document);
+
+ /**
+ * Called when a Paragraph is written.
+ * paragraphPosition
will hold the height at which the
+ * paragraph will be written to. This is useful to insert bookmarks with
+ * more control.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position the paragraph will be written to
+ */
+ void OnParagraph(PdfWriter writer, Document document, float paragraphPosition);
+
+ /**
+ * Called when a Paragraph is written.
+ * paragraphPosition
will hold the height of the end of the paragraph.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position of the end of the paragraph
+ */
+ void OnParagraphEnd(PdfWriter writer,Document document,float paragraphPosition);
+
+ /**
+ * Called when a Chapter is written.
+ * position
will hold the height at which the
+ * chapter will be written to.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position the chapter will be written to
+ * @param title the title of the Chapter
+ */
+ void OnChapter(PdfWriter writer,Document document,float paragraphPosition, Paragraph title);
+
+ /**
+ * Called when the end of a Chapter is reached.
+ * position
will hold the height of the end of the chapter.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position the chapter will be written to
+ */
+ void OnChapterEnd(PdfWriter writer,Document document,float paragraphPosition);
+
+ /**
+ * Called when a Section is written.
+ * position
will hold the height at which the
+ * section will be written to.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position the chapter will be written to
+ * @param title the title of the Chapter
+ */
+ void OnSection(PdfWriter writer,Document document,float paragraphPosition, int depth, Paragraph title);
+
+ /**
+ * Called when the end of a Section is reached.
+ * position
will hold the height of the section end.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position the chapter will be written to
+ */
+ void OnSectionEnd(PdfWriter writer,Document document,float paragraphPosition);
+
+ /**
+ * Called when a Chunk
with a generic tag is written.
+ * Chunk
location to generate
+ * bookmarks, for example.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param rect the Rectangle
containing the Chunk
+ * @param text the text of the tag
+ */
+ void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, string text);
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/IntHashtable.cs b/iTechSharp/iTextSharp/text/pdf/IntHashtable.cs
new file mode 100644
index 0000000..57aae9e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/IntHashtable.cs
@@ -0,0 +1,312 @@
+using System;
+
+// IntHashtable - a Hashtable that uses ints as the keys
+//
+// This is 90% based on JavaSoft's java.util.Hashtable.
+//
+// Visit the ACME Labs Java page for up-to-date versions of this and other
+// fine Java utilities: http://www.acme.com/java/
+
+namespace iTextSharp.text.pdf {
+
+ /// A Hashtable that uses ints as the keys.
+ //
+ // Fetch the entire Acme package.
+ // newstring
to the end of oldstring
.
+ */
+ public byte[] ComposeString(byte[] oldstring, byte newstring) {
+ int length = oldstring.Length;
+ byte[] str = new byte[length + 1];
+ Array.Copy(oldstring, 0, str, 0, length);
+ str[length] = newstring;
+
+ return str;
+ }
+
+ // Returns the next 9, 10, 11 or 12 bits
+ public int NextCode {
+ get {
+ // Attempt to get the next code. The exception is caught to make
+ // this robust to cases wherein the EndOfInformation code has been
+ // omitted from a strip. Examples of such cases have been observed
+ // in practice.
+ try {
+ nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
+ nextBits += 8;
+
+ if (nextBits < bitsToGet) {
+ nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
+ nextBits += 8;
+ }
+
+ int code =
+ (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet-9];
+ nextBits -= bitsToGet;
+
+ return code;
+ } catch {
+ // Strip not terminated as expected: return EndOfInformation code.
+ return 257;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/MultiColumnText.cs b/iTechSharp/iTextSharp/text/pdf/MultiColumnText.cs
new file mode 100644
index 0000000..3551982
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/MultiColumnText.cs
@@ -0,0 +1,605 @@
+using System;
+using System.Collections;
+using iTextSharp.text;
+/*
+ * $Id: MultiColumnText.cs,v 1.13 2008/05/13 11:25:18 psoares33 Exp $
+ *
+ *
+ * Copyright 2004 Steve Appling
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Formats content into one or more columns bounded by a
+ * rectangle. The columns may be simple rectangles or
+ * more complicated shapes. Add all of the columns before
+ * adding content. Column continuation is supported. A MultiColumnText object may be added to
+ * a document using Document.add
.
+ * @author Steve Appling
+ */
+ public class MultiColumnText : IElement {
+
+ /** special constant for automatic calculation of height */
+ public const float AUTOMATIC = -1f;
+
+ /**
+ * total desiredHeight of columns. If AUTOMATIC
, this means fill pages until done.
+ * This may be larger than one page
+ */
+ private float desiredHeight;
+
+ /**
+ * total height of element written out so far
+ */
+ private float totalHeight;
+
+ /**
+ * true if all the text could not be written out due to height restriction
+ */
+ private bool overflow;
+
+ /**
+ * Top of the columns - y position on starting page.
+ * If AUTOMATIC
, it means current y position when added to document
+ */
+ private float top;
+
+ /**
+ * used to store the y position of the bottom of the page
+ */
+ private float pageBottom;
+
+ /**
+ * ColumnText object used to do all the real work. This same object is used for all columns
+ */
+ private ColumnText columnText;
+
+ /**
+ * Array of ColumnDef
objects used to define the columns
+ */
+ private ArrayList columnDefs;
+
+ /**
+ * true if all columns are simple (rectangular)
+ */
+ private bool simple = true;
+
+ private int currentColumn = 0;
+
+ private float nextY = AUTOMATIC;
+
+ private bool columnsRightToLeft = false;
+
+ private PdfDocument document;
+ /**
+ * Default constructor. Sets height to AUTOMATIC
.
+ * Columns will repeat on each page as necessary to accomodate content length.
+ */
+ public MultiColumnText() : this(AUTOMATIC) {
+ }
+
+ /**
+ * Construct a MultiColumnText container of the specified height.
+ * If height is AUTOMATIC
, fill complete pages until done.
+ * If a specific height is used, it may span one or more pages.
+ *
+ * @param height
+ */
+ public MultiColumnText(float height) {
+ columnDefs = new ArrayList();
+ desiredHeight = height;
+ top = AUTOMATIC;
+ // canvas will be set later
+ columnText = new ColumnText(null);
+ totalHeight = 0f;
+ }
+
+ /**
+ * Construct a MultiColumnText container of the specified height
+ * starting at the specified Y position.
+ *
+ * @param height
+ * @param top
+ */
+ public MultiColumnText(float top, float height) {
+ columnDefs = new ArrayList();
+ desiredHeight = height;
+ this.top = top;
+ nextY = top;
+ // canvas will be set later
+ columnText = new ColumnText(null);
+ totalHeight = 0f;
+ }
+
+ /**
+ * Indicates that all of the text did not fit in the
+ * specified height. Note that isOverflow will return
+ * false before the MultiColumnText object has been
+ * added to the document. It will always be false if
+ * the height is AUTOMATIC.
+ *
+ * @return true if there is still space left in the column
+ */
+ public bool IsOverflow() {
+ return overflow;
+ }
+
+ /**
+ * Copy the parameters from the specified ColumnText to use
+ * when rendering. Parameters like setArabicOptions
+ * must be set in this way.
+ *
+ * @param sourceColumn
+ */
+ public void UseColumnParams(ColumnText sourceColumn) {
+ // note that canvas will be overwritten later
+ columnText.SetSimpleVars(sourceColumn);
+ }
+
+ /**
+ * Add a new column. The parameters are limits for each column
+ * wall in the format of a sequence of points (x1,y1,x2,y2,...).
+ *
+ * @param left limits for left column
+ * @param right limits for right column
+ */
+ public void AddColumn(float[] left, float[] right) {
+ ColumnDef nextDef = new ColumnDef(left, right, this);
+ simple = nextDef.IsSimple();
+ columnDefs.Add(nextDef);
+ }
+
+ /**
+ * Add a simple rectangular column with specified left
+ * and right x position boundaries.
+ *
+ * @param left left boundary
+ * @param right right boundary
+ */
+ public void AddSimpleColumn(float left, float right) {
+ ColumnDef newCol = new ColumnDef(left, right, this);
+ columnDefs.Add(newCol);
+ }
+
+ /**
+ * Add the specified number of evenly spaced rectangular columns.
+ * Columns will be seperated by the specified gutterWidth.
+ *
+ * @param left left boundary of first column
+ * @param right right boundary of last column
+ * @param gutterWidth width of gutter spacing between columns
+ * @param numColumns number of columns to add
+ */
+ public void AddRegularColumns(float left, float right, float gutterWidth, int numColumns) {
+ float currX = left;
+ float width = right - left;
+ float colWidth = (width - (gutterWidth * (numColumns - 1))) / numColumns;
+ for (int i = 0; i < numColumns; i++) {
+ AddSimpleColumn(currX, currX + colWidth);
+ currX += colWidth + gutterWidth;
+ }
+ }
+
+ /**
+ * Add an element to be rendered in a column.
+ * Note that you can only add a Phrase
+ * or a Chunk
if the columns are
+ * not all simple. This is an underlying restriction in
+ * {@link com.lowagie.text.pdf.ColumnText}
+ *
+ * @param element element to add
+ * @throws DocumentException if element can't be added
+ */
+ public void AddElement(IElement element) {
+ if (simple) {
+ columnText.AddElement(element);
+ } else if (element is Phrase) {
+ columnText.AddText((Phrase) element);
+ } else if (element is Chunk) {
+ columnText.AddText((Chunk) element);
+ } else {
+ throw new DocumentException("Can't add " + element.GetType().ToString() + " to MultiColumnText with complex columns");
+ }
+ }
+
+
+ /**
+ * Write out the columns. After writing, use
+ * {@link #isOverflow()} to see if all text was written.
+ * @param canvas PdfContentByte to write with
+ * @param document document to write to (only used to get page limit info)
+ * @param documentY starting y position to begin writing at
+ * @return the current height (y position) after writing the columns
+ * @throws DocumentException on error
+ */
+ public float Write(PdfContentByte canvas, PdfDocument document, float documentY) {
+ this.document = document;
+ columnText.Canvas = canvas;
+ if (columnDefs.Count == 0) {
+ throw new DocumentException("MultiColumnText has no columns");
+ }
+ overflow = false;
+ pageBottom = document.Bottom;
+ float currentHeight = 0;
+ bool done = false;
+ while (!done) {
+ if (top == AUTOMATIC) {
+ top = document.GetVerticalPosition(true);
+ }
+ else if (nextY == AUTOMATIC) {
+ nextY = document.GetVerticalPosition(true); // RS - 07/07/2005 - - Get current doc writing position for top of columns on new page.
+ }
+
+ ColumnDef currentDef = (ColumnDef) columnDefs[CurrentColumn];
+ columnText.YLine = top;
+
+ float[] left = currentDef.ResolvePositions(Rectangle.LEFT_BORDER);
+ float[] right = currentDef.ResolvePositions(Rectangle.RIGHT_BORDER);
+ if (document.IsMarginMirroring() && document.PageNumber % 2 == 0){
+ float delta = document.RightMargin - document.Left;
+ left = (float[])left.Clone();
+ right = (float[])right.Clone();
+ for (int i = 0; i < left.Length; i += 2) {
+ left[i] -= delta;
+ }
+ for (int i = 0; i < right.Length; i += 2) {
+ right[i] -= delta;
+ }
+ }
+ currentHeight = Math.Max(currentHeight, GetHeight(left, right));
+
+ if (currentDef.IsSimple()) {
+ columnText.SetSimpleColumn(left[2], left[3], right[0], right[1]);
+ } else {
+ columnText.SetColumns(left, right);
+ }
+
+ int result = columnText.Go();
+ if ((result & ColumnText.NO_MORE_TEXT) != 0) {
+ done = true;
+ top = columnText.YLine;
+ } else if (ShiftCurrentColumn()) {
+ top = nextY;
+ } else { // check if we are done because of height
+ totalHeight += currentHeight;
+
+ if ((desiredHeight != AUTOMATIC) && (totalHeight >= desiredHeight)) {
+ overflow = true;
+ break;
+ } else { // need to start new page and reset the columns
+ documentY = nextY;
+ NewPage();
+ currentHeight = 0;
+ }
+ }
+ }
+ if (desiredHeight == AUTOMATIC && columnDefs.Count == 1) {
+ currentHeight = documentY - columnText.YLine;
+ }
+ return currentHeight;
+ }
+
+ private void NewPage() {
+ ResetCurrentColumn();
+ if (desiredHeight == AUTOMATIC) {
+ top = nextY = AUTOMATIC;
+ }
+ else {
+ top = nextY;
+ }
+ totalHeight = 0;
+ if (document != null) {
+ document.NewPage();
+ }
+ }
+
+ /**
+ * Figure out the height of a column from the border extents
+ *
+ * @param left left border
+ * @param right right border
+ * @return height
+ */
+ private float GetHeight(float[] left, float[] right) {
+ float max = float.MinValue;
+ float min = float.MaxValue;
+ for (int i = 0; i < left.Length; i += 2) {
+ min = Math.Min(min, left[i + 1]);
+ max = Math.Max(max, left[i + 1]);
+ }
+ for (int i = 0; i < right.Length; i += 2) {
+ min = Math.Min(min, right[i + 1]);
+ max = Math.Max(max, right[i + 1]);
+ }
+ return max - min;
+ }
+
+
+ /**
+ * Processes the element by adding it to an
+ * ElementListener
.
+ *
+ * @param listener an ElementListener
+ * @return true
if the element was processed successfully
+ */
+ public bool Process(IElementListener listener) {
+ try {
+ return listener.Add(this);
+ } catch (DocumentException) {
+ return false;
+ }
+ }
+
+ /**
+ * Gets the type of the text element.
+ *
+ * @return a type
+ */
+
+ public int Type {
+ get {
+ return Element.MULTI_COLUMN_TEXT;
+ }
+ }
+
+ /**
+ * Returns null - not used
+ *
+ * @return null
+ */
+
+ public ArrayList Chunks {
+ get {
+ return null;
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.Element#isContent()
+ * @since iText 2.0.8
+ */
+ public bool IsContent() {
+ return true;
+ }
+
+ /**
+ * @see com.lowagie.text.Element#isNestable()
+ * @since iText 2.0.8
+ */
+ public bool IsNestable() {
+ return false;
+ }
+
+ /**
+ * Calculates the appropriate y position for the bottom
+ * of the columns on this page.
+ *
+ * @return the y position of the bottom of the columns
+ */
+ private float GetColumnBottom() {
+ if (desiredHeight == AUTOMATIC) {
+ return pageBottom;
+ } else {
+ return Math.Max(top - (desiredHeight - totalHeight), pageBottom);
+ }
+ }
+
+ /**
+ * Moves the text insertion point to the beginning of the next column, issuing a page break if
+ * needed.
+ * @throws DocumentException on error
+ */
+ public void NextColumn() {
+ currentColumn = (currentColumn + 1) % columnDefs.Count;
+ top = nextY;
+ if (currentColumn == 0) {
+ NewPage();
+ }
+ }
+
+ /**
+ * Gets the current column.
+ * @return the current column
+ */
+ public int CurrentColumn {
+ get {
+ if (columnsRightToLeft) {
+ return (columnDefs.Count - currentColumn - 1);
+ }
+ return currentColumn;
+ }
+ }
+
+ /**
+ * Resets the current column.
+ */
+ public void ResetCurrentColumn() {
+ currentColumn = 0;
+ }
+
+ /**
+ * Shifts the current column.
+ * @return true if the currentcolumn has changed
+ */
+ public bool ShiftCurrentColumn() {
+ if (currentColumn + 1 < columnDefs.Count) {
+ currentColumn++;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Sets the direction of the columns.
+ * @param direction true = right2left; false = left2right
+ */
+ public void SetColumnsRightToLeft(bool direction) {
+ columnsRightToLeft = direction;
+ }
+
+ /** Sets the ratio between the extra word spacing and the extra character spacing
+ * when the text is fully justified.
+ * Extra word spacing will grow spaceCharRatio
times more than extra character spacing.
+ * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO
then the extra character spacing
+ * will be zero.
+ * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing
+ */
+ public float SpaceCharRatio {
+ set {
+ columnText.SpaceCharRatio = value;
+ }
+ }
+
+ /** Sets the run direction.
+ * @param runDirection the run direction
+ */
+ public int RunDirection {
+ set {
+ columnText.RunDirection = value;
+ }
+ }
+
+ /** Sets the arabic shaping options. The option can be AR_NOVOWEL,
+ * AR_COMPOSEDTASHKEEL and AR_LIG.
+ * @param arabicOptions the arabic shaping options
+ */
+ public int ArabicOptions {
+ set {
+ columnText.ArabicOptions = value;
+ }
+ }
+
+ /** Sets the default alignment
+ * @param alignment the default alignment
+ */
+ public int Alignment {
+ set {
+ columnText.Alignment = value;
+ }
+ }
+
+ public override string ToString() {
+ return base.ToString();
+ }
+
+ /**
+ * Inner class used to define a column
+ */
+ internal class ColumnDef {
+ private float[] left;
+ private float[] right;
+ private MultiColumnText mc;
+
+ internal ColumnDef(float[] newLeft, float[] newRight, MultiColumnText mc) {
+ this.mc = mc;
+ left = newLeft;
+ right = newRight;
+ }
+
+ internal ColumnDef(float leftPosition, float rightPosition, MultiColumnText mc) {
+ this.mc = mc;
+ left = new float[4];
+ left[0] = leftPosition; // x1
+ left[1] = mc.top; // y1
+ left[2] = leftPosition; // x2
+ if (mc.desiredHeight == AUTOMATIC || mc.top == AUTOMATIC) {
+ left[3] = AUTOMATIC;
+ } else {
+ left[3] = mc.top - mc.desiredHeight;
+ }
+
+ right = new float[4];
+ right[0] = rightPosition; // x1
+ right[1] = mc.top; // y1
+ right[2] = rightPosition; // x2
+ if (mc.desiredHeight == AUTOMATIC || mc.top == AUTOMATIC) {
+ right[3] = AUTOMATIC;
+ } else {
+ right[3] = mc.top - mc.desiredHeight;
+ }
+ }
+
+ /**
+ * Resolves the positions for the specified side of the column
+ * into real numbers once the top of the column is known.
+ *
+ * @param side either Rectangle.LEFT_BORDER
+ * or Rectangle.RIGHT_BORDER
+ * @return the array of floats for the side
+ */
+ internal float[] ResolvePositions(int side) {
+ if (side == Rectangle.LEFT_BORDER) {
+ return ResolvePositions(left);
+ } else {
+ return ResolvePositions(right);
+ }
+ }
+
+ internal float[] ResolvePositions(float[] positions) {
+ if (!IsSimple()) {
+ return positions;
+ }
+ if (mc.top == AUTOMATIC) {
+ // this is bad - must be programmer error
+ throw new Exception("resolvePositions called with top=AUTOMATIC (-1). " +
+ "Top position must be set befure lines can be resolved");
+ }
+ positions[1] = mc.top;
+ positions[3] = mc.GetColumnBottom();
+ return positions;
+ }
+
+ /**
+ * Checks if column definition is a simple rectangle
+ * @return true if it is a simple column
+ */
+ internal bool IsSimple() {
+ return (left.Length == 4 && right.Length == 4) && (left[0] == left[2] && right[0] == right[2]);
+ }
+
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/OutputStreamCounter.cs b/iTechSharp/iTextSharp/text/pdf/OutputStreamCounter.cs
new file mode 100644
index 0000000..0058116
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/OutputStreamCounter.cs
@@ -0,0 +1,81 @@
+using System;
+using System.IO;
+
+namespace iTextSharp.text.pdf {
+ public class OutputStreamCounter : Stream {
+ protected Stream outc;
+ protected int counter = 0;
+
+ public OutputStreamCounter(Stream _outc) {
+ outc = _outc;
+ }
+
+ public int Counter {
+ get {
+ return counter;
+ }
+ }
+
+ public void ResetCounter() {
+ counter = 0;
+ }
+
+ public override bool CanRead {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanSeek {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanWrite {
+ get {
+ return true;
+ }
+ }
+
+ public override long Length {
+ get {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override long Position {
+ get {
+ throw new NotSupportedException();
+ }
+ set {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override void Flush() {
+ outc.Flush();
+ }
+
+ public override int Read(byte[] buffer, int offset, int count) {
+ throw new NotSupportedException();
+ }
+
+ public override long Seek(long offset, SeekOrigin origin) {
+ throw new NotSupportedException();
+ }
+
+ public override void SetLength(long value) {
+ throw new NotSupportedException();
+ }
+
+ public override void Write(byte[] buffer, int offset, int count) {
+ counter += count;
+ outc.Write(buffer, offset, count);
+ }
+
+ public override void Close() {
+ outc.Close ();
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/OutputStreamEncryption.cs b/iTechSharp/iTextSharp/text/pdf/OutputStreamEncryption.cs
new file mode 100644
index 0000000..a6295c9
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/OutputStreamEncryption.cs
@@ -0,0 +1,170 @@
+using System;
+using System.IO;
+using iTextSharp.text.pdf.crypto;
+/*
+ * $Id: OutputStreamEncryption.cs,v 1.3 2007/04/29 13:57:07 psoares33 Exp $
+ *
+ * Copyright 2006 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ public class OutputStreamEncryption : Stream {
+ protected Stream outc;
+ protected ARCFOUREncryption arcfour;
+ protected AESCipher cipher;
+ private byte[] buf = new byte[1];
+ private const int AES_128 = 4;
+ private bool aes;
+ private bool finished;
+
+ public OutputStreamEncryption(Stream outc, byte[] key, int off, int len, int revision) {
+ this.outc = outc;
+ aes = revision == AES_128;
+ if (aes) {
+ byte[] iv = IVGenerator.GetIV();
+ byte[] nkey = new byte[len];
+ System.Array.Copy(key, off, nkey, 0, len);
+ cipher = new AESCipher(true, nkey, iv);
+ Write(iv, 0, iv.Length);
+ }
+ else {
+ arcfour = new ARCFOUREncryption();
+ arcfour.PrepareARCFOURKey(key, off, len);
+ }
+ }
+
+ public OutputStreamEncryption(Stream outc, byte[] key, int revision) : this(outc, key, 0, key.Length, revision) {
+ }
+
+ public override bool CanRead {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanSeek {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanWrite {
+ get {
+ return true;
+ }
+ }
+
+ public override long Length {
+ get {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override long Position {
+ get {
+ throw new NotSupportedException();
+ }
+ set {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override void Flush() {
+ outc.Flush();
+ }
+
+ public override int Read(byte[] buffer, int offset, int count) {
+ throw new NotSupportedException();
+ }
+
+ public override long Seek(long offset, SeekOrigin origin) {
+ throw new NotSupportedException();
+ }
+
+ public override void SetLength(long value) {
+ throw new NotSupportedException();
+ }
+
+ public override void Write(byte[] b, int off, int len) {
+ if (aes) {
+ byte[] b2 = cipher.Update(b, off, len);
+ if (b2 == null || b2.Length == 0)
+ return;
+ outc.Write(b2, 0, b2.Length);
+ }
+ else {
+ byte[] b2 = new byte[Math.Min(len, 4192)];
+ while (len > 0) {
+ int sz = Math.Min(len, b2.Length);
+ arcfour.EncryptARCFOUR(b, off, sz, b2, 0);
+ outc.Write(b2, 0, sz);
+ len -= sz;
+ off += sz;
+ }
+ }
+ }
+
+ public override void Close() {
+ Finish();
+ outc.Close();
+ }
+
+ public override void WriteByte(byte value) {
+ buf[0] = value;
+ Write(buf, 0, 1);
+ }
+
+ public void Finish() {
+ if (!finished) {
+ finished = true;
+ if (aes) {
+ byte[] b = cipher.DoFinal();
+ outc.Write(b, 0, b.Length);
+ }
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PRAcroForm.cs b/iTechSharp/iTextSharp/text/pdf/PRAcroForm.cs
new file mode 100644
index 0000000..f3c66f3
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PRAcroForm.cs
@@ -0,0 +1,225 @@
+using System;
+using System.Collections;
+/*
+ * $Id: PRAcroForm.cs,v 1.5 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * This class written by Mark Thompson, Copyright (C) 2002 by Mark Thompson.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * This class captures an AcroForm on input. Basically, it extends Dictionary
+ * by indexing the fields of an AcroForm
+ * @author Mark Thompson
+ */
+
+ public class PRAcroForm : PdfDictionary {
+
+ /**
+ * This class holds the information for a single field
+ */
+ public class FieldInformation {
+ internal String name;
+ internal PdfDictionary info;
+ internal PRIndirectReference refi;
+
+ internal FieldInformation(String name, PdfDictionary info, PRIndirectReference refi) {
+ this.name = name; this.info = info; this.refi = refi;
+ }
+ public String Name {
+ get {
+ return name;
+ }
+ }
+ public PdfDictionary Info {
+ get {
+ return info;
+ }
+ }
+ public PRIndirectReference Ref {
+ get {
+ return refi;
+ }
+ }
+ }
+
+ internal ArrayList fields;
+ internal ArrayList stack;
+ internal Hashtable fieldByName;
+ internal PdfReader reader;
+
+ /**
+ * Constructor
+ * @param reader reader of the input file
+ */
+ public PRAcroForm(PdfReader reader) {
+ this.reader = reader;
+ fields = new ArrayList();
+ fieldByName = new Hashtable();
+ stack = new ArrayList();
+ }
+ /**
+ * Number of fields found
+ * @return size
+ */
+ public new int Size {
+ get {
+ return fields.Count;
+ }
+ }
+
+ public ArrayList Fields {
+ get {
+ return fields;
+ }
+ }
+
+ public FieldInformation GetField(String name) {
+ return (FieldInformation)fieldByName[name];
+ }
+
+ /**
+ * Given the title (/T) of a reference, return the associated reference
+ * @param name a string containing the path
+ * @return a reference to the field, or null
+ */
+ public PRIndirectReference GetRefByName(String name) {
+ FieldInformation fi = (FieldInformation)fieldByName[name];
+ if (fi == null) return null;
+ return fi.Ref;
+ }
+ /**
+ * Read, and comprehend the acroform
+ * @param root the docment root
+ */
+ public void ReadAcroForm(PdfDictionary root) {
+ if (root == null)
+ return;
+ hashMap = root.hashMap;
+ PushAttrib(root);
+ PdfArray fieldlist = (PdfArray)PdfReader.GetPdfObjectRelease(root.Get(PdfName.FIELDS));
+ IterateFields(fieldlist, null, null);
+ }
+
+ /**
+ * After reading, we index all of the fields. Recursive.
+ * @param fieldlist An array of fields
+ * @param fieldDict the last field dictionary we encountered (recursively)
+ * @param title the pathname of the field, up to this point or null
+ */
+ protected void IterateFields(PdfArray fieldlist, PRIndirectReference fieldDict, String title) {
+ foreach (PRIndirectReference refi in fieldlist.ArrayList) {
+ PdfDictionary dict = (PdfDictionary) PdfReader.GetPdfObjectRelease(refi);
+
+ // if we are not a field dictionary, pass our parent's values
+ PRIndirectReference myFieldDict = fieldDict;
+ String myTitle = title;
+ PdfString tField = (PdfString)dict.Get(PdfName.T);
+ bool isFieldDict = tField != null;
+
+ if (isFieldDict) {
+ myFieldDict = refi;
+ if (title == null) myTitle = tField.ToString();
+ else myTitle = title + '.' + tField.ToString();
+ }
+
+ PdfArray kids = (PdfArray)dict.Get(PdfName.KIDS);
+ if (kids != null) {
+ PushAttrib(dict);
+ IterateFields(kids, myFieldDict, myTitle);
+ stack.RemoveAt(stack.Count - 1); // pop
+ }
+ else { // leaf node
+ if (myFieldDict != null) {
+ PdfDictionary mergedDict = (PdfDictionary)stack[stack.Count - 1];
+ if (isFieldDict)
+ mergedDict = MergeAttrib(mergedDict, dict);
+
+ mergedDict.Put(PdfName.T, new PdfString(myTitle));
+ FieldInformation fi = new FieldInformation(myTitle, mergedDict, myFieldDict);
+ fields.Add(fi);
+ fieldByName[myTitle] = fi;
+ }
+ }
+ }
+ }
+ /**
+ * merge field attributes from two dictionaries
+ * @param parent one dictionary
+ * @param child the other dictionary
+ * @return a merged dictionary
+ */
+ protected PdfDictionary MergeAttrib(PdfDictionary parent, PdfDictionary child) {
+ PdfDictionary targ = new PdfDictionary();
+ if (parent != null) targ.Merge(parent);
+
+ foreach (PdfName key in child.Keys) {
+ if (key.Equals(PdfName.DR) || key.Equals(PdfName.DA) ||
+ key.Equals(PdfName.Q) || key.Equals(PdfName.FF) ||
+ key.Equals(PdfName.DV) || key.Equals(PdfName.V)
+ || key.Equals(PdfName.FT)
+ || key.Equals(PdfName.F)) {
+ targ.Put(key,child.Get(key));
+ }
+ }
+ return targ;
+ }
+ /**
+ * stack a level of dictionary. Merge in a dictionary from this level
+ */
+ protected void PushAttrib(PdfDictionary dict) {
+ PdfDictionary dic = null;
+ if (stack.Count != 0) {
+ dic = (PdfDictionary)stack[stack.Count - 1];
+ }
+ dic = MergeAttrib(dic, dict);
+ stack.Add(dic);
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PRIndirectReference.cs b/iTechSharp/iTextSharp/text/pdf/PRIndirectReference.cs
new file mode 100644
index 0000000..3800c9e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PRIndirectReference.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Text;
+using System.IO;
+
+/*
+ * $Id: PRIndirectReference.cs,v 1.3 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ public class PRIndirectReference : PdfIndirectReference {
+
+ protected PdfReader reader;
+ // membervariables
+
+ // constructors
+
+ /**
+ * Constructs a PdfIndirectReference
.
+ *
+ * @param reader a PdfReader
+ * @param number the object number.
+ * @param generation the generation number.
+ */
+
+ internal PRIndirectReference(PdfReader reader, int number, int generation) {
+ type = INDIRECT;
+ this.number = number;
+ this.generation = generation;
+ this.reader = reader;
+ }
+
+ /**
+ * Constructs a PdfIndirectReference
.
+ *
+ * @param reader a PdfReader
+ * @param number the object number.
+ */
+
+ internal PRIndirectReference(PdfReader reader, int number) : this(reader, number, 0) {}
+
+ // methods
+
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ int n = writer.GetNewObjectNumber(reader, number, generation);
+ byte[] b = PdfEncodings.ConvertToBytes(new StringBuilder().Append(n).Append(" 0 R").ToString(), null);
+ os.Write(b, 0, b.Length);
+ }
+
+ public PdfReader Reader {
+ get {
+ return reader;
+ }
+ }
+
+ public void SetNumber(int number, int generation) {
+ this.number = number;
+ this.generation = generation;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PRStream.cs b/iTechSharp/iTextSharp/text/pdf/PRStream.cs
new file mode 100644
index 0000000..d381d03
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PRStream.cs
@@ -0,0 +1,205 @@
+using System;
+using System.IO;
+
+using System.util.zlib;
+
+/*
+ * $Id: PRStream.cs,v 1.6 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+public class PRStream : PdfStream {
+
+ protected PdfReader reader;
+ protected int offset;
+ protected int length;
+
+ //added by ujihara for decryption
+ protected int objNum = 0;
+ protected int objGen = 0;
+
+ public PRStream(PRStream stream, PdfDictionary newDic) {
+ reader = stream.reader;
+ offset = stream.offset;
+ length = stream.Length;
+ compressed = stream.compressed;
+ streamBytes = stream.streamBytes;
+ bytes = stream.bytes;
+ objNum = stream.objNum;
+ objGen = stream.objGen;
+ if (newDic != null)
+ Merge(newDic);
+ else
+ Merge(stream);
+ }
+
+ public PRStream(PRStream stream, PdfDictionary newDic, PdfReader reader) : this(stream, newDic) {
+ this.reader = reader;
+ }
+
+ public PRStream(PdfReader reader, int offset) {
+ this.reader = reader;
+ this.offset = offset;
+ }
+
+ public PRStream(PdfReader reader, byte[] conts) {
+ this.reader = reader;
+ this.offset = -1;
+ if (Document.Compress) {
+ MemoryStream stream = new MemoryStream();
+ ZDeflaterOutputStream zip = new ZDeflaterOutputStream(stream);
+ zip.Write(conts, 0, conts.Length);
+ zip.Close();
+ bytes = stream.ToArray();
+ Put(PdfName.FILTER, PdfName.FLATEDECODE);
+ }
+ else
+ bytes = conts;
+ Length = bytes.Length;
+ }
+
+ /**
+ * Sets the data associated with the stream, either compressed or
+ * uncompressed. Note that the data will never be compressed if
+ * Document.compress is set to false.
+ *
+ * @param data raw data, decrypted and uncompressed.
+ * @param compress true if you want the stream to be compresssed.
+ * @since iText 2.1.1
+ */
+ public void SetData(byte[] data, bool compress) {
+ Remove(PdfName.FILTER);
+ this.offset = -1;
+ if (Document.Compress && compress) {
+ MemoryStream stream = new MemoryStream();
+ ZDeflaterOutputStream zip = new ZDeflaterOutputStream(stream);
+ zip.Write(data, 0, data.Length);
+ zip.Close();
+ bytes = stream.ToArray();
+ Put(PdfName.FILTER, PdfName.FLATEDECODE);
+ }
+ else
+ bytes = data;
+ Length = bytes.Length;
+ }
+
+ /**Sets the data associated with the stream
+ * @param data raw data, decrypted and uncompressed.
+ */
+ public void SetData(byte[] data) {
+ SetData(data, true);
+ }
+
+ public new int Length {
+ set {
+ length = value;
+ Put(PdfName.LENGTH, new PdfNumber(length));
+ }
+ get {
+ return length;
+ }
+ }
+
+ public int Offset {
+ get {
+ return offset;
+ }
+ }
+
+ public PdfReader Reader {
+ get {
+ return reader;
+ }
+ }
+
+ public new byte[] GetBytes() {
+ return bytes;
+ }
+
+ public int ObjNum {
+ get {
+ return objNum;
+ }
+ set {
+ objNum = value;
+ }
+ }
+
+ public int ObjGen {
+ get {
+ return objGen;
+ }
+ set {
+ objGen = value;
+ }
+ }
+
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ byte[] b = PdfReader.GetStreamBytesRaw(this);
+ PdfEncryption crypto = null;
+ if (writer != null)
+ crypto = writer.Encryption;
+ PdfObject objLen = Get(PdfName.LENGTH);
+ int nn = b.Length;
+ if (crypto != null)
+ nn = crypto.CalculateStreamSize(nn);
+ Put(PdfName.LENGTH, new PdfNumber(nn));
+ SuperToPdf(writer, os);
+ Put(PdfName.LENGTH, objLen);
+ os.Write(STARTSTREAM, 0, STARTSTREAM.Length);
+ if (length > 0) {
+ if (crypto != null)
+ b = crypto.EncryptByteArray(b);
+ os.Write(b, 0, b.Length);
+ }
+ os.Write(ENDSTREAM, 0, ENDSTREAM.Length);
+ }
+}
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PRTokeniser.cs b/iTechSharp/iTextSharp/text/pdf/PRTokeniser.cs
new file mode 100644
index 0000000..d8c7235
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PRTokeniser.cs
@@ -0,0 +1,565 @@
+using System;
+using System.IO;
+using System.Text;
+
+/*
+ * Copyright 2001, 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PRTokeniser {
+
+ public const int TK_NUMBER = 1;
+ public const int TK_STRING = 2;
+ public const int TK_NAME = 3;
+ public const int TK_COMMENT = 4;
+ public const int TK_START_ARRAY = 5;
+ public const int TK_END_ARRAY = 6;
+ public const int TK_START_DIC = 7;
+ public const int TK_END_DIC = 8;
+ public const int TK_REF = 9;
+ public const int TK_OTHER = 10;
+
+ internal const string EMPTY = "";
+
+
+ protected RandomAccessFileOrArray file;
+ protected int type;
+ protected string stringValue;
+ protected int reference;
+ protected int generation;
+ protected bool hexString;
+
+ public PRTokeniser(string filename) {
+ file = new RandomAccessFileOrArray(filename);
+ }
+
+ public PRTokeniser(byte[] pdfIn) {
+ file = new RandomAccessFileOrArray(pdfIn);
+ }
+
+ public PRTokeniser(RandomAccessFileOrArray file) {
+ this.file = file;
+ }
+
+ public void Seek(int pos) {
+ file.Seek(pos);
+ }
+
+ public int FilePointer {
+ get {
+ return file.FilePointer;
+ }
+ }
+
+ public void Close() {
+ file.Close();
+ }
+
+ public int Length {
+ get {
+ return file.Length;
+ }
+ }
+
+ public int Read() {
+ return file.Read();
+ }
+
+ public RandomAccessFileOrArray SafeFile {
+ get {
+ return new RandomAccessFileOrArray(file);
+ }
+ }
+
+ public RandomAccessFileOrArray File {
+ get {
+ return file;
+ }
+ }
+
+ public string ReadString(int size) {
+ StringBuilder buf = new StringBuilder();
+ int ch;
+ while ((size--) > 0) {
+ ch = file.Read();
+ if (ch == -1)
+ break;
+ buf.Append((char)ch);
+ }
+ return buf.ToString();
+ }
+
+ public static bool IsWhitespace(int ch) {
+ return (ch == 0 || ch == 9 || ch == 10 || ch == 12 || ch == 13 || ch == 32);
+ }
+
+ public static bool IsDelimiter(int ch) {
+ return (ch == '(' || ch == ')' || ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '/' || ch == '%');
+ }
+
+ public int TokenType {
+ get {
+ return type;
+ }
+ }
+
+ public string StringValue {
+ get {
+ return stringValue;
+ }
+ }
+
+ public int Reference {
+ get {
+ return reference;
+ }
+ }
+
+ public int Generation {
+ get {
+ return generation;
+ }
+ }
+
+ public void BackOnePosition(int ch) {
+ if (ch != -1)
+ file.PushBack((byte)ch);
+ }
+
+ public void ThrowError(string error) {
+ throw new IOException(error + " at file pointer " + file.FilePointer);
+ }
+
+ public char CheckPdfHeader() {
+ file.StartOffset = 0;
+ String str = ReadString(1024);
+ int idx = str.IndexOf("%PDF-");
+ if (idx < 0)
+ throw new IOException("PDF header signature not found.");
+ file.StartOffset = idx;
+ return str[idx + 7];
+ }
+
+ public void CheckFdfHeader() {
+ file.StartOffset = 0;
+ String str = ReadString(1024);
+ int idx = str.IndexOf("%FDF-1.2");
+ if (idx < 0)
+ throw new IOException("FDF header signature not found.");
+ file.StartOffset = idx;
+ }
+
+ public int Startxref {
+ get {
+ int size = Math.Min(1024, file.Length);
+ int pos = file.Length - size;
+ file.Seek(pos);
+ string str = ReadString(1024);
+ int idx = str.LastIndexOf("startxref");
+ if (idx < 0)
+ throw new IOException("PDF startxref not found.");
+ return pos + idx;
+ }
+ }
+
+ public static int GetHex(int v) {
+ if (v >= '0' && v <= '9')
+ return v - '0';
+ if (v >= 'A' && v <= 'F')
+ return v - 'A' + 10;
+ if (v >= 'a' && v <= 'f')
+ return v - 'a' + 10;
+ return -1;
+ }
+
+ public void NextValidToken() {
+ int level = 0;
+ string n1 = null;
+ string n2 = null;
+ int ptr = 0;
+ while (NextToken()) {
+ if (type == TK_COMMENT)
+ continue;
+ switch (level) {
+ case 0: {
+ if (type != TK_NUMBER)
+ return;
+ ptr = file.FilePointer;
+ n1 = stringValue;
+ ++level;
+ break;
+ }
+ case 1: {
+ if (type != TK_NUMBER) {
+ file.Seek(ptr);
+ type = TK_NUMBER;
+ stringValue = n1;
+ return;
+ }
+ n2 = stringValue;
+ ++level;
+ break;
+ }
+ default: {
+ if (type != TK_OTHER || !stringValue.Equals("R")) {
+ file.Seek(ptr);
+ type = TK_NUMBER;
+ stringValue = n1;
+ return;
+ }
+ type = TK_REF;
+ reference = int.Parse(n1);
+ generation = int.Parse(n2);
+ return;
+ }
+ }
+ }
+ ThrowError("Unexpected end of file");
+ }
+
+ public bool NextToken() {
+ StringBuilder outBuf = null;
+ stringValue = EMPTY;
+ int ch = 0;
+ do {
+ ch = file.Read();
+ } while (ch != -1 && IsWhitespace(ch));
+ if (ch == -1)
+ return false;
+ switch (ch) {
+ case '[':
+ type = TK_START_ARRAY;
+ break;
+ case ']':
+ type = TK_END_ARRAY;
+ break;
+ case '/': {
+ outBuf = new StringBuilder();
+ type = TK_NAME;
+ while (true) {
+ ch = file.Read();
+ if (ch == -1 || IsDelimiter(ch) || IsWhitespace(ch))
+ break;
+ if (ch == '#') {
+ ch = (GetHex(file.Read()) << 4) + GetHex(file.Read());
+ }
+ outBuf.Append((char)ch);
+ }
+ BackOnePosition(ch);
+ break;
+ }
+ case '>':
+ ch = file.Read();
+ if (ch != '>')
+ ThrowError("'>' not expected");
+ type = TK_END_DIC;
+ break;
+ case '<': {
+ int v1 = file.Read();
+ if (v1 == '<') {
+ type = TK_START_DIC;
+ break;
+ }
+ outBuf = new StringBuilder();
+ type = TK_STRING;
+ hexString = true;
+ int v2 = 0;
+ while (true) {
+ while (IsWhitespace(v1))
+ v1 = file.Read();
+ if (v1 == '>')
+ break;
+ v1 = GetHex(v1);
+ if (v1 < 0)
+ break;
+ v2 = file.Read();
+ while (IsWhitespace(v2))
+ v2 = file.Read();
+ if (v2 == '>') {
+ ch = v1 << 4;
+ outBuf.Append((char)ch);
+ break;
+ }
+ v2 = GetHex(v2);
+ if (v2 < 0)
+ break;
+ ch = (v1 << 4) + v2;
+ outBuf.Append((char)ch);
+ v1 = file.Read();
+ }
+ if (v1 < 0 || v2 < 0)
+ ThrowError("Error reading string");
+ break;
+ }
+ case '%':
+ type = TK_COMMENT;
+ do {
+ ch = file.Read();
+ } while (ch != -1 && ch != '\r' && ch != '\n');
+ break;
+ case '(': {
+ outBuf = new StringBuilder();
+ type = TK_STRING;
+ hexString = false;
+ int nesting = 0;
+ while (true) {
+ ch = file.Read();
+ if (ch == -1)
+ break;
+ if (ch == '(') {
+ ++nesting;
+ }
+ else if (ch == ')') {
+ --nesting;
+ }
+ else if (ch == '\\') {
+ bool lineBreak = false;
+ ch = file.Read();
+ switch (ch) {
+ case 'n':
+ ch = '\n';
+ break;
+ case 'r':
+ ch = '\r';
+ break;
+ case 't':
+ ch = '\t';
+ break;
+ case 'b':
+ ch = '\b';
+ break;
+ case 'f':
+ ch = '\f';
+ break;
+ case '(':
+ case ')':
+ case '\\':
+ break;
+ case '\r':
+ lineBreak = true;
+ ch = file.Read();
+ if (ch != '\n')
+ BackOnePosition(ch);
+ break;
+ case '\n':
+ lineBreak = true;
+ break;
+ default: {
+ if (ch < '0' || ch > '7') {
+ break;
+ }
+ int octal = ch - '0';
+ ch = file.Read();
+ if (ch < '0' || ch > '7') {
+ BackOnePosition(ch);
+ ch = octal;
+ break;
+ }
+ octal = (octal << 3) + ch - '0';
+ ch = file.Read();
+ if (ch < '0' || ch > '7') {
+ BackOnePosition(ch);
+ ch = octal;
+ break;
+ }
+ octal = (octal << 3) + ch - '0';
+ ch = octal & 0xff;
+ break;
+ }
+ }
+ if (lineBreak)
+ continue;
+ if (ch < 0)
+ break;
+ }
+ else if (ch == '\r') {
+ ch = file.Read();
+ if (ch < 0)
+ break;
+ if (ch != '\n') {
+ BackOnePosition(ch);
+ ch = '\n';
+ }
+ }
+ if (nesting == -1)
+ break;
+ outBuf.Append((char)ch);
+ }
+ if (ch == -1)
+ ThrowError("Error reading string");
+ break;
+ }
+ default: {
+ outBuf = new StringBuilder();
+ if (ch == '-' || ch == '+' || ch == '.' || (ch >= '0' && ch <= '9')) {
+ type = TK_NUMBER;
+ do {
+ outBuf.Append((char)ch);
+ ch = file.Read();
+ } while (ch != -1 && ((ch >= '0' && ch <= '9') || ch == '.'));
+ }
+ else {
+ type = TK_OTHER;
+ do {
+ outBuf.Append((char)ch);
+ ch = file.Read();
+ } while (ch != -1 && !IsDelimiter(ch) && !IsWhitespace(ch));
+ }
+ BackOnePosition(ch);
+ break;
+ }
+ }
+ if (outBuf != null)
+ stringValue = outBuf.ToString();
+ return true;
+ }
+
+ public int IntValue {
+ get {
+ return int.Parse(stringValue);
+ }
+ }
+
+ public bool ReadLineSegment(byte[] input) {
+ int c = -1;
+ bool eol = false;
+ int ptr = 0;
+ int len = input.Length;
+ // ssteward, pdftk-1.10, 040922:
+ // skip initial whitespace; added this because PdfReader.RebuildXref()
+ // assumes that line provided by readLineSegment does not have init. whitespace;
+ if ( ptr < len ) {
+ while ( IsWhitespace( (c = Read()) ) );
+ }
+ while ( !eol && ptr < len ) {
+ switch (c) {
+ case -1:
+ case '\n':
+ eol = true;
+ break;
+ case '\r':
+ eol = true;
+ int cur = FilePointer;
+ if ((Read()) != '\n') {
+ Seek(cur);
+ }
+ break;
+ default:
+ input[ptr++] = (byte)c;
+ break;
+ }
+
+ // break loop? do it before we Read() again
+ if ( eol || len <= ptr ) {
+ break;
+ }
+ else {
+ c = Read();
+ }
+ }
+ if (ptr >= len) {
+ eol = false;
+ while (!eol) {
+ switch (c = Read()) {
+ case -1:
+ case '\n':
+ eol = true;
+ break;
+ case '\r':
+ eol = true;
+ int cur = FilePointer;
+ if ((Read()) != '\n') {
+ Seek(cur);
+ }
+ break;
+ }
+ }
+ }
+
+ if ((c == -1) && (ptr == 0)) {
+ return false;
+ }
+ if (ptr + 2 <= len) {
+ input[ptr++] = (byte)' ';
+ input[ptr] = (byte)'X';
+ }
+ return true;
+ }
+
+ public static int[] CheckObjectStart(byte[] line) {
+ try {
+ PRTokeniser tk = new PRTokeniser(line);
+ int num = 0;
+ int gen = 0;
+ if (!tk.NextToken() || tk.TokenType != TK_NUMBER)
+ return null;
+ num = tk.IntValue;
+ if (!tk.NextToken() || tk.TokenType != TK_NUMBER)
+ return null;
+ gen = tk.IntValue;
+ if (!tk.NextToken())
+ return null;
+ if (!tk.StringValue.Equals("obj"))
+ return null;
+ return new int[]{num, gen};
+ }
+ catch {
+ }
+ return null;
+ }
+
+ public bool IsHexString() {
+ return this.hexString;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PageResources.cs b/iTechSharp/iTextSharp/text/pdf/PageResources.cs
new file mode 100644
index 0000000..81d44a8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PageResources.cs
@@ -0,0 +1,194 @@
+using System;
+using System.Collections;
+
+/*
+ * $Id: PageResources.cs,v 1.6 2006/09/24 15:48:24 psoares33 Exp $
+ *
+ * Copyright 2003-2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ public class PageResources {
+
+ protected PdfDictionary fontDictionary = new PdfDictionary();
+ protected PdfDictionary xObjectDictionary = new PdfDictionary();
+ protected PdfDictionary colorDictionary = new PdfDictionary();
+ protected PdfDictionary patternDictionary = new PdfDictionary();
+ protected PdfDictionary shadingDictionary = new PdfDictionary();
+ protected PdfDictionary extGStateDictionary = new PdfDictionary();
+ protected PdfDictionary propertyDictionary = new PdfDictionary();
+ protected Hashtable forbiddenNames;
+ protected PdfDictionary originalResources;
+ protected int[] namePtr = {0};
+ protected Hashtable usedNames;
+
+ internal PageResources() {
+ }
+
+ internal void SetOriginalResources(PdfDictionary resources, int[] newNamePtr) {
+ if (newNamePtr != null)
+ namePtr = newNamePtr;
+ forbiddenNames = new Hashtable();
+ usedNames = new Hashtable();
+ if (resources == null)
+ return;
+ originalResources = new PdfDictionary();
+ originalResources.Merge(resources);
+ foreach (PdfName key in resources.Keys) {
+ PdfObject sub = PdfReader.GetPdfObject(resources.Get(key));
+ if (sub != null && sub.IsDictionary()) {
+ PdfDictionary dic = (PdfDictionary)sub;
+ foreach (PdfName name in dic.Keys) {
+ forbiddenNames[name] = null;
+ }
+ PdfDictionary dic2 = new PdfDictionary();
+ dic2.Merge(dic);
+ originalResources.Put(key, dic2);
+ }
+ }
+ }
+
+ internal PdfName TranslateName(PdfName name) {
+ PdfName translated = name;
+ if (forbiddenNames != null) {
+ translated = (PdfName)usedNames[name];
+ if (translated == null) {
+ while (true) {
+ translated = new PdfName("Xi" + (namePtr[0]++));
+ if (!forbiddenNames.ContainsKey(translated))
+ break;
+ }
+ usedNames[name] = translated;
+ }
+ }
+ return translated;
+ }
+
+ internal PdfName AddFont(PdfName name, PdfIndirectReference reference) {
+ name = TranslateName(name);
+ fontDictionary.Put(name, reference);
+ return name;
+ }
+
+ internal PdfName AddXObject(PdfName name, PdfIndirectReference reference) {
+ name = TranslateName(name);
+ xObjectDictionary.Put(name, reference);
+ return name;
+ }
+
+ internal PdfName AddColor(PdfName name, PdfIndirectReference reference) {
+ name = TranslateName(name);
+ colorDictionary.Put(name, reference);
+ return name;
+ }
+
+ internal void AddDefaultColor(PdfName name, PdfObject obj) {
+ if (obj == null || obj.IsNull())
+ colorDictionary.Remove(name);
+ else
+ colorDictionary.Put(name, obj);
+ }
+
+ internal void AddDefaultColor(PdfDictionary dic) {
+ colorDictionary.Merge(dic);
+ }
+
+ internal void AddDefaultColorDiff(PdfDictionary dic) {
+ colorDictionary.MergeDifferent(dic);
+ }
+
+ internal PdfName AddShading(PdfName name, PdfIndirectReference reference) {
+ name = TranslateName(name);
+ shadingDictionary.Put(name, reference);
+ return name;
+ }
+
+ internal PdfName AddPattern(PdfName name, PdfIndirectReference reference) {
+ name = TranslateName(name);
+ patternDictionary.Put(name, reference);
+ return name;
+ }
+
+ internal PdfName AddExtGState(PdfName name, PdfIndirectReference reference) {
+ name = TranslateName(name);
+ extGStateDictionary.Put(name, reference);
+ return name;
+ }
+
+ internal PdfName AddProperty(PdfName name, PdfIndirectReference reference) {
+ name = TranslateName(name);
+ propertyDictionary.Put(name, reference);
+ return name;
+ }
+
+ internal PdfDictionary Resources {
+ get {
+ PdfResources resources = new PdfResources();
+ if (originalResources != null)
+ resources.Merge(originalResources);
+ resources.Put(PdfName.PROCSET, new PdfLiteral("[/PDF /Text /ImageB /ImageC /ImageI]"));
+ resources.Add(PdfName.FONT, fontDictionary);
+ resources.Add(PdfName.XOBJECT, xObjectDictionary);
+ resources.Add(PdfName.COLORSPACE, colorDictionary);
+ resources.Add(PdfName.PATTERN, patternDictionary);
+ resources.Add(PdfName.SHADING, shadingDictionary);
+ resources.Add(PdfName.EXTGSTATE, extGStateDictionary);
+ resources.Add(PdfName.PROPERTIES, propertyDictionary);
+ return resources;
+ }
+ }
+
+ internal bool HasResources() {
+ return (fontDictionary.Size > 0
+ || xObjectDictionary.Size > 0
+ || colorDictionary.Size > 0
+ || patternDictionary.Size > 0
+ || shadingDictionary.Size > 0
+ || extGStateDictionary.Size > 0
+ || propertyDictionary.Size > 0);
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PatternColor.cs b/iTechSharp/iTextSharp/text/pdf/PatternColor.cs
new file mode 100644
index 0000000..b2d693a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PatternColor.cs
@@ -0,0 +1,82 @@
+using System;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Represents a pattern. Can be used in high-level constructs (Paragraph, Cell, etc.).
+ */
+ public class PatternColor : ExtendedColor {
+ /** The actual pattern.
+ */
+ PdfPatternPainter painter;
+
+ /** Creates a color representing a pattern.
+ * @param painter the actual pattern
+ */
+ public PatternColor(PdfPatternPainter painter) : base(TYPE_PATTERN, .5f, .5f, .5f) {
+ this.painter = painter;
+ }
+
+ /** Gets the pattern.
+ * @return the pattern
+ */
+ public PdfPatternPainter Painter {
+ get {
+ return this.painter;
+ }
+ }
+
+ public override bool Equals(Object obj) {
+ return this == obj;
+ }
+
+ public override int GetHashCode() {
+ return painter.GetHashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfAcroForm.cs b/iTechSharp/iTextSharp/text/pdf/PdfAcroForm.cs
new file mode 100644
index 0000000..a82f2d3
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfAcroForm.cs
@@ -0,0 +1,490 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.util;
+
+/*
+ * $Id: PdfAcroForm.cs,v 1.9 2008/05/13 11:25:18 psoares33 Exp $
+ *
+ *
+ * Copyright 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+/**
+ * Each PDF document can contain maximum 1 AcroForm.
+ */
+
+public class PdfAcroForm : PdfDictionary {
+
+ private PdfWriter writer;
+
+
+ /** This is a map containing FieldTemplates. */
+ private Hashtable fieldTemplates = new Hashtable();
+
+ /** This is an array containing DocumentFields. */
+ private PdfArray documentFields = new PdfArray();
+
+ /** This is an array containing the calculationorder of the fields. */
+ private PdfArray calculationOrder = new PdfArray();
+
+ /** Contains the signature flags. */
+ private int sigFlags = 0;
+
+ /** Creates new PdfAcroForm */
+ public PdfAcroForm(PdfWriter writer) : base() {
+ this.writer = writer;
+ }
+
+ public bool NeedAppearances {
+ set {
+ Put(PdfName.NEEDAPPEARANCES, value ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE);
+ }
+ }
+
+
+ /**
+ * Adds fieldTemplates.
+ */
+
+ public void AddFieldTemplates(Hashtable ft) {
+ foreach (object key in ft.Keys) {
+ fieldTemplates[key] = ft[key];
+ }
+ }
+
+ /**
+ * Adds documentFields.
+ */
+
+ public void AddDocumentField(PdfIndirectReference piref) {
+ documentFields.Add(piref);
+ }
+
+ /**
+ * Closes the AcroForm.
+ */
+
+ public bool IsValid() {
+ if (documentFields.Size == 0) return false;
+ Put(PdfName.FIELDS, documentFields);
+ if (sigFlags != 0)
+ Put(PdfName.SIGFLAGS, new PdfNumber(sigFlags));
+ if (calculationOrder.Size > 0)
+ Put(PdfName.CO, calculationOrder);
+ if (fieldTemplates.Count == 0) return true;
+ PdfDictionary dic = new PdfDictionary();
+ foreach (PdfTemplate template in fieldTemplates.Keys) {
+ PdfFormField.MergeResources(dic, (PdfDictionary)template.Resources);
+ }
+ Put(PdfName.DR, dic);
+ Put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
+ PdfDictionary fonts = (PdfDictionary)dic.Get(PdfName.FONT);
+ if (fonts != null) {
+ writer.EliminateFontSubset(fonts);
+ }
+ return true;
+ }
+
+ /**
+ * Adds an object to the calculationOrder.
+ */
+
+ public void AddCalculationOrder(PdfFormField formField) {
+ calculationOrder.Add(formField.IndirectReference);
+ }
+
+ /**
+ * Sets the signature flags.
+ */
+
+ public int SigFlags {
+ set {
+ sigFlags |= value;
+ }
+ }
+
+ /**
+ * Adds a formfield to the AcroForm.
+ */
+
+ public void AddFormField(PdfFormField formField) {
+ writer.AddAnnotation(formField);
+ }
+
+ public PdfFormField AddHtmlPostButton(string name, string caption, string value, string url, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfAction action = PdfAction.CreateSubmitForm(url, null, PdfAction.SUBMIT_HTML_FORMAT);
+ PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action);
+ SetButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, value);
+ DrawButton(button, caption, font, fontSize, llx, lly, urx, ury);
+ AddFormField(button);
+ return button;
+ }
+
+ public PdfFormField AddResetButton(string name, string caption, string value, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfAction action = PdfAction.CreateResetForm(null, 0);
+ PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action);
+ SetButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, value);
+ DrawButton(button, caption, font, fontSize, llx, lly, urx, ury);
+ AddFormField(button);
+ return button;
+ }
+
+ public PdfFormField AddMap(string name, string value, string url, PdfContentByte appearance, float llx, float lly, float urx, float ury) {
+ PdfAction action = PdfAction.CreateSubmitForm(url, null, PdfAction.SUBMIT_HTML_FORMAT | PdfAction.SUBMIT_COORDINATES);
+ PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action);
+ SetButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, null);
+ PdfAppearance pa = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ pa.Add(appearance);
+ button.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, pa);
+ AddFormField(button);
+ return button;
+ }
+
+ public void SetButtonParams(PdfFormField button, int characteristics, string name, string value) {
+ button.Button = characteristics;
+ button.Flags = PdfAnnotation.FLAGS_PRINT;
+ button.SetPage();
+ button.FieldName = name;
+ if (value != null) button.ValueAsString = value;
+ }
+
+ public void DrawButton(PdfFormField button, string caption, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfAppearance pa = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ pa.DrawButton(0f, 0f, urx - llx, ury - lly, caption, font, fontSize);
+ button.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, pa);
+ }
+
+ public PdfFormField AddHiddenField(string name, string value) {
+ PdfFormField hidden = PdfFormField.CreateEmpty(writer);
+ hidden.FieldName = name;
+ hidden.ValueAsName = value;
+ AddFormField(hidden);
+ return hidden;
+ }
+
+ public PdfFormField AddSingleLineTextField(string name, string text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfFormField field = PdfFormField.CreateTextField(writer, PdfFormField.SINGLELINE, PdfFormField.PLAINTEXT, 0);
+ SetTextFieldParams(field, text, name, llx, lly, urx, ury);
+ DrawSingleLineOfText(field, text, font, fontSize, llx, lly, urx, ury);
+ AddFormField(field);
+ return field;
+ }
+
+ public PdfFormField AddMultiLineTextField(string name, string text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfFormField field = PdfFormField.CreateTextField(writer, PdfFormField.MULTILINE, PdfFormField.PLAINTEXT, 0);
+ SetTextFieldParams(field, text, name, llx, lly, urx, ury);
+ DrawMultiLineOfText(field, text, font, fontSize, llx, lly, urx, ury);
+ AddFormField(field);
+ return field;
+ }
+
+ public PdfFormField AddSingleLinePasswordField(string name, string text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfFormField field = PdfFormField.CreateTextField(writer, PdfFormField.SINGLELINE, PdfFormField.PASSWORD, 0);
+ SetTextFieldParams(field, text, name, llx, lly, urx, ury);
+ DrawSingleLineOfText(field, text, font, fontSize, llx, lly, urx, ury);
+ AddFormField(field);
+ return field;
+ }
+
+ public void SetTextFieldParams(PdfFormField field, string text, string name, float llx, float lly, float urx, float ury) {
+ field.SetWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT);
+ field.ValueAsString = text;
+ field.DefaultValueAsString = text;
+ field.FieldName = name;
+ field.Flags = PdfAnnotation.FLAGS_PRINT;
+ field.SetPage();
+ }
+
+ public void DrawSingleLineOfText(PdfFormField field, string text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfAppearance tp = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ PdfAppearance tp2 = (PdfAppearance)tp.Duplicate;
+ tp2.SetFontAndSize(font, fontSize);
+ tp2.ResetRGBColorFill();
+ field.DefaultAppearanceString = tp2;
+ tp.DrawTextField(0f, 0f, urx - llx, ury - lly);
+ tp.BeginVariableText();
+ tp.SaveState();
+ tp.Rectangle(3f, 3f, urx - llx - 6f, ury - lly - 6f);
+ tp.Clip();
+ tp.NewPath();
+ tp.BeginText();
+ tp.SetFontAndSize(font, fontSize);
+ tp.ResetRGBColorFill();
+ tp.SetTextMatrix(4, (ury - lly) / 2 - (fontSize * 0.3f));
+ tp.ShowText(text);
+ tp.EndText();
+ tp.RestoreState();
+ tp.EndVariableText();
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
+ }
+
+ public void DrawMultiLineOfText(PdfFormField field, string text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfAppearance tp = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ PdfAppearance tp2 = (PdfAppearance)tp.Duplicate;
+ tp2.SetFontAndSize(font, fontSize);
+ tp2.ResetRGBColorFill();
+ field.DefaultAppearanceString = tp2;
+ tp.DrawTextField(0f, 0f, urx - llx, ury - lly);
+ tp.BeginVariableText();
+ tp.SaveState();
+ tp.Rectangle(3f, 3f, urx - llx - 6f, ury - lly - 6f);
+ tp.Clip();
+ tp.NewPath();
+ tp.BeginText();
+ tp.SetFontAndSize(font, fontSize);
+ tp.ResetRGBColorFill();
+ tp.SetTextMatrix(4, 5);
+ System.util.StringTokenizer tokenizer = new System.util.StringTokenizer(text, "\n");
+ float yPos = ury - lly;
+ while (tokenizer.HasMoreTokens()) {
+ yPos -= fontSize * 1.2f;
+ tp.ShowTextAligned(PdfContentByte.ALIGN_LEFT, tokenizer.NextToken(), 3, yPos, 0);
+ }
+ tp.EndText();
+ tp.RestoreState();
+ tp.EndVariableText();
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
+ }
+
+ public PdfFormField AddCheckBox(string name, string value, bool status, float llx, float lly, float urx, float ury) {
+ PdfFormField field = PdfFormField.CreateCheckBox(writer);
+ SetCheckBoxParams(field, name, value, status, llx, lly, urx, ury);
+ DrawCheckBoxAppearences(field, value, llx, lly, urx, ury);
+ AddFormField(field);
+ return field;
+ }
+
+ public void SetCheckBoxParams(PdfFormField field, string name, string value, bool status, float llx, float lly, float urx, float ury) {
+ field.SetWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_TOGGLE);
+ field.FieldName = name;
+ if (status) {
+ field.ValueAsName = value;
+ field.AppearanceState = value;
+ }
+ else {
+ field.ValueAsName = "Off";
+ field.AppearanceState = "Off";
+ }
+ field.Flags = PdfAnnotation.FLAGS_PRINT;
+ field.SetPage();
+ field.BorderStyle = new PdfBorderDictionary(1, PdfBorderDictionary.STYLE_SOLID);
+ }
+
+ public void DrawCheckBoxAppearences(PdfFormField field, string value, float llx, float lly, float urx, float ury) {
+ BaseFont font = BaseFont.CreateFont(BaseFont.ZAPFDINGBATS, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
+ float size = (ury - lly);
+ PdfAppearance tpOn = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ PdfAppearance tp2 = (PdfAppearance)tpOn.Duplicate;
+ tp2.SetFontAndSize(font, size);
+ tp2.ResetRGBColorFill();
+ field.DefaultAppearanceString = tp2;
+ tpOn.DrawTextField(0f, 0f, urx - llx, ury - lly);
+ tpOn.SaveState();
+ tpOn.ResetRGBColorFill();
+ tpOn.BeginText();
+ tpOn.SetFontAndSize(font, size);
+ tpOn.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "4", (urx - llx) / 2, (ury - lly) / 2 - (size * 0.3f), 0);
+ tpOn.EndText();
+ tpOn.RestoreState();
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, value, tpOn);
+ PdfAppearance tpOff = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ tpOff.DrawTextField(0f, 0f, urx - llx, ury - lly);
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpOff);
+ }
+
+ public PdfFormField GetRadioGroup(string name, string defaultValue, bool noToggleToOff) {
+ PdfFormField radio = PdfFormField.CreateRadioButton(writer, noToggleToOff);
+ radio.FieldName = name;
+ radio.ValueAsName = defaultValue;
+ return radio;
+ }
+
+ public void AddRadioGroup(PdfFormField radiogroup) {
+ AddFormField(radiogroup);
+ }
+
+ public PdfFormField AddRadioButton(PdfFormField radiogroup, string value, float llx, float lly, float urx, float ury) {
+ PdfFormField radio = PdfFormField.CreateEmpty(writer);
+ radio.SetWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_TOGGLE);
+ string name = ((PdfName)radiogroup.Get(PdfName.V)).ToString().Substring(1);
+ if (name.Equals(value)) {
+ radio.AppearanceState = value;
+ }
+ else {
+ radio.AppearanceState = "Off";
+ }
+ DrawRadioAppearences(radio, value, llx, lly, urx, ury);
+ radiogroup.AddKid(radio);
+ return radio;
+ }
+
+ public void DrawRadioAppearences(PdfFormField field, string value, float llx, float lly, float urx, float ury) {
+ PdfAppearance tpOn = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ tpOn.DrawRadioField(0f, 0f, urx - llx, ury - lly, true);
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, value, tpOn);
+ PdfAppearance tpOff = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ tpOff.DrawRadioField(0f, 0f, urx - llx, ury - lly, false);
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpOff);
+ }
+
+ public PdfFormField AddSelectList(string name, string[] options, string defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfFormField choice = PdfFormField.CreateList(writer, options, 0);
+ SetChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
+ StringBuilder text = new StringBuilder();
+ for (int i = 0; i < options.Length; i++) {
+ text.Append(options[i]).Append('\n');
+ }
+ DrawMultiLineOfText(choice, text.ToString(), font, fontSize, llx, lly, urx, ury);
+ AddFormField(choice);
+ return choice;
+ }
+
+ public PdfFormField AddSelectList(string name, string[,] options, string defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfFormField choice = PdfFormField.CreateList(writer, options, 0);
+ SetChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
+ StringBuilder text = new StringBuilder();
+ for (int i = 0; i < options.GetLength(0); i++) {
+ text.Append(options[i, 1]).Append('\n');
+ }
+ DrawMultiLineOfText(choice, text.ToString(), font, fontSize, llx, lly, urx, ury);
+ AddFormField(choice);
+ return choice;
+ }
+
+ public PdfFormField AddComboBox(string name, string[] options, string defaultValue, bool editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfFormField choice = PdfFormField.CreateCombo(writer, editable, options, 0);
+ SetChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
+ if (defaultValue == null) {
+ defaultValue = options[0];
+ }
+ DrawSingleLineOfText(choice, defaultValue, font, fontSize, llx, lly, urx, ury);
+ AddFormField(choice);
+ return choice;
+ }
+
+ public PdfFormField AddComboBox(string name, string[,] options, string defaultValue, bool editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
+ PdfFormField choice = PdfFormField.CreateCombo(writer, editable, options, 0);
+ SetChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
+ string value = null;
+ for (int i = 0; i < options.GetLength(0); i++) {
+ if (options[i, 0].Equals(defaultValue)) {
+ value = options[i, 1];
+ break;
+ }
+ }
+ if (value == null) {
+ value = options[0, 1];
+ }
+ DrawSingleLineOfText(choice, value, font, fontSize, llx, lly, urx, ury);
+ AddFormField(choice);
+ return choice;
+ }
+
+ public void SetChoiceParams(PdfFormField field, string name, string defaultValue, float llx, float lly, float urx, float ury) {
+ field.SetWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT);
+ if (defaultValue != null) {
+ field.ValueAsString = defaultValue;
+ field.DefaultValueAsString = defaultValue;
+ }
+ field.FieldName = name;
+ field.Flags = PdfAnnotation.FLAGS_PRINT;
+ field.SetPage();
+ field.BorderStyle = new PdfBorderDictionary(2, PdfBorderDictionary.STYLE_SOLID);
+ }
+
+ public PdfFormField AddSignature(String name, float llx, float lly, float urx, float ury) {
+ PdfFormField signature = PdfFormField.CreateSignature(writer);
+ SetSignatureParams(signature, name, llx, lly, urx, ury);
+ DrawSignatureAppearences(signature, llx, lly, urx, ury);
+ AddFormField(signature);
+ return signature;
+ }
+
+ /**
+ * @param field
+ * @param name
+ * @param llx
+ * @param lly
+ * @param urx
+ * @param ury
+ */
+ public void SetSignatureParams(PdfFormField field, String name, float llx, float lly, float urx, float ury) {
+ field.SetWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT);
+ field.FieldName = name;
+ field.Flags = PdfAnnotation.FLAGS_PRINT;
+ field.SetPage();
+ field.MKBorderColor = Color.BLACK;
+ field.MKBackgroundColor = Color.WHITE;
+ }
+
+ /**
+ * @param field
+ * @param llx
+ * @param lly
+ * @param urx
+ * @param ury
+ */
+ public void DrawSignatureAppearences(PdfFormField field, float llx, float lly, float urx, float ury) {
+ PdfAppearance tp = PdfAppearance.CreateAppearance(writer, urx - llx, ury - lly);
+ tp.SetGrayFill(1.0f);
+ tp.Rectangle(0, 0, urx - llx, ury - lly);
+ tp.Fill();
+ tp.SetGrayStroke(0);
+ tp.SetLineWidth(1);
+ tp.Rectangle(0.5f, 0.5f, urx - llx - 0.5f, ury - lly - 0.5f);
+ tp.ClosePathStroke();
+ tp.SaveState();
+ tp.Rectangle(1, 1, urx - llx - 2, ury - lly - 2);
+ tp.Clip();
+ tp.NewPath();
+ tp.RestoreState();
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
+ }
+}
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfAction.cs b/iTechSharp/iTextSharp/text/pdf/PdfAction.cs
new file mode 100644
index 0000000..cc606de
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfAction.cs
@@ -0,0 +1,521 @@
+using System;
+using System.Collections;
+using System.util;
+using iTextSharp.text.pdf.collection;
+
+/*
+ * $Id: PdfAction.cs,v 1.6 2008/05/13 11:25:18 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /**
+ * A PdfAction
defines an action that can be triggered from a PDF file.
+ *
+ * @see PdfDictionary
+ */
+
+ public class PdfAction : PdfDictionary {
+
+ /** A named action to go to the first page.
+ */
+ public const int FIRSTPAGE = 1;
+ /** A named action to go to the previous page.
+ */
+ public const int PREVPAGE = 2;
+ /** A named action to go to the next page.
+ */
+ public const int NEXTPAGE = 3;
+ /** A named action to go to the last page.
+ */
+ public const int LASTPAGE = 4;
+
+ /** A named action to open a print dialog.
+ */
+ public const int PRINTDIALOG = 5;
+
+ // constructors
+ public const int SUBMIT_EXCLUDE = 1;
+ public const int SUBMIT_INCLUDE_NO_VALUE_FIELDS = 2;
+ public const int SUBMIT_HTML_FORMAT = 4;
+ public const int SUBMIT_HTML_GET = 8;
+ public const int SUBMIT_COORDINATES = 16;
+ /** a possible submitvalue */
+ public const int SUBMIT_XFDF = 32;
+ /** a possible submitvalue */
+ public const int SUBMIT_INCLUDE_APPEND_SAVES = 64;
+ /** a possible submitvalue */
+ public const int SUBMIT_INCLUDE_ANNOTATIONS = 128;
+ /** a possible submitvalue */
+ public const int SUBMIT_PDF = 256;
+ /** a possible submitvalue */
+ public const int SUBMIT_CANONICAL_FORMAT = 512;
+ /** a possible submitvalue */
+ public const int SUBMIT_EXCL_NON_USER_ANNOTS = 1024;
+ /** a possible submitvalue */
+ public const int SUBMIT_EXCL_F_KEY = 2048;
+ /** a possible submitvalue */
+ public const int SUBMIT_EMBED_FORM = 8196;
+ /** a possible submitvalue */
+ public const int RESET_EXCLUDE = 1;
+
+ /** Create an empty action.
+ */
+ public PdfAction() {
+ }
+
+ /**
+ * Constructs a new PdfAction
of Subtype URI.
+ *
+ * @param url the Url to go to
+ */
+
+ public PdfAction(Uri url) : this(url.AbsoluteUri) {}
+
+ public PdfAction(Uri url, bool isMap) : this(url.AbsoluteUri, isMap) {}
+
+ /**
+ * Constructs a new PdfAction
of Subtype URI.
+ *
+ * @param url the url to go to
+ */
+
+ public PdfAction(string url) : this(url, false) {}
+
+ public PdfAction(string url, bool isMap) {
+ Put(PdfName.S, PdfName.URI);
+ Put(PdfName.URI, new PdfString(url));
+ if (isMap)
+ Put(PdfName.ISMAP, PdfBoolean.PDFTRUE);
+ }
+
+ /**
+ * Constructs a new PdfAction
of Subtype GoTo.
+ * @param destination the destination to go to
+ */
+
+ internal PdfAction(PdfIndirectReference destination) {
+ Put(PdfName.S, PdfName.GOTO);
+ Put(PdfName.D, destination);
+ }
+
+ /**
+ * Constructs a new PdfAction
of Subtype GoToR.
+ * @param filename the file name to go to
+ * @param name the named destination to go to
+ */
+
+ public PdfAction(string filename, string name) {
+ Put(PdfName.S, PdfName.GOTOR);
+ Put(PdfName.F, new PdfString(filename));
+ Put(PdfName.D, new PdfString(name));
+ }
+
+ /**
+ * Constructs a new PdfAction
of Subtype GoToR.
+ * @param filename the file name to go to
+ * @param page the page destination to go to
+ */
+
+ public PdfAction(string filename, int page) {
+ Put(PdfName.S, PdfName.GOTOR);
+ Put(PdfName.F, new PdfString(filename));
+ Put(PdfName.D, new PdfLiteral("[" + (page - 1) + " /FitH 10000]"));
+ }
+
+ /** Implements name actions. The action can be FIRSTPAGE, LASTPAGE,
+ * NEXTPAGE and PREVPAGE.
+ * @param named the named action
+ */
+ public PdfAction(int named) {
+ Put(PdfName.S, PdfName.NAMED);
+ switch (named) {
+ case FIRSTPAGE:
+ Put(PdfName.N, PdfName.FIRSTPAGE);
+ break;
+ case LASTPAGE:
+ Put(PdfName.N, PdfName.LASTPAGE);
+ break;
+ case NEXTPAGE:
+ Put(PdfName.N, PdfName.NEXTPAGE);
+ break;
+ case PREVPAGE:
+ Put(PdfName.N, PdfName.PREVPAGE);
+ break;
+ case PRINTDIALOG:
+ Put(PdfName.S, PdfName.JAVASCRIPT);
+ Put(PdfName.JS, new PdfString("this.print(true);\r"));
+ break;
+ default:
+ throw new ArgumentException("Invalid named action.");
+ }
+ }
+
+ /** Launchs an application or a document.
+ * @param application the application to be launched or the document to be opened or printed.
+ * @param parameters (Windows-specific) A parameter string to be passed to the application.
+ * It can be null
.
+ * @param operation (Windows-specific) the operation to perform: "open" - Open a document,
+ * "print" - Print a document.
+ * It can be null
.
+ * @param defaultDir (Windows-specific) the default directory in standard DOS syntax.
+ * It can be null
.
+ */
+ public PdfAction(string application, string parameters, string operation, string defaultDir) {
+ Put(PdfName.S, PdfName.LAUNCH);
+ if (parameters == null && operation == null && defaultDir == null)
+ Put(PdfName.F, new PdfString(application));
+ else {
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.F, new PdfString(application));
+ if (parameters != null)
+ dic.Put(PdfName.P, new PdfString(parameters));
+ if (operation != null)
+ dic.Put(PdfName.O, new PdfString(operation));
+ if (defaultDir != null)
+ dic.Put(PdfName.D, new PdfString(defaultDir));
+ Put(PdfName.WIN, dic);
+ }
+ }
+
+ /** Launchs an application or a document.
+ * @param application the application to be launched or the document to be opened or printed.
+ * @param parameters (Windows-specific) A parameter string to be passed to the application.
+ * It can be null
.
+ * @param operation (Windows-specific) the operation to perform: "open" - Open a document,
+ * "print" - Print a document.
+ * It can be null
.
+ * @param defaultDir (Windows-specific) the default directory in standard DOS syntax.
+ * It can be null
.
+ * @return a Launch action
+ */
+ public static PdfAction CreateLaunch(String application, String parameters, String operation, String defaultDir) {
+ return new PdfAction(application, parameters, operation, defaultDir);
+ }
+
+ /**Creates a Rendition action
+ * @param file
+ * @param fs
+ * @param mimeType
+ * @param ref
+ * @return a Media Clip action
+ * @throws IOException
+ */
+ public static PdfAction Rendition(String file, PdfFileSpecification fs, String mimeType, PdfIndirectReference refi) {
+ PdfAction js = new PdfAction();
+ js.Put(PdfName.S, PdfName.RENDITION);
+ js.Put(PdfName.R, new PdfRendition(file, fs, mimeType));
+ js.Put(new PdfName("OP"), new PdfNumber(0));
+ js.Put(new PdfName("AN"), refi);
+ return js;
+ }
+
+ /** Creates a JavaScript action. If the JavaScript is smaller than
+ * 50 characters it will be placed as a string, otherwise it will
+ * be placed as a compressed stream.
+ * @param code the JavaScript code
+ * @param writer the writer for this action
+ * @param unicode select JavaScript unicode. Note that the internal
+ * Acrobat JavaScript engine does not support unicode,
+ * so this may or may not work for you
+ * @return the JavaScript action
+ */
+ public static PdfAction JavaScript(string code, PdfWriter writer, bool unicode) {
+ PdfAction js = new PdfAction();
+ js.Put(PdfName.S, PdfName.JAVASCRIPT);
+ if (unicode && code.Length < 50) {
+ js.Put(PdfName.JS, new PdfString(code, PdfObject.TEXT_UNICODE));
+ }
+ else if (!unicode && code.Length < 100) {
+ js.Put(PdfName.JS, new PdfString(code));
+ }
+ else {
+ byte[] b = PdfEncodings.ConvertToBytes(code, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING);
+ PdfStream stream = new PdfStream(b);
+ stream.FlateCompress();
+ js.Put(PdfName.JS, writer.AddToBody(stream).IndirectReference);
+ }
+ return js;
+ }
+
+ /** Creates a JavaScript action. If the JavaScript is smaller than
+ * 50 characters it will be place as a string, otherwise it will
+ * be placed as a compressed stream.
+ * @param code the JavaScript code
+ * @param writer the writer for this action
+ * @return the JavaScript action
+ */
+ public static PdfAction JavaScript(string code, PdfWriter writer) {
+ return JavaScript(code, writer, false);
+ }
+
+ internal static PdfAction CreateHide(PdfObject obj, bool hide) {
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.S, PdfName.HIDE);
+ action.Put(PdfName.T, obj);
+ if (!hide)
+ action.Put(PdfName.H, PdfBoolean.PDFFALSE);
+ return action;
+ }
+
+ public static PdfAction CreateHide(PdfAnnotation annot, bool hide) {
+ return CreateHide(annot.IndirectReference, hide);
+ }
+
+ public static PdfAction CreateHide(string name, bool hide) {
+ return CreateHide(new PdfString(name), hide);
+ }
+
+ internal static PdfArray BuildArray(Object[] names) {
+ PdfArray array = new PdfArray();
+ for (int k = 0; k < names.Length; ++k) {
+ Object obj = names[k];
+ if (obj is string)
+ array.Add(new PdfString((string)obj));
+ else if (obj is PdfAnnotation)
+ array.Add(((PdfAnnotation)obj).IndirectReference);
+ else
+ throw new ArgumentException("The array must contain string or PdfAnnotation.");
+ }
+ return array;
+ }
+
+ public static PdfAction CreateHide(Object[] names, bool hide) {
+ return CreateHide(BuildArray(names), hide);
+ }
+
+ public static PdfAction CreateSubmitForm(string file, Object[] names, int flags) {
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.S, PdfName.SUBMITFORM);
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.F, new PdfString(file));
+ dic.Put(PdfName.FS, PdfName.URL);
+ action.Put(PdfName.F, dic);
+ if (names != null)
+ action.Put(PdfName.FIELDS, BuildArray(names));
+ action.Put(PdfName.FLAGS, new PdfNumber(flags));
+ return action;
+ }
+
+ public static PdfAction CreateResetForm(Object[] names, int flags) {
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.S, PdfName.RESETFORM);
+ if (names != null)
+ action.Put(PdfName.FIELDS, BuildArray(names));
+ action.Put(PdfName.FLAGS, new PdfNumber(flags));
+ return action;
+ }
+
+ public static PdfAction CreateImportData(string file) {
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.S, PdfName.IMPORTDATA);
+ action.Put(PdfName.F, new PdfString(file));
+ return action;
+ }
+
+ /** Add a chained action.
+ * @param na the next action
+ */
+ public void Next(PdfAction na) {
+ PdfObject nextAction = Get(PdfName.NEXT);
+ if (nextAction == null)
+ Put(PdfName.NEXT, na);
+ else if (nextAction.IsDictionary()) {
+ PdfArray array = new PdfArray(nextAction);
+ array.Add(na);
+ Put(PdfName.NEXT, array);
+ }
+ else {
+ ((PdfArray)nextAction).Add(na);
+ }
+ }
+
+ /** Creates a GoTo action to an internal page.
+ * @param page the page to go. First page is 1
+ * @param dest the destination for the page
+ * @param writer the writer for this action
+ * @return a GoTo action
+ */
+ public static PdfAction GotoLocalPage(int page, PdfDestination dest, PdfWriter writer) {
+ PdfIndirectReference piref = writer.GetPageReference(page);
+ dest.AddPage(piref);
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.S, PdfName.GOTO);
+ action.Put(PdfName.D, dest);
+ return action;
+ }
+
+ /**
+ * Creates a GoTo action to a named destination.
+ * @param dest the named destination
+ * @param isName if true sets the destination as a name, if false sets it as a String
+ * @return a GoToR action
+ */
+ public static PdfAction GotoLocalPage(String dest, bool isName) {
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.S, PdfName.GOTO);
+ if (isName)
+ action.Put(PdfName.D, new PdfName(dest));
+ else
+ action.Put(PdfName.D, new PdfString(dest, null));
+ return action;
+ }
+
+ /**
+ * Creates a GoToR action to a named destination.
+ * @param filename the file name to go to
+ * @param dest the destination name
+ * @param isName if true sets the destination as a name, if false sets it as a String
+ * @param newWindow open the document in a new window if true
, if false the current document is replaced by the new document.
+ * @return a GoToR action
+ */
+ public static PdfAction GotoRemotePage(String filename, String dest, bool isName, bool newWindow) {
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.F, new PdfString(filename));
+ action.Put(PdfName.S, PdfName.GOTOR);
+ if (isName)
+ action.Put(PdfName.D, new PdfName(dest));
+ else
+ action.Put(PdfName.D, new PdfString(dest, null));
+ if (newWindow)
+ action.Put(PdfName.NEWWINDOW, PdfBoolean.PDFTRUE);
+ return action;
+ }
+
+ /**
+ * Creates a GoToE action to an embedded file.
+ * @param filename the root document of the target (null if the target is in the same document)
+ * @param dest the named destination
+ * @param isName if true sets the destination as a name, if false sets it as a String
+ * @return a GoToE action
+ */
+ public static PdfAction GotoEmbedded(String filename, PdfTargetDictionary target, String dest, bool isName, bool newWindow) {
+ if (isName)
+ return GotoEmbedded(filename, target, new PdfName(dest), newWindow);
+ else
+ return GotoEmbedded(filename, target, new PdfString(dest, null), newWindow);
+ }
+
+ /**
+ * Creates a GoToE action to an embedded file.
+ * @param filename the root document of the target (null if the target is in the same document)
+ * @param target a path to the target document of this action
+ * @param dest the destination inside the target document, can be of type PdfDestination, PdfName, or PdfString
+ * @param newWindow if true, the destination document should be opened in a new window
+ * @return a GoToE action
+ */
+ public static PdfAction GotoEmbedded(String filename, PdfTargetDictionary target, PdfObject dest, bool newWindow) {
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.S, PdfName.GOTOE);
+ action.Put(PdfName.T, target);
+ action.Put(PdfName.D, dest);
+ action.Put(PdfName.NEWWINDOW, new PdfBoolean(newWindow));
+ if (filename != null) {
+ action.Put(PdfName.F, new PdfString(filename));
+ }
+ return action;
+ }
+
+ /**
+ * A set-OCG-state action (PDF 1.5) sets the state of one or more optional content
+ * groups.
+ * @param state an array consisting of any number of sequences beginning with a PdfName
+ * or String
(ON, OFF, or Toggle) followed by one or more optional content group dictionaries
+ * PdfLayer
or a PdfIndirectReference
to a PdfLayer
.
+ * The array elements are processed from left to right; each name is applied
+ * to the subsequent groups until the next name is encountered:
+ *
+ *
+ * @param preserveRB if true
, indicates that radio-button state relationships between optional
+ * content groups (as specified by the RBGroups entry in the current configuration
+ * dictionary) should be preserved when the states in the
+ * state
array are applied. That is, if a group is set to ON (either by ON or Toggle) during
+ * processing of the state
array, any other groups belong to the same radio-button
+ * group are turned OFF. If a group is set to OFF, there is no effect on other groups.
+ * If false
, radio-button state relationships, if any, are ignored
+ * @return the action
+ */
+ public static PdfAction SetOCGstate(ArrayList state, bool preserveRB) {
+ PdfAction action = new PdfAction();
+ action.Put(PdfName.S, PdfName.SETOCGSTATE);
+ PdfArray a = new PdfArray();
+ for (int k = 0; k < state.Count; ++k) {
+ Object o = state[k];
+ if (o == null)
+ continue;
+ if (o is PdfIndirectReference)
+ a.Add((PdfIndirectReference)o);
+ else if (o is PdfLayer)
+ a.Add(((PdfLayer)o).Ref);
+ else if (o is PdfName)
+ a.Add((PdfName)o);
+ else if (o is String) {
+ PdfName name = null;
+ String s = (String)o;
+ if (Util.EqualsIgnoreCase(s, "on"))
+ name = PdfName.ON;
+ else if (Util.EqualsIgnoreCase(s, "off"))
+ name = PdfName.OFF;
+ else if (Util.EqualsIgnoreCase(s, "toggle"))
+ name = PdfName.TOGGLE;
+ else
+ throw new ArgumentException("A string '" + s + " was passed in state. Only 'ON', 'OFF' and 'Toggle' are allowed.");
+ a.Add(name);
+ }
+ else
+ throw new ArgumentException("Invalid type was passed in state: " + o.GetType().ToString());
+ }
+ action.Put(PdfName.STATE, a);
+ if (!preserveRB)
+ action.Put(PdfName.PRESERVERB, PdfBoolean.PDFFALSE);
+ return action;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfAnnotation.cs b/iTechSharp/iTextSharp/text/pdf/PdfAnnotation.cs
new file mode 100644
index 0000000..05593f5
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfAnnotation.cs
@@ -0,0 +1,824 @@
+using System;
+using System.Collections;
+using System.util;
+using iTextSharp.text;
+/*
+ * $Id: PdfAnnotation.cs,v 1.12 2008/05/24 18:41:23 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * A PdfAnnotation
is a note that is associated with a page.
+ *
+ * @see PdfDictionary
+ */
+ public class PdfAnnotation : PdfDictionary {
+
+ public static readonly PdfName HIGHLIGHT_NONE = PdfName.N;
+ public static readonly PdfName HIGHLIGHT_INVERT = PdfName.I;
+ public static readonly PdfName HIGHLIGHT_OUTLINE = PdfName.O;
+ public static readonly PdfName HIGHLIGHT_PUSH = PdfName.P;
+ public static readonly PdfName HIGHLIGHT_TOGGLE = PdfName.T;
+ public const int FLAGS_INVISIBLE = 1;
+ public const int FLAGS_HIDDEN = 2;
+ public const int FLAGS_PRINT = 4;
+ public const int FLAGS_NOZOOM = 8;
+ public const int FLAGS_NOROTATE = 16;
+ public const int FLAGS_NOVIEW = 32;
+ public const int FLAGS_READONLY = 64;
+ public const int FLAGS_LOCKED = 128;
+ public const int FLAGS_TOGGLENOVIEW = 256;
+ public static readonly PdfName APPEARANCE_NORMAL = PdfName.N;
+ public static readonly PdfName APPEARANCE_ROLLOVER = PdfName.R;
+ public static readonly PdfName APPEARANCE_DOWN = PdfName.D;
+ public static readonly PdfName AA_ENTER = PdfName.E;
+ public static readonly PdfName AA_EXIT = PdfName.X;
+ public static readonly PdfName AA_DOWN = PdfName.D;
+ public static readonly PdfName AA_UP = PdfName.U;
+ public static readonly PdfName AA_FOCUS = PdfName.FO;
+ public static readonly PdfName AA_BLUR = PdfName.BL;
+ public static readonly PdfName AA_JS_KEY = PdfName.K;
+ public static readonly PdfName AA_JS_FORMAT = PdfName.F;
+ public static readonly PdfName AA_JS_CHANGE = PdfName.V;
+ public static readonly PdfName AA_JS_OTHER_CHANGE = PdfName.C;
+ public const int MARKUP_HIGHLIGHT = 0;
+ public const int MARKUP_UNDERLINE = 1;
+ public const int MARKUP_STRIKEOUT = 2;
+ /** attributevalue */
+ public const int MARKUP_SQUIGGLY = 3;
+ protected internal PdfWriter writer;
+ protected internal PdfIndirectReference reference;
+ protected internal Hashtable templates;
+ protected internal bool form = false;
+ protected internal bool annotation = true;
+
+ /** Holds value of property used. */
+ protected internal bool used = false;
+
+ /** Holds value of property placeInPage. */
+ private int placeInPage = -1;
+
+ // constructors
+ public PdfAnnotation(PdfWriter writer, Rectangle rect) {
+ this.writer = writer;
+ if (rect != null)
+ Put(PdfName.RECT, new PdfRectangle(rect));
+ }
+
+ /**
+ * Constructs a new PdfAnnotation
of subtype text.
+ */
+
+ public PdfAnnotation(PdfWriter writer, float llx, float lly, float urx, float ury, PdfString title, PdfString content) {
+ this.writer = writer;
+ Put(PdfName.SUBTYPE, PdfName.TEXT);
+ Put(PdfName.T, title);
+ Put(PdfName.RECT, new PdfRectangle(llx, lly, urx, ury));
+ Put(PdfName.CONTENTS, content);
+ }
+
+ /**
+ * Constructs a new PdfAnnotation
of subtype link (Action).
+ */
+
+ public PdfAnnotation(PdfWriter writer, float llx, float lly, float urx, float ury, PdfAction action) {
+ this.writer = writer;
+ Put(PdfName.SUBTYPE, PdfName.LINK);
+ Put(PdfName.RECT, new PdfRectangle(llx, lly, urx, ury));
+ Put(PdfName.A, action);
+ Put(PdfName.BORDER, new PdfBorderArray(0, 0, 0));
+ Put(PdfName.C, new PdfColor(0x00, 0x00, 0xFF));
+ }
+
+ /**
+ * Creates a screen PdfAnnotation
+ * @param writer
+ * @param rect
+ * @param clipTitle
+ * @param fs
+ * @param mimeType
+ * @param playOnDisplay
+ * @return a screen PdfAnnotation
+ * @throws IOException
+ */
+ public static PdfAnnotation CreateScreen(PdfWriter writer, Rectangle rect, String clipTitle, PdfFileSpecification fs,
+ String mimeType, bool playOnDisplay) {
+ PdfAnnotation ann = new PdfAnnotation(writer, rect);
+ ann.Put(PdfName.SUBTYPE, PdfName.SCREEN);
+ ann.Put (PdfName.F, new PdfNumber(FLAGS_PRINT));
+ ann.Put(PdfName.TYPE, PdfName.ANNOT);
+ ann.SetPage();
+ PdfIndirectReference refi = ann.IndirectReference;
+ PdfAction action = PdfAction.Rendition(clipTitle,fs,mimeType, refi);
+ PdfIndirectReference actionRef = writer.AddToBody(action).IndirectReference;
+ // for play on display add trigger event
+ if (playOnDisplay)
+ {
+ PdfDictionary aa = new PdfDictionary();
+ aa.Put(new PdfName("PV"), actionRef);
+ ann.Put(PdfName.AA, aa);
+ }
+ ann.Put(PdfName.A, actionRef);
+ return ann;
+ }
+
+ public PdfIndirectReference IndirectReference {
+ get {
+ if (reference == null) {
+ reference = writer.PdfIndirectReference;
+ }
+ return reference;
+ }
+ }
+
+ public static PdfAnnotation CreateText(PdfWriter writer, Rectangle rect, string title, string contents, bool open, string icon) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ annot.Put(PdfName.SUBTYPE, PdfName.TEXT);
+ if (title != null)
+ annot.Put(PdfName.T, new PdfString(title, PdfObject.TEXT_UNICODE));
+ if (contents != null)
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ if (open)
+ annot.Put(PdfName.OPEN, PdfBoolean.PDFTRUE);
+ if (icon != null) {
+ annot.Put(PdfName.NAME, new PdfName(icon));
+ }
+ return annot;
+ }
+
+ protected static PdfAnnotation CreateLink(PdfWriter writer, Rectangle rect, PdfName highlight) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ annot.Put(PdfName.SUBTYPE, PdfName.LINK);
+ if (!highlight.Equals(HIGHLIGHT_INVERT))
+ annot.Put(PdfName.H, highlight);
+ return annot;
+ }
+
+ public static PdfAnnotation CreateLink(PdfWriter writer, Rectangle rect, PdfName highlight, PdfAction action) {
+ PdfAnnotation annot = CreateLink(writer, rect, highlight);
+ annot.PutEx(PdfName.A, action);
+ return annot;
+ }
+
+ public static PdfAnnotation CreateLink(PdfWriter writer, Rectangle rect, PdfName highlight, string namedDestination) {
+ PdfAnnotation annot = CreateLink(writer, rect, highlight);
+ annot.Put(PdfName.DEST, new PdfString(namedDestination));
+ return annot;
+ }
+
+ public static PdfAnnotation CreateLink(PdfWriter writer, Rectangle rect, PdfName highlight, int page, PdfDestination dest) {
+ PdfAnnotation annot = CreateLink(writer, rect, highlight);
+ PdfIndirectReference piref = writer.GetPageReference(page);
+ dest.AddPage(piref);
+ annot.Put(PdfName.DEST, dest);
+ return annot;
+ }
+
+ public static PdfAnnotation CreateFreeText(PdfWriter writer, Rectangle rect, string contents, PdfContentByte defaultAppearance) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ annot.Put(PdfName.SUBTYPE, PdfName.FREETEXT);
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ annot.DefaultAppearanceString = defaultAppearance;
+ return annot;
+ }
+
+ public static PdfAnnotation CreateLine(PdfWriter writer, Rectangle rect, string contents, float x1, float y1, float x2, float y2) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ annot.Put(PdfName.SUBTYPE, PdfName.LINE);
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ PdfArray array = new PdfArray(new PdfNumber(x1));
+ array.Add(new PdfNumber(y1));
+ array.Add(new PdfNumber(x2));
+ array.Add(new PdfNumber(y2));
+ annot.Put(PdfName.L, array);
+ return annot;
+ }
+
+ public static PdfAnnotation CreateSquareCircle(PdfWriter writer, Rectangle rect, string contents, bool square) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ if (square)
+ annot.Put(PdfName.SUBTYPE, PdfName.SQUARE);
+ else
+ annot.Put(PdfName.SUBTYPE, PdfName.CIRCLE);
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ return annot;
+ }
+
+ public static PdfAnnotation CreateMarkup(PdfWriter writer, Rectangle rect, string contents, int type, float[] quadPoints) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ PdfName name = PdfName.HIGHLIGHT;
+ switch (type) {
+ case MARKUP_UNDERLINE:
+ name = PdfName.UNDERLINE;
+ break;
+ case MARKUP_STRIKEOUT:
+ name = PdfName.STRIKEOUT;
+ break;
+ case MARKUP_SQUIGGLY:
+ name = PdfName.SQUIGGLY;
+ break;
+ }
+ annot.Put(PdfName.SUBTYPE, name);
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ PdfArray array = new PdfArray();
+ for (int k = 0; k < quadPoints.Length; ++k)
+ array.Add(new PdfNumber(quadPoints[k]));
+ annot.Put(PdfName.QUADPOINTS, array);
+ return annot;
+ }
+
+ public static PdfAnnotation CreateStamp(PdfWriter writer, Rectangle rect, string contents, string name) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ annot.Put(PdfName.SUBTYPE, PdfName.STAMP);
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ annot.Put(PdfName.NAME, new PdfName(name));
+ return annot;
+ }
+
+ public static PdfAnnotation CreateInk(PdfWriter writer, Rectangle rect, string contents, float[][] inkList) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ annot.Put(PdfName.SUBTYPE, PdfName.INK);
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ PdfArray outer = new PdfArray();
+ for (int k = 0; k < inkList.Length; ++k) {
+ PdfArray inner = new PdfArray();
+ float[] deep = inkList[k];
+ for (int j = 0; j < deep.Length; ++j)
+ inner.Add(new PdfNumber(deep[j]));
+ outer.Add(inner);
+ }
+ annot.Put(PdfName.INKLIST, outer);
+ return annot;
+ }
+
+ /** Creates a file attachment annotation.
+ * @param writer the PdfWriter
+ * @param rect the dimensions in the page of the annotation
+ * @param contents the file description
+ * @param fileStore an array with the file. If it's null
+ * the file will be read from the disk
+ * @param file the path to the file. It will only be used if
+ * fileStore
is not null
+ * @param fileDisplay the actual file name stored in the pdf
+ * @throws IOException on error
+ * @return the annotation
+ */
+ public static PdfAnnotation CreateFileAttachment(PdfWriter writer, Rectangle rect, String contents, byte[] fileStore, String file, String fileDisplay) {
+ return CreateFileAttachment(writer, rect, contents, PdfFileSpecification.FileEmbedded(writer, file, fileDisplay, fileStore));
+ }
+
+ /** Creates a file attachment annotation
+ * @param writer
+ * @param rect
+ * @param contents
+ * @param fs
+ * @return the annotation
+ * @throws IOException
+ */
+ public static PdfAnnotation CreateFileAttachment(PdfWriter writer, Rectangle rect, String contents, PdfFileSpecification fs) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ annot.Put(PdfName.SUBTYPE, PdfName.FILEATTACHMENT);
+ if (contents != null)
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ annot.Put(PdfName.FS, fs.Reference);
+ return annot;
+ }
+
+ public static PdfAnnotation CreatePopup(PdfWriter writer, Rectangle rect, string contents, bool open) {
+ PdfAnnotation annot = new PdfAnnotation(writer, rect);
+ annot.Put(PdfName.SUBTYPE, PdfName.POPUP);
+ if (contents != null)
+ annot.Put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE));
+ if (open)
+ annot.Put(PdfName.OPEN, PdfBoolean.PDFTRUE);
+ return annot;
+ }
+
+ public PdfContentByte DefaultAppearanceString {
+ set {
+ byte[] b = value.InternalBuffer.ToByteArray();
+ int len = b.Length;
+ for (int k = 0; k < len; ++k) {
+ if (b[k] == '\n')
+ b[k] = 32;
+ }
+ Put(PdfName.DA, new PdfString(b));
+ }
+ }
+
+ public int Flags {
+ set {
+ if (value == 0)
+ Remove(PdfName.F);
+ else
+ Put(PdfName.F, new PdfNumber(value));
+ }
+ }
+
+ public PdfBorderArray Border {
+ set {
+ Put(PdfName.BORDER, value);
+ }
+ }
+
+ public PdfBorderDictionary BorderStyle {
+ set {
+ Put(PdfName.BS, value);
+ }
+ }
+
+ /**
+ * Sets the annotation's highlighting mode. The values can be
+ * HIGHLIGHT_NONE
, HIGHLIGHT_INVERT
,
+ * HIGHLIGHT_OUTLINE
and HIGHLIGHT_PUSH
;
+ * @param highlight the annotation's highlighting mode
+ */
+ public void SetHighlighting(PdfName highlight) {
+ if (highlight.Equals(HIGHLIGHT_INVERT))
+ Remove(PdfName.H);
+ else
+ Put(PdfName.H, highlight);
+ }
+
+ public void SetAppearance(PdfName ap, PdfTemplate template) {
+ PdfDictionary dic = (PdfDictionary)Get(PdfName.AP);
+ if (dic == null)
+ dic = new PdfDictionary();
+ dic.Put(ap, template.IndirectReference);
+ Put(PdfName.AP, dic);
+ if (!form)
+ return;
+ if (templates == null)
+ templates = new Hashtable();
+ templates[template] = null;
+ }
+
+ public void SetAppearance(PdfName ap, string state, PdfTemplate template) {
+ PdfDictionary dicAp = (PdfDictionary)Get(PdfName.AP);
+ if (dicAp == null)
+ dicAp = new PdfDictionary();
+
+ PdfDictionary dic;
+ PdfObject obj = dicAp.Get(ap);
+ if (obj != null && obj.IsDictionary())
+ dic = (PdfDictionary)obj;
+ else
+ dic = new PdfDictionary();
+ dic.Put(new PdfName(state), template.IndirectReference);
+ dicAp.Put(ap, dic);
+ Put(PdfName.AP, dicAp);
+ if (!form)
+ return;
+ if (templates == null)
+ templates = new Hashtable();
+ templates[template] = null;
+ }
+
+ public string AppearanceState {
+ set {
+ if (value == null) {
+ Remove(PdfName.AS);
+ return;
+ }
+ Put(PdfName.AS, new PdfName(value));
+ }
+ }
+
+ public Color Color {
+ set {
+ Put(PdfName.C, new PdfColor(value));
+ }
+ }
+
+ public string Title {
+ set {
+ if (value == null) {
+ Remove(PdfName.T);
+ return;
+ }
+ Put(PdfName.T, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public PdfAnnotation Popup {
+ set {
+ Put(PdfName.POPUP, value.IndirectReference);
+ value.Put(PdfName.PARENT, this.IndirectReference);
+ }
+ }
+
+ public PdfAction Action {
+ set {
+ Put(PdfName.A, value);
+ }
+ }
+
+ public void SetAdditionalActions(PdfName key, PdfAction action) {
+ PdfDictionary dic;
+ PdfObject obj = Get(PdfName.AA);
+ if (obj != null && obj.IsDictionary())
+ dic = (PdfDictionary)obj;
+ else
+ dic = new PdfDictionary();
+ dic.Put(key, action);
+ Put(PdfName.AA, dic);
+ }
+
+ internal virtual bool IsUsed() {
+ return used;
+ }
+
+ public virtual void SetUsed() {
+ used = true;
+ }
+
+ public Hashtable Templates {
+ get {
+ return templates;
+ }
+ }
+
+ /** Getter for property form.
+ * @return Value of property form.
+ */
+ public bool IsForm() {
+ return form;
+ }
+
+ /** Getter for property annotation.
+ * @return Value of property annotation.
+ */
+ public bool IsAnnotation() {
+ return annotation;
+ }
+
+ public int Page {
+ set {
+ Put(PdfName.P, writer.GetPageReference(value));
+ }
+ }
+
+ public void SetPage() {
+ Put(PdfName.P, writer.CurrentPage);
+ }
+
+ /** Getter for property placeInPage.
+ * @return Value of property placeInPage.
+ */
+ public int PlaceInPage {
+ get {
+ return placeInPage;
+ }
+
+ set {
+ this.placeInPage = value;
+ }
+ }
+
+ public static PdfAnnotation ShallowDuplicate(PdfAnnotation annot) {
+ PdfAnnotation dup;
+ if (annot.IsForm()) {
+ dup = new PdfFormField(annot.writer);
+ PdfFormField dupField = (PdfFormField)dup;
+ PdfFormField srcField = (PdfFormField)annot;
+ dupField.parent = srcField.parent;
+ dupField.kids = srcField.kids;
+ }
+ else
+ dup = new PdfAnnotation(annot.writer, null);
+ dup.Merge(annot);
+ dup.form = annot.form;
+ dup.annotation = annot.annotation;
+ dup.templates = annot.templates;
+ return dup;
+ }
+
+ public int Rotate {
+ set {
+ Put(PdfName.ROTATE, new PdfNumber(value));
+ }
+ }
+
+ internal PdfDictionary MK {
+ get {
+ PdfDictionary mk = (PdfDictionary)Get(PdfName.MK);
+ if (mk == null) {
+ mk = new PdfDictionary();
+ Put(PdfName.MK, mk);
+ }
+ return mk;
+ }
+ }
+
+ public int MKRotation {
+ set {
+ MK.Put(PdfName.R, new PdfNumber(value));
+ }
+ }
+
+ public static PdfArray GetMKColor(Color color) {
+ PdfArray array = new PdfArray();
+ int type = ExtendedColor.GetType(color);
+ switch (type) {
+ case ExtendedColor.TYPE_GRAY: {
+ array.Add(new PdfNumber(((GrayColor)color).Gray));
+ break;
+ }
+ case ExtendedColor.TYPE_CMYK: {
+ CMYKColor cmyk = (CMYKColor)color;
+ array.Add(new PdfNumber(cmyk.Cyan));
+ array.Add(new PdfNumber(cmyk.Magenta));
+ array.Add(new PdfNumber(cmyk.Yellow));
+ array.Add(new PdfNumber(cmyk.Black));
+ break;
+ }
+ case ExtendedColor.TYPE_SEPARATION:
+ case ExtendedColor.TYPE_PATTERN:
+ case ExtendedColor.TYPE_SHADING:
+ throw new Exception("Separations, patterns and shadings are not allowed in MK dictionary.");
+ default:
+ array.Add(new PdfNumber(color.R / 255f));
+ array.Add(new PdfNumber(color.G / 255f));
+ array.Add(new PdfNumber(color.B / 255f));
+ break;
+ }
+ return array;
+ }
+
+ public Color MKBorderColor {
+ set {
+ if (value == null)
+ MK.Remove(PdfName.BC);
+ else
+ MK.Put(PdfName.BC, GetMKColor(value));
+ }
+ }
+
+ public Color MKBackgroundColor {
+ set {
+ if (value == null)
+ MK.Remove(PdfName.BG);
+ else
+ MK.Put(PdfName.BG, GetMKColor(value));
+ }
+ }
+
+ public string MKNormalCaption {
+ set {
+ MK.Put(PdfName.CA, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public string MKRolloverCaption {
+ set {
+ MK.Put(PdfName.RC, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public string MKAlternateCaption {
+ set {
+ MK.Put(PdfName.AC, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public PdfTemplate MKNormalIcon {
+ set {
+ MK.Put(PdfName.I, value.IndirectReference);
+ }
+ }
+
+ public PdfTemplate MKRolloverIcon {
+ set {
+ MK.Put(PdfName.RI, value.IndirectReference);
+ }
+ }
+
+ public PdfTemplate MKAlternateIcon {
+ set {
+ MK.Put(PdfName.IX, value.IndirectReference);
+ }
+ }
+
+ public void SetMKIconFit(PdfName scale, PdfName scalingType, float leftoverLeft, float leftoverBottom, bool fitInBounds) {
+ PdfDictionary dic = new PdfDictionary();
+ if (!scale.Equals(PdfName.A))
+ dic.Put(PdfName.SW, scale);
+ if (!scalingType.Equals(PdfName.P))
+ dic.Put(PdfName.S, scalingType);
+ if (leftoverLeft != 0.5f || leftoverBottom != 0.5f) {
+ PdfArray array = new PdfArray(new PdfNumber(leftoverLeft));
+ array.Add(new PdfNumber(leftoverBottom));
+ dic.Put(PdfName.A, array);
+ }
+ if (fitInBounds)
+ dic.Put(PdfName.FB, PdfBoolean.PDFTRUE);
+ MK.Put(PdfName.IF, dic);
+ }
+
+ public int MKTextPosition {
+ set {
+ MK.Put(PdfName.TP, new PdfNumber(value));
+ }
+ }
+
+ /**
+ * Sets the layer this annotation belongs to.
+ * @param layer the layer this annotation belongs to
+ */
+ public IPdfOCG Layer {
+ set {
+ Put(PdfName.OC, value.Ref);
+ }
+ }
+
+ /**
+ * Sets the name of the annotation.
+ * With this name the annotation can be identified among
+ * all the annotations on a page (it has to be unique).
+ */
+ public String Name {
+ set {
+ Put(PdfName.NM, new PdfString(value));
+ }
+ }
+
+ /**
+ * This class processes links from imported pages so that they may be active. The following example code reads a group
+ * of files and places them all on the output PDF, four pages in a single page, keeping the links active.
+ *
+ * String[] files = new String[] {"input1.pdf", "input2.pdf"};
+ * String outputFile = "output.pdf";
+ * int firstPage=1;
+ * Document document = new Document();
+ * PdfWriter writer = PdfWriter.GetInstance(document, new FileOutputStream(outputFile));
+ * document.SetPageSize(PageSize.A4);
+ * float W = PageSize.A4.GetWidth() / 2;
+ * float H = PageSize.A4.GetHeight() / 2;
+ * document.Open();
+ * PdfContentByte cb = writer.GetDirectContent();
+ * for (int i = 0; i < files.length; i++) {
+ * PdfReader currentReader = new PdfReader(files[i]);
+ * currentReader.ConsolidateNamedDestinations();
+ * for (int page = 1; page <= currentReader.GetNumberOfPages(); page++) {
+ * PdfImportedPage importedPage = writer.GetImportedPage(currentReader, page);
+ * float a = 0.5f;
+ * float e = (page % 2 == 0) ? W : 0;
+ * float f = (page % 4 == 1 || page % 4 == 2) ? H : 0;
+ * ArrayList links = currentReader.GetLinks(page);
+ * cb.AddTemplate(importedPage, a, 0, 0, a, e, f);
+ * for (int j = 0; j < links.Size(); j++) {
+ * PdfAnnotation.PdfImportedLink link = (PdfAnnotation.PdfImportedLink)links.Get(j);
+ * if (link.IsInternal()) {
+ * int dPage = link.GetDestinationPage();
+ * int newDestPage = (dPage-1)/4 + firstPage;
+ * float ee = (dPage % 2 == 0) ? W : 0;
+ * float ff = (dPage % 4 == 1 || dPage % 4 == 2) ? H : 0;
+ * link.SetDestinationPage(newDestPage);
+ * link.TransformDestination(a, 0, 0, a, ee, ff);
+ * }
+ * link.TransformRect(a, 0, 0, a, e, f);
+ * writer.AddAnnotation(link.CreateAnnotation(writer));
+ * }
+ * if (page % 4 == 0)
+ * document.NewPage();
+ * }
+ * if (i < files.length - 1)
+ * document.NewPage();
+ * firstPage += (currentReader.GetNumberOfPages()+3)/4;
+ * }
+ * document.Close();
+ *
+ */
+ public class PdfImportedLink {
+ float llx, lly, urx, ury;
+ Hashtable parameters;
+ PdfArray destination = null;
+ int newPage=0;
+
+ internal PdfImportedLink(PdfDictionary annotation) {
+ parameters = (Hashtable)annotation.hashMap.Clone();
+ try {
+ destination = (PdfArray)parameters[PdfName.DEST];
+ parameters.Remove(PdfName.DEST);
+ } catch (Exception) {
+ throw new ArgumentException("You have to consolidate the named destinations of your reader.");
+ }
+ if (destination != null) {
+ destination = new PdfArray(destination);
+ }
+ PdfArray rc = (PdfArray)parameters[PdfName.RECT];
+ parameters.Remove(PdfName.RECT);
+ llx = rc.GetAsNumber(0).FloatValue;
+ lly = rc.GetAsNumber(1).FloatValue;
+ urx = rc.GetAsNumber(2).FloatValue;
+ ury = rc.GetAsNumber(3).FloatValue;
+ }
+
+ public bool IsInternal() {
+ return destination != null;
+ }
+
+ public int GetDestinationPage() {
+ if (!IsInternal()) return 0;
+
+ // here destination is something like
+ // [132 0 R, /XYZ, 29.3898, 731.864502, null]
+ PdfIndirectReference refi = destination.GetAsIndirectObject(0);
+
+ PRIndirectReference pr = (PRIndirectReference) refi;
+ PdfReader r = pr.Reader;
+ for (int i = 1; i <= r.NumberOfPages; i++) {
+ PRIndirectReference pp = r.GetPageOrigRef(i);
+ if (pp.Generation == pr.Generation && pp.Number == pr.Number) return i;
+ }
+ throw new ArgumentException("Page not found.");
+ }
+
+ public void SetDestinationPage(int newPage) {
+ if (!IsInternal()) throw new ArgumentException("Cannot change destination of external link");
+ this.newPage=newPage;
+ }
+
+ public void TransformDestination(float a, float b, float c, float d, float e, float f) {
+ if (!IsInternal()) throw new ArgumentException("Cannot change destination of external link");
+ if (destination.GetAsName(1).Equals(PdfName.XYZ)) {
+ float x = destination.GetAsNumber(2).FloatValue;
+ float y = destination.GetAsNumber(3).FloatValue;
+ float xx = x * a + y * c + e;
+ float yy = x * b + y * d + f;
+ destination.ArrayList[2] = new PdfNumber(xx);
+ destination.ArrayList[3] = new PdfNumber(yy);
+ }
+ }
+
+ public void TransformRect(float a, float b, float c, float d, float e, float f) {
+ float x = llx * a + lly * c + e;
+ float y = llx * b + lly * d + f;
+ llx = x;
+ lly = y;
+ x = urx * a + ury * c + e;
+ y = urx * b + ury * d + f;
+ urx = x;
+ ury = y;
+ }
+
+ public PdfAnnotation CreateAnnotation(PdfWriter writer) {
+ PdfAnnotation annotation = new PdfAnnotation(writer, new Rectangle(llx, lly, urx, ury));
+ if (newPage != 0) {
+ PdfIndirectReference refi = writer.GetPageReference(newPage);
+ destination.ArrayList[0] = refi;
+ }
+ if (destination != null) annotation.Put(PdfName.DEST, destination);
+ foreach (object key in parameters.Keys)
+ annotation.hashMap[key] = parameters[key];
+ return annotation;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfAppearance.cs b/iTechSharp/iTextSharp/text/pdf/PdfAppearance.cs
new file mode 100644
index 0000000..3f780f8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfAppearance.cs
@@ -0,0 +1,175 @@
+using System;
+using System.Collections;
+
+/*
+ * Copyright 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * Implements the appearance stream to be used with form fields..
+ */
+
+ public class PdfAppearance : PdfTemplate {
+
+ public static Hashtable stdFieldFontNames = new Hashtable();
+
+ static PdfAppearance() {
+ stdFieldFontNames["Courier-BoldOblique"] = new PdfName("CoBO");
+ stdFieldFontNames["Courier-Bold"] = new PdfName("CoBo");
+ stdFieldFontNames["Courier-Oblique"] = new PdfName("CoOb");
+ stdFieldFontNames["Courier"] = new PdfName("Cour");
+ stdFieldFontNames["Helvetica-BoldOblique"] = new PdfName("HeBO");
+ stdFieldFontNames["Helvetica-Bold"] = new PdfName("HeBo");
+ stdFieldFontNames["Helvetica-Oblique"] = new PdfName("HeOb");
+ stdFieldFontNames["Helvetica"] = PdfName.HELV;
+ stdFieldFontNames["Symbol"] = new PdfName("Symb");
+ stdFieldFontNames["Times-BoldItalic"] = new PdfName("TiBI");
+ stdFieldFontNames["Times-Bold"] = new PdfName("TiBo");
+ stdFieldFontNames["Times-Italic"] = new PdfName("TiIt");
+ stdFieldFontNames["Times-Roman"] = new PdfName("TiRo");
+ stdFieldFontNames["ZapfDingbats"] = PdfName.ZADB;
+ stdFieldFontNames["HYSMyeongJo-Medium"] = new PdfName("HySm");
+ stdFieldFontNames["HYGoThic-Medium"] = new PdfName("HyGo");
+ stdFieldFontNames["HeiseiKakuGo-W5"] = new PdfName("KaGo");
+ stdFieldFontNames["HeiseiMin-W3"] = new PdfName("KaMi");
+ stdFieldFontNames["MHei-Medium"] = new PdfName("MHei");
+ stdFieldFontNames["MSung-Light"] = new PdfName("MSun");
+ stdFieldFontNames["STSong-Light"] = new PdfName("STSo");
+ stdFieldFontNames["MSungStd-Light"] = new PdfName("MSun");
+ stdFieldFontNames["STSongStd-Light"] = new PdfName("STSo");
+ stdFieldFontNames["HYSMyeongJoStd-Medium"] = new PdfName("HySm");
+ stdFieldFontNames["KozMinPro-Regular"] = new PdfName("KaMi");
+ }
+
+ /**
+ *Creates a PdfAppearance
.
+ */
+
+ internal PdfAppearance() : base() {
+ separator = ' ';
+ }
+
+ internal PdfAppearance(PdfIndirectReference iref) {
+ thisReference = iref;
+ }
+ /**
+ * Creates new PdfTemplate
+ *
+ * @param wr the PdfWriter
+ */
+
+ internal PdfAppearance(PdfWriter wr) : base(wr) {
+ separator = ' ';
+ }
+
+ /**
+ * Creates a new appearance to be used with form fields.
+ *
+ * @param width the bounding box width
+ * @param height the bounding box height
+ * @return the appearance created
+ */
+ public static PdfAppearance CreateAppearance(PdfWriter writer, float width, float height) {
+ return CreateAppearance(writer, width, height, null);
+ }
+
+ internal static PdfAppearance CreateAppearance(PdfWriter writer, float width, float height, PdfName forcedName) {
+ PdfAppearance template = new PdfAppearance(writer);
+ template.Width = width;
+ template.Height = height;
+ writer.AddDirectTemplateSimple(template, forcedName);
+ return template;
+ }
+
+ /**
+ * Set the font and the size for the subsequent text writing.
+ *
+ * @param bf the font
+ * @param size the font size in points
+ */
+ public override void SetFontAndSize(BaseFont bf, float size) {
+ CheckWriter();
+ state.size = size;
+ if (bf.FontType == BaseFont.FONT_TYPE_DOCUMENT) {
+ state.fontDetails = new FontDetails(null, ((DocumentFont)bf).IndirectReference, bf);
+ }
+ else
+ state.fontDetails = writer.AddSimple(bf);
+ PdfName psn = (PdfName)stdFieldFontNames[bf.PostscriptFontName];
+ if (psn == null) {
+ if (bf.Subset && bf.FontType == BaseFont.FONT_TYPE_TTUNI)
+ psn = state.fontDetails.FontName;
+ else {
+ psn = new PdfName(bf.PostscriptFontName);
+ state.fontDetails.Subset = false;
+ }
+ }
+ PageResources prs = PageResources;
+ prs.AddFont(psn, state.fontDetails.IndirectReference);
+ content.Append(psn.GetBytes()).Append(' ').Append(size).Append(" Tf").Append_i(separator);
+ }
+
+ public override PdfContentByte Duplicate {
+ get {
+ PdfAppearance tpl = new PdfAppearance();
+ tpl.writer = writer;
+ tpl.pdf = pdf;
+ tpl.thisReference = thisReference;
+ tpl.pageResources = pageResources;
+ tpl.bBox = new Rectangle(bBox);
+ tpl.group = group;
+ tpl.layer = layer;
+ if (matrix != null) {
+ tpl.matrix = new PdfArray(matrix);
+ }
+ tpl.separator = separator;
+ return tpl;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfArray.cs b/iTechSharp/iTextSharp/text/pdf/PdfArray.cs
new file mode 100644
index 0000000..ca8f0bf
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfArray.cs
@@ -0,0 +1,295 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.util;
+
+/*
+ * $Id: PdfArray.cs,v 1.7 2008/05/13 11:25:18 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+/**
+ * PdfArray
is the PDF Array object.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.6 (page 40).
+ *
+ * @see PdfObject
+ */
+
+public class PdfArray : PdfObject {
+
+ // membervariables
+
+/** this is the actual array of PdfObjects */
+ protected ArrayList arrayList;
+
+ // constructors
+
+/**
+ * Constructs an empty PdfArray
-object.
+ */
+
+ public PdfArray() : base(ARRAY) {
+ arrayList = new ArrayList();
+ }
+
+/**
+ * Constructs an PdfArray
-object, containing 1 PdfObject
.
+ *
+ * @param object a PdfObject
that has to be added to the array
+ */
+
+ public PdfArray(PdfObject obj) : base(ARRAY) {
+ arrayList = new ArrayList();
+ arrayList.Add(obj);
+ }
+
+ public PdfArray(float[] values) : base(ARRAY) {
+ arrayList = new ArrayList();
+ Add(values);
+ }
+
+ public PdfArray(int[] values) : base(ARRAY) {
+ arrayList = new ArrayList();
+ Add(values);
+ }
+
+/**
+ * Constructs an PdfArray
-object, containing all the PdfObject
s in a given PdfArray
.
+ *
+ * @param array a PdfArray
that has to be added to the array
+ */
+
+ public PdfArray(PdfArray array) : base(ARRAY) {
+ arrayList = new ArrayList(array.ArrayList);
+ }
+
+ // methods overriding some methods in PdfObject
+
+/**
+ * Returns the PDF representation of this PdfArray
.
+ *
+ * @return an array of byte
s
+ */
+
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ os.WriteByte((byte)'[');
+ bool first = true;
+ PdfObject obj = null;
+ foreach (PdfObject obja in arrayList) {
+ obj = (obja == null) ? PdfNull.PDFNULL : obja;
+ type = obj.Type;
+ if (!first && type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING)
+ os.WriteByte((byte)' ');
+ first = false;
+ obj.ToPdf(writer, os);
+ }
+ os.WriteByte((byte)']');
+ }
+
+ // methods concerning the ArrayList-membervalue
+
+/**
+ * Returns an ArrayList containing PdfObject
s.
+ *
+ * @return an ArrayList
+ */
+
+ public ArrayList ArrayList {
+ get {
+ return arrayList;
+ }
+ }
+
+/**
+ * Returns the number of entries in the array.
+ *
+ * @return the size of the ArrayList
+ */
+
+ public int Size {
+ get {
+ return arrayList.Count;
+ }
+ }
+
+/**
+ * Adds a PdfObject
to the PdfArray
.
+ *
+ * @param object PdfObject
to add
+ * @return true
+ */
+
+ public virtual bool Add(PdfObject obj) {
+ arrayList.Add(obj);
+ return true;
+ }
+
+ public bool Add(float[] values) {
+ for (int k = 0; k < values.Length; ++k)
+ arrayList.Add(new PdfNumber(values[k]));
+ return true;
+ }
+
+ public bool Add(int[] values) {
+ for (int k = 0; k < values.Length; ++k)
+ arrayList.Add(new PdfNumber(values[k]));
+ return true;
+ }
+
+/**
+ * Adds a PdfObject
to the PdfArray
.
+ * ArrayList
.
+ *
+ * @param object PdfObject
to add
+ */
+
+ public void AddFirst(PdfObject obj) {
+ arrayList.Insert(0, obj);
+ }
+
+/**
+ * Checks if the PdfArray
allready contains a certain PdfObject
.
+ *
+ * @param object PdfObject
to check
+ * @return true
+ */
+
+ public bool Contains(PdfObject obj) {
+ return arrayList.Contains(obj);
+ }
+
+ public ListIterator GetListIterator() {
+ return new ListIterator(arrayList);
+ }
+
+ public override string ToString() {
+ return arrayList.ToString();
+ }
+
+ public PdfObject GetPdfObject( int idx ) {
+ return (PdfObject)arrayList[idx];
+ }
+
+ public PdfObject GetDirectObject( int idx ) {
+ return PdfReader.GetPdfObject(GetPdfObject(idx));
+ }
+
+ // more of the same like PdfDictionary. (MAS 2/17/06)
+ public PdfDictionary GetAsDict(int idx) {
+ PdfDictionary dict = null;
+ PdfObject orig = GetDirectObject(idx);
+ if (orig != null && orig.IsDictionary())
+ dict = (PdfDictionary) orig;
+ return dict;
+ }
+
+ public PdfArray GetAsArray(int idx) {
+ PdfArray array = null;
+ PdfObject orig = GetDirectObject(idx);
+ if (orig != null && orig.IsArray())
+ array = (PdfArray) orig;
+ return array;
+ }
+
+ public PdfStream GetAsStream(int idx) {
+ PdfStream stream = null;
+ PdfObject orig = GetDirectObject(idx);
+ if (orig != null && orig.IsStream())
+ stream = (PdfStream) orig;
+ return stream;
+ }
+
+ public PdfString GetAsString(int idx) {
+ PdfString str = null;
+ PdfObject orig = GetDirectObject(idx);
+ if (orig != null && orig.IsString())
+ str = (PdfString) orig;
+ return str;
+ }
+
+ public PdfNumber GetAsNumber(int idx) {
+ PdfNumber number = null;
+ PdfObject orig = GetDirectObject(idx);
+ if (orig != null && orig.IsNumber())
+ number = (PdfNumber) orig;
+ return number;
+ }
+
+ public PdfName GetAsName(int idx) {
+ PdfName name = null;
+ PdfObject orig = GetDirectObject(idx);
+ if (orig != null && orig.IsName())
+ name = (PdfName) orig;
+ return name;
+ }
+
+ public PdfBoolean GetAsBoolean(int idx) {
+ PdfBoolean b = null;
+ PdfObject orig = GetDirectObject(idx);
+ if (orig != null && orig.IsBoolean())
+ b = (PdfBoolean) orig;
+ return b;
+ }
+
+ public PdfIndirectReference GetAsIndirectObject(int idx) {
+ PdfIndirectReference refi = null;
+ PdfObject orig = GetPdfObject(idx); // not getDirect this time.
+ if (orig != null && orig.IsIndirect())
+ refi = (PdfIndirectReference) orig;
+ return refi;
+ }
+}
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfBoolean.cs b/iTechSharp/iTextSharp/text/pdf/PdfBoolean.cs
new file mode 100644
index 0000000..785308a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfBoolean.cs
@@ -0,0 +1,137 @@
+using System;
+
+/*
+ * $Id: PdfBoolean.cs,v 1.5 2008/05/13 11:25:18 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfBoolean
is the bool object represented by the keywords true or false.
+ * PdfBoolean
*/
+ public const string TRUE = "true";
+
+ /** A possible value of PdfBoolean
*/
+ public const string FALSE = "false";
+
+ // membervariables
+
+ /** the bool value of this object */
+ private bool value;
+
+ // constructors
+
+ /**
+ * Constructs a PdfBoolean
-object.
+ *
+ * @param value the value of the new PdfObject
+ */
+
+ public PdfBoolean(bool value) : base(BOOLEAN) {
+ if (value) {
+ this.Content = TRUE;
+ }
+ else {
+ this.Content = FALSE;
+ }
+ this.value = value;
+ }
+
+ /**
+ * Constructs a PdfBoolean
-object.
+ *
+ * @param value the value of the new PdfObject
, represented as a string
+ *
+ * @throws BadPdfFormatException thrown if the value isn't 'true
' or 'false
'
+ */
+
+ public PdfBoolean(string value) : base(BOOLEAN, value) {
+ if (value.Equals(TRUE)) {
+ this.value = true;
+ }
+ else if (value.Equals(FALSE)) {
+ this.value = false;
+ }
+ else {
+ throw new BadPdfFormatException("The value has to be 'true' of 'false', instead of '" + value + "'.");
+ }
+ }
+
+ // methods returning the value of this object
+
+ /**
+ * Returns the primitive value of the PdfBoolean
-object.
+ *
+ * @return the actual value of the object.
+ */
+
+ public bool BooleanValue {
+ get {
+ return value;
+ }
+ }
+
+ public override string ToString() {
+ return value ? TRUE : FALSE;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfBorderArray.cs b/iTechSharp/iTextSharp/text/pdf/PdfBorderArray.cs
new file mode 100644
index 0000000..8654d8f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfBorderArray.cs
@@ -0,0 +1,82 @@
+using System;
+
+/*
+ * $Id: PdfBorderArray.cs,v 1.3 2008/05/13 11:25:18 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfBorderArray
defines the border of a PdfAnnotation
.
+ *
+ * @see PdfArray
+ */
+
+ public class PdfBorderArray : PdfArray {
+
+ // constructors
+
+ /**
+ * Constructs a new PdfBorderArray
.
+ */
+
+ public PdfBorderArray(float hRadius, float vRadius, float width) : this(hRadius, vRadius, width, null) {}
+
+ /**
+ * Constructs a new PdfBorderArray
.
+ */
+
+ public PdfBorderArray(float hRadius, float vRadius, float width, PdfDashPattern dash) : base(new PdfNumber(hRadius)) {
+ Add(new PdfNumber(vRadius));
+ Add(new PdfNumber(width));
+ if (dash != null)
+ Add(dash);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfBorderDictionary.cs b/iTechSharp/iTextSharp/text/pdf/PdfBorderDictionary.cs
new file mode 100644
index 0000000..1604521
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfBorderDictionary.cs
@@ -0,0 +1,101 @@
+using System;
+
+/*
+ * $Id: PdfBorderDictionary.cs,v 1.3 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfBorderDictionary
define the appearance of a Border (Annotations).
+ *
+ * @see PdfDictionary
+ */
+
+ public class PdfBorderDictionary : PdfDictionary {
+
+ public const int STYLE_SOLID = 0;
+ public const int STYLE_DASHED = 1;
+ public const int STYLE_BEVELED = 2;
+ public const int STYLE_INSET = 3;
+ public const int STYLE_UNDERLINE = 4;
+ // constructors
+
+ /**
+ * Constructs a PdfBorderDictionary
.
+ */
+
+ public PdfBorderDictionary(float borderWidth, int borderStyle, PdfDashPattern dashes) {
+ Put(PdfName.W, new PdfNumber(borderWidth));
+ switch (borderStyle) {
+ case STYLE_SOLID:
+ Put(PdfName.S, PdfName.S);
+ break;
+ case STYLE_DASHED:
+ if (dashes != null)
+ Put(PdfName.D, dashes);
+ Put(PdfName.S, PdfName.D);
+ break;
+ case STYLE_BEVELED:
+ Put(PdfName.S, PdfName.B);
+ break;
+ case STYLE_INSET:
+ Put(PdfName.S, PdfName.I);
+ break;
+ case STYLE_UNDERLINE:
+ Put(PdfName.S, PdfName.U);
+ break;
+ default:
+ throw new ArgumentException("Invalid border style.");
+ }
+ }
+
+ public PdfBorderDictionary(float borderWidth, int borderStyle) : this(borderWidth, borderStyle, null) {}
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfCell.cs b/iTechSharp/iTextSharp/text/pdf/PdfCell.cs
new file mode 100644
index 0000000..c0633f8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfCell.cs
@@ -0,0 +1,875 @@
+using System;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfCell.cs,v 1.10 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfCell
is the PDF translation of a Cell
.
+ * PdfCell
is an ArrayList
of PdfLine
s.
+ *
+ * @see iTextSharp.text.Rectangle
+ * @see iTextSharp.text.Cell
+ * @see PdfLine
+ * @see PdfTable
+ */
+
+ public class PdfCell : Rectangle {
+
+ // membervariables
+
+ /** These are the PdfLines in the Cell. */
+ private ArrayList lines;
+
+ /** These are the PdfLines in the Cell. */
+ private PdfLine line;
+
+ /** These are the Images in the Cell. */
+ private ArrayList images;
+
+ /** This is the leading of the lines. */
+ private float leading;
+
+ /** This is the number of the row the cell is in. */
+ private int rownumber;
+
+ /** This is the rowspan of the cell. */
+ private int rowspan;
+
+ /** This is the cellspacing of the cell. */
+ private float cellspacing;
+
+ /** This is the cellpadding of the cell. */
+ private float cellpadding;
+
+ /** Indicates if this cell belongs to the header of a PdfTable
*/
+ private bool header = false;
+
+ /**
+ * This is the total height of the content of the cell. Note that the actual cell
+ * height may be larger due to another cell on the row *
+ */
+ private float contentHeight = 0.0f;
+
+ /**
+ * Indicates that the largest ascender height should be used to
+ * determine the height of the first line. Setting this to true can help
+ * with vertical alignment problems. */
+ private bool useAscender;
+
+ /**
+ * Indicates that the largest descender height should be added to the height of
+ * the last line (so characters like y don't dip into the border). */
+ private bool useDescender;
+
+ /**
+ * Adjusts the cell contents to compensate for border widths.
+ */
+ private bool useBorderPadding;
+
+ private int verticalAlignment;
+
+ private PdfLine firstLine;
+ private PdfLine lastLine;
+
+ // constructors
+
+ /**
+ * Constructs a PdfCell
-object.
+ *
+ * @param cell the original Cell
+ * @param rownumber the number of the Row
the Cell
was in.
+ * @param left the left border of the PdfCell
+ * @param right the right border of the PdfCell
+ * @param top the top border of the PdfCell
+ * @param cellspacing the cellspacing of the Table
+ * @param cellpadding the cellpadding of the Table
+ */
+
+ public PdfCell(Cell cell, int rownumber, float left, float right, float top, float cellspacing, float cellpadding) : base(left, top, right, top) {
+ // copying the other Rectangle attributes from class Cell
+ CloneNonPositionParameters(cell);
+ this.cellpadding = cellpadding;
+ this.cellspacing = cellspacing;
+ this.verticalAlignment = cell.VerticalAlignment;
+ this.useAscender = cell.UseAscender;
+ this.useDescender = cell.UseDescender;
+ this.useBorderPadding = cell.UseBorderPadding;
+
+ // initialisation of some parameters
+ PdfChunk chunk;
+ PdfChunk overflow;
+ lines = new ArrayList();
+ images = new ArrayList();
+ leading = cell.Leading;
+ int alignment = cell.HorizontalAlignment;
+ left += cellspacing + cellpadding;
+ right -= cellspacing + cellpadding;
+
+ left += GetBorderWidthInside(LEFT_BORDER);
+ right -= GetBorderWidthInside(RIGHT_BORDER);
+ contentHeight = 0;
+ rowspan = cell.Rowspan;
+
+ ArrayList allActions;
+ int aCounter;
+ // we loop over all the elements of the cell
+ foreach (IElement ele in cell.Elements) {
+ switch (ele.Type) {
+ case Element.JPEG:
+ case Element.JPEG2000:
+ case Element.IMGRAW:
+ case Element.IMGTEMPLATE:
+ AddImage((Image)ele, left, right, 0.4f * leading, alignment);
+ break;
+ // if the element is a list
+ case Element.LIST:
+ if (line != null && line.Size > 0) {
+ line.ResetAlignment();
+ AddLine(line);
+ }
+ // we loop over all the listitems
+ AddList((List)ele, left, right, alignment);
+ line = new PdfLine(left, right, alignment, leading);
+ break;
+ // if the element is something else
+ default:
+ allActions = new ArrayList();
+ ProcessActions(ele, null, allActions);
+ aCounter = 0;
+
+ float currentLineLeading = leading;
+ float currentLeft = left;
+ float currentRight = right;
+ if (ele is Phrase) {
+ currentLineLeading = ((Phrase) ele).Leading;
+ }
+ if (ele is Paragraph) {
+ Paragraph p = (Paragraph) ele;
+ currentLeft += p.IndentationLeft;
+ currentRight -= p.IndentationRight;
+ }
+ if (line == null) {
+ line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
+ }
+ // we loop over the chunks
+ ArrayList chunks = ele.Chunks;
+ if (chunks.Count == 0) {
+ AddLine(line); // add empty line - all cells need some lines even if they are empty
+ line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
+ }
+ else {
+ foreach (Chunk c in chunks) {
+ chunk = new PdfChunk(c, (PdfAction)allActions[aCounter++]);
+ while ((overflow = line.Add(chunk)) != null) {
+ AddLine(line);
+ line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
+ chunk = overflow;
+ }
+ }
+ }
+ // if the element is a paragraph, section or chapter, we reset the alignment and add the line
+ switch (ele.Type) {
+ case Element.PARAGRAPH:
+ case Element.SECTION:
+ case Element.CHAPTER:
+ line.ResetAlignment();
+ FlushCurrentLine();
+ break;
+ }
+ break;
+ }
+ }
+ FlushCurrentLine();
+ if (lines.Count > cell.MaxLines) {
+ while (lines.Count > cell.MaxLines) {
+ RemoveLine(lines.Count - 1);
+ }
+ if (cell.MaxLines > 0) {
+ String more = cell.ShowTruncation;
+ if (more != null && more.Length > 0) {
+ // Denote that the content has been truncated
+ lastLine = (PdfLine) lines[lines.Count - 1];
+ if (lastLine.Size >= 0) {
+ PdfChunk lastChunk = lastLine.GetChunk(lastLine.Size - 1);
+ float moreWidth = new PdfChunk(more, lastChunk).Width;
+ while (lastChunk.ToString().Length > 0 && lastChunk.Width + moreWidth > right - left) {
+ // Remove characters to leave room for the 'more' indicator
+ lastChunk.Value = lastChunk.ToString().Substring(0, lastChunk.Length - 1);
+ }
+ lastChunk.Value = lastChunk.ToString() + more;
+ } else {
+ lastLine.Add(new PdfChunk(new Chunk(more), null));
+ }
+ }
+ }
+ }
+ // we set some additional parameters
+ if (useDescender && lastLine != null) {
+ contentHeight -= lastLine.Descender;
+ }
+
+ // adjust first line height so that it touches the top
+ if (lines.Count > 0) {
+ firstLine = (PdfLine) lines[0];
+ float firstLineRealHeight = FirstLineRealHeight;
+ contentHeight -= firstLine.Height;
+ firstLine.height = firstLineRealHeight;
+ contentHeight += firstLineRealHeight;
+ }
+
+ float newBottom = top - contentHeight - (2f * Cellpadding) - (2f * Cellspacing);
+ newBottom -= GetBorderWidthInside(TOP_BORDER) + GetBorderWidthInside(BOTTOM_BORDER);
+ Bottom = newBottom;
+
+ this.rownumber = rownumber;
+ }
+
+ private void AddList(List list, float left, float right, int alignment) {
+ PdfChunk chunk;
+ PdfChunk overflow;
+ ArrayList allActions = new ArrayList();
+ ProcessActions(list, null, allActions);
+ int aCounter = 0;
+ foreach (IElement ele in list.Items) {
+ switch (ele.Type) {
+ case Element.LISTITEM:
+ ListItem item = (ListItem)ele;
+ line = new PdfLine(left + item.IndentationLeft, right, alignment, item.Leading);
+ line.ListItem = item;
+ foreach (Chunk c in item.Chunks) {
+ chunk = new PdfChunk(c, (PdfAction)(allActions[aCounter++]));
+ while ((overflow = line.Add(chunk)) != null) {
+ AddLine(line);
+ line = new PdfLine(left + item.IndentationLeft, right, alignment, item.Leading);
+ chunk = overflow;
+ }
+ line.ResetAlignment();
+ AddLine(line);
+ line = new PdfLine(left + item.IndentationLeft, right, alignment, leading);
+ }
+ break;
+ case Element.LIST:
+ List sublist = (List)ele;
+ AddList(sublist, left + sublist.IndentationLeft, right, alignment);
+ break;
+ }
+ }
+ }
+
+ // overriding of the Rectangle methods
+
+ /**
+ * Returns the lower left x-coordinaat.
+ *
+ * @return the lower left x-coordinaat
+ */
+
+ public override float Left {
+ get {
+ return base.GetLeft(cellspacing);
+ }
+ }
+
+ /**
+ * Returns the upper right x-coordinate.
+ *
+ * @return the upper right x-coordinate
+ */
+
+ public override float Right {
+ get {
+ return base.GetRight(cellspacing);
+ }
+ }
+
+ /**
+ * Returns the upper right y-coordinate.
+ *
+ * @return the upper right y-coordinate
+ */
+
+ public override float Top {
+ get {
+ return base.GetTop(cellspacing);
+ }
+ }
+
+ /**
+ * Returns the lower left y-coordinate.
+ *
+ * @return the lower left y-coordinate
+ */
+
+ public override float Bottom {
+ get {
+ return base.GetBottom(cellspacing);
+ }
+ set {
+ base.Bottom = value;
+ float firstLineRealHeight = FirstLineRealHeight;
+
+ float totalHeight = ury - value; // can't use top (already compensates for cellspacing)
+ float nonContentHeight = (Cellpadding * 2f) + (Cellspacing * 2f);
+ nonContentHeight += GetBorderWidthInside(TOP_BORDER) + GetBorderWidthInside(BOTTOM_BORDER);
+
+ float interiorHeight = totalHeight - nonContentHeight;
+ float extraHeight = 0.0f;
+
+ switch (verticalAlignment) {
+ case Element.ALIGN_BOTTOM:
+ extraHeight = interiorHeight - contentHeight;
+ break;
+ case Element.ALIGN_MIDDLE:
+ extraHeight = (interiorHeight - contentHeight) / 2.0f;
+ break;
+ default: // ALIGN_TOP
+ extraHeight = 0f;
+ break;
+ }
+
+ extraHeight += Cellpadding + Cellspacing;
+ extraHeight += GetBorderWidthInside(TOP_BORDER);
+ if (firstLine != null) {
+ firstLine.height = firstLineRealHeight + extraHeight;
+ }
+ }
+ }
+
+ // methods
+
+ private void AddLine(PdfLine line) {
+ lines.Add(line);
+ contentHeight += line.Height;
+ lastLine = line;
+ this.line = null;
+ }
+
+ private PdfLine RemoveLine(int index) {
+ PdfLine oldLine = (PdfLine)lines[index];
+ lines.RemoveAt(index);
+ contentHeight -= oldLine.Height;
+ if (index == 0) {
+ if (lines.Count > 0) {
+ firstLine = (PdfLine) lines[0];
+ float firstLineRealHeight = FirstLineRealHeight;
+ contentHeight -= firstLine.Height;
+ firstLine.height = firstLineRealHeight;
+ contentHeight += firstLineRealHeight;
+ }
+ }
+ return oldLine;
+ }
+
+ private void FlushCurrentLine() {
+ if (line != null && line.Size > 0) {
+ AddLine(line);
+ }
+ }
+
+ /**
+ * Calculates what the height of the first line should be so that the content will be
+ * flush with the top. For text, this is the height of the ascender. For an image,
+ * it is the actual height of the image.
+ * @return the real height of the first line
+ */
+ private float FirstLineRealHeight {
+ get {
+ float firstLineRealHeight = 0f;
+ if (firstLine != null) {
+ PdfChunk chunk = firstLine.GetChunk(0);
+ if (chunk != null) {
+ Image image = chunk.Image;
+ if (image != null) {
+ firstLineRealHeight = firstLine.GetChunk(0).Image.ScaledHeight;
+ } else {
+ firstLineRealHeight = useAscender ? firstLine.Ascender : leading;
+ }
+ }
+ }
+ return firstLineRealHeight;
+ }
+ }
+
+ /**
+ * Gets the amount of the border for the specified side that is inside the Rectangle.
+ * For non-variable width borders this is only 1/2 the border width on that side. This
+ * always returns 0 if {@link #useBorderPadding} is false;
+ * @param side the side to check. One of the side constants in {@link com.lowagie.text.Rectangle}
+ * @return the borderwidth inside the cell
+ */
+ private float GetBorderWidthInside(int side) {
+ float width = 0f;
+ if (useBorderPadding) {
+ switch (side) {
+ case iTextSharp.text.Rectangle.LEFT_BORDER:
+ width = BorderWidthLeft;
+ break;
+
+ case iTextSharp.text.Rectangle.RIGHT_BORDER:
+ width = BorderWidthRight;
+ break;
+
+ case iTextSharp.text.Rectangle.TOP_BORDER:
+ width = BorderWidthTop;
+ break;
+
+ default: // default and BOTTOM
+ width = BorderWidthBottom;
+ break;
+ }
+ // non-variable (original style) borders overlap the rectangle (only 1/2 counts)
+ if (!UseVariableBorders) {
+ width = width / 2f;
+ }
+ }
+ return width;
+ }
+
+
+ /**
+ * Adds an image to this Cell.
+ *
+ * @param i the image to add
+ * @param left the left border
+ * @param right the right border
+ * @param extraHeight extra height to add above image
+ * @param alignment horizontal alignment (constant from Element class)
+ * @return the height of the image
+ */
+
+ private float AddImage(Image i, float left, float right, float extraHeight, int alignment) {
+ Image image = Image.GetInstance(i);
+ if (image.ScaledWidth > right - left) {
+ image.ScaleToFit(right - left, float.MaxValue);
+ }
+ FlushCurrentLine();
+ if (line == null) {
+ line = new PdfLine(left, right, alignment, leading);
+ }
+ PdfLine imageLine = line;
+
+ // left and right in chunk is relative to the start of the line
+ right = right - left;
+ left = 0f;
+
+ if ((image.Alignment & Image.RIGHT_ALIGN) == Image.RIGHT_ALIGN) { // fix Uwe Zimmerman
+ left = right - image.ScaledWidth;
+ } else if ((image.Alignment & Image.MIDDLE_ALIGN) == Image.MIDDLE_ALIGN) {
+ left = left + ((right - left - image.ScaledWidth) / 2f);
+ }
+ Chunk imageChunk = new Chunk(image, left, 0);
+ imageLine.Add(new PdfChunk(imageChunk, null));
+ AddLine(imageLine);
+ return imageLine.Height;
+ }
+
+ /**
+ * Gets the lines of a cell that can be drawn between certain limits.
+ * ArrayList
of PdfLine
s
+ */
+
+ public ArrayList GetLines(float top, float bottom) {
+ float lineHeight;
+ float currentPosition = Math.Min(this.Top, top);
+ this.Top = currentPosition + cellspacing;
+ ArrayList result = new ArrayList();
+
+ // if the bottom of the page is higher than the top of the cell: do nothing
+ if (Top < bottom) {
+ return result;
+ }
+
+ // we loop over the lines
+ int size = lines.Count;
+ bool aboveBottom = true;
+ for (int i = 0; i < size && aboveBottom; i++) {
+ line = (PdfLine) lines[i];
+ lineHeight = line.Height;
+ currentPosition -= lineHeight;
+ // if the currentPosition is higher than the bottom, we add the line to the result
+ if (currentPosition > (bottom + cellpadding + GetBorderWidthInside(BOTTOM_BORDER))) { // bugfix by Tom Ring and Veerendra Namineni
+ result.Add(line);
+ }
+ else {
+ aboveBottom = false;
+ }
+ }
+ // if the bottom of the cell is higher than the bottom of the page, the cell is written, so we can remove all lines
+ float difference = 0f;
+ if (!header) {
+ if (aboveBottom) {
+ lines = new ArrayList();
+ contentHeight = 0f;
+ }
+ else {
+ size = result.Count;
+ for (int i = 0; i < size; i++) {
+ line = RemoveLine(0);
+ difference += line.Height;
+ }
+ }
+ }
+ if (difference > 0) {
+ foreach (Image image in images) {
+ image.SetAbsolutePosition(image.AbsoluteX, image.AbsoluteY - difference - leading);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Gets the images of a cell that can be drawn between certain limits.
+ * ArrayList
of Image
s
+ */
+
+ public ArrayList GetImages(float top, float bottom) {
+
+ // if the bottom of the page is higher than the top of the cell: do nothing
+ if (this.Top < bottom) {
+ return new ArrayList();
+ }
+ top = Math.Min(this.Top, top);
+ // initialisations
+ float height;
+ ArrayList result = new ArrayList();
+ // we loop over the images
+ ArrayList remove = new ArrayList();
+ foreach (Image image in images) {
+ height = image.AbsoluteY;
+ // if the currentPosition is higher than the bottom, we add the line to the result
+ if (top - height > (bottom + cellpadding)) {
+ image.SetAbsolutePosition(image.AbsoluteX, top - height);
+ result.Add(image);
+ remove.Add(image);
+ }
+ }
+ foreach (Image image in remove) {
+ images.Remove(image);
+ }
+ return result;
+ }
+
+ /**
+ * Checks if this cell belongs to the header of a PdfTable
.
+ *
+ * @return void
+ */
+
+ internal void SetHeader() {
+ header = true;
+ }
+
+ /**
+ * Indicates that this cell belongs to the header of a PdfTable
.
+ */
+
+ internal bool Header {
+ get {
+ return header;
+ }
+ }
+
+ /**
+ * Checks if the cell may be removed.
+ * true
if all the lines are allready drawn; false
otherwise.
+ */
+
+ internal bool MayBeRemoved() {
+ return (header || (lines.Count == 0 && images.Count == 0));
+ }
+
+ /**
+ * Returns the number of lines in the cell.
+ *
+ * @return a value
+ */
+
+ public int Size {
+ get {
+ return lines.Count;
+ }
+ }
+
+ /**
+ * Returns the total height of all the lines in the cell.
+ *
+ * @return a value
+ */
+
+ private float RemainingLinesHeight() {
+ if (lines.Count == 0) return 0;
+ float result = 0;
+ int size = lines.Count;
+ PdfLine line;
+ for (int i = 0; i < size; i++) {
+ line = (PdfLine) lines[i];
+ result += line.Height;
+ }
+ return result;
+ }
+
+ /**
+ * Returns the height needed to draw the remaining text.
+ *
+ * @return a height
+ */
+
+ public float RemainingHeight {
+ get {
+ float result = 0f;
+ foreach (Image image in images) {
+ result += image.ScaledHeight;
+ }
+ return RemainingLinesHeight() + cellspacing + 2 * cellpadding + result;
+ }
+ }
+
+ // methods to retrieve membervariables
+
+ /**
+ * Gets the leading of a cell.
+ *
+ * @return the leading of the lines is the cell.
+ */
+
+ public float Leading {
+ get {
+ return leading;
+ }
+ }
+
+ /**
+ * Gets the number of the row this cell is in..
+ *
+ * @return a number
+ */
+
+ public int Rownumber {
+ get {
+ return rownumber;
+ }
+ }
+
+ /**
+ * Gets the rowspan of a cell.
+ *
+ * @return the rowspan of the cell
+ */
+
+ public int Rowspan {
+ get {
+ return rowspan;
+ }
+ }
+
+ /**
+ * Gets the cellspacing of a cell.
+ *
+ * @return a value
+ */
+
+ public float Cellspacing {
+ get {
+ return cellspacing;
+ }
+ }
+
+ /**
+ * Gets the cellpadding of a cell..
+ *
+ * @return a value
+ */
+
+ public float Cellpadding {
+ get {
+ return cellpadding;
+ }
+ }
+
+ /**
+ * Processes all actions contained in the cell.
+ */
+
+ protected void ProcessActions(IElement element, PdfAction action, ArrayList allActions) {
+ if (element.Type == Element.ANCHOR) {
+ string url = ((Anchor)element).Reference;
+ if (url != null) {
+ action = new PdfAction(url);
+ }
+ }
+ switch (element.Type) {
+ case Element.PHRASE:
+ case Element.SECTION:
+ case Element.ANCHOR:
+ case Element.CHAPTER:
+ case Element.LISTITEM:
+ case Element.PARAGRAPH:
+ foreach (IElement ele in ((ArrayList)element)) {
+ ProcessActions(ele, action, allActions);
+ }
+ break;
+ case Element.CHUNK:
+ allActions.Add(action);
+ break;
+ case Element.LIST:
+ foreach (IElement ele in ((List)element).Items) {
+ ProcessActions(ele, action, allActions);
+ }
+ break;
+ default:
+ int n = element.Chunks.Count;
+ while (n-- > 0)
+ allActions.Add(action);
+ break;
+ }
+ }
+
+ /**
+ * This is the number of the group the cell is in.
+ */
+ private int groupNumber;
+
+ /**
+ * Gets the number of the group this cell is in..
+ *
+ * @return a number
+ */
+
+ public int GroupNumber {
+ get {
+ return groupNumber;
+ }
+ set {
+ groupNumber = value;
+ }
+ }
+
+ /**
+ * Gets a Rectangle that is altered to fit on the page.
+ *
+ * @param top the top position
+ * @param bottom the bottom position
+ * @return a Rectangle
+ */
+
+ public Rectangle Rectangle(float top, float bottom) {
+ Rectangle tmp = new Rectangle(Left, Bottom, Right, Top);
+ tmp.CloneNonPositionParameters(this);
+ if (Top > top) {
+ tmp.Top = top;
+ tmp.Border = border - (border & TOP_BORDER);
+ }
+ if (Bottom < bottom) {
+ tmp.Bottom = bottom;
+ tmp.Border = border - (border & BOTTOM_BORDER);
+ }
+ return tmp;
+ }
+
+ /**
+ * Gets the value of {@link #useAscender}
+ * @return useAscender
+ */
+ public bool UseAscender {
+ get {
+ return useAscender;
+ }
+ set {
+ useAscender = value;
+ }
+ }
+
+ /**
+ * Gets the value of {@link #useDescender}
+ * @return useDescender
+ */
+ public bool UseDescender {
+ get {
+ return useDescender;
+ }
+ set {
+ useDescender = value;
+ }
+ }
+
+ /**
+ * Sets the value of {@link #useBorderPadding}.
+ * @param use adjust layour for borders if true
+ */
+ public bool UseBorderPadding {
+ set {
+ useBorderPadding = value;
+ }
+ get {
+ return useBorderPadding;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfChunk.cs b/iTechSharp/iTextSharp/text/pdf/PdfChunk.cs
new file mode 100644
index 0000000..bb90e36
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfChunk.cs
@@ -0,0 +1,841 @@
+using System;
+using System.Collections;
+using System.util;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfChunk.cs,v 1.11 2008/05/22 22:11:10 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfChunk
is the PDF translation of a Chunk
.
+ * PdfChunk
is a PdfString
in a certain
+ * PdfFont
and Color
.
+ *
+ * @see PdfString
+ * @see PdfFont
+ * @see iTextSharp.text.Chunk
+ * @see iTextSharp.text.Font
+ */
+
+ public class PdfChunk {
+
+
+ private static char[] singleSpace = {' '};
+ private static PdfChunk[] thisChunk = new PdfChunk[1];
+ private const float ITALIC_ANGLE = 0.21256f;
+
+ /** The allowed attributes in variable attributes
. */
+ private static Hashtable keysAttributes = new Hashtable();
+
+ /** The allowed attributes in variable noStroke
. */
+ private static Hashtable keysNoStroke = new Hashtable();
+
+ static PdfChunk() {
+ keysAttributes.Add(Chunk.ACTION, null);
+ keysAttributes.Add(Chunk.UNDERLINE, null);
+ keysAttributes.Add(Chunk.REMOTEGOTO, null);
+ keysAttributes.Add(Chunk.LOCALGOTO, null);
+ keysAttributes.Add(Chunk.LOCALDESTINATION, null);
+ keysAttributes.Add(Chunk.GENERICTAG, null);
+ keysAttributes.Add(Chunk.NEWPAGE, null);
+ keysAttributes.Add(Chunk.IMAGE, null);
+ keysAttributes.Add(Chunk.BACKGROUND, null);
+ keysAttributes.Add(Chunk.PDFANNOTATION, null);
+ keysAttributes.Add(Chunk.SKEW, null);
+ keysAttributes.Add(Chunk.HSCALE, null);
+ keysAttributes.Add(Chunk.SEPARATOR, null);
+ keysAttributes.Add(Chunk.TAB, null);
+ keysNoStroke.Add(Chunk.SUBSUPSCRIPT, null);
+ keysNoStroke.Add(Chunk.SPLITCHARACTER, null);
+ keysNoStroke.Add(Chunk.HYPHENATION, null);
+ keysNoStroke.Add(Chunk.TEXTRENDERMODE, null);
+ }
+
+ // membervariables
+
+ /** The value of this object. */
+ protected string value = PdfObject.NOTHING;
+
+ /** The encoding. */
+ protected string encoding = BaseFont.WINANSI;
+
+
+ /** The font for this PdfChunk
. */
+ protected PdfFont font;
+
+ protected BaseFont baseFont;
+
+ protected ISplitCharacter splitCharacter;
+ /**
+ * Metric attributes.
+ * true
if the chunk split was cause by a newline. */
+ protected bool newlineSplit;
+
+ /** The image in this PdfChunk
, if it has one */
+ protected Image image;
+
+ /** The offset in the x direction for the image */
+ protected float offsetX;
+
+ /** The offset in the y direction for the image */
+ protected float offsetY;
+
+ /** Indicates if the height and offset of the Image has to be taken into account */
+ protected bool changeLeading = false;
+
+ // constructors
+
+ /**
+ * Constructs a PdfChunk
-object.
+ *
+ * @param string the content of the PdfChunk
-object
+ * @param font the PdfFont
+ * @param attributes the metrics attributes
+ * @param noStroke the non metric attributes
+ */
+
+ internal PdfChunk(string str, PdfChunk other) {
+ thisChunk[0] = this;
+ value = str;
+ this.font = other.font;
+ this.attributes = other.attributes;
+ this.noStroke = other.noStroke;
+ this.baseFont = other.baseFont;
+ Object[] obj = (Object[])attributes[Chunk.IMAGE];
+ if (obj == null)
+ image = null;
+ else {
+ image = (Image)obj[0];
+ offsetX = (float)obj[1];
+ offsetY = (float)obj[2];
+ changeLeading = (bool)obj[3];
+ }
+ encoding = font.Font.Encoding;
+ splitCharacter = (ISplitCharacter)noStroke[Chunk.SPLITCHARACTER];
+ if (splitCharacter == null)
+ splitCharacter = DefaultSplitCharacter.DEFAULT;
+ }
+
+ /**
+ * Constructs a PdfChunk
-object.
+ *
+ * @param chunk the original Chunk
-object
+ * @param action the PdfAction
if the Chunk
comes from an Anchor
+ */
+
+ internal PdfChunk(Chunk chunk, PdfAction action) {
+ thisChunk[0] = this;
+ value = chunk.Content;
+
+ Font f = chunk.Font;
+ float size = f.Size;
+ if (size == iTextSharp.text.Font.UNDEFINED)
+ size = 12;
+ baseFont = f.BaseFont;
+ BaseFont bf = f.BaseFont;
+ int style = f.Style;
+ if (style == iTextSharp.text.Font.UNDEFINED) {
+ style = iTextSharp.text.Font.NORMAL;
+ }
+ if (baseFont == null) {
+ // translation of the font-family to a PDF font-family
+ baseFont = f.GetCalculatedBaseFont(false);
+ }
+ else{
+ // bold simulation
+ if ((style & iTextSharp.text.Font.BOLD) != 0)
+ attributes[Chunk.TEXTRENDERMODE] = new Object[]{PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, size / 30f, null};
+ // italic simulation
+ if ((style & iTextSharp.text.Font.ITALIC) != 0)
+ attributes[Chunk.SKEW] = new float[]{0, ITALIC_ANGLE};
+ }
+ font = new PdfFont(baseFont, size);
+ // other style possibilities
+ Hashtable attr = chunk.Attributes;
+ if (attr != null) {
+ foreach (DictionaryEntry entry in attr) {
+ string name = (string)entry.Key;
+ if (keysAttributes.ContainsKey(name)) {
+ attributes[name] = entry.Value;
+ }
+ else if (keysNoStroke.ContainsKey(name)) {
+ noStroke[name] = entry.Value;
+ }
+ }
+ if ("".Equals(attr[Chunk.GENERICTAG])) {
+ attributes[Chunk.GENERICTAG] = chunk.Content;
+ }
+ }
+ if (f.IsUnderlined()) {
+ Object[] obj = {null, new float[]{0, 1f / 15, 0, -1f / 3, 0}};
+ Object[][] unders = Utilities.AddToArray((Object[][])attributes[Chunk.UNDERLINE], obj);
+ attributes[Chunk.UNDERLINE] = unders;
+ }
+ if (f.IsStrikethru()) {
+ Object[] obj = {null, new float[]{0, 1f / 15, 0, 1f / 3, 0}};
+ Object[][] unders = Utilities.AddToArray((Object[][])attributes[Chunk.UNDERLINE], obj);
+ attributes[Chunk.UNDERLINE] = unders;
+ }
+ if (action != null)
+ attributes[Chunk.ACTION] = action;
+ // the color can't be stored in a PdfFont
+ noStroke[Chunk.COLOR] = f.Color;
+ noStroke[Chunk.ENCODING] = font.Font.Encoding;
+ Object[] obj2 = (Object[])attributes[Chunk.IMAGE];
+ if (obj2 == null)
+ image = null;
+ else {
+ attributes.Remove(Chunk.HSCALE); // images are scaled in other ways
+ image = (Image)obj2[0];
+ offsetX = ((float)obj2[1]);
+ offsetY = ((float)obj2[2]);
+ changeLeading = (bool)obj2[3];
+ }
+ font.Image = image;
+ object hs = attributes[Chunk.HSCALE];
+ if (hs != null)
+ font.HorizontalScaling = (float)hs;
+ encoding = font.Font.Encoding;
+ splitCharacter = (ISplitCharacter)noStroke[Chunk.SPLITCHARACTER];
+ if (splitCharacter == null)
+ splitCharacter = DefaultSplitCharacter.DEFAULT;
+ }
+
+ // methods
+
+ /** Gets the Unicode equivalent to a CID.
+ * The (inexistent) CID PdfChunk
if it's too long for the given width.
+ * PdfChunk
wasn't truncated.
+ *
+ * @param width a given width
+ * @return the PdfChunk
that doesn't fit into the width.
+ */
+
+ internal PdfChunk Split(float width) {
+ newlineSplit = false;
+ if (image != null) {
+ if (image.ScaledWidth > width) {
+ PdfChunk pc = new PdfChunk(Chunk.OBJECT_REPLACEMENT_CHARACTER, this);
+ value = "";
+ attributes = new Hashtable();
+ image = null;
+ font = PdfFont.DefaultFont;
+ return pc;
+ }
+ else
+ return null;
+ }
+ IHyphenationEvent hyphenationEvent = (IHyphenationEvent)noStroke[Chunk.HYPHENATION];
+ int currentPosition = 0;
+ int splitPosition = -1;
+ float currentWidth = 0;
+
+ // loop over all the characters of a string
+ // or until the totalWidth is reached
+ int lastSpace = -1;
+ float lastSpaceWidth = 0;
+ int length = value.Length;
+ char[] valueArray = value.ToCharArray();
+ char character = (char)0;
+ BaseFont ft = font.Font;
+ bool surrogate = false;
+ if (ft.FontType == BaseFont.FONT_TYPE_CJK && ft.GetUnicodeEquivalent(' ') != ' ') {
+ while (currentPosition < length) {
+ // the width of every character is added to the currentWidth
+ char cidChar = valueArray[currentPosition];
+ character = (char)ft.GetUnicodeEquivalent(cidChar);
+ // if a newLine or carriageReturn is encountered
+ if (character == '\n') {
+ newlineSplit = true;
+ string returnValue = value.Substring(currentPosition + 1);
+ value = value.Substring(0, currentPosition);
+ if (value.Length < 1) {
+ value = "\u0001";
+ }
+ PdfChunk pc = new PdfChunk(returnValue, this);
+ return pc;
+ }
+ currentWidth += font.Width(cidChar);
+ if (character == ' ') {
+ lastSpace = currentPosition + 1;
+ lastSpaceWidth = currentWidth;
+ }
+ if (currentWidth > width)
+ break;
+ // if a split-character is encountered, the splitPosition is altered
+ if (splitCharacter.IsSplitCharacter(0, currentPosition, length, valueArray, thisChunk))
+ splitPosition = currentPosition + 1;
+ currentPosition++;
+ }
+ }
+ else {
+ while (currentPosition < length) {
+ // the width of every character is added to the currentWidth
+ character = valueArray[currentPosition];
+ // if a newLine or carriageReturn is encountered
+ if (character == '\r' || character == '\n') {
+ newlineSplit = true;
+ int inc = 1;
+ if (character == '\r' && currentPosition + 1 < length && valueArray[currentPosition + 1] == '\n')
+ inc = 2;
+ string returnValue = value.Substring(currentPosition + inc);
+ value = value.Substring(0, currentPosition);
+ if (value.Length < 1) {
+ value = " ";
+ }
+ PdfChunk pc = new PdfChunk(returnValue, this);
+ return pc;
+ }
+ surrogate = Utilities.IsSurrogatePair(valueArray, currentPosition);
+ if (surrogate)
+ currentWidth += font.Width(Utilities.ConvertToUtf32(valueArray[currentPosition], valueArray[currentPosition + 1]));
+ else
+ currentWidth += font.Width(character);
+ if (character == ' ') {
+ lastSpace = currentPosition + 1;
+ lastSpaceWidth = currentWidth;
+ }
+ if (surrogate)
+ currentPosition++;
+ if (currentWidth > width)
+ break;
+ // if a split-character is encountered, the splitPosition is altered
+ if (splitCharacter.IsSplitCharacter(0, currentPosition, length, valueArray, null))
+ splitPosition = currentPosition + 1;
+ currentPosition++;
+ }
+ }
+
+ // if all the characters fit in the total width, null is returned (there is no overflow)
+ if (currentPosition == length) {
+ return null;
+ }
+ // otherwise, the string has to be truncated
+ if (splitPosition < 0) {
+ string returnValue = value;
+ value = "";
+ PdfChunk pc = new PdfChunk(returnValue, this);
+ return pc;
+ }
+ if (lastSpace > splitPosition && splitCharacter.IsSplitCharacter(0, 0, 1, singleSpace, null))
+ splitPosition = lastSpace;
+ if (hyphenationEvent != null && lastSpace >= 0 && lastSpace < currentPosition) {
+ int wordIdx = GetWord(value, lastSpace);
+ if (wordIdx > lastSpace) {
+ string pre = hyphenationEvent.GetHyphenatedWordPre(value.Substring(lastSpace, wordIdx - lastSpace), font.Font, font.Size, width - lastSpaceWidth);
+ string post = hyphenationEvent.HyphenatedWordPost;
+ if (pre.Length > 0) {
+ string returnValue = post + value.Substring(wordIdx);
+ value = Trim(value.Substring(0, lastSpace) + pre);
+ PdfChunk pc = new PdfChunk(returnValue, this);
+ return pc;
+ }
+ }
+ }
+ string retVal = value.Substring(splitPosition);
+ value = Trim(value.Substring(0, splitPosition));
+ PdfChunk tmp = new PdfChunk(retVal, this);
+ return tmp;
+ }
+
+ /**
+ * Truncates this PdfChunk
if it's too long for the given width.
+ * PdfChunk
wasn't truncated.
+ *
+ * @param width a given width
+ * @return the PdfChunk
that doesn't fit into the width.
+ */
+
+ internal PdfChunk Truncate(float width) {
+ if (image != null) {
+ if (image.ScaledWidth > width) {
+ PdfChunk pc = new PdfChunk("", this);
+ value = "";
+ attributes.Remove(Chunk.IMAGE);
+ image = null;
+ font = PdfFont.DefaultFont;
+ return pc;
+ }
+ else
+ return null;
+ }
+
+ int currentPosition = 0;
+ float currentWidth = 0;
+
+ // it's no use trying to split if there isn't even enough place for a space
+ if (width < font.Width()) {
+ string returnValue = value.Substring(1);
+ value = value.Substring(0, 1);
+ PdfChunk pc = new PdfChunk(returnValue, this);
+ return pc;
+ }
+
+ // loop over all the characters of a string
+ // or until the totalWidth is reached
+ int length = value.Length;
+ bool surrogate = false;
+ while (currentPosition < length) {
+ // the width of every character is added to the currentWidth
+ surrogate = Utilities.IsSurrogatePair(value, currentPosition);
+ if (surrogate)
+ currentWidth += font.Width(Utilities.ConvertToUtf32(value, currentPosition));
+ else
+ currentWidth += font.Width(value[currentPosition]);
+ if (currentWidth > width)
+ break;
+ if (surrogate)
+ currentPosition++;
+ currentPosition++;
+ }
+
+ // if all the characters fit in the total width, null is returned (there is no overflow)
+ if (currentPosition == length) {
+ return null;
+ }
+
+ // otherwise, the string has to be truncated
+ //currentPosition -= 2;
+ // we have to chop off minimum 1 character from the chunk
+ if (currentPosition == 0) {
+ currentPosition = 1;
+ if (surrogate)
+ ++currentPosition;
+ }
+ string retVal = value.Substring(currentPosition);
+ value = value.Substring(0, currentPosition);
+ PdfChunk tmp = new PdfChunk(retVal, this);
+ return tmp;
+ }
+
+ // methods to retrieve the membervariables
+
+ /**
+ * Returns the font of this Chunk
.
+ *
+ * @return a PdfFont
+ */
+
+ internal PdfFont Font {
+ get {
+ return font;
+ }
+ }
+
+ /**
+ * Returns the color of this Chunk
.
+ *
+ * @return a Color
+ */
+
+ internal Color Color {
+ get {
+ return (Color)noStroke[Chunk.COLOR];
+ }
+ }
+
+ /**
+ * Returns the width of this PdfChunk
.
+ *
+ * @return a width
+ */
+
+ internal float Width {
+ get {
+ return font.Width(this.value);
+ }
+ }
+
+ /**
+ * Checks if the PdfChunk
split was caused by a newline.
+ * @return true
if the PdfChunk
split was caused by a newline.
+ */
+
+ public bool IsNewlineSplit() {
+ return newlineSplit;
+ }
+
+ /**
+ * Gets the width of the PdfChunk
taking into account the
+ * extra character and word spacing.
+ * @param charSpacing the extra character spacing
+ * @param wordSpacing the extra word spacing
+ * @return the calculated width
+ */
+
+ public float GetWidthCorrected(float charSpacing, float wordSpacing) {
+ if (image != null) {
+ return image.ScaledWidth + charSpacing;
+ }
+ int numberOfSpaces = 0;
+ int idx = -1;
+ while ((idx = value.IndexOf(' ', idx + 1)) >= 0)
+ ++numberOfSpaces;
+ return Width + (value.Length * charSpacing + numberOfSpaces * wordSpacing);
+ }
+
+ /**
+ * Gets the text displacement relatiev to the baseline.
+ * @return a displacement in points
+ */
+ public float TextRise {
+ get {
+ object f = GetAttribute(Chunk.SUBSUPSCRIPT);
+ if (f != null) {
+ return (float)f;
+ }
+ return 0.0f;
+ }
+ }
+
+ /**
+ * Trims the last space.
+ * @return the width of the space trimmed, otherwise 0
+ */
+
+ public float TrimLastSpace() {
+ BaseFont ft = font.Font;
+ if (ft.FontType == BaseFont.FONT_TYPE_CJK && ft.GetUnicodeEquivalent(' ') != ' ') {
+ if (value.Length > 1 && value.EndsWith("\u0001")) {
+ value = value.Substring(0, value.Length - 1);
+ return font.Width('\u0001');
+ }
+ }
+ else {
+ if (value.Length > 1 && value.EndsWith(" ")) {
+ value = value.Substring(0, value.Length - 1);
+ return font.Width(' ');
+ }
+ }
+ return 0;
+ }
+
+ public float TrimFirstSpace()
+ {
+ BaseFont ft = font.Font;
+ if (ft.FontType == BaseFont.FONT_TYPE_CJK && ft.GetUnicodeEquivalent(' ') != ' ') {
+ if (value.Length > 1 && value.StartsWith("\u0001")) {
+ value = value.Substring(1);
+ return font.Width('\u0001');
+ }
+ }
+ else {
+ if (value.Length > 1 && value.StartsWith(" ")) {
+ value = value.Substring(1);
+ return font.Width(' ');
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Gets an attribute. The search is made in attributes
+ * and noStroke
.
+ * @param name the attribute key
+ * @return the attribute value or null if not found
+ */
+
+ internal Object GetAttribute(string name) {
+ if (attributes.ContainsKey(name))
+ return attributes[name];
+ return noStroke[name];
+ }
+
+ /**
+ *Checks if the attribute exists.
+ * @param name the attribute key
+ * @return true
if the attribute exists
+ */
+
+ internal bool IsAttribute(string name) {
+ if (attributes.ContainsKey(name))
+ return true;
+ return noStroke.ContainsKey(name);
+ }
+
+ /**
+ * Checks if this PdfChunk
needs some special metrics handling.
+ * @return true
if this PdfChunk
needs some special metrics handling.
+ */
+
+ internal bool IsStroked() {
+ return (attributes.Count > 0);
+ }
+
+ /**
+ * Checks if this PdfChunk
is a Separator Chunk.
+ * @return true if this chunk is a separator.
+ * @since 2.1.2
+ */
+ internal bool IsSeparator() {
+ return IsAttribute(Chunk.SEPARATOR);
+ }
+
+ /**
+ * Checks if this PdfChunk
is a horizontal Separator Chunk.
+ * @return true if this chunk is a horizontal separator.
+ * @since 2.1.2
+ */
+ internal bool IsHorizontalSeparator() {
+ if (IsAttribute(Chunk.SEPARATOR)) {
+ Object[] o = (Object[])GetAttribute(Chunk.SEPARATOR);
+ return !(bool)o[1];
+ }
+ return false;
+ }
+
+ /**
+ * Checks if this PdfChunk
is a tab Chunk.
+ * @return true if this chunk is a separator.
+ * @since 2.1.2
+ */
+ internal bool IsTab() {
+ return IsAttribute(Chunk.TAB);
+ }
+
+ /**
+ * Correction for the tab position based on the left starting position.
+ * @param newValue the new value for the left X.
+ * @since 2.1.2
+ */
+ internal void AdjustLeft(float newValue) {
+ Object[] o = (Object[])attributes[Chunk.TAB];
+ if (o != null) {
+ attributes[Chunk.TAB] = new Object[]{o[0], o[1], o[2], newValue};
+ }
+ }
+
+ /**
+ * Checks if there is an image in the PdfChunk
.
+ * @return true
if an image is present
+ */
+
+ internal bool IsImage() {
+ return image != null;
+ }
+
+ /**
+ * Gets the image in the PdfChunk
.
+ * @return the image or null
+ */
+
+ internal Image Image {
+ get {
+ return image;
+ }
+ }
+
+ /**
+ * Gets the image offset in the x direction
+ * @return the image offset in the x direction
+ */
+
+ internal float ImageOffsetX {
+ get {
+ return offsetX;
+ }
+
+ set {
+ this.offsetX = value;
+ }
+ }
+
+ /**
+ * Gets the image offset in the y direction
+ * @return Gets the image offset in the y direction
+ */
+
+ internal float ImageOffsetY {
+ get {
+ return offsetY;
+ }
+
+ set {
+ this.offsetY = value;
+ }
+ }
+
+ /**
+ * sets the value.
+ */
+
+ internal string Value {
+ set {
+ this.value = value;
+ }
+ }
+
+ public override string ToString() {
+ return value;
+ }
+
+ /**
+ * Tells you if this string is in Chinese, Japanese, Korean or Identity-H.
+ */
+
+ internal bool IsSpecialEncoding() {
+ return encoding.Equals(CJKFont.CJK_ENCODING) || encoding.Equals(BaseFont.IDENTITY_H);
+ }
+
+ /**
+ * Gets the encoding of this string.
+ *
+ * @return a string
+ */
+
+ internal string Encoding {
+ get {
+ return encoding;
+ }
+ }
+
+ internal int Length {
+ get {
+ return value.Length;
+ }
+ }
+
+ internal int LengthUtf32 {
+ get {
+ if (!BaseFont.IDENTITY_H.Equals(encoding))
+ return value.Length;
+ int total = 0;
+ int len = value.Length;
+ for (int k = 0; k < len; ++k) {
+ if (Utilities.IsSurrogateHigh(value[k]))
+ ++k;
+ ++total;
+ }
+ return total;
+ }
+ }
+
+ internal bool IsExtSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) {
+ return splitCharacter.IsSplitCharacter(start, current, end, cc, ck);
+ }
+
+ /**
+ * Removes all the ' ' and '-'-characters on the right of a string
.
+ * string
corresponding with the key
+ */
+
+ public PdfObject Get(PdfName key) {
+ return (PdfObject) hashMap[key];
+ }
+
+ // methods concerning the type of Dictionary
+
+ /**
+ * Checks if a that has to be trimmed.
+ * @return the trimmed
PdfObjectstring
+ */
+ internal string Trim(string str) {
+ BaseFont ft = font.Font;
+ if (ft.FontType == BaseFont.FONT_TYPE_CJK && ft.GetUnicodeEquivalent(' ') != ' ') {
+ while (str.EndsWith("\u0001")) {
+ str = str.Substring(0, str.Length - 1);
+ }
+ }
+ else {
+ while (str.EndsWith(" ") || str.EndsWith("\t")) {
+ str = str.Substring(0, str.Length - 1);
+ }
+ }
+ return str;
+ }
+
+ public bool ChangeLeading {
+ get {
+ return changeLeading;
+ }
+ }
+
+ internal float GetCharWidth(int c) {
+ if (NoPrint(c))
+ return 0;
+ return font.Width(c);
+ }
+
+ public static bool NoPrint(int c) {
+ return ((c >= 0x200b && c <= 0x200f) || (c >= 0x202a && c <= 0x202e));
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfColor.cs b/iTechSharp/iTextSharp/text/pdf/PdfColor.cs
new file mode 100644
index 0000000..4b6c831
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfColor.cs
@@ -0,0 +1,80 @@
+using System;
+using iTextSharp.text;
+
+/*
+ * $Id: PdfColor.cs,v 1.3 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * A PdfColor
defines a Color (it's a PdfArray
containing 3 values).
+ *
+ * @see PdfDictionary
+ */
+
+ internal class PdfColor : PdfArray {
+
+ // constructors
+
+ /**
+ * Constructs a new PdfColor
.
+ *
+ * @param red a value between 0 and 255
+ * @param green a value between 0 and 255
+ * @param blue a value between 0 and 255
+ */
+
+ internal PdfColor(int red, int green, int blue) : base(new PdfNumber((double)(red & 0xFF) / 0xFF)) {
+ Add(new PdfNumber((double)(green & 0xFF) / 0xFF));
+ Add(new PdfNumber((double)(blue & 0xFF) / 0xFF));
+ }
+
+ internal PdfColor(Color color) : this(color.R, color.G, color.B) {}
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfContentByte.cs b/iTechSharp/iTextSharp/text/pdf/PdfContentByte.cs
new file mode 100644
index 0000000..b7a817d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfContentByte.cs
@@ -0,0 +1,2898 @@
+using System;
+using System.Collections;
+using System.Text;
+using iTextSharp.text.pdf;
+using iTextSharp.text.pdf.intern;
+
+/*
+ * $Id: PdfContentByte.cs,v 1.23 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfContentByte
is an object containing the user positioned
+ * text and graphic contents of a page. It knows how to apply the proper
+ * font encoding.
+ */
+
+ public class PdfContentByte {
+
+ /**
+ * This class keeps the graphic state of the current page
+ */
+
+ public class GraphicState {
+
+ /** This is the font in use */
+ internal FontDetails fontDetails;
+
+ /** This is the color in use */
+ internal ColorDetails colorDetails;
+
+ /** This is the font size in use */
+ internal float size;
+
+ /** The x position of the text line matrix. */
+ protected internal float xTLM = 0;
+ /** The y position of the text line matrix. */
+ protected internal float yTLM = 0;
+ /** The current text leading. */
+ protected internal float leading = 0;
+
+ /** The current horizontal scaling */
+ protected internal float scale = 100;
+
+ /** The current character spacing */
+ protected internal float charSpace = 0;
+
+ /** The current word spacing */
+ protected internal float wordSpace = 0;
+
+ internal GraphicState() {
+ }
+
+ internal GraphicState(GraphicState cp) {
+ fontDetails = cp.fontDetails;
+ colorDetails = cp.colorDetails;
+ size = cp.size;
+ xTLM = cp.xTLM;
+ yTLM = cp.yTLM;
+ leading = cp.leading;
+ scale = cp.scale;
+ charSpace = cp.charSpace;
+ wordSpace = cp.wordSpace;
+ }
+ }
+
+ /** The alignement is center */
+ public const int ALIGN_CENTER = Element.ALIGN_CENTER;
+
+ /** The alignement is left */
+ public const int ALIGN_LEFT = Element.ALIGN_LEFT;
+
+ /** The alignement is right */
+ public const int ALIGN_RIGHT = Element.ALIGN_RIGHT;
+
+ /** A possible line cap value */
+ public const int LINE_CAP_BUTT = 0;
+ /** A possible line cap value */
+ public const int LINE_CAP_ROUND = 1;
+ /** A possible line cap value */
+ public const int LINE_CAP_PROJECTING_SQUARE = 2;
+
+ /** A possible line join value */
+ public const int LINE_JOIN_MITER = 0;
+ /** A possible line join value */
+ public const int LINE_JOIN_ROUND = 1;
+ /** A possible line join value */
+ public const int LINE_JOIN_BEVEL = 2;
+
+ /** A possible text rendering value */
+ public const int TEXT_RENDER_MODE_FILL = 0;
+ /** A possible text rendering value */
+ public const int TEXT_RENDER_MODE_STROKE = 1;
+ /** A possible text rendering value */
+ public const int TEXT_RENDER_MODE_FILL_STROKE = 2;
+ /** A possible text rendering value */
+ public const int TEXT_RENDER_MODE_INVISIBLE = 3;
+ /** A possible text rendering value */
+ public const int TEXT_RENDER_MODE_FILL_CLIP = 4;
+ /** A possible text rendering value */
+ public const int TEXT_RENDER_MODE_STROKE_CLIP = 5;
+ /** A possible text rendering value */
+ public const int TEXT_RENDER_MODE_FILL_STROKE_CLIP = 6;
+ /** A possible text rendering value */
+ public const int TEXT_RENDER_MODE_CLIP = 7;
+
+ private static float[] unitRect = {0, 0, 0, 1, 1, 0, 1, 1};
+ // membervariables
+
+ /** This is the actual content */
+ protected ByteBuffer content = new ByteBuffer();
+
+ /** This is the writer */
+ protected PdfWriter writer;
+
+ /** This is the PdfDocument */
+ protected PdfDocument pdf;
+
+ /** This is the GraphicState in use */
+ protected GraphicState state = new GraphicState();
+
+ /** The list were we save/restore the layer depth */
+ protected ArrayList layerDepth;
+
+ /** The list were we save/restore the state */
+ protected ArrayList stateList = new ArrayList();
+
+ /** The separator between commands.
+ */
+ protected int separator = '\n';
+
+ private static Hashtable abrev = new Hashtable();
+
+ static PdfContentByte() {
+ abrev[PdfName.BITSPERCOMPONENT] = "/BPC ";
+ abrev[PdfName.COLORSPACE] = "/CS ";
+ abrev[PdfName.DECODE] = "/D ";
+ abrev[PdfName.DECODEPARMS] = "/DP ";
+ abrev[PdfName.FILTER] = "/F ";
+ abrev[PdfName.HEIGHT] = "/H ";
+ abrev[PdfName.IMAGEMASK] = "/IM ";
+ abrev[PdfName.INTENT] = "/Intent ";
+ abrev[PdfName.INTERPOLATE] = "/I ";
+ abrev[PdfName.WIDTH] = "/W ";
+ }
+
+ // constructors
+
+ /**
+ * Constructs a new PdfContentByte
-object.
+ *
+ * @param wr the writer associated to this content
+ */
+
+ public PdfContentByte(PdfWriter wr) {
+ if (wr != null) {
+ writer = wr;
+ pdf = writer.PdfDocument;
+ }
+ }
+
+ // methods to get the content of this object
+
+ /**
+ * Returns the string
representation of this PdfContentByte
-object.
+ *
+ * @return a string
+ */
+
+ public override string ToString() {
+ return content.ToString();
+ }
+
+ /**
+ * Gets the internal buffer.
+ * @return the internal buffer
+ */
+ public ByteBuffer InternalBuffer {
+ get {
+ return content;
+ }
+ }
+
+ /** Returns the PDF representation of this PdfContentByte
-object.
+ *
+ * @param writer the PdfWriter
+ * @return a byte
array with the representation
+ */
+
+ public byte[] ToPdf(PdfWriter writer) {
+ return content.ToByteArray();
+ }
+
+ // methods to add graphical content
+
+ /**
+ * Adds the content of another PdfContent
-object to this object.
+ *
+ * @param other another PdfByteContent
-object
+ */
+
+ public void Add(PdfContentByte other) {
+ if (other.writer != null && writer != other.writer)
+ throw new Exception("Inconsistent writers. Are you mixing two documents?");
+ content.Append(other.content);
+ }
+
+ /**
+ * Gets the x position of the text line matrix.
+ *
+ * @return the x position of the text line matrix
+ */
+ public float XTLM {
+ get {
+ return state.xTLM;
+ }
+ }
+
+ /**
+ * Gets the y position of the text line matrix.
+ *
+ * @return the y position of the text line matrix
+ */
+ public float YTLM {
+ get {
+ return state.yTLM;
+ }
+ }
+
+ /**
+ * Gets the current character spacing.
+ *
+ * @return the current character spacing
+ */
+ public float CharacterSpacing {
+ get {
+ return state.charSpace;
+ }
+ }
+
+ /**
+ * Gets the current word spacing.
+ *
+ * @return the current word spacing
+ */
+ public float WordSpacing {
+ get {
+ return state.wordSpace;
+ }
+ }
+
+ /**
+ * Gets the current character spacing.
+ *
+ * @return the current character spacing
+ */
+ public float HorizontalScaling {
+ get {
+ return state.scale;
+ }
+ }
+
+ /**
+ * Gets the current text leading.
+ *
+ * @return the current text leading
+ */
+ public float Leading {
+ get {
+ return state.leading;
+ }
+ }
+
+ public void SetLeading(float v) {
+ state.leading = v;
+ content.Append(v).Append(" TL").Append_i(separator);
+ }
+
+ /**
+ * Changes the Flatness.
+ *
+ *
+ * @param flatness a value
+ */
+
+ public void SetFlatness(float value) {
+ if (value >= 0 && value <= 100) {
+ content.Append(value).Append(" i").Append_i(separator);
+ }
+ }
+
+ /**
+ * Changes the Line cap style.
+ *
+ * Allowed values are 0 (Butt end caps), 1 (Round end caps) and 2 (Projecting square end caps).
+ *
+ * @param style a value
+ */
+
+ public void SetLineCap(int value) {
+ if (value >= 0 && value <= 2) {
+ content.Append(value).Append(" J").Append_i(separator);
+ }
+ }
+
+ /**
+ * Changes the value of the line dash pattern.
+ *
+ *
+ * @param phase the value of the phase
+ */
+
+ public void SetLineDash(float value) {
+ content.Append("[] ").Append(value).Append(" d").Append_i(separator);
+ }
+
+ /**
+ * Changes the value of the line dash pattern.
+ *
+ *
+ * @param phase the value of the phase
+ * @param unitsOn the number of units that must be 'on' (equals the number of units that must be 'off').
+ */
+
+ public void SetLineDash(float unitsOn, float phase) {
+ content.Append('[').Append(unitsOn).Append("] ").Append(phase).Append(" d").Append_i(separator);
+ }
+
+ /**
+ * Changes the value of the line dash pattern.
+ *
+ *
+ * @param phase the value of the phase
+ * @param unitsOn the number of units that must be 'on'
+ * @param unitsOff the number of units that must be 'off'
+ */
+
+ public void SetLineDash(float unitsOn, float unitsOff, float phase) {
+ content.Append('[').Append(unitsOn).Append(' ').Append(unitsOff).Append("] ").Append(phase).Append(" d").Append_i(separator);
+ }
+
+ /**
+ * Changes the value of the line dash pattern.
+ *
+ *
+ * @param array length of the alternating dashes and gaps
+ * @param phase the value of the phase
+ */
+
+ public void SetLineDash(float[] array, float phase) {
+ content.Append('[');
+ for (int i = 0; i < array.Length; i++) {
+ content.Append(array[i]);
+ if (i < array.Length - 1) content.Append(' ');
+ }
+ content.Append("] ").Append(phase).Append(" d").Append_i(separator);
+ }
+
+ /**
+ * Changes the Line join style.
+ *
+ * Allowed values are 0 (Miter joins), 1 (Round joins) and 2 (Bevel joins).
+ *
+ * @param style a value
+ */
+
+ public void SetLineJoin(int value) {
+ if (value >= 0 && value <= 2) {
+ content.Append(value).Append(" j").Append_i(separator);
+ }
+ }
+
+ /**
+ * Changes the line width.
+ *
+ *
+ * @param w a width
+ */
+
+ public void SetLineWidth(float value) {
+ content.Append(value).Append(" w").Append_i(separator);
+ }
+
+ /**
+ * Changes the Miter limit.
+ *
+ *
+ * @param miterLimit a miter limit
+ */
+
+ public void SetMiterLimit(float value) {
+ if (value > 1) {
+ content.Append(value).Append(" M").Append_i(separator);
+ }
+ }
+
+ /**
+ * Modify the current clipping path by intersecting it with the current path, using the
+ * nonzero winding number rule to determine which regions lie inside the clipping
+ * path.
+ */
+
+ public void Clip() {
+ content.Append('W').Append_i(separator);
+ }
+
+ /**
+ * Modify the current clipping path by intersecting it with the current path, using the
+ * even-odd rule to determine which regions lie inside the clipping path.
+ */
+
+ public void EoClip() {
+ content.Append("W*").Append_i(separator);
+ }
+
+ /**
+ * Changes the currentgray tint for filling paths (device dependent colors!).
+ * Rectangle
+ */
+ public void VariableRectangle(Rectangle rect) {
+ float t = rect.Top;
+ float b = rect.Bottom;
+ float r = rect.Right;
+ float l = rect.Left;
+ float wt = rect.BorderWidthTop;
+ float wb = rect.BorderWidthBottom;
+ float wr = rect.BorderWidthRight;
+ float wl = rect.BorderWidthLeft;
+ Color ct = rect.BorderColorTop;
+ Color cb = rect.BorderColorBottom;
+ Color cr = rect.BorderColorRight;
+ Color cl = rect.BorderColorLeft;
+ SaveState();
+ SetLineCap(PdfContentByte.LINE_CAP_BUTT);
+ SetLineJoin(PdfContentByte.LINE_JOIN_MITER);
+ float clw = 0;
+ bool cdef = false;
+ Color ccol = null;
+ bool cdefi = false;
+ Color cfil = null;
+ // draw top
+ if (wt > 0) {
+ SetLineWidth(clw = wt);
+ cdef = true;
+ if (ct == null)
+ ResetRGBColorStroke();
+ else
+ SetColorStroke(ct);
+ ccol = ct;
+ MoveTo(l, t - wt / 2f);
+ LineTo(r, t - wt / 2f);
+ Stroke();
+ }
+
+ // Draw bottom
+ if (wb > 0) {
+ if (wb != clw)
+ SetLineWidth(clw = wb);
+ if (!cdef || !CompareColors(ccol, cb)) {
+ cdef = true;
+ if (cb == null)
+ ResetRGBColorStroke();
+ else
+ SetColorStroke(cb);
+ ccol = cb;
+ }
+ MoveTo(r, b + wb / 2f);
+ LineTo(l, b + wb / 2f);
+ Stroke();
+ }
+
+ // Draw right
+ if (wr > 0) {
+ if (wr != clw)
+ SetLineWidth(clw = wr);
+ if (!cdef || !CompareColors(ccol, cr)) {
+ cdef = true;
+ if (cr == null)
+ ResetRGBColorStroke();
+ else
+ SetColorStroke(cr);
+ ccol = cr;
+ }
+ bool bt = CompareColors(ct, cr);
+ bool bb = CompareColors(cb, cr);
+ MoveTo(r - wr / 2f, bt ? t : t - wt);
+ LineTo(r - wr / 2f, bb ? b : b + wb);
+ Stroke();
+ if (!bt || !bb) {
+ cdefi = true;
+ if (cr == null)
+ ResetRGBColorFill();
+ else
+ SetColorFill(cr);
+ cfil = cr;
+ if (!bt) {
+ MoveTo(r, t);
+ LineTo(r, t - wt);
+ LineTo(r - wr, t - wt);
+ Fill();
+ }
+ if (!bb) {
+ MoveTo(r, b);
+ LineTo(r, b + wb);
+ LineTo(r - wr, b + wb);
+ Fill();
+ }
+ }
+ }
+
+ // Draw Left
+ if (wl > 0) {
+ if (wl != clw)
+ SetLineWidth(wl);
+ if (!cdef || !CompareColors(ccol, cl)) {
+ if (cl == null)
+ ResetRGBColorStroke();
+ else
+ SetColorStroke(cl);
+ }
+ bool bt = CompareColors(ct, cl);
+ bool bb = CompareColors(cb, cl);
+ MoveTo(l + wl / 2f, bt ? t : t - wt);
+ LineTo(l + wl / 2f, bb ? b : b + wb);
+ Stroke();
+ if (!bt || !bb) {
+ if (!cdefi || !CompareColors(cfil, cl)) {
+ if (cl == null)
+ ResetRGBColorFill();
+ else
+ SetColorFill(cl);
+ }
+ if (!bt) {
+ MoveTo(l, t);
+ LineTo(l, t - wt);
+ LineTo(l + wl, t - wt);
+ Fill();
+ }
+ if (!bb) {
+ MoveTo(l, b);
+ LineTo(l, b + wb);
+ LineTo(l + wl, b + wb);
+ Fill();
+ }
+ }
+ }
+ RestoreState();
+ }
+
+ /**
+ * Adds a border (complete or partially) to the current path..
+ *
+ * @param rectangle a Rectangle
+ */
+
+ public void Rectangle(Rectangle rectangle) {
+ // the coordinates of the border are retrieved
+ float x1 = rectangle.Left;
+ float y1 = rectangle.Bottom;
+ float x2 = rectangle.Right;
+ float y2 = rectangle.Top;
+
+ // the backgroundcolor is set
+ Color background = rectangle.BackgroundColor;
+ if (background != null) {
+ SetColorFill(background);
+ Rectangle(x1, y1, x2 - x1, y2 - y1);
+ Fill();
+ ResetRGBColorFill();
+ }
+
+ // if the element hasn't got any borders, nothing is added
+ if (! rectangle.HasBorders()) {
+ return;
+ }
+
+ // if any of the individual border colors are set
+ // we draw the borders all around using the
+ // different colors
+ if (rectangle.UseVariableBorders) {
+ VariableRectangle(rectangle);
+ }
+ else {
+ // the width is set to the width of the element
+ if (rectangle.BorderWidth != iTextSharp.text.Rectangle.UNDEFINED) {
+ SetLineWidth(rectangle.BorderWidth);
+ }
+
+ // the color is set to the color of the element
+ Color color = rectangle.BorderColor;
+ if (color != null) {
+ SetColorStroke(color);
+ }
+
+ // if the box is a rectangle, it is added as a rectangle
+ if (rectangle.HasBorder(iTextSharp.text.Rectangle.BOX)) {
+ this.Rectangle(x1, y1, x2 - x1, y2 - y1);
+ }
+ // if the border isn't a rectangle, the different sides are added apart
+ else {
+ if (rectangle.HasBorder(iTextSharp.text.Rectangle.RIGHT_BORDER)) {
+ MoveTo(x2, y1);
+ LineTo(x2, y2);
+ }
+ if (rectangle.HasBorder(iTextSharp.text.Rectangle.LEFT_BORDER)) {
+ MoveTo(x1, y1);
+ LineTo(x1, y2);
+ }
+ if (rectangle.HasBorder(iTextSharp.text.Rectangle.BOTTOM_BORDER)) {
+ MoveTo(x1, y1);
+ LineTo(x2, y1);
+ }
+ if (rectangle.HasBorder(iTextSharp.text.Rectangle.TOP_BORDER)) {
+ MoveTo(x1, y2);
+ LineTo(x2, y2);
+ }
+ }
+
+ Stroke();
+
+ if (color != null) {
+ ResetRGBColorStroke();
+ }
+ }
+ }
+
+ /**
+ * Closes the current subpath by appending a straight line segment from the current point
+ * to the starting point of the subpath.
+ */
+
+ public void ClosePath() {
+ content.Append('h').Append_i(separator);
+ }
+
+ /**
+ * Ends the path without filling or stroking it.
+ */
+
+ public void NewPath() {
+ content.Append('n').Append_i(separator);
+ }
+
+ /**
+ * Strokes the path.
+ */
+
+ public void Stroke() {
+ content.Append('S').Append_i(separator);
+ }
+
+ /**
+ * Closes the path and strokes it.
+ */
+
+ public void ClosePathStroke() {
+ content.Append('s').Append_i(separator);
+ }
+
+ /**
+ * Fills the path, using the non-zero winding number rule to determine the region to fill.
+ */
+
+ public void Fill() {
+ content.Append('f').Append_i(separator);
+ }
+
+ /**
+ * Fills the path, using the even-odd rule to determine the region to fill.
+ */
+
+ public void EoFill() {
+ content.Append("f*").Append_i(separator);
+ }
+
+ /**
+ * Fills the path using the non-zero winding number rule to determine the region to fill and strokes it.
+ */
+
+ public void FillStroke() {
+ content.Append('B').Append_i(separator);
+ }
+
+ /**
+ * Closes the path, fills it using the non-zero winding number rule to determine the region to fill and strokes it.
+ */
+
+ public void ClosePathFillStroke() {
+ content.Append('b').Append_i(separator);
+ }
+
+ /**
+ * Fills the path, using the even-odd rule to determine the region to fill and strokes it.
+ */
+
+ public void EoFillStroke() {
+ content.Append("B*").Append_i(separator);
+ }
+
+ /**
+ * Closes the path, fills it using the even-odd rule to determine the region to fill and strokes it.
+ */
+
+ public void ClosePathEoFillStroke() {
+ content.Append("b*").Append_i(separator);
+ }
+
+ /**
+ * Adds an Image
to the page. The Image
must have
+ * absolute positioning.
+ * @param image the Image
object
+ * @throws DocumentException if the Image
does not have absolute positioning
+ */
+ public virtual void AddImage(Image image) {
+ AddImage(image, false);
+ }
+
+ /**
+ * Adds an Image
to the page. The Image
must have
+ * absolute positioning. The image can be placed inline.
+ * @param image the Image
object
+ * @param inlineImage true
to place this image inline, false
otherwise
+ * @throws DocumentException if the Image
does not have absolute positioning
+ */
+ public virtual void AddImage(Image image, bool inlineImage) {
+ if (!image.HasAbsolutePosition())
+ throw new DocumentException("The image must have absolute positioning.");
+ float[] matrix = image.Matrix;
+ matrix[Image.CX] = image.AbsoluteX - matrix[Image.CX];
+ matrix[Image.CY] = image.AbsoluteY - matrix[Image.CY];
+ AddImage(image, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], inlineImage);
+ }
+
+ /**
+ * Adds an Image
to the page. The positioning of the Image
+ * is done with the transformation matrix. To position an image
at (x,y)
+ * use AddImage(image, image_width, 0, 0, image_height, x, y).
+ * @param image the Image
object
+ * @param a an element of the transformation matrix
+ * @param b an element of the transformation matrix
+ * @param c an element of the transformation matrix
+ * @param d an element of the transformation matrix
+ * @param e an element of the transformation matrix
+ * @param f an element of the transformation matrix
+ * @throws DocumentException on error
+ */
+ public virtual void AddImage(Image image, float a, float b, float c, float d, float e, float f) {
+ AddImage(image, a, b, c, d, e, f, false);
+ }
+
+ /**
+ * Adds an Image
to the page. The positioning of the Image
+ * is done with the transformation matrix. To position an image
at (x,y)
+ * use AddImage(image, image_width, 0, 0, image_height, x, y). The image can be placed inline.
+ * @param image the Image
object
+ * @param a an element of the transformation matrix
+ * @param b an element of the transformation matrix
+ * @param c an element of the transformation matrix
+ * @param d an element of the transformation matrix
+ * @param e an element of the transformation matrix
+ * @param f an element of the transformation matrix
+ * @param inlineImage true
to place this image inline, false
otherwise
+ * @throws DocumentException on error
+ */
+ public virtual void AddImage(Image image, float a, float b, float c, float d, float e, float f, bool inlineImage) {
+ if (image.Layer != null)
+ BeginLayer(image.Layer);
+ if (image.IsImgTemplate()) {
+ writer.AddDirectImageSimple(image);
+ PdfTemplate template = image.TemplateData;
+ float w = template.Width;
+ float h = template.Height;
+ AddTemplate(template, a / w, b / w, c / h, d / h, e, f);
+ }
+ else {
+ content.Append("q ");
+ content.Append(a).Append(' ');
+ content.Append(b).Append(' ');
+ content.Append(c).Append(' ');
+ content.Append(d).Append(' ');
+ content.Append(e).Append(' ');
+ content.Append(f).Append(" cm");
+ if (inlineImage) {
+ content.Append("\nBI\n");
+ PdfImage pimage = new PdfImage(image, "", null);
+ foreach (PdfName key in pimage.Keys) {
+ PdfObject value = pimage.Get(key);
+ String s = (String)abrev[key];
+ if (s == null)
+ continue;
+ content.Append(s);
+ bool check = true;
+ if (key.Equals(PdfName.COLORSPACE) && value.IsArray()) {
+ ArrayList ar = ((PdfArray)value).ArrayList;
+ if (ar.Count == 4
+ && PdfName.INDEXED.Equals(ar[0])
+ && ((PdfObject)ar[1]).IsName()
+ && ((PdfObject)ar[2]).IsNumber()
+ && ((PdfObject)ar[3]).IsString()
+ ) {
+ check = false;
+ }
+
+ }
+ if (check && key.Equals(PdfName.COLORSPACE) && !value.IsName()) {
+ PdfName cs = writer.GetColorspaceName();
+ PageResources prs = PageResources;
+ prs.AddColor(cs, writer.AddToBody(value).IndirectReference);
+ value = cs;
+ }
+ value.ToPdf(null, content);
+ content.Append('\n');
+ }
+ content.Append("ID\n");
+ pimage.WriteContent(content);
+ content.Append("\nEI\nQ").Append_i(separator);
+ }
+ else {
+ PdfName name;
+ PageResources prs = PageResources;
+ Image maskImage = image.ImageMask;
+ if (maskImage != null) {
+ name = writer.AddDirectImageSimple(maskImage);
+ prs.AddXObject(name, writer.GetImageReference(name));
+ }
+ name = writer.AddDirectImageSimple(image);
+ name = prs.AddXObject(name, writer.GetImageReference(name));
+ content.Append(' ').Append(name.GetBytes()).Append(" Do Q").Append_i(separator);
+ }
+ }
+ if (image.HasBorders()) {
+ SaveState();
+ float w = image.Width;
+ float h = image.Height;
+ ConcatCTM(a / w, b / w, c / h, d / h, e, f);
+ Rectangle(image);
+ RestoreState();
+ }
+ if (image.Layer != null)
+ EndLayer();
+ Annotation annot = image.Annotation;
+ if (annot == null)
+ return;
+ float[] r = new float[unitRect.Length];
+ for (int k = 0; k < unitRect.Length; k += 2) {
+ r[k] = a * unitRect[k] + c * unitRect[k + 1] + e;
+ r[k + 1] = b * unitRect[k] + d * unitRect[k + 1] + f;
+ }
+ float llx = r[0];
+ float lly = r[1];
+ float urx = llx;
+ float ury = lly;
+ for (int k = 2; k < r.Length; k += 2) {
+ llx = Math.Min(llx, r[k]);
+ lly = Math.Min(lly, r[k + 1]);
+ urx = Math.Max(urx, r[k]);
+ ury = Math.Max(ury, r[k + 1]);
+ }
+ annot = new Annotation(annot);
+ annot.SetDimensions(llx, lly, urx, ury);
+ PdfAnnotation an = PdfAnnotationsImp.ConvertAnnotation(writer, annot, new Rectangle(llx, lly, urx, ury));
+ if (an == null)
+ return;
+ AddAnnotation(an);
+ }
+
+ /**
+ * Makes this PdfContentByte
empty.
+ */
+ public void Reset() {
+ content.Reset();
+ stateList.Clear();
+ state = new GraphicState();
+ }
+
+ /**
+ * Starts the writing of text.
+ */
+ public void BeginText() {
+ state.xTLM = 0;
+ state.yTLM = 0;
+ content.Append("BT").Append_i(separator);
+ }
+
+ /**
+ * Ends the writing of text and makes the current font invalid.
+ */
+ public void EndText() {
+ content.Append("ET").Append_i(separator);
+ }
+
+ /**
+ * Saves the graphic state. saveState
and
+ * restoreState
must be balanced.
+ */
+ public void SaveState() {
+ content.Append('q').Append_i(separator);
+ stateList.Add(new GraphicState(state));
+ }
+
+ /**
+ * Restores the graphic state. saveState
and
+ * restoreState
must be balanced.
+ */
+ public void RestoreState() {
+ content.Append('Q').Append_i(separator);
+ int idx = stateList.Count - 1;
+ if (idx < 0)
+ throw new Exception("Unbalanced save/restore state operators.");
+ state = (GraphicState)stateList[idx];
+ stateList.RemoveAt(idx);
+ }
+
+ /**
+ * Sets the character spacing parameter.
+ *
+ * @param charSpace a parameter
+ */
+ public void SetCharacterSpacing(float value) {
+ state.charSpace = value;
+ content.Append(value).Append(" Tc").Append_i(separator);
+ }
+
+ /**
+ * Sets the word spacing parameter.
+ *
+ * @param wordSpace a parameter
+ */
+ public void SetWordSpacing(float value) {
+ state.wordSpace = value;
+ content.Append(value).Append(" Tw").Append_i(separator);
+ }
+
+ /**
+ * Sets the horizontal scaling parameter.
+ *
+ * @param scale a parameter
+ */
+ public void SetHorizontalScaling(float value) {
+ state.scale = value;
+ content.Append(value).Append(" Tz").Append_i(separator);
+ }
+
+ /**
+ * Set the font and the size for the subsequent text writing.
+ *
+ * @param bf the font
+ * @param size the font size in points
+ */
+ public virtual void SetFontAndSize(BaseFont bf, float size) {
+ CheckWriter();
+ if (size < 0.0001f && size > -0.0001f)
+ throw new ArgumentException("Font size too small: " + size);
+ state.size = size;
+ state.fontDetails = writer.AddSimple(bf);
+ PageResources prs = PageResources;
+ PdfName name = state.fontDetails.FontName;
+ name = prs.AddFont(name, state.fontDetails.IndirectReference);
+ content.Append(name.GetBytes()).Append(' ').Append(size).Append(" Tf").Append_i(separator);
+ }
+
+ /**
+ * Sets the text rendering parameter.
+ *
+ * @param rendering a parameter
+ */
+ public void SetTextRenderingMode(int value) {
+ content.Append(value).Append(" Tr").Append_i(separator);
+ }
+
+ /**
+ * Sets the text rise parameter.
+ * text
+ * converted to bytes according to the font's encoding.
+ *
+ * @param text the text to write
+ */
+ private void ShowText2(string text) {
+ if (state.fontDetails == null)
+ throw new Exception("Font and size must be set before writing any text");
+ byte[] b = state.fontDetails.ConvertToBytes(text);
+ EscapeString(b, content);
+ }
+
+ /**
+ * Shows the text
.
+ *
+ * @param text the text to write
+ */
+ public void ShowText(string text) {
+ ShowText2(text);
+ content.Append("Tj").Append_i(separator);
+ }
+
+ /**
+ * Constructs a kern array for a text in a certain font
+ * @param text the text
+ * @param font the font
+ * @return a PdfTextArray
+ */
+ public static PdfTextArray GetKernArray(String text, BaseFont font) {
+ PdfTextArray pa = new PdfTextArray();
+ StringBuilder acc = new StringBuilder();
+ int len = text.Length - 1;
+ char[] c = text.ToCharArray();
+ if (len >= 0)
+ acc.Append(c, 0, 1);
+ for (int k = 0; k < len; ++k) {
+ char c2 = c[k + 1];
+ int kern = font.GetKerning(c[k], c2);
+ if (kern == 0) {
+ acc.Append(c2);
+ }
+ else {
+ pa.Add(acc.ToString());
+ acc.Length = 0;
+ acc.Append(c, k + 1, 1);
+ pa.Add(-kern);
+ }
+ }
+ pa.Add(acc.ToString());
+ return pa;
+ }
+
+ /**
+ * Shows the text
kerned.
+ *
+ * @param text the text to write
+ */
+ public void ShowTextKerned(String text) {
+ if (state.fontDetails == null)
+ throw new ArgumentNullException("Font and size must be set before writing any text");
+ BaseFont bf = state.fontDetails.BaseFont;
+ if (bf.HasKernPairs())
+ ShowText(GetKernArray(text, bf));
+ else
+ ShowText(text);
+ }
+
+ /**
+ * Moves to the next line and shows text
.
+ *
+ * @param text the text to write
+ */
+ public void NewlineShowText(string text) {
+ state.yTLM -= state.leading;
+ ShowText2(text);
+ content.Append('\'').Append_i(separator);
+ }
+
+ /**
+ * Moves to the next line and shows text string, using the given values of the character and word spacing parameters.
+ *
+ * @param wordSpacing a parameter
+ * @param charSpacing a parameter
+ * @param text the text to write
+ */
+ public void NewlineShowText(float wordSpacing, float charSpacing, string text) {
+ state.yTLM -= state.leading;
+ content.Append(wordSpacing).Append(' ').Append(charSpacing);
+ ShowText2(text);
+ content.Append("\"").Append_i(separator);
+
+ // The " operator sets charSpace and wordSpace into graphics state
+ // (cfr PDF reference v1.6, table 5.6)
+ state.charSpace = charSpacing;
+ state.wordSpace = wordSpacing;
+ }
+
+ /**
+ * Changes the text matrix.
+ * byte
array according to the PDF conventions.
+ *
+ * @param b the byte
array to escape
+ * @return an escaped byte
array
+ */
+ internal static byte[] EscapeString(byte[] b) {
+ ByteBuffer content = new ByteBuffer();
+ EscapeString(b, content);
+ return content.ToByteArray();
+ }
+
+ /**
+ * Escapes a byte
array according to the PDF conventions.
+ *
+ * @param b the byte
array to escape
+ */
+ internal static void EscapeString(byte[] b, ByteBuffer content) {
+ content.Append_i('(');
+ for (int k = 0; k < b.Length; ++k) {
+ byte c = b[k];
+ switch ((int)c) {
+ case '\r':
+ content.Append("\\r");
+ break;
+ case '\n':
+ content.Append("\\n");
+ break;
+ case '\t':
+ content.Append("\\t");
+ break;
+ case '\b':
+ content.Append("\\b");
+ break;
+ case '\f':
+ content.Append("\\f");
+ break;
+ case '(':
+ case ')':
+ case '\\':
+ content.Append_i('\\').Append_i(c);
+ break;
+ default:
+ content.Append_i(c);
+ break;
+ }
+ }
+ content.Append(')');
+ }
+
+ /**
+ * Adds a named outline to the document.
+ *
+ * @param outline the outline
+ * @param name the name for the local destination
+ */
+ public void AddOutline(PdfOutline outline, string name) {
+ CheckWriter();
+ pdf.AddOutline(outline, name);
+ }
+ /**
+ * Gets the root outline.
+ *
+ * @return the root outline
+ */
+ public PdfOutline RootOutline {
+ get {
+ CheckWriter();
+ return pdf.RootOutline;
+ }
+ }
+
+ /**
+ * Computes the width of the given string taking in account
+ * the current values of "Character spacing", "Word Spacing"
+ * and "Horizontal Scaling".
+ * The additional spacing is not computed for the last character
+ * of the string.
+ * @param text the string to get width of
+ * @param kerned the kerning option
+ * @return the width
+ */
+
+ public float GetEffectiveStringWidth(String text, bool kerned) {
+ BaseFont bf = state.fontDetails.BaseFont;
+
+ float w;
+ if (kerned)
+ w = bf.GetWidthPointKerned(text, state.size);
+ else
+ w = bf.GetWidthPoint(text, state.size);
+
+ if (state.charSpace != 0.0f && text.Length > 1) {
+ w += state.charSpace * (text.Length -1);
+ }
+
+ int ft = bf.FontType;
+ if (state.wordSpace != 0.0f && (ft == BaseFont.FONT_TYPE_T1 || ft == BaseFont.FONT_TYPE_TT || ft == BaseFont.FONT_TYPE_T3)) {
+ for (int i = 0; i < (text.Length -1); i++) {
+ if (text[i] == ' ')
+ w += state.wordSpace;
+ }
+ }
+ if (state.scale != 100.0)
+ w = (w * state.scale) / 100.0f;
+
+ //System.out.Println("String width = " + Float.ToString(w));
+ return w;
+ }
+
+ /**
+ * Shows text right, left or center aligned with rotation.
+ * @param alignment the alignment can be ALIGN_CENTER, ALIGN_RIGHT or ALIGN_LEFT
+ * @param text the text to show
+ * @param x the x pivot position
+ * @param y the y pivot position
+ * @param rotation the rotation to be applied in degrees counterclockwise
+ */
+ public void ShowTextAligned(int alignment, String text, float x, float y, float rotation) {
+ ShowTextAligned(alignment, text, x, y, rotation, false);
+ }
+
+ private void ShowTextAligned(int alignment, String text, float x, float y, float rotation, bool kerned) {
+ if (state.fontDetails == null)
+ throw new Exception("Font and size must be set before writing any text");
+ if (rotation == 0) {
+ switch (alignment) {
+ case ALIGN_CENTER:
+ x -= GetEffectiveStringWidth(text, kerned) / 2;
+ break;
+ case ALIGN_RIGHT:
+ x -= GetEffectiveStringWidth(text, kerned);
+ break;
+ }
+ SetTextMatrix(x, y);
+ if (kerned)
+ ShowTextKerned(text);
+ else
+ ShowText(text);
+ }
+ else {
+ double alpha = rotation * Math.PI / 180.0;
+ float cos = (float)Math.Cos(alpha);
+ float sin = (float)Math.Sin(alpha);
+ float len;
+ switch (alignment) {
+ case ALIGN_CENTER:
+ len = GetEffectiveStringWidth(text, kerned) / 2;
+ x -= len * cos;
+ y -= len * sin;
+ break;
+ case ALIGN_RIGHT:
+ len = GetEffectiveStringWidth(text, kerned);
+ x -= len * cos;
+ y -= len * sin;
+ break;
+ }
+ SetTextMatrix(cos, sin, -sin, cos, x, y);
+ if (kerned)
+ ShowTextKerned(text);
+ else
+ ShowText(text);
+ SetTextMatrix(0f, 0f);
+ }
+ }
+
+ /**
+ * Shows text kerned right, left or center aligned with rotation.
+ * @param alignment the alignment can be ALIGN_CENTER, ALIGN_RIGHT or ALIGN_LEFT
+ * @param text the text to show
+ * @param x the x pivot position
+ * @param y the y pivot position
+ * @param rotation the rotation to be applied in degrees counterclockwise
+ */
+ public void ShowTextAlignedKerned(int alignment, String text, float x, float y, float rotation) {
+ ShowTextAligned(alignment, text, x, y, rotation, true);
+ }
+
+ /**
+ * Concatenate a matrix to the current transformation matrix.
+ * @param a an element of the transformation matrix
+ * @param b an element of the transformation matrix
+ * @param c an element of the transformation matrix
+ * @param d an element of the transformation matrix
+ * @param e an element of the transformation matrix
+ * @param f an element of the transformation matrix
+ **/
+ public void ConcatCTM(float a, float b, float c, float d, float e, float f) {
+ content.Append(a).Append(' ').Append(b).Append(' ').Append(c).Append(' ');
+ content.Append(d).Append(' ').Append(e).Append(' ').Append(f).Append(" cm").Append_i(separator);
+ }
+
+ /**
+ * Generates an array of bezier curves to draw an arc.
+ * PdfPatternPainter
where the pattern will be created
+ */
+ public PdfPatternPainter CreatePattern(float width, float height, float xstep, float ystep) {
+ CheckWriter();
+ if ( xstep == 0.0f || ystep == 0.0f )
+ throw new Exception("XStep or YStep can not be ZERO.");
+ PdfPatternPainter painter = new PdfPatternPainter(writer);
+ painter.Width = width;
+ painter.Height = height;
+ painter.XStep = xstep;
+ painter.YStep = ystep;
+ writer.AddSimplePattern(painter);
+ return painter;
+ }
+
+ /**
+ * Create a new colored tiling pattern. Variables xstep and ystep are set to the same values
+ * of width and height.
+ * @param width the width of the pattern
+ * @param height the height of the pattern
+ * @return the PdfPatternPainter
where the pattern will be created
+ */
+ public PdfPatternPainter CreatePattern(float width, float height) {
+ return CreatePattern(width, height, width, height);
+ }
+
+ /**
+ * Create a new uncolored tiling pattern.
+ *
+ * @param width the width of the pattern
+ * @param height the height of the pattern
+ * @param xstep the desired horizontal spacing between pattern cells.
+ * May be either positive or negative, but not zero.
+ * @param ystep the desired vertical spacing between pattern cells.
+ * May be either positive or negative, but not zero.
+ * @param color the default color. Can be null
+ * @return the PdfPatternPainter
where the pattern will be created
+ */
+ public PdfPatternPainter CreatePattern(float width, float height, float xstep, float ystep, Color color) {
+ CheckWriter();
+ if ( xstep == 0.0f || ystep == 0.0f )
+ throw new Exception("XStep or YStep can not be ZERO.");
+ PdfPatternPainter painter = new PdfPatternPainter(writer, color);
+ painter.Width = width;
+ painter.Height = height;
+ painter.XStep = xstep;
+ painter.YStep = ystep;
+ writer.AddSimplePattern(painter);
+ return painter;
+ }
+
+ /**
+ * Create a new uncolored tiling pattern.
+ * Variables xstep and ystep are set to the same values
+ * of width and height.
+ * @param width the width of the pattern
+ * @param height the height of the pattern
+ * @param color the default color. Can be null
+ * @return the PdfPatternPainter
where the pattern will be created
+ */
+ public PdfPatternPainter CreatePattern(float width, float height, Color color) {
+ return CreatePattern(width, height, width, height, color);
+ }
+
+ /**
+ * Creates a new template.
+ * PdfContentByte
or in another template. Templates are only written
+ * to the output when the document is closed permitting things like showing text in the first page
+ * that is only defined in the last page.
+ *
+ * @param width the bounding box width
+ * @param height the bounding box height
+ * @return the templated created
+ */
+ public PdfTemplate CreateTemplate(float width, float height) {
+ return CreateTemplate(width, height, null);
+ }
+
+ internal PdfTemplate CreateTemplate(float width, float height, PdfName forcedName) {
+ CheckWriter();
+ PdfTemplate template = new PdfTemplate(writer);
+ template.Width = width;
+ template.Height = height;
+ writer.AddDirectTemplateSimple(template, forcedName);
+ return template;
+ }
+
+ /**
+ * Creates a new appearance to be used with form fields.
+ *
+ * @param width the bounding box width
+ * @param height the bounding box height
+ * @return the appearance created
+ */
+ public PdfAppearance CreateAppearance(float width, float height) {
+ return CreateAppearance(width, height, null);
+ }
+
+ internal PdfAppearance CreateAppearance(float width, float height, PdfName forcedName) {
+ CheckWriter();
+ PdfAppearance template = new PdfAppearance(writer);
+ template.Width = width;
+ template.Height = height;
+ writer.AddDirectTemplateSimple(template, forcedName);
+ return template;
+ }
+
+ /**
+ * Adds a PostScript XObject to this content.
+ *
+ * @param psobject the object
+ */
+ public void AddPSXObject(PdfPSXObject psobject) {
+ CheckWriter();
+ PdfName name = writer.AddDirectTemplateSimple(psobject, null);
+ PageResources prs = PageResources;
+ name = prs.AddXObject(name, psobject.IndirectReference);
+ content.Append(name.GetBytes()).Append(" Do").Append_i(separator);
+ }
+
+ /**
+ * Adds a template to this content.
+ *
+ * @param template the template
+ * @param a an element of the transformation matrix
+ * @param b an element of the transformation matrix
+ * @param c an element of the transformation matrix
+ * @param d an element of the transformation matrix
+ * @param e an element of the transformation matrix
+ * @param f an element of the transformation matrix
+ */
+ public virtual void AddTemplate(PdfTemplate template, float a, float b, float c, float d, float e, float f) {
+ CheckWriter();
+ CheckNoPattern(template);
+ PdfName name = writer.AddDirectTemplateSimple(template, null);
+ PageResources prs = PageResources;
+ name = prs.AddXObject(name, template.IndirectReference);
+ content.Append("q ");
+ content.Append(a).Append(' ');
+ content.Append(b).Append(' ');
+ content.Append(c).Append(' ');
+ content.Append(d).Append(' ');
+ content.Append(e).Append(' ');
+ content.Append(f).Append(" cm ");
+ content.Append(name.GetBytes()).Append(" Do Q").Append_i(separator);
+ }
+
+ internal void AddTemplateReference(PdfIndirectReference template, PdfName name, float a, float b, float c, float d, float e, float f) {
+ CheckWriter();
+ PageResources prs = PageResources;
+ name = prs.AddXObject(name, template);
+ content.Append("q ");
+ content.Append(a).Append(' ');
+ content.Append(b).Append(' ');
+ content.Append(c).Append(' ');
+ content.Append(d).Append(' ');
+ content.Append(e).Append(' ');
+ content.Append(f).Append(" cm ");
+ content.Append(name.GetBytes()).Append(" Do Q").Append_i(separator);
+ }
+
+ /**
+ * Adds a template to this content.
+ *
+ * @param template the template
+ * @param x the x location of this template
+ * @param y the y location of this template
+ */
+ public void AddTemplate(PdfTemplate template, float x, float y) {
+ AddTemplate(template, 1, 0, 0, 1, x, y);
+ }
+
+ /**
+ * Changes the current color for filling paths (device dependent colors!).
+ * color
can be an
+ * ExtendedColor
.
+ * @param color the color
+ */
+ public virtual void SetColorStroke(Color value) {
+ PdfXConformanceImp.CheckPDFXConformance(writer, PdfXConformanceImp.PDFXKEY_COLOR, value);
+ int type = ExtendedColor.GetType(value);
+ switch (type) {
+ case ExtendedColor.TYPE_GRAY: {
+ SetGrayStroke(((GrayColor)value).Gray);
+ break;
+ }
+ case ExtendedColor.TYPE_CMYK: {
+ CMYKColor cmyk = (CMYKColor)value;
+ SetCMYKColorStrokeF(cmyk.Cyan, cmyk.Magenta, cmyk.Yellow, cmyk.Black);
+ break;
+ }
+ case ExtendedColor.TYPE_SEPARATION: {
+ SpotColor spot = (SpotColor)value;
+ SetColorStroke(spot.PdfSpotColor, spot.Tint);
+ break;
+ }
+ case ExtendedColor.TYPE_PATTERN: {
+ PatternColor pat = (PatternColor)value;
+ SetPatternStroke(pat.Painter);
+ break;
+ }
+ case ExtendedColor.TYPE_SHADING: {
+ ShadingColor shading = (ShadingColor)value;
+ SetShadingStroke(shading.PdfShadingPattern);
+ break;
+ }
+ default:
+ SetRGBColorStroke(value.R, value.G, value.B);
+ break;
+ }
+ }
+
+ /** Sets the fill color. color
can be an
+ * ExtendedColor
.
+ * @param color the color
+ */
+ public virtual void SetColorFill(Color value) {
+ PdfXConformanceImp.CheckPDFXConformance(writer, PdfXConformanceImp.PDFXKEY_COLOR, value);
+ int type = ExtendedColor.GetType(value);
+ switch (type) {
+ case ExtendedColor.TYPE_GRAY: {
+ SetGrayFill(((GrayColor)value).Gray);
+ break;
+ }
+ case ExtendedColor.TYPE_CMYK: {
+ CMYKColor cmyk = (CMYKColor)value;
+ SetCMYKColorFillF(cmyk.Cyan, cmyk.Magenta, cmyk.Yellow, cmyk.Black);
+ break;
+ }
+ case ExtendedColor.TYPE_SEPARATION: {
+ SpotColor spot = (SpotColor)value;
+ SetColorFill(spot.PdfSpotColor, spot.Tint);
+ break;
+ }
+ case ExtendedColor.TYPE_PATTERN: {
+ PatternColor pat = (PatternColor)value;
+ SetPatternFill(pat.Painter);
+ break;
+ }
+ case ExtendedColor.TYPE_SHADING: {
+ ShadingColor shading = (ShadingColor)value;
+ SetShadingFill(shading.PdfShadingPattern);
+ break;
+ }
+ default:
+ SetRGBColorFill(value.R, value.G, value.B);
+ break;
+ }
+ }
+
+ /** Sets the fill color to a spot color.
+ * @param sp the spot color
+ * @param tint the tint for the spot color. 0 is no color and 1
+ * is 100% color
+ */
+ public virtual void SetColorFill(PdfSpotColor sp, float tint) {
+ CheckWriter();
+ state.colorDetails = writer.AddSimple(sp);
+ PageResources prs = PageResources;
+ PdfName name = state.colorDetails.ColorName;
+ name = prs.AddColor(name, state.colorDetails.IndirectReference);
+ content.Append(name.GetBytes()).Append(" cs ").Append(tint).Append(" scn").Append_i(separator);
+ }
+
+ /** Sets the stroke color to a spot color.
+ * @param sp the spot color
+ * @param tint the tint for the spot color. 0 is no color and 1
+ * is 100% color
+ */
+ public virtual void SetColorStroke(PdfSpotColor sp, float tint) {
+ CheckWriter();
+ state.colorDetails = writer.AddSimple(sp);
+ PageResources prs = PageResources;
+ PdfName name = state.colorDetails.ColorName;
+ name = prs.AddColor(name, state.colorDetails.IndirectReference);
+ content.Append(name.GetBytes()).Append(" CS ").Append(tint).Append(" SCN").Append_i(separator);
+ }
+
+ /** Sets the fill color to a pattern. The pattern can be
+ * colored or uncolored.
+ * @param p the pattern
+ */
+ public virtual void SetPatternFill(PdfPatternPainter p) {
+ if (p.IsStencil()) {
+ SetPatternFill(p, p.DefaultColor);
+ return;
+ }
+ CheckWriter();
+ PageResources prs = PageResources;
+ PdfName name = writer.AddSimplePattern(p);
+ name = prs.AddPattern(name, p.IndirectReference);
+ content.Append(PdfName.PATTERN.GetBytes()).Append(" cs ").Append(name.GetBytes()).Append(" scn").Append_i(separator);
+ }
+
+ /** Outputs the color values to the content.
+ * @param color The color
+ * @param tint the tint if it is a spot color, ignored otherwise
+ */
+ internal void OutputColorNumbers(Color color, float tint) {
+ PdfXConformanceImp.CheckPDFXConformance(writer, PdfXConformanceImp.PDFXKEY_COLOR, color);
+ int type = ExtendedColor.GetType(color);
+ switch (type) {
+ case ExtendedColor.TYPE_RGB:
+ content.Append((float)(color.R) / 0xFF);
+ content.Append(' ');
+ content.Append((float)(color.G) / 0xFF);
+ content.Append(' ');
+ content.Append((float)(color.B) / 0xFF);
+ break;
+ case ExtendedColor.TYPE_GRAY:
+ content.Append(((GrayColor)color).Gray);
+ break;
+ case ExtendedColor.TYPE_CMYK: {
+ CMYKColor cmyk = (CMYKColor)color;
+ content.Append(cmyk.Cyan).Append(' ').Append(cmyk.Magenta);
+ content.Append(' ').Append(cmyk.Yellow).Append(' ').Append(cmyk.Black);
+ break;
+ }
+ case ExtendedColor.TYPE_SEPARATION:
+ content.Append(tint);
+ break;
+ default:
+ throw new Exception("Invalid color type.");
+ }
+ }
+
+ /** Sets the fill color to an uncolored pattern.
+ * @param p the pattern
+ * @param color the color of the pattern
+ */
+ public virtual void SetPatternFill(PdfPatternPainter p, Color color) {
+ if (ExtendedColor.GetType(color) == ExtendedColor.TYPE_SEPARATION)
+ SetPatternFill(p, color, ((SpotColor)color).Tint);
+ else
+ SetPatternFill(p, color, 0);
+ }
+
+ /** Sets the fill color to an uncolored pattern.
+ * @param p the pattern
+ * @param color the color of the pattern
+ * @param tint the tint if the color is a spot color, ignored otherwise
+ */
+ public virtual void SetPatternFill(PdfPatternPainter p, Color color, float tint) {
+ CheckWriter();
+ if (!p.IsStencil())
+ throw new Exception("An uncolored pattern was expected.");
+ PageResources prs = PageResources;
+ PdfName name = writer.AddSimplePattern(p);
+ name = prs.AddPattern(name, p.IndirectReference);
+ ColorDetails csDetail = writer.AddSimplePatternColorspace(color);
+ PdfName cName = prs.AddColor(csDetail.ColorName, csDetail.IndirectReference);
+ content.Append(cName.GetBytes()).Append(" cs").Append_i(separator);
+ OutputColorNumbers(color, tint);
+ content.Append(' ').Append(name.GetBytes()).Append(" scn").Append_i(separator);
+ }
+
+ /** Sets the stroke color to an uncolored pattern.
+ * @param p the pattern
+ * @param color the color of the pattern
+ */
+ public virtual void SetPatternStroke(PdfPatternPainter p, Color color) {
+ if (ExtendedColor.GetType(color) == ExtendedColor.TYPE_SEPARATION)
+ SetPatternStroke(p, color, ((SpotColor)color).Tint);
+ else
+ SetPatternStroke(p, color, 0);
+ }
+
+ /** Sets the stroke color to an uncolored pattern.
+ * @param p the pattern
+ * @param color the color of the pattern
+ * @param tint the tint if the color is a spot color, ignored otherwise
+ */
+ public virtual void SetPatternStroke(PdfPatternPainter p, Color color, float tint) {
+ CheckWriter();
+ if (!p.IsStencil())
+ throw new Exception("An uncolored pattern was expected.");
+ PageResources prs = PageResources;
+ PdfName name = writer.AddSimplePattern(p);
+ name = prs.AddPattern(name, p.IndirectReference);
+ ColorDetails csDetail = writer.AddSimplePatternColorspace(color);
+ PdfName cName = prs.AddColor(csDetail.ColorName, csDetail.IndirectReference);
+ content.Append(cName.GetBytes()).Append(" CS").Append_i(separator);
+ OutputColorNumbers(color, tint);
+ content.Append(' ').Append(name.GetBytes()).Append(" SCN").Append_i(separator);
+ }
+
+ /** Sets the stroke color to a pattern. The pattern can be
+ * colored or uncolored.
+ * @param p the pattern
+ */
+ public virtual void SetPatternStroke(PdfPatternPainter p) {
+ if (p.IsStencil()) {
+ SetPatternStroke(p, p.DefaultColor);
+ return;
+ }
+ CheckWriter();
+ PageResources prs = PageResources;
+ PdfName name = writer.AddSimplePattern(p);
+ name = prs.AddPattern(name, p.IndirectReference);
+ content.Append(PdfName.PATTERN.GetBytes()).Append(" CS ").Append(name.GetBytes()).Append(" SCN").Append_i(separator);
+ }
+
+ /**
+ * Paints using a shading object.
+ * @param shading the shading object
+ */
+ public virtual void PaintShading(PdfShading shading) {
+ writer.AddSimpleShading(shading);
+ PageResources prs = PageResources;
+ PdfName name = prs.AddShading(shading.ShadingName, shading.ShadingReference);
+ content.Append(name.GetBytes()).Append(" sh").Append_i(separator);
+ ColorDetails details = shading.ColorDetails;
+ if (details != null)
+ prs.AddColor(details.ColorName, details.IndirectReference);
+ }
+
+ /**
+ * Paints using a shading pattern.
+ * @param shading the shading pattern
+ */
+ public virtual void PaintShading(PdfShadingPattern shading) {
+ PaintShading(shading.Shading);
+ }
+
+ /**
+ * Sets the shading fill pattern.
+ * @param shading the shading pattern
+ */
+ public virtual void SetShadingFill(PdfShadingPattern shading) {
+ writer.AddSimpleShadingPattern(shading);
+ PageResources prs = PageResources;
+ PdfName name = prs.AddPattern(shading.PatternName, shading.PatternReference);
+ content.Append(PdfName.PATTERN.GetBytes()).Append(" cs ").Append(name.GetBytes()).Append(" scn").Append_i(separator);
+ ColorDetails details = shading.ColorDetails;
+ if (details != null)
+ prs.AddColor(details.ColorName, details.IndirectReference);
+ }
+
+ /**
+ * Sets the shading stroke pattern
+ * @param shading the shading pattern
+ */
+ public virtual void SetShadingStroke(PdfShadingPattern shading) {
+ writer.AddSimpleShadingPattern(shading);
+ PageResources prs = PageResources;
+ PdfName name = prs.AddPattern(shading.PatternName, shading.PatternReference);
+ content.Append(PdfName.PATTERN.GetBytes()).Append(" CS ").Append(name.GetBytes()).Append(" SCN").Append_i(separator);
+ ColorDetails details = shading.ColorDetails;
+ if (details != null)
+ prs.AddColor(details.ColorName, details.IndirectReference);
+ }
+
+ /** Check if we have a valid PdfWriter.
+ *
+ */
+ protected virtual void CheckWriter() {
+ if (writer == null)
+ throw new ArgumentNullException("The writer in PdfContentByte is null.");
+ }
+
+ /**
+ * Show an array of text.
+ * @param text array of text
+ */
+ public void ShowText(PdfTextArray text) {
+ if (state.fontDetails == null)
+ throw new ArgumentNullException("Font and size must be set before writing any text");
+ content.Append('[');
+ ArrayList arrayList = text.ArrayList;
+ bool lastWasNumber = false;
+ for (int k = 0; k < arrayList.Count; ++k) {
+ Object obj = arrayList[k];
+ if (obj is string) {
+ ShowText2((string)obj);
+ lastWasNumber = false;
+ }
+ else {
+ if (lastWasNumber)
+ content.Append(' ');
+ else
+ lastWasNumber = true;
+ content.Append(((float)obj));
+ }
+ }
+ content.Append("]TJ").Append_i(separator);
+ }
+
+ /**
+ * Gets the PdfWriter
in use by this object.
+ * @return the PdfWriter
in use by this object
+ */
+ public PdfWriter PdfWriter {
+ get {
+ return writer;
+ }
+ }
+
+ /**
+ * Gets the PdfDocument
in use by this object.
+ * @return the PdfDocument
in use by this object
+ */
+ public PdfDocument PdfDocument {
+ get {
+ return pdf;
+ }
+ }
+
+ /**
+ * Implements a link to other part of the document. The jump will
+ * be made to a local destination with the same name, that must exist.
+ * @param name the name for this link
+ * @param llx the lower left x corner of the activation area
+ * @param lly the lower left y corner of the activation area
+ * @param urx the upper right x corner of the activation area
+ * @param ury the upper right y corner of the activation area
+ */
+ public void LocalGoto(string name, float llx, float lly, float urx, float ury) {
+ pdf.LocalGoto(name, llx, lly, urx, ury);
+ }
+
+ /**
+ * The local destination to where a local goto with the same
+ * name will jump.
+ * @param name the name of this local destination
+ * @param destination the PdfDestination
with the jump coordinates
+ * @return true
if the local destination was added,
+ * false
if a local destination with the same name
+ * already exists
+ */
+ public bool LocalDestination(string name, PdfDestination destination) {
+ return pdf.LocalDestination(name, destination);
+ }
+
+ /**
+ * Gets a duplicate of this PdfContentByte
. All
+ * the members are copied by reference but the buffer stays different.
+ *
+ * @return a copy of this PdfContentByte
+ */
+ public virtual PdfContentByte Duplicate {
+ get {
+ return new PdfContentByte(writer);
+ }
+ }
+
+ /**
+ * Implements a link to another document.
+ * @param filename the filename for the remote document
+ * @param name the name to jump to
+ * @param llx the lower left x corner of the activation area
+ * @param lly the lower left y corner of the activation area
+ * @param urx the upper right x corner of the activation area
+ * @param ury the upper right y corner of the activation area
+ */
+ public void RemoteGoto(string filename, string name, float llx, float lly, float urx, float ury) {
+ RemoteGoto(filename, name, llx, lly, urx, ury);
+ }
+
+ /**
+ * Implements a link to another document.
+ * @param filename the filename for the remote document
+ * @param page the page to jump to
+ * @param llx the lower left x corner of the activation area
+ * @param lly the lower left y corner of the activation area
+ * @param urx the upper right x corner of the activation area
+ * @param ury the upper right y corner of the activation area
+ */
+ public void RemoteGoto(string filename, int page, float llx, float lly, float urx, float ury) {
+ pdf.RemoteGoto(filename, page, llx, lly, urx, ury);
+ }
+ /**
+ * Adds a round rectangle to the current path.
+ *
+ * @param x x-coordinate of the starting point
+ * @param y y-coordinate of the starting point
+ * @param w width
+ * @param h height
+ * @param r radius of the arc corner
+ */
+ public void RoundRectangle(float x, float y, float w, float h, float r) {
+ if (w < 0) {
+ x += w;
+ w = -w;
+ }
+ if (h < 0) {
+ y += h;
+ h = -h;
+ }
+ if (r < 0)
+ r = -r;
+ float b = 0.4477f;
+ MoveTo(x + r, y);
+ LineTo(x + w - r, y);
+ CurveTo(x + w - r * b, y, x + w, y + r * b, x + w, y + r);
+ LineTo(x + w, y + h - r);
+ CurveTo(x + w, y + h - r * b, x + w - r * b, y + h, x + w - r, y + h);
+ LineTo(x + r, y + h);
+ CurveTo(x + r * b, y + h, x, y + h - r * b, x, y + h - r);
+ LineTo(x, y + r);
+ CurveTo(x, y + r * b, x + r * b, y, x + r, y);
+ }
+
+ /** Implements an action in an area.
+ * @param action the PdfAction
+ * @param llx the lower left x corner of the activation area
+ * @param lly the lower left y corner of the activation area
+ * @param urx the upper right x corner of the activation area
+ * @param ury the upper right y corner of the activation area
+ */
+ public virtual void SetAction(PdfAction action, float llx, float lly, float urx, float ury) {
+ pdf.SetAction(action, llx, lly, urx, ury);
+ }
+
+ /** Outputs a string
directly to the content.
+ * @param s the string
+ */
+ public void SetLiteral(string s) {
+ content.Append(s);
+ }
+
+ /** Outputs a char
directly to the content.
+ * @param c the char
+ */
+ public void SetLiteral(char c) {
+ content.Append(c);
+ }
+
+ /** Outputs a float
directly to the content.
+ * @param n the float
+ */
+ public void SetLiteral(float n) {
+ content.Append(n);
+ }
+
+ /** Throws an error if it is a pattern.
+ * @param t the object to check
+ */
+ internal void CheckNoPattern(PdfTemplate t) {
+ if (t.Type == PdfTemplate.TYPE_PATTERN)
+ throw new ArgumentException("Invalid use of a pattern. A template was expected.");
+ }
+
+ /**
+ * Draws a TextField.
+ */
+
+ public void DrawRadioField(float llx, float lly, float urx, float ury, bool on) {
+ if (llx > urx) { float x = llx; llx = urx; urx = x; }
+ if (lly > ury) { float y = lly; lly = ury; ury = y; }
+ // silver circle
+ SetLineWidth(1);
+ SetLineCap(1);
+ SetColorStroke(new Color(0xC0, 0xC0, 0xC0));
+ Arc(llx + 1f, lly + 1f, urx - 1f, ury - 1f, 0f, 360f);
+ Stroke();
+ // gray circle-segment
+ SetLineWidth(1);
+ SetLineCap(1);
+ SetColorStroke(new Color(0xA0, 0xA0, 0xA0));
+ Arc(llx + 0.5f, lly + 0.5f, urx - 0.5f, ury - 0.5f, 45, 180);
+ Stroke();
+ // black circle-segment
+ SetLineWidth(1);
+ SetLineCap(1);
+ SetColorStroke(new Color(0x00, 0x00, 0x00));
+ Arc(llx + 1.5f, lly + 1.5f, urx - 1.5f, ury - 1.5f, 45, 180);
+ Stroke();
+ if (on) {
+ // gray circle
+ SetLineWidth(1);
+ SetLineCap(1);
+ SetColorFill(new Color(0x00, 0x00, 0x00));
+ Arc(llx + 4f, lly + 4f, urx - 4f, ury - 4f, 0, 360);
+ Fill();
+ }
+ }
+
+ /**
+ * Draws a TextField.
+ */
+
+ public void DrawTextField(float llx, float lly, float urx, float ury) {
+ if (llx > urx) { float x = llx; llx = urx; urx = x; }
+ if (lly > ury) { float y = lly; lly = ury; ury = y; }
+ // silver rectangle not filled
+ SetColorStroke(new Color(0xC0, 0xC0, 0xC0));
+ SetLineWidth(1);
+ SetLineCap(0);
+ Rectangle(llx, lly, urx - llx, ury - lly);
+ Stroke();
+ // white rectangle filled
+ SetLineWidth(1);
+ SetLineCap(0);
+ SetColorFill(new Color(0xFF, 0xFF, 0xFF));
+ Rectangle(llx + 0.5f, lly + 0.5f, urx - llx - 1f, ury -lly - 1f);
+ Fill();
+ // silver lines
+ SetColorStroke(new Color(0xC0, 0xC0, 0xC0));
+ SetLineWidth(1);
+ SetLineCap(0);
+ MoveTo(llx + 1f, lly + 1.5f);
+ LineTo(urx - 1.5f, lly + 1.5f);
+ LineTo(urx - 1.5f, ury - 1f);
+ Stroke();
+ // gray lines
+ SetColorStroke(new Color(0xA0, 0xA0, 0xA0));
+ SetLineWidth(1);
+ SetLineCap(0);
+ MoveTo(llx + 1f, lly + 1);
+ LineTo(llx + 1f, ury - 1f);
+ LineTo(urx - 1f, ury - 1f);
+ Stroke();
+ // black lines
+ SetColorStroke(new Color(0x00, 0x00, 0x00));
+ SetLineWidth(1);
+ SetLineCap(0);
+ MoveTo(llx + 2f, lly + 2f);
+ LineTo(llx + 2f, ury - 2f);
+ LineTo(urx - 2f, ury - 2f);
+ Stroke();
+ }
+
+ /**
+ * Draws a button.
+ */
+
+ public void DrawButton(float llx, float lly, float urx, float ury, string text, BaseFont bf, float size) {
+ if (llx > urx) { float x = llx; llx = urx; urx = x; }
+ if (lly > ury) { float y = lly; lly = ury; ury = y; }
+ // black rectangle not filled
+ SetColorStroke(new Color(0x00, 0x00, 0x00));
+ SetLineWidth(1);
+ SetLineCap(0);
+ Rectangle(llx, lly, urx - llx, ury - lly);
+ Stroke();
+ // silver rectangle filled
+ SetLineWidth(1);
+ SetLineCap(0);
+ SetColorFill(new Color(0xC0, 0xC0, 0xC0));
+ Rectangle(llx + 0.5f, lly + 0.5f, urx - llx - 1f, ury -lly - 1f);
+ Fill();
+ // white lines
+ SetColorStroke(new Color(0xFF, 0xFF, 0xFF));
+ SetLineWidth(1);
+ SetLineCap(0);
+ MoveTo(llx + 1f, lly + 1f);
+ LineTo(llx + 1f, ury - 1f);
+ LineTo(urx - 1f, ury - 1f);
+ Stroke();
+ // dark grey lines
+ SetColorStroke(new Color(0xA0, 0xA0, 0xA0));
+ SetLineWidth(1);
+ SetLineCap(0);
+ MoveTo(llx + 1f, lly + 1f);
+ LineTo(urx - 1f, lly + 1f);
+ LineTo(urx - 1f, ury - 1f);
+ Stroke();
+ // text
+ ResetRGBColorFill();
+ BeginText();
+ SetFontAndSize(bf, size);
+ ShowTextAligned(PdfContentByte.ALIGN_CENTER, text, llx + (urx - llx) / 2, lly + (ury - lly - size) / 2, 0);
+ EndText();
+ }
+
+ internal virtual PageResources PageResources {
+ get {
+ return pdf.PageResources;
+ }
+ }
+
+ /** Sets the graphic state
+ * @param gstate the graphic state
+ */
+ public void SetGState(PdfGState gstate) {
+ PdfObject[] obj = writer.AddSimpleExtGState(gstate);
+ PageResources prs = PageResources;
+ PdfName name = prs.AddExtGState((PdfName)obj[0], (PdfIndirectReference)obj[1]);
+ content.Append(name.GetBytes()).Append(" gs").Append_i(separator);
+ }
+
+ /**
+ * Begins a graphic block whose visibility is controled by the layer
.
+ * Blocks can be nested. Each block must be terminated by an {@link #endLayer()}.PdfName.DEFAULTGRAY
, PdfName.DEFAULTRGB
+ * or PdfName.DEFAULTCMYK
+ * @param obj the colorspace. A null
or PdfNull
removes any colorspace with the same name
+ */
+ public virtual void SetDefaultColorspace(PdfName name, PdfObject obj) {
+ PageResources prs = PageResources;
+ prs.AddDefaultColor(name, obj);
+ }
+
+ public void Transform(System.Drawing.Drawing2D.Matrix tx) {
+ float[] c = tx.Elements;
+ ConcatCTM(c[0], c[1], c[2], c[3], c[4], c[5]);
+ }
+
+ /**
+ * Begins a marked content sequence. This sequence will be tagged with the structure struc
.
+ * The same structure can be used several times to connect text that belongs to the same logical segment
+ * but is in a different location, like the same paragraph crossing to another page, for example.
+ * @param struc the tagging structure
+ */
+ public void BeginMarkedContentSequence(PdfStructureElement struc) {
+ PdfObject obj = struc.Get(PdfName.K);
+ int mark = pdf.GetMarkPoint();
+ if (obj != null) {
+ PdfArray ar = null;
+ if (obj.IsNumber()) {
+ ar = new PdfArray();
+ ar.Add(obj);
+ struc.Put(PdfName.K, ar);
+ }
+ else if (obj.IsArray()) {
+ ar = (PdfArray)obj;
+ if (!((PdfObject)ar.ArrayList[0]).IsNumber())
+ throw new ArgumentException("The structure has kids.");
+ }
+ else
+ throw new ArgumentException("Unknown object at /K " + obj.GetType().ToString());
+ PdfDictionary dic = new PdfDictionary(PdfName.MCR);
+ dic.Put(PdfName.PG, writer.CurrentPage);
+ dic.Put(PdfName.MCID, new PdfNumber(mark));
+ ar.Add(dic);
+ struc.SetPageMark(writer.PageNumber - 1, -1);
+ }
+ else {
+ struc.SetPageMark(writer.PageNumber - 1, mark);
+ struc.Put(PdfName.PG, writer.CurrentPage);
+ }
+ pdf.IncMarkPoint();
+ content.Append(struc.Get(PdfName.S).GetBytes()).Append(" <> BDC").Append_i(separator);
+ }
+
+ /**
+ * Ends a marked content sequence
+ */
+ public void EndMarkedContentSequence() {
+ content.Append("EMC").Append_i(separator);
+ }
+
+ /**
+ * Begins a marked content sequence. If property is null
the mark will be of the type
+ * BMC
otherwise it will be BDC
.
+ * @param tag the tag
+ * @param property the property
+ * @param inline true
to include the property in the content or false
+ * to include the property in the resource dictionary with the possibility of reusing
+ */
+ public void BeginMarkedContentSequence(PdfName tag, PdfDictionary property, bool inline) {
+ if (property == null) {
+ content.Append(tag.GetBytes()).Append(" BMC").Append_i(separator);
+ return;
+ }
+ content.Append(tag.GetBytes()).Append(' ');
+ if (inline)
+ property.ToPdf(writer, content);
+ else {
+ PdfObject[] objs;
+ if (writer.PropertyExists(property))
+ objs = writer.AddSimpleProperty(property, null);
+ else
+ objs = writer.AddSimpleProperty(property, writer.PdfIndirectReference);
+ PdfName name = (PdfName)objs[0];
+ PageResources prs = PageResources;
+ name = prs.AddProperty(name, (PdfIndirectReference)objs[1]);
+ content.Append(name.GetBytes());
+ }
+ content.Append(" BDC").Append_i(separator);
+ }
+
+ /**
+ * This is just a shorthand to beginMarkedContentSequence(tag, null, false)
.
+ * @param tag the tag
+ */
+ public void BeginMarkedContentSequence(PdfName tag) {
+ BeginMarkedContentSequence(tag, null, false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfContentParser.cs b/iTechSharp/iTextSharp/text/pdf/PdfContentParser.cs
new file mode 100644
index 0000000..78e4a06
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfContentParser.cs
@@ -0,0 +1,211 @@
+using System;
+using System.Collections;
+using System.IO;
+
+/*
+ * $Id: PdfContentParser.cs,v 1.4 2006/09/17 15:55:03 psoares33 Exp $
+ *
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Parses the page or template content.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfContentParser {
+
+ /**
+ * Commands have this type.
+ */
+ public const int COMMAND_TYPE = 200;
+ /**
+ * Holds value of property tokeniser.
+ */
+ private PRTokeniser tokeniser;
+
+ /**
+ * Creates a new instance of PdfContentParser
+ * @param tokeniser the tokeniser with the content
+ */
+ public PdfContentParser(PRTokeniser tokeniser) {
+ this.tokeniser = tokeniser;
+ }
+
+ /**
+ * Parses a single command from the content. Each command is output as an array of arguments
+ * having the command itself as the last element. The returned array will be empty if the
+ * end of content was reached.
+ * @param ls an ArrayList
to use. It will be cleared before using. If it's
+ * null
will create a new ArrayList
+ * @return the same ArrayList
given as argument or a new one
+ * @throws IOException on error
+ */
+ public ArrayList Parse(ArrayList ls) {
+ if (ls == null)
+ ls = new ArrayList();
+ else
+ ls.Clear();
+ PdfObject ob = null;
+ while ((ob = ReadPRObject()) != null) {
+ ls.Add(ob);
+ if (ob.Type == COMMAND_TYPE)
+ break;
+ }
+ return ls;
+ }
+
+ /**
+ * Gets the tokeniser.
+ * @return the tokeniser.
+ */
+ public PRTokeniser GetTokeniser() {
+ return this.tokeniser;
+ }
+
+ /**
+ * Sets the tokeniser.
+ * @param tokeniser the tokeniser
+ */
+ public PRTokeniser Tokeniser {
+ set {
+ tokeniser = value;
+ }
+ get {
+ return tokeniser;
+ }
+ }
+
+ /**
+ * Reads a dictionary. The tokeniser must be positioned past the "<<" token.
+ * @return the dictionary
+ * @throws IOException on error
+ */
+ public PdfDictionary ReadDictionary() {
+ PdfDictionary dic = new PdfDictionary();
+ while (true) {
+ if (!NextValidToken())
+ throw new IOException("Unexpected end of file.");
+ if (tokeniser.TokenType == PRTokeniser.TK_END_DIC)
+ break;
+ if (tokeniser.TokenType != PRTokeniser.TK_NAME)
+ throw new IOException("Dictionary key is not a name.");
+ PdfName name = new PdfName(tokeniser.StringValue, false);
+ PdfObject obj = ReadPRObject();
+ int type = obj.Type;
+ if (-type == PRTokeniser.TK_END_DIC)
+ throw new IOException("Unexpected '>>'");
+ if (-type == PRTokeniser.TK_END_ARRAY)
+ throw new IOException("Unexpected ']'");
+ dic.Put(name, obj);
+ }
+ return dic;
+ }
+
+ /**
+ * Reads an array. The tokeniser must be positioned past the "[" token.
+ * @return an array
+ * @throws IOException on error
+ */
+ public PdfArray ReadArray() {
+ PdfArray array = new PdfArray();
+ while (true) {
+ PdfObject obj = ReadPRObject();
+ int type = obj.Type;
+ if (-type == PRTokeniser.TK_END_ARRAY)
+ break;
+ if (-type == PRTokeniser.TK_END_DIC)
+ throw new IOException("Unexpected '>>'");
+ array.Add(obj);
+ }
+ return array;
+ }
+
+ /**
+ * Reads a pdf object.
+ * @return the pdf object
+ * @throws IOException on error
+ */
+ public PdfObject ReadPRObject() {
+ if (!NextValidToken())
+ return null;
+ int type = tokeniser.TokenType;
+ switch (type) {
+ case PRTokeniser.TK_START_DIC: {
+ PdfDictionary dic = ReadDictionary();
+ return dic;
+ }
+ case PRTokeniser.TK_START_ARRAY:
+ return ReadArray();
+ case PRTokeniser.TK_STRING:
+ PdfString str = new PdfString(tokeniser.StringValue, null).SetHexWriting(tokeniser.IsHexString());
+ return str;
+ case PRTokeniser.TK_NAME:
+ return new PdfName(tokeniser.StringValue, false);
+ case PRTokeniser.TK_NUMBER:
+ return new PdfNumber(tokeniser.StringValue);
+ case PRTokeniser.TK_OTHER:
+ return new PdfLiteral(COMMAND_TYPE, tokeniser.StringValue);
+ default:
+ return new PdfLiteral(-type, tokeniser.StringValue);
+ }
+ }
+
+ /**
+ * Reads the next token skipping over the comments.
+ * @return true
if a token was read, false
if the end of content was reached
+ * @throws IOException on error
+ */
+ public bool NextValidToken() {
+ while (tokeniser.NextToken()) {
+ if (tokeniser.TokenType == PRTokeniser.TK_COMMENT)
+ continue;
+ return true;
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfContents.cs b/iTechSharp/iTextSharp/text/pdf/PdfContents.cs
new file mode 100644
index 0000000..271f689
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfContents.cs
@@ -0,0 +1,148 @@
+using System;
+using System.IO;
+
+using iTextSharp.text;
+
+using System.util.zlib;
+
+/*
+ * $Id: PdfContents.cs,v 1.4 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfContents
is a PdfStream
containing the contents (text + graphics) of a PdfPage
.
+ */
+
+ public class PdfContents : PdfStream {
+
+ internal static byte[] SAVESTATE = DocWriter.GetISOBytes("q\n");
+ internal static byte[] RESTORESTATE = DocWriter.GetISOBytes("Q\n");
+ internal static byte[] ROTATE90 = DocWriter.GetISOBytes("0 1 -1 0 ");
+ internal static byte[] ROTATE180 = DocWriter.GetISOBytes("-1 0 0 -1 ");
+ internal static byte[] ROTATE270 = DocWriter.GetISOBytes("0 -1 1 0 ");
+ internal static byte[] ROTATEFINAL = DocWriter.GetISOBytes(" cm\n");
+ // constructor
+
+ /**
+ * Constructs a PdfContents
-object, containing text and general graphics.
+ *
+ * @param under the direct content that is under all others
+ * @param content the graphics in a page
+ * @param text the text in a page
+ * @param secondContent the direct content that is over all others
+ * @throws BadPdfFormatException on error
+ */
+
+ internal PdfContents(PdfContentByte under, PdfContentByte content, PdfContentByte text, PdfContentByte secondContent, Rectangle page) : base() {
+ Stream ostr = null;
+ streamBytes = new MemoryStream();
+ if (Document.Compress) {
+ compressed = true;
+ ostr = new ZDeflaterOutputStream(streamBytes);
+ }
+ else
+ ostr = streamBytes;
+ int rotation = page.Rotation;
+ byte[] tmp;
+ switch (rotation) {
+ case 90:
+ ostr.Write(ROTATE90, 0, ROTATE90.Length);
+ tmp = DocWriter.GetISOBytes(ByteBuffer.FormatDouble(page.Top));
+ ostr.Write(tmp, 0, tmp.Length);
+ ostr.WriteByte((byte)' ');
+ ostr.WriteByte((byte)'0');
+ ostr.Write(ROTATEFINAL, 0, ROTATEFINAL.Length);
+ break;
+ case 180:
+ ostr.Write(ROTATE180, 0, ROTATE180.Length);
+ tmp = DocWriter.GetISOBytes(ByteBuffer.FormatDouble(page.Right));
+ ostr.Write(tmp, 0, tmp.Length);
+ ostr.WriteByte((byte)' ');
+ tmp = DocWriter.GetISOBytes(ByteBuffer.FormatDouble(page.Top));
+ ostr.Write(tmp, 0, tmp.Length);
+ ostr.Write(ROTATEFINAL, 0, ROTATEFINAL.Length);
+ break;
+ case 270:
+ ostr.Write(ROTATE270, 0, ROTATE270.Length);
+ ostr.WriteByte((byte)'0');
+ ostr.WriteByte((byte)' ');
+ tmp = DocWriter.GetISOBytes(ByteBuffer.FormatDouble(page.Right));
+ ostr.Write(tmp, 0, tmp.Length);
+ ostr.Write(ROTATEFINAL, 0, ROTATEFINAL.Length);
+ break;
+ }
+ if (under.Size > 0) {
+ ostr.Write(SAVESTATE, 0, SAVESTATE.Length);
+ under.InternalBuffer.WriteTo(ostr);
+ ostr.Write(RESTORESTATE, 0, RESTORESTATE.Length);
+ }
+ if (content.Size > 0) {
+ ostr.Write(SAVESTATE, 0, SAVESTATE.Length);
+ content.InternalBuffer.WriteTo(ostr);
+ ostr.Write(RESTORESTATE, 0, RESTORESTATE.Length);
+ }
+ if (text != null) {
+ ostr.Write(SAVESTATE, 0, SAVESTATE.Length);
+ text.InternalBuffer.WriteTo(ostr);
+ ostr.Write(RESTORESTATE, 0, RESTORESTATE.Length);
+ }
+ if (secondContent.Size > 0) {
+ secondContent.InternalBuffer.WriteTo(ostr);
+ }
+
+ if (ostr is ZDeflaterOutputStream)
+ ((ZDeflaterOutputStream)ostr).Finish();
+ Put(PdfName.LENGTH, new PdfNumber(streamBytes.Length));
+ if (compressed)
+ Put(PdfName.FILTER, PdfName.FLATEDECODE);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfCopy.cs b/iTechSharp/iTextSharp/text/pdf/PdfCopy.cs
new file mode 100644
index 0000000..df1f91e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfCopy.cs
@@ -0,0 +1,759 @@
+using System;
+using System.Collections;
+using System.IO;
+using iTextSharp.text;
+/*
+ * $Id: PdfCopy.cs,v 1.24 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * This module by Mark Thompson. Copyright (C) 2002 Mark Thompson
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Make copies of PDF documents. Documents can be edited after reading and
+ * before writing them out.
+ * @author Mark Thompson
+ */
+
+ public class PdfCopy : PdfWriter {
+ /**
+ * This class holds information about indirect references, since they are
+ * renumbered by iText.
+ */
+ internal class IndirectReferences {
+ PdfIndirectReference theRef;
+ bool hasCopied;
+ internal IndirectReferences(PdfIndirectReference refi) {
+ theRef = refi;
+ hasCopied = false;
+ }
+ internal void SetCopied() { hasCopied = true; }
+ internal bool Copied {
+ get {
+ return hasCopied;
+ }
+ }
+ internal PdfIndirectReference Ref {
+ get {
+ return theRef;
+ }
+ }
+ };
+ protected Hashtable indirects;
+ protected Hashtable indirectMap;
+ protected int currentObjectNum = 1;
+ protected PdfReader reader;
+ protected PdfIndirectReference acroForm;
+ protected int[] namePtr = {0};
+ /** Holds value of property rotateContents. */
+ private bool rotateContents = true;
+ protected internal PdfArray fieldArray;
+ protected internal Hashtable fieldTemplates;
+
+ /**
+ * A key to allow us to hash indirect references
+ */
+ protected class RefKey {
+ internal int num;
+ internal int gen;
+ internal RefKey(int num, int gen) {
+ this.num = num;
+ this.gen = gen;
+ }
+ internal RefKey(PdfIndirectReference refi) {
+ num = refi.Number;
+ gen = refi.Generation;
+ }
+ internal RefKey(PRIndirectReference refi) {
+ num = refi.Number;
+ gen = refi.Generation;
+ }
+ public override int GetHashCode() {
+ return (gen<<16)+num;
+ }
+ public override bool Equals(Object o) {
+ if (!(o is RefKey)) return false;
+ RefKey other = (RefKey)o;
+ return this.gen == other.gen && this.num == other.num;
+ }
+ public override String ToString() {
+ return "" + num + " " + gen;
+ }
+ }
+
+ /**
+ * Constructor
+ * @param document
+ * @param os outputstream
+ */
+ public PdfCopy(Document document, Stream os) : base(new PdfDocument(), os) {
+ document.AddDocListener(pdf);
+ pdf.AddWriter(this);
+ indirectMap = new Hashtable();
+ }
+
+ /** Checks if the content is automatically adjusted to compensate
+ * the original page rotation.
+ * @return the auto-rotation status
+ */
+ /** Flags the content to be automatically adjusted to compensate
+ * the original page rotation. The default is true
.
+ * @param rotateContents true
to set auto-rotation, false
+ * otherwise
+ */
+ public bool RotateContents {
+ set {
+ rotateContents = value;
+ }
+ get {
+ return rotateContents;
+ }
+ }
+
+ /**
+ * Grabs a page from the input document
+ * @param reader the reader of the document
+ * @param pageNumber which page to get
+ * @return the page
+ */
+ public override PdfImportedPage GetImportedPage(PdfReader reader, int pageNumber) {
+ if (currentPdfReaderInstance != null) {
+ if (currentPdfReaderInstance.Reader != reader) {
+ try {
+ currentPdfReaderInstance.Reader.Close();
+ currentPdfReaderInstance.ReaderFile.Close();
+ }
+ catch (IOException) {
+ // empty on purpose
+ }
+ currentPdfReaderInstance = reader.GetPdfReaderInstance(this);
+ }
+ }
+ else {
+ currentPdfReaderInstance = reader.GetPdfReaderInstance(this);
+ }
+ return currentPdfReaderInstance.GetImportedPage(pageNumber);
+ }
+
+
+ /**
+ * Translate a PRIndirectReference to a PdfIndirectReference
+ * In addition, translates the object numbers, and copies the
+ * referenced object to the output file.
+ * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what
+ * file they came from, because each file has its own namespace. The translation
+ * we do from their namespace to ours is *at best* heuristic, and guaranteed to
+ * fail under some circumstances.
+ */
+ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp) {
+ PdfIndirectReference theRef;
+ RefKey key = new RefKey(inp);
+ IndirectReferences iRef = (IndirectReferences)indirects[key] ;
+ if (iRef != null) {
+ theRef = iRef.Ref;
+ if (iRef.Copied) {
+ return theRef;
+ }
+ }
+ else {
+ theRef = body.PdfIndirectReference;
+ iRef = new IndirectReferences(theRef);
+ indirects[key] = iRef;
+ }
+ PdfObject obj = PdfReader.GetPdfObjectRelease(inp);
+ if (obj != null && obj.IsDictionary()) {
+ PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE));
+ if (type != null && PdfName.PAGE.Equals(type)) {
+ return theRef;
+ }
+ }
+ iRef.SetCopied();
+ obj = CopyObject(obj);
+ AddToBody(obj, theRef);
+ return theRef;
+ }
+
+ /**
+ * Translate a PRDictionary to a PdfDictionary. Also translate all of the
+ * objects contained in it.
+ */
+ protected PdfDictionary CopyDictionary(PdfDictionary inp) {
+ PdfDictionary outp = new PdfDictionary();
+ PdfObject type = PdfReader.GetPdfObjectRelease(inp.Get(PdfName.TYPE));
+
+ foreach (PdfName key in inp.Keys) {
+ PdfObject value = inp.Get(key);
+ if (type != null && PdfName.PAGE.Equals(type)) {
+ if (!key.Equals(PdfName.B) && !key.Equals(PdfName.PARENT))
+ outp.Put(key, CopyObject(value));
+ }
+ else
+ outp.Put(key, CopyObject(value));
+ }
+ return outp;
+ }
+
+ /**
+ * Translate a PRStream to a PdfStream. The data part copies itself.
+ */
+ protected PdfStream CopyStream(PRStream inp) {
+ PRStream outp = new PRStream(inp, null);
+
+ foreach (PdfName key in inp.Keys) {
+ PdfObject value = inp.Get(key);
+ outp.Put(key, CopyObject(value));
+ }
+
+ return outp;
+ }
+
+
+ /**
+ * Translate a PRArray to a PdfArray. Also translate all of the objects contained
+ * in it
+ */
+ protected PdfArray CopyArray(PdfArray inp) {
+ PdfArray outp = new PdfArray();
+
+ foreach (PdfObject value in inp.ArrayList) {
+ outp.Add(CopyObject(value));
+ }
+ return outp;
+ }
+
+ /**
+ * Translate a PR-object to a Pdf-object
+ */
+ protected PdfObject CopyObject(PdfObject inp) {
+ if (inp == null)
+ return PdfNull.PDFNULL;
+ switch (inp.Type) {
+ case PdfObject.DICTIONARY:
+ return CopyDictionary((PdfDictionary)inp);
+ case PdfObject.INDIRECT:
+ return CopyIndirect((PRIndirectReference)inp);
+ case PdfObject.ARRAY:
+ return CopyArray((PdfArray)inp);
+ case PdfObject.NUMBER:
+ case PdfObject.NAME:
+ case PdfObject.STRING:
+ case PdfObject.NULL:
+ case PdfObject.BOOLEAN:
+ case 0:
+ return inp;
+ case PdfObject.STREAM:
+ return CopyStream((PRStream)inp);
+ // return in;
+ default:
+ if (inp.Type < 0) {
+ String lit = ((PdfLiteral)inp).ToString();
+ if (lit.Equals("true") || lit.Equals("false")) {
+ return new PdfBoolean(lit);
+ }
+ return new PdfLiteral(lit);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * convenience method. Given an importedpage, set our "globals"
+ */
+ protected int SetFromIPage(PdfImportedPage iPage) {
+ int pageNum = iPage.PageNumber;
+ PdfReaderInstance inst = currentPdfReaderInstance = iPage.PdfReaderInstance;
+ reader = inst.Reader;
+ SetFromReader(reader);
+ return pageNum;
+ }
+
+ /**
+ * convenience method. Given a reader, set our "globals"
+ */
+ protected void SetFromReader(PdfReader reader) {
+ this.reader = reader;
+ indirects = (Hashtable)indirectMap[reader] ;
+ if (indirects == null) {
+ indirects = new Hashtable();
+ indirectMap[reader] = indirects;
+ PdfDictionary catalog = reader.Catalog;
+ PRIndirectReference refi = null;
+ PdfObject o = catalog.Get(PdfName.ACROFORM);
+ if (o == null || o.Type != PdfObject.INDIRECT)
+ return;
+ refi = (PRIndirectReference)o;
+ if (acroForm == null) acroForm = body.PdfIndirectReference;
+ indirects[new RefKey(refi)] = new IndirectReferences(acroForm);
+ }
+ }
+ /**
+ * Add an imported page to our output
+ * @param iPage an imported page
+ * @throws IOException, BadPdfFormatException
+ */
+ public void AddPage(PdfImportedPage iPage) {
+ int pageNum = SetFromIPage(iPage);
+
+ PdfDictionary thePage = reader.GetPageN(pageNum);
+ PRIndirectReference origRef = reader.GetPageOrigRef(pageNum);
+ reader.ReleasePage(pageNum);
+ RefKey key = new RefKey(origRef);
+ PdfIndirectReference pageRef;
+ IndirectReferences iRef = (IndirectReferences)indirects[key] ;
+ if (iRef != null && !iRef.Copied) {
+ pageReferences.Add(iRef.Ref);
+ iRef.SetCopied();
+ }
+ pageRef = CurrentPage;
+ if (iRef == null) {
+ iRef = new IndirectReferences(pageRef);
+ indirects[key] = iRef;
+ }
+ iRef.SetCopied();
+ PdfDictionary newPage = CopyDictionary(thePage);
+ root.AddPage(newPage);
+ ++currentPageNumber;
+ }
+
+ /**
+ * Copy the acroform for an input document. Note that you can only have one,
+ * we make no effort to merge them.
+ * @param reader The reader of the input file that is being copied
+ * @throws IOException, BadPdfFormatException
+ */
+ public void CopyAcroForm(PdfReader reader) {
+ SetFromReader(reader);
+
+ PdfDictionary catalog = reader.Catalog;
+ PRIndirectReference hisRef = null;
+ PdfObject o = catalog.Get(PdfName.ACROFORM);
+ if (o != null && o.Type == PdfObject.INDIRECT)
+ hisRef = (PRIndirectReference)o;
+ if (hisRef == null) return; // bugfix by John Engla
+ RefKey key = new RefKey(hisRef);
+ PdfIndirectReference myRef;
+ IndirectReferences iRef = (IndirectReferences)indirects[key] ;
+ if (iRef != null) {
+ acroForm = myRef = iRef.Ref;
+ }
+ else {
+ acroForm = myRef = body.PdfIndirectReference;
+ iRef = new IndirectReferences(myRef);
+ indirects[key] = iRef;
+ }
+ if (! iRef.Copied) {
+ iRef.SetCopied();
+ PdfDictionary theForm = CopyDictionary((PdfDictionary)PdfReader.GetPdfObject(hisRef));
+ AddToBody(theForm, myRef);
+ }
+ }
+
+ /*
+ * the getCatalog method is part of PdfWriter.
+ * we wrap this so that we can extend it
+ */
+ protected override PdfDictionary GetCatalog(PdfIndirectReference rootObj) {
+ PdfDictionary theCat = pdf.GetCatalog(rootObj);
+ if (fieldArray == null) {
+ if (acroForm != null) theCat.Put(PdfName.ACROFORM, acroForm);
+ }
+ else
+ AddFieldResources(theCat);
+ WriteOutlines(theCat, false);
+ return theCat;
+ }
+
+ private void AddFieldResources(PdfDictionary catalog) {
+ if (fieldArray == null)
+ return;
+ PdfDictionary acroForm = new PdfDictionary();
+ catalog.Put(PdfName.ACROFORM, acroForm);
+ acroForm.Put(PdfName.FIELDS, fieldArray);
+ acroForm.Put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
+ if (fieldTemplates.Count == 0)
+ return;
+ PdfDictionary dr = new PdfDictionary();
+ acroForm.Put(PdfName.DR, dr);
+ foreach (PdfTemplate template in fieldTemplates.Keys) {
+ PdfFormField.MergeResources(dr, (PdfDictionary)template.Resources);
+ }
+ if (dr.Get(PdfName.ENCODING) == null)
+ dr.Put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING);
+ PdfDictionary fonts = (PdfDictionary)PdfReader.GetPdfObject(dr.Get(PdfName.FONT));
+ if (fonts == null) {
+ fonts = new PdfDictionary();
+ dr.Put(PdfName.FONT, fonts);
+ }
+ if (!fonts.Contains(PdfName.HELV)) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONT);
+ dic.Put(PdfName.BASEFONT, PdfName.HELVETICA);
+ dic.Put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING);
+ dic.Put(PdfName.NAME, PdfName.HELV);
+ dic.Put(PdfName.SUBTYPE, PdfName.TYPE1);
+ fonts.Put(PdfName.HELV, AddToBody(dic).IndirectReference);
+ }
+ if (!fonts.Contains(PdfName.ZADB)) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONT);
+ dic.Put(PdfName.BASEFONT, PdfName.ZAPFDINGBATS);
+ dic.Put(PdfName.NAME, PdfName.ZADB);
+ dic.Put(PdfName.SUBTYPE, PdfName.TYPE1);
+ fonts.Put(PdfName.ZADB, AddToBody(dic).IndirectReference);
+ }
+ }
+
+ /**
+ * Signals that the Document
was closed and that no other
+ * Elements
will be added.
+ *
+ * PdfImportedPage page = copy.getImportedPage(reader, 1);
+ * PdfCopy.PageStamp ps = copy.createPageStamp(page);
+ * ps.addAnnotation(PdfAnnotation.createText(copy, new Rectangle(50, 180, 70, 200), "Hello", "No Thanks", true, "Comment"));
+ * PdfContentByte under = ps.getUnderContent();
+ * under.addImage(img);
+ * PdfContentByte over = ps.getOverContent();
+ * over.beginText();
+ * over.setFontAndSize(bf, 18);
+ * over.setTextMatrix(30, 30);
+ * over.showText("total page " + totalPage);
+ * over.endText();
+ * ps.alterContents();
+ * copy.addPage(page);
+ *
+ * @param iPage an imported page
+ * @return the PageStamp
+ */
+ public PageStamp CreatePageStamp(PdfImportedPage iPage) {
+ int pageNum = iPage.PageNumber;
+ PdfReader reader = iPage.PdfReaderInstance.Reader;
+ PdfDictionary pageN = reader.GetPageN(pageNum);
+ return new PageStamp(reader, pageN, this);
+ }
+
+ public class PageStamp {
+
+ PdfDictionary pageN;
+ PdfCopy.StampContent under;
+ PdfCopy.StampContent over;
+ PageResources pageResources;
+ PdfReader reader;
+ PdfCopy cstp;
+
+ internal PageStamp(PdfReader reader, PdfDictionary pageN, PdfCopy cstp) {
+ this.pageN = pageN;
+ this.reader = reader;
+ this.cstp = cstp;
+ }
+
+ public PdfContentByte GetUnderContent(){
+ if (under == null) {
+ if (pageResources == null) {
+ pageResources = new PageResources();
+ PdfDictionary resources = (PdfDictionary)PdfReader.GetPdfObject(pageN.Get(PdfName.RESOURCES));
+ pageResources.SetOriginalResources(resources, cstp.namePtr);
+ }
+ under = new PdfCopy.StampContent(cstp, pageResources);
+ }
+ return under;
+ }
+
+ public PdfContentByte GetOverContent(){
+ if (over == null) {
+ if (pageResources == null) {
+ pageResources = new PageResources();
+ PdfDictionary resources = (PdfDictionary)PdfReader.GetPdfObject(pageN.Get(PdfName.RESOURCES));
+ pageResources.SetOriginalResources(resources, cstp.namePtr);
+ }
+ over = new PdfCopy.StampContent(cstp, pageResources);
+ }
+ return over;
+ }
+
+ public void AlterContents() {
+ if (over == null && under == null)
+ return;
+ PdfArray ar = null;
+ PdfObject content = PdfReader.GetPdfObject(pageN.Get(PdfName.CONTENTS), pageN);
+ if (content == null) {
+ ar = new PdfArray();
+ pageN.Put(PdfName.CONTENTS, ar);
+ }
+ else if (content.IsArray()) {
+ ar = (PdfArray)content;
+ }
+ else if (content.IsStream()) {
+ ar = new PdfArray();
+ ar.Add(pageN.Get(PdfName.CONTENTS));
+ pageN.Put(PdfName.CONTENTS, ar);
+ }
+ else {
+ ar = new PdfArray();
+ pageN.Put(PdfName.CONTENTS, ar);
+ }
+ ByteBuffer out_p = new ByteBuffer();
+ if (under != null) {
+ out_p.Append(PdfContents.SAVESTATE);
+ ApplyRotation(pageN, out_p);
+ out_p.Append(under.InternalBuffer);
+ out_p.Append(PdfContents.RESTORESTATE);
+ }
+ if (over != null)
+ out_p.Append(PdfContents.SAVESTATE);
+ PdfStream stream = new PdfStream(out_p.ToByteArray());
+ stream.FlateCompress();
+ PdfIndirectReference ref1 = cstp.AddToBody(stream).IndirectReference;
+ ar.AddFirst(ref1);
+ out_p.Reset();
+ if (over != null) {
+ out_p.Append(' ');
+ out_p.Append(PdfContents.RESTORESTATE);
+ out_p.Append(PdfContents.SAVESTATE);
+ ApplyRotation(pageN, out_p);
+ out_p.Append(over.InternalBuffer);
+ out_p.Append(PdfContents.RESTORESTATE);
+ stream = new PdfStream(out_p.ToByteArray());
+ stream.FlateCompress();
+ ar.Add(cstp.AddToBody(stream).IndirectReference);
+ }
+ pageN.Put(PdfName.RESOURCES, pageResources.Resources);
+ }
+
+ void ApplyRotation(PdfDictionary pageN, ByteBuffer out_p) {
+ if (!cstp.rotateContents)
+ return;
+ Rectangle page = reader.GetPageSizeWithRotation(pageN);
+ int rotation = page.Rotation;
+ switch (rotation) {
+ case 90:
+ out_p.Append(PdfContents.ROTATE90);
+ out_p.Append(page.Top);
+ out_p.Append(' ').Append('0').Append(PdfContents.ROTATEFINAL);
+ break;
+ case 180:
+ out_p.Append(PdfContents.ROTATE180);
+ out_p.Append(page.Right);
+ out_p.Append(' ');
+ out_p.Append(page.Top);
+ out_p.Append(PdfContents.ROTATEFINAL);
+ break;
+ case 270:
+ out_p.Append(PdfContents.ROTATE270);
+ out_p.Append('0').Append(' ');
+ out_p.Append(page.Right);
+ out_p.Append(PdfContents.ROTATEFINAL);
+ break;
+ }
+ }
+
+ private void AddDocumentField(PdfIndirectReference refi) {
+ if (cstp.fieldArray == null)
+ cstp.fieldArray = new PdfArray();
+ cstp.fieldArray.Add(refi);
+ }
+
+ private void ExpandFields(PdfFormField field, ArrayList allAnnots) {
+ allAnnots.Add(field);
+ ArrayList kids = field.Kids;
+ if (kids != null) {
+ for (int k = 0; k < kids.Count; ++k)
+ ExpandFields((PdfFormField)kids[k], allAnnots);
+ }
+ }
+
+ public void AddAnnotation(PdfAnnotation annot) {
+ ArrayList allAnnots = new ArrayList();
+ if (annot.IsForm()) {
+ PdfFormField field = (PdfFormField)annot;
+ if (field.Parent != null)
+ return;
+ ExpandFields(field, allAnnots);
+ if (cstp.fieldTemplates == null)
+ cstp.fieldTemplates = new Hashtable();
+ }
+ else
+ allAnnots.Add(annot);
+ for (int k = 0; k < allAnnots.Count; ++k) {
+ annot = (PdfAnnotation)allAnnots[k];
+ if (annot.IsForm()) {
+ if (!annot.IsUsed()) {
+ Hashtable templates = annot.Templates;
+ if (templates != null) {
+ foreach (object tpl in templates.Keys) {
+ cstp.fieldTemplates[tpl] = null;
+ }
+ }
+ }
+ PdfFormField field = (PdfFormField)annot;
+ if (field.Parent == null)
+ AddDocumentField(field.IndirectReference);
+ }
+ if (annot.IsAnnotation()) {
+ PdfObject pdfobj = PdfReader.GetPdfObject(pageN.Get(PdfName.ANNOTS), pageN);
+ PdfArray annots = null;
+ if (pdfobj == null || !pdfobj.IsArray()) {
+ annots = new PdfArray();
+ pageN.Put(PdfName.ANNOTS, annots);
+ }
+ else
+ annots = (PdfArray)pdfobj;
+ annots.Add(annot.IndirectReference);
+ if (!annot.IsUsed()) {
+ PdfRectangle rect = (PdfRectangle)annot.Get(PdfName.RECT);
+ if (rect != null && (rect.Left != 0 || rect.Right != 0 || rect.Top != 0 || rect.Bottom != 0)) {
+ int rotation = reader.GetPageRotation(pageN);
+ Rectangle pageSize = reader.GetPageSizeWithRotation(pageN);
+ switch (rotation) {
+ case 90:
+ annot.Put(PdfName.RECT, new PdfRectangle(
+ pageSize.Top - rect.Bottom,
+ rect.Left,
+ pageSize.Top - rect.Top,
+ rect.Right));
+ break;
+ case 180:
+ annot.Put(PdfName.RECT, new PdfRectangle(
+ pageSize.Right - rect.Left,
+ pageSize.Top - rect.Bottom,
+ pageSize.Right - rect.Right,
+ pageSize.Top - rect.Top));
+ break;
+ case 270:
+ annot.Put(PdfName.RECT, new PdfRectangle(
+ rect.Bottom,
+ pageSize.Right - rect.Left,
+ rect.Top,
+ pageSize.Right - rect.Right));
+ break;
+ }
+ }
+ }
+ }
+ if (!annot.IsUsed()) {
+ annot.SetUsed();
+ cstp.AddToBody(annot, annot.IndirectReference);
+ }
+ }
+ }
+ }
+
+ public class StampContent : PdfContentByte {
+ PageResources pageResources;
+
+ /** Creates a new instance of StampContent */
+ internal StampContent(PdfWriter writer, PageResources pageResources) : base(writer) {
+ this.pageResources = pageResources;
+ }
+
+ /**
+ * Gets a duplicate of this PdfContentByte
. All
+ * the members are copied by reference but the buffer stays different.
+ *
+ * @return a copy of this PdfContentByte
+ */
+ public override PdfContentByte Duplicate {
+ get {
+ return new PdfCopy.StampContent(writer, pageResources);
+ }
+ }
+
+ internal override PageResources PageResources {
+ get {
+ return pageResources;
+ }
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfCopyFields.cs b/iTechSharp/iTextSharp/text/pdf/PdfCopyFields.cs
new file mode 100644
index 0000000..0704eb7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfCopyFields.cs
@@ -0,0 +1,244 @@
+using System;
+using System.Collections;
+using System.IO;
+using iTextSharp.text.pdf.interfaces;
+using Org.BouncyCastle.X509;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Concatenates PDF documents including form fields. The rules for the form field
+ * concatenation are the same as in Acrobat. All the documents are kept in memory unlike
+ * PdfCopy.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfCopyFields : IPdfViewerPreferences, IPdfEncryptionSettings {
+
+ private PdfCopyFieldsImp fc;
+
+ /**
+ * Creates a new instance.
+ * @param os the output stream
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public PdfCopyFields(Stream os) {
+ fc = new PdfCopyFieldsImp(os);
+ }
+
+ /**
+ * Creates a new instance.
+ * @param os the output stream
+ * @param pdfVersion the pdf version the output will have
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public PdfCopyFields(Stream os, char pdfVersion) {
+ fc = new PdfCopyFieldsImp(os, pdfVersion);
+ }
+
+ /**
+ * Concatenates a PDF document.
+ * @param reader the PDF document
+ * @throws DocumentException on error
+ */
+ public void AddDocument(PdfReader reader) {
+ fc.AddDocument(reader);
+ }
+
+ /**
+ * Concatenates a PDF document selecting the pages to keep. The pages are described as a
+ * List
of Integer
. The page ordering can be changed but
+ * no page repetitions are allowed.
+ * @param reader the PDF document
+ * @param pagesToKeep the pages to keep
+ * @throws DocumentException on error
+ */
+ public void AddDocument(PdfReader reader, ArrayList pagesToKeep) {
+ fc.AddDocument(reader, pagesToKeep);
+ }
+
+ /**
+ * Concatenates a PDF document selecting the pages to keep. The pages are described as
+ * ranges. The page ordering can be changed but
+ * no page repetitions are allowed.
+ * @param reader the PDF document
+ * @param ranges the comma separated ranges as described in {@link SequenceList}
+ * @throws DocumentException on error
+ */
+ public void AddDocument(PdfReader reader, String ranges) {
+ fc.AddDocument(reader, SequenceList.Expand(ranges, reader.NumberOfPages));
+ }
+
+ /** Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param strength128Bits true
for 128 bit key length, false
for 40 bit key length
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, bool strength128Bits) {
+ fc.SetEncryption(userPassword, ownerPassword, permissions, strength128Bits ? PdfWriter.STANDARD_ENCRYPTION_128 : PdfWriter.STANDARD_ENCRYPTION_40);
+ }
+
+ /**
+ * Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param strength true for 128 bit key length. false for 40 bit key length
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(bool strength, String userPassword, String ownerPassword, int permissions) {
+ SetEncryption(DocWriter.GetISOBytes(userPassword), DocWriter.GetISOBytes(ownerPassword), permissions, strength);
+ }
+
+ /**
+ * Closes the output document.
+ */
+ public void Close() {
+ fc.Close();
+ }
+
+ /**
+ * Opens the document. This is usually not needed as AddDocument() will do it
+ * automatically.
+ */
+ public void Open() {
+ fc.OpenDoc();
+ }
+
+ /**
+ * Adds JavaScript to the global document
+ * @param js the JavaScript
+ */
+ public void AddJavaScript(String js) {
+ fc.AddJavaScript(js, !PdfEncodings.IsPdfDocEncoding(js));
+ }
+
+ /**
+ * Sets the bookmarks. The list structure is defined in
+ * {@link SimpleBookmark}.
+ * @param outlines the bookmarks or null
to remove any
+ */
+ public ArrayList Outlines {
+ set {
+ fc.Outlines = value;
+ }
+ }
+
+ /** Gets the underlying PdfWriter.
+ * @return the underlying PdfWriter
+ */
+ public PdfWriter Writer {
+ get {
+ return fc;
+ }
+ }
+
+ /**
+ * Gets the 1.5 compression status.
+ * @return true
if the 1.5 compression is on
+ */
+ public bool FullCompression {
+ get {
+ return fc.FullCompression;
+ }
+ }
+
+ /**
+ * Sets the document's compression to the new 1.5 mode with object streams and xref
+ * streams. It can be set at any time but once set it can't be unset.
+ * PdfDashPattern
defines a dash pattern as described in
+ * the PDF Reference Manual version 1.3 p 325 (section 8.4.3).
+ *
+ * @see PdfArray
+ */
+
+ public class PdfDashPattern : PdfArray {
+
+ // membervariables
+
+ /** This is the length of a dash. */
+ private float dash = -1;
+
+ /** This is the length of a gap. */
+ private float gap = -1;
+
+ /** This is the phase. */
+ private float phase = -1;
+
+ // constructors
+
+ /**
+ * Constructs a new PdfDashPattern
.
+ */
+
+ public PdfDashPattern() : base() {}
+
+ /**
+ * Constructs a new PdfDashPattern
.
+ */
+
+ public PdfDashPattern(float dash) : base(new PdfNumber(dash)) {
+ this.dash = dash;
+ }
+
+ /**
+ * Constructs a new PdfDashPattern
.
+ */
+
+ public PdfDashPattern(float dash, float gap) : base(new PdfNumber(dash)) {
+ Add(new PdfNumber(gap));
+ this.dash = dash;
+ this.gap = gap;
+ }
+
+ /**
+ * Constructs a new PdfDashPattern
.
+ */
+
+ public PdfDashPattern(float dash, float gap, float phase) : base(new PdfNumber(dash)) {
+ Add(new PdfNumber(gap));
+ this.dash = dash;
+ this.gap = gap;
+ this.phase = phase;
+ }
+
+ public void Add(float n) {
+ Add(new PdfNumber(n));
+ }
+
+ /**
+ * Returns the PDF representation of this PdfArray
.
+ *
+ * @return an array of byte
s
+ */
+
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ os.WriteByte((byte)'[');
+
+ if (dash >= 0) {
+ new PdfNumber(dash).ToPdf(writer, os);
+ if (gap >= 0) {
+ os.WriteByte((byte)' ');
+ new PdfNumber(gap).ToPdf(writer, os);
+ }
+ }
+ os.WriteByte((byte)']');
+ if (phase >=0) {
+ os.WriteByte((byte)' ');
+ new PdfNumber(phase).ToPdf(writer, os);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfDate.cs b/iTechSharp/iTextSharp/text/pdf/PdfDate.cs
new file mode 100644
index 0000000..b189a51
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfDate.cs
@@ -0,0 +1,215 @@
+using System;
+using System.Text;
+using System.Globalization;
+
+/*
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfDate
is the PDF date object.
+ * PdfString
of the form:
+ *
+ * (D:YYYYMMDDHHmmSSOHH'mm')
+ *
PdfDate
-object.
+ *
+ * @param d the date that has to be turned into a PdfDate
-object
+ */
+
+ public PdfDate(DateTime d) : base() {
+ //d = d.ToUniversalTime();
+
+ value = d.ToString("\\D\\:yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ string timezone = d.ToString("zzz", DateTimeFormatInfo.InvariantInfo);
+ timezone = timezone.Replace(":", "'");
+ value += timezone + "'";
+ }
+
+ /**
+ * Constructs a PdfDate
-object, representing the current day and time.
+ */
+
+ public PdfDate() : this(DateTime.Now) {}
+
+ /**
+ * Adds a number of leading zeros to a given string
in order to get a string
+ * of a certain length.
+ *
+ * @param i a given number
+ * @param length the length of the resulting string
+ * @return the resulting string
+ */
+
+ private static String SetLength(int i, int length) {
+ return i.ToString().PadLeft(length, '0');
+ }
+
+ /**
+ * Gives the W3C format of the PdfDate.
+ * @return a formatted date
+ */
+ public String GetW3CDate() {
+ return GetW3CDate(value);
+ }
+
+ /**
+ * Gives the W3C format of the PdfDate.
+ * @param d the date in the format D:YYYYMMDDHHmmSSOHH'mm'
+ * @return a formatted date
+ */
+ public static String GetW3CDate(String d) {
+ if (d.StartsWith("D:"))
+ d = d.Substring(2);
+ StringBuilder sb = new StringBuilder();
+ if (d.Length < 4)
+ return "0000";
+ sb.Append(d.Substring(0, 4)); //year
+ d = d.Substring(4);
+ if (d.Length < 2)
+ return sb.ToString();
+ sb.Append('-').Append(d.Substring(0, 2)); //month
+ d = d.Substring(2);
+ if (d.Length < 2)
+ return sb.ToString();
+ sb.Append('-').Append(d.Substring(0, 2)); //day
+ d = d.Substring(2);
+ if (d.Length < 2)
+ return sb.ToString();
+ sb.Append('T').Append(d.Substring(0, 2)); //hour
+ d = d.Substring(2);
+ if (d.Length < 2) {
+ sb.Append(":00Z");
+ return sb.ToString();
+ }
+ sb.Append(':').Append(d.Substring(0, 2)); //minute
+ d = d.Substring(2);
+ if (d.Length < 2) {
+ sb.Append('Z');
+ return sb.ToString();
+ }
+ sb.Append(':').Append(d.Substring(0, 2)); //second
+ d = d.Substring(2);
+ if (d.StartsWith("-") || d.StartsWith("+")) {
+ String sign = d.Substring(0, 1);
+ d = d.Substring(1);
+ String h = "00";
+ String m = "00";
+ if (d.Length >= 2) {
+ h = d.Substring(0, 2);
+ if (d.Length > 2) {
+ d = d.Substring(3);
+ if (d.Length >= 2)
+ m = d.Substring(0, 2);
+ }
+ sb.Append(sign).Append(h).Append(':').Append(m);
+ return sb.ToString();
+ }
+ }
+ sb.Append('Z');
+ return sb.ToString();
+ }
+
+ public static DateTime Decode(string date) {
+ if (date.StartsWith("D:"))
+ date = date.Substring(2);
+ int year, month = 1, day = 1, hour = 0, minute = 0, second = 0;
+ int offsetHour = 0, offsetMinute = 0;
+ char variation = '\0';
+ year = int.Parse(date.Substring(0, 4));
+ if (date.Length >= 6) {
+ month = int.Parse(date.Substring(4, 2));
+ if (date.Length >= 8) {
+ day = int.Parse(date.Substring(6, 2));
+ if (date.Length >= 10) {
+ hour = int.Parse(date.Substring(8, 2));
+ if (date.Length >= 12) {
+ minute = int.Parse(date.Substring(10, 2));
+ if (date.Length >= 14) {
+ second = int.Parse(date.Substring(12, 2));
+ }
+ }
+ }
+ }
+ }
+ DateTime d = new DateTime(year, month, day, hour, minute, second);
+ if (date.Length <= 14)
+ return d;
+ variation = date[14];
+ if (variation == 'Z')
+ return d.ToLocalTime();
+ if (date.Length >= 17) {
+ offsetHour = int.Parse(date.Substring(15, 2));
+ if (date.Length >= 20) {
+ offsetMinute = int.Parse(date.Substring(18, 2));
+ }
+ }
+ TimeSpan span = new TimeSpan(offsetHour, offsetMinute, 0);
+ if (variation == '-')
+ d += span;
+ else
+ d -= span;
+ return d.ToLocalTime();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfDestination.cs b/iTechSharp/iTextSharp/text/pdf/PdfDestination.cs
new file mode 100644
index 0000000..db36a53
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfDestination.cs
@@ -0,0 +1,221 @@
+using System;
+
+/*
+ * $Id: PdfDestination.cs,v 1.3 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfColor
defines a Color (it's a PdfArray
containing 3 values).
+ *
+ * @see PdfDictionary
+ */
+
+ public class PdfDestination : PdfArray {
+
+ // public static member-variables
+
+ /** This is a possible destination type */
+ public const int XYZ = 0;
+
+ /** This is a possible destination type */
+ public const int FIT = 1;
+
+ /** This is a possible destination type */
+ public const int FITH = 2;
+
+ /** This is a possible destination type */
+ public const int FITV = 3;
+
+ /** This is a possible destination type */
+ public const int FITR = 4;
+
+ /** This is a possible destination type */
+ public const int FITB = 5;
+
+ /** This is a possible destination type */
+ public const int FITBH = 6;
+
+ /** This is a possible destination type */
+ public const int FITBV = 7;
+
+ // member variables
+
+ /** Is the indirect reference to a page already added? */
+ private bool status = false;
+
+ // constructors
+
+ /**
+ * Constructs a new PdfDestination
.
+ * PdfDestination
.
+ * PdfDestination
.
+ * PdfDestination
.
+ * true
or false
+ */
+
+ public bool HasPage() {
+ return status;
+ }
+
+ /** Adds the indirect reference of the destination page.
+ *
+ * @param page an indirect reference
+ * @return true if the page reference was added
+ */
+
+ public bool AddPage(PdfIndirectReference page) {
+ if (!status) {
+ AddFirst(page);
+ status = true;
+ return true;
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfDictionary.cs b/iTechSharp/iTextSharp/text/pdf/PdfDictionary.cs
new file mode 100644
index 0000000..a43b1c9
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfDictionary.cs
@@ -0,0 +1,375 @@
+using System;
+using System.IO;
+using System.Collections;
+
+/*
+ * $Id: PdfDictionary.cs,v 1.10 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfDictionary
is the Pdf dictionary object.
+ * PdfName
.
+ * A value can be any kind of PdfObject
, including a dictionary. A dictionary is
+ * generally used to collect and tie together the attributes of a complex object, with each
+ * key-value pair specifying the name and value of an attribute.
+ * A dictionary is represented by two left angle brackets (<<), followed by a sequence of
+ * key-value pairs, followed by two right angle brackets (>>).
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.7 (page 40-41).
+ * PdfDictionary
-object.
+ */
+
+ public PdfDictionary() : base(DICTIONARY) {
+ hashMap = new Hashtable();
+ }
+
+ /**
+ * Constructs a PdfDictionary
-object of a certain type.
+ *
+ * @param type a PdfName
+ */
+
+ public PdfDictionary(PdfName type) : this() {
+ dictionaryType = type;
+ Put(PdfName.TYPE, dictionaryType);
+ }
+
+ // methods overriding some methods in PdfObject
+
+ /**
+ * Returns the PDF representation of this PdfDictionary
.
+ *
+ * @return an array of byte
+ */
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ os.WriteByte((byte)'<');
+ os.WriteByte((byte)'<');
+
+ // loop over all the object-pairs in the Hashtable
+ PdfObject value;
+ foreach (PdfName key in hashMap.Keys) {
+ value = (PdfObject) hashMap[key];
+ key.ToPdf(writer, os);
+ int type = value.Type;
+ if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING)
+ os.WriteByte((byte)' ');
+ value.ToPdf(writer, os);
+ }
+ os.WriteByte((byte)'>');
+ os.WriteByte((byte)'>');
+ }
+
+
+ // methods concerning the Hashtable member value
+
+ /**
+ * Adds a PdfObject
and its key to the PdfDictionary
.
+ * If the value is null
or PdfNull
the key is deleted.
+ *
+ * @param key key of the entry (a PdfName
)
+ * @param value value of the entry (a PdfObject
)
+ */
+
+ public void Put(PdfName key, PdfObject value) {
+ if (value == null || value.IsNull())
+ hashMap.Remove(key);
+ else
+ hashMap[key] = value;
+ }
+
+ /**
+ * Adds a PdfObject
and its key to the PdfDictionary
.
+ * If the value is null it does nothing.
+ *
+ * @param key key of the entry (a PdfName
)
+ * @param value value of the entry (a PdfObject
)
+ */
+ public void PutEx(PdfName key, PdfObject value) {
+ if (value == null)
+ return;
+ Put(key, value);
+ }
+
+ /**
+ * Removes a PdfObject
and its key from the PdfDictionary
.
+ *
+ * @param key key of the entry (a PdfName
)
+ */
+
+ public void Remove(PdfName key) {
+ hashMap.Remove(key);
+ }
+
+ /**
+ * Gets a PdfObject
with a certain key from the PdfDictionary
.
+ *
+ * @param key key of the entry (a PdfName
)
+ * @return the previous Dictionary
is of the type FONT.
+ *
+ * @return true
if it is, false
if it isn't.
+ */
+
+ public bool IsFont() {
+ return FONT.Equals(dictionaryType);
+ }
+
+ /**
+ * Checks if a Dictionary
is of the type PAGE.
+ *
+ * @return true
if it is, false
if it isn't.
+ */
+
+ public bool IsPage() {
+ return PAGE.Equals(dictionaryType);
+ }
+
+ /**
+ * Checks if a Dictionary
is of the type PAGES.
+ *
+ * @return true
if it is, false
if it isn't.
+ */
+
+ public bool IsPages() {
+ return PAGES.Equals(dictionaryType);
+ }
+
+ /**
+ * Checks if a Dictionary
is of the type CATALOG.
+ *
+ * @return true
if it is, false
if it isn't.
+ */
+
+ public bool IsCatalog() {
+ return CATALOG.Equals(dictionaryType);
+ }
+
+ /**
+ * Checks if a Dictionary
is of the type OUTLINES.
+ *
+ * @return true
if it is, false
if it isn't.
+ */
+
+ public bool IsOutlineTree() {
+ return OUTLINES.Equals(dictionaryType);
+ }
+
+ public void Merge(PdfDictionary other) {
+ foreach (object key in other.hashMap.Keys) {
+ hashMap[key] = other.hashMap[key];
+ }
+ }
+
+ public void MergeDifferent(PdfDictionary other) {
+ foreach (Object key in other.hashMap.Keys) {
+ if (!hashMap.ContainsKey(key)) {
+ hashMap[key] = other.hashMap[key];
+ }
+ }
+ }
+
+ public ICollection Keys {
+ get {
+ return hashMap.Keys;
+ }
+ }
+
+ public int Size {
+ get {
+ return hashMap.Count;
+ }
+ }
+
+ public bool Contains(PdfName key) {
+ return hashMap.ContainsKey(key);
+ }
+
+ public virtual IDictionaryEnumerator GetEnumerator() {
+ return hashMap.GetEnumerator();
+ }
+
+ public override String ToString() {
+ if (Get(PdfName.TYPE) == null) return "Dictionary";
+ return "Dictionary of type: " + Get(PdfName.TYPE);
+ }
+
+ /**
+ * This function behaves the same as 'get', but will never return an indirect reference,
+ * it will always look such references up and return the actual object.
+ * @param key
+ * @return null, or a non-indirect object
+ */
+ public PdfObject GetDirectObject(PdfName key) {
+ return PdfReader.GetPdfObject(Get(key));
+ }
+
+ /**
+ * All the getAs functions will return either null, or the specified object type
+ * This function will automatically look up indirect references. There's one obvious
+ * exception, the one that will only return an indirect reference. All direct objects
+ * come back as a null.
+ * Mark A Storer (2/17/06)
+ * @param key
+ * @return the appropriate object in its final type, or null
+ */
+ public PdfDictionary GetAsDict(PdfName key) {
+ PdfDictionary dict = null;
+ PdfObject orig = GetDirectObject(key);
+ if (orig != null && orig.IsDictionary())
+ dict = (PdfDictionary) orig;
+ return dict;
+ }
+
+ public PdfArray GetAsArray(PdfName key) {
+ PdfArray array = null;
+ PdfObject orig = GetDirectObject(key);
+ if (orig != null && orig.IsArray())
+ array = (PdfArray) orig;
+ return array;
+ }
+
+ public PdfStream GetAsStream(PdfName key) {
+ PdfStream stream = null;
+ PdfObject orig = GetDirectObject(key);
+ if (orig != null && orig.IsStream())
+ stream = (PdfStream) orig;
+ return stream;
+ }
+
+ public PdfString GetAsString(PdfName key) {
+ PdfString str = null;
+ PdfObject orig = GetDirectObject(key);
+ if (orig != null && orig.IsString())
+ str = (PdfString) orig;
+ return str;
+ }
+
+ public PdfNumber GetAsNumber(PdfName key) {
+ PdfNumber number = null;
+ PdfObject orig = GetDirectObject(key);
+ if (orig != null && orig.IsNumber())
+ number = (PdfNumber) orig;
+ return number;
+ }
+
+ public PdfName GetAsName(PdfName key) {
+ PdfName name = null;
+ PdfObject orig = GetDirectObject(key);
+ if (orig != null && orig.IsName())
+ name = (PdfName) orig;
+ return name;
+ }
+
+ public PdfBoolean GetAsBoolean(PdfName key) {
+ PdfBoolean b = null;
+ PdfObject orig = GetDirectObject(key);
+ if (orig != null && orig.IsBoolean())
+ b = (PdfBoolean)orig;
+ return b;
+ }
+
+ public PdfIndirectReference GetAsIndirectObject( PdfName key ) {
+ PdfIndirectReference refi = null;
+ PdfObject orig = Get(key); // not getDirect this time.
+ if (orig != null && orig.IsIndirect())
+ refi = (PdfIndirectReference) orig;
+ return refi;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfDocument.cs b/iTechSharp/iTextSharp/text/pdf/PdfDocument.cs
new file mode 100644
index 0000000..434eaaa
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfDocument.cs
@@ -0,0 +1,2987 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.util.collections;
+using iTextSharp.text;
+using iTextSharp.text.pdf.intern;
+using iTextSharp.text.pdf.draw;
+using iTextSharp.text.pdf.collection;
+using System.util;
+/*
+ *
+ * $Id: PdfDocument.cs,v 1.75 2008/05/13 11:25:19 psoares33 Exp $
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfDocument
is the class that is used by PdfWriter
+ * to translate a Document
into a PDF with different pages.
+ * PdfDocument
always listens to a Document
+ * and adds the Pdf representation of every Element
that is
+ * added to the Document
.
+ *
+ * @see com.lowagie.text.Document
+ * @see com.lowagie.text.DocListener
+ * @see PdfWriter
+ */
+
+ public class PdfDocument : Document {
+
+ /**
+ * PdfInfo
is the PDF InfoDictionary.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 6.10 (page 120-121)
+ */
+
+ public class PdfInfo : PdfDictionary {
+
+ // constructors
+
+ /**
+ * Construct a PdfInfo
-object.
+ */
+
+ internal PdfInfo() {
+ AddProducer();
+ AddCreationDate();
+ }
+
+ /**
+ * Constructs a PdfInfo
-object.
+ *
+ * @param author name of the author of the document
+ * @param title title of the document
+ * @param subject subject of the document
+ */
+
+ internal PdfInfo(String author, String title, String subject) : base() {
+ AddTitle(title);
+ AddSubject(subject);
+ AddAuthor(author);
+ }
+
+ /**
+ * Adds the title of the document.
+ *
+ * @param title the title of the document
+ */
+
+ internal void AddTitle(String title) {
+ Put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE));
+ }
+
+ /**
+ * Adds the subject to the document.
+ *
+ * @param subject the subject of the document
+ */
+
+ internal void AddSubject(String subject) {
+ Put(PdfName.SUBJECT, new PdfString(subject, PdfObject.TEXT_UNICODE));
+ }
+
+ /**
+ * Adds some keywords to the document.
+ *
+ * @param keywords the keywords of the document
+ */
+
+ internal void AddKeywords(String keywords) {
+ Put(PdfName.KEYWORDS, new PdfString(keywords, PdfObject.TEXT_UNICODE));
+ }
+
+ /**
+ * Adds the name of the author to the document.
+ *
+ * @param author the name of the author
+ */
+
+ internal void AddAuthor(String author) {
+ Put(PdfName.AUTHOR, new PdfString(author, PdfObject.TEXT_UNICODE));
+ }
+
+ /**
+ * Adds the name of the creator to the document.
+ *
+ * @param creator the name of the creator
+ */
+
+ internal void AddCreator(String creator) {
+ Put(PdfName.CREATOR, new PdfString(creator, PdfObject.TEXT_UNICODE));
+ }
+
+ /**
+ * Adds the name of the producer to the document.
+ */
+
+ internal void AddProducer() {
+ // This line may only be changed by Bruno Lowagie or Paulo Soares
+ Put(PdfName.PRODUCER, new PdfString(Version));
+ // Do not edit the line above!
+ }
+
+ /**
+ * Adds the date of creation to the document.
+ */
+
+ internal void AddCreationDate() {
+ PdfString date = new PdfDate();
+ Put(PdfName.CREATIONDATE, date);
+ Put(PdfName.MODDATE, date);
+ }
+
+ internal void Addkey(String key, String value) {
+ if (key.Equals("Producer") || key.Equals("CreationDate"))
+ return;
+ Put(new PdfName(key), new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ /**
+ * PdfCatalog
is the PDF Catalog-object.
+ *
+ * In this class however, only the reference to the tree of pages is implemented.
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 6.2 (page 67-71)
+ */
+
+ internal class PdfCatalog : PdfDictionary {
+
+ internal PdfWriter writer;
+ // constructors
+
+ /**
+ * Constructs a PdfCatalog
.
+ *
+ * @param pages an indirect reference to the root of the document's Pages tree.
+ * @param writer the writer the catalog applies to
+ */
+
+ internal PdfCatalog(PdfIndirectReference pages, PdfWriter writer) : base(CATALOG) {
+ this.writer = writer;
+ Put(PdfName.PAGES, pages);
+ }
+
+ /**
+ * Adds the names of the named destinations to the catalog.
+ * @param localDestinations the local destinations
+ * @param documentJavaScript the javascript used in the document
+ * @param writer the writer the catalog applies to
+ */
+ internal void AddNames(k_Tree localDestinations, Hashtable documentLevelJS, Hashtable documentFileAttachment, PdfWriter writer) {
+ if (localDestinations.Count == 0 && documentLevelJS.Count == 0 && documentFileAttachment.Count == 0)
+ return;
+ PdfDictionary names = new PdfDictionary();
+ if (localDestinations.Count > 0) {
+ PdfArray ar = new PdfArray();
+ foreach (DictionaryEntry entry in localDestinations) {
+ String name = (String)entry.Key;
+ Object[] obj = (Object[])entry.Value;
+ PdfIndirectReference refi = (PdfIndirectReference)obj[1];
+ ar.Add(new PdfString(name, null));
+ ar.Add(refi);
+ }
+ PdfDictionary dests = new PdfDictionary();
+ dests.Put(PdfName.NAMES, ar);
+ names.Put(PdfName.DESTS, writer.AddToBody(dests).IndirectReference);
+ }
+ if (documentLevelJS.Count > 0) {
+ PdfDictionary tree = PdfNameTree.WriteTree(documentLevelJS, writer);
+ names.Put(PdfName.JAVASCRIPT, writer.AddToBody(tree).IndirectReference);
+ }
+ if (documentFileAttachment.Count > 0) {
+ names.Put(PdfName.EMBEDDEDFILES, writer.AddToBody(PdfNameTree.WriteTree(documentFileAttachment, writer)).IndirectReference);
+ }
+ Put(PdfName.NAMES, writer.AddToBody(names).IndirectReference);
+ }
+
+ internal PdfAction OpenAction {
+ set {
+ Put(PdfName.OPENACTION, value);
+ }
+ }
+
+
+ /** Sets the document level additional actions.
+ * @param actions dictionary of actions
+ */
+ internal PdfDictionary AdditionalActions {
+ set {
+ Put(PdfName.AA, writer.AddToBody(value).IndirectReference);
+ }
+ }
+ }
+
+ // CONSTRUCTING A PdfDocument/PdfWriter INSTANCE
+
+ /**
+ * Constructs a new PDF document.
+ * @throws DocumentException on error
+ */
+ internal PdfDocument() {
+ AddProducer();
+ AddCreationDate();
+ }
+
+ /** The PdfWriter
. */
+ protected internal PdfWriter writer;
+
+ /**
+ * Adds a PdfWriter
to the PdfDocument
.
+ *
+ * @param writer the PdfWriter
that writes everything
+ * what is added to this document to an outputstream.
+ * @throws DocumentException on error
+ */
+ internal void AddWriter(PdfWriter writer) {
+ if (this.writer == null) {
+ this.writer = writer;
+ annotationsImp = new PdfAnnotationsImp(writer);
+ return;
+ }
+ throw new DocumentException("You can only add a writer to a PdfDocument once.");
+ }
+
+ // LISTENER METHODS START
+
+ // [L0] ElementListener interface
+
+ /** This is the PdfContentByte object, containing the text. */
+ protected internal PdfContentByte text;
+
+ /** This is the PdfContentByte object, containing the borders and other Graphics. */
+ protected internal PdfContentByte graphics;
+
+ /** This represents the leading of the lines. */
+ protected internal float leading = 0;
+
+ /**
+ * Getter for the current leading.
+ * @return the current leading
+ * @since 2.1.2
+ */
+ public float Leading {
+ get {
+ return leading;
+ }
+ }
+ /** This is the current height of the document. */
+ protected internal float currentHeight = 0;
+
+ /**
+ * Signals that onParagraph is valid (to avoid that a Chapter/Section title is treated as a Paragraph).
+ * @since 2.1.2
+ */
+ protected bool isSectionTitle = false;
+
+ /**
+ * Signals that the current leading has to be subtracted from a YMark object.
+ * @since 2.1.2
+ */
+ protected int leadingCount = 0;
+
+ /** This represents the current alignment of the PDF Elements. */
+ protected internal int alignment = Element.ALIGN_LEFT;
+
+ /** The current active PdfAction
when processing an Anchor
. */
+ protected internal PdfAction anchorAction = null;
+
+ /**
+ * Signals that an Element
was added to the Document
.
+ *
+ * @param element the element to add
+ * @return true
if the element was added, false
if not.
+ * @throws DocumentException when a document isn't open yet, or has been closed
+ */
+ public override bool Add(IElement element) {
+ if (writer != null && writer.IsPaused()) {
+ return false;
+ }
+ switch (element.Type) {
+
+ // Information (headers)
+ case Element.HEADER:
+ info.Addkey(((Meta)element).Name, ((Meta)element).Content);
+ break;
+ case Element.TITLE:
+ info.AddTitle(((Meta)element).Content);
+ break;
+ case Element.SUBJECT:
+ info.AddSubject(((Meta)element).Content);
+ break;
+ case Element.KEYWORDS:
+ info.AddKeywords(((Meta)element).Content);
+ break;
+ case Element.AUTHOR:
+ info.AddAuthor(((Meta)element).Content);
+ break;
+ case Element.CREATOR:
+ info.AddCreator(((Meta)element).Content);
+ break;
+ case Element.PRODUCER:
+ // you can not change the name of the producer
+ info.AddProducer();
+ break;
+ case Element.CREATIONDATE:
+ // you can not set the creation date, only reset it
+ info.AddCreationDate();
+ break;
+
+ // content (text)
+ case Element.CHUNK: {
+ // if there isn't a current line available, we make one
+ if (line == null) {
+ CarriageReturn();
+ }
+
+ // we cast the element to a chunk
+ PdfChunk chunk = new PdfChunk((Chunk) element, anchorAction);
+ // we try to add the chunk to the line, until we succeed
+ {
+ PdfChunk overflow;
+ while ((overflow = line.Add(chunk)) != null) {
+ CarriageReturn();
+ chunk = overflow;
+ chunk.TrimFirstSpace();
+ }
+ }
+ pageEmpty = false;
+ if (chunk.IsAttribute(Chunk.NEWPAGE)) {
+ NewPage();
+ }
+ break;
+ }
+ case Element.ANCHOR: {
+ leadingCount++;
+ Anchor anchor = (Anchor) element;
+ String url = anchor.Reference;
+ leading = anchor.Leading;
+ if (url != null) {
+ anchorAction = new PdfAction(url);
+ }
+
+ // we process the element
+ element.Process(this);
+ anchorAction = null;
+ leadingCount--;
+ break;
+ }
+ case Element.ANNOTATION: {
+ if (line == null) {
+ CarriageReturn();
+ }
+ Annotation annot = (Annotation) element;
+ Rectangle rect = new Rectangle(0, 0);
+ if (line != null)
+ rect = new Rectangle(annot.GetLlx(IndentRight - line.WidthLeft), annot.GetLly(IndentTop - currentHeight), annot.GetUrx(IndentRight - line.WidthLeft + 20), annot.GetUry(IndentTop - currentHeight - 20));
+ PdfAnnotation an = PdfAnnotationsImp.ConvertAnnotation(writer, annot, rect);
+ annotationsImp.AddPlainAnnotation(an);
+ pageEmpty = false;
+ break;
+ }
+ case Element.PHRASE: {
+ leadingCount++;
+ // we cast the element to a phrase and set the leading of the document
+ leading = ((Phrase) element).Leading;
+ // we process the element
+ element.Process(this);
+ leadingCount--;
+ break;
+ }
+ case Element.PARAGRAPH: {
+ leadingCount++;
+ // we cast the element to a paragraph
+ Paragraph paragraph = (Paragraph) element;
+
+ AddSpacing(paragraph.SpacingBefore, leading, paragraph.Font);
+
+ // we adjust the parameters of the document
+ alignment = paragraph.Alignment;
+ leading = paragraph.TotalLeading;
+
+ CarriageReturn();
+ // we don't want to make orphans/widows
+ if (currentHeight + line.Height + leading > IndentTop - IndentBottom) {
+ NewPage();
+ }
+
+ indentation.indentLeft += paragraph.IndentationLeft;
+ indentation.indentRight += paragraph.IndentationRight;
+
+ CarriageReturn();
+
+ IPdfPageEvent pageEvent = writer.PageEvent;
+ if (pageEvent != null && !isSectionTitle)
+ pageEvent.OnParagraph(writer, this, IndentTop - currentHeight);
+
+ // if a paragraph has to be kept together, we wrap it in a table object
+ if (paragraph.KeepTogether) {
+ CarriageReturn();
+ PdfPTable table = new PdfPTable(1);
+ table.WidthPercentage = 100f;
+ PdfPCell cell = new PdfPCell();
+ cell.AddElement(paragraph);
+ cell.Border = Rectangle.NO_BORDER;
+ cell.Padding = 0;
+ table.AddCell(cell);
+ indentation.indentLeft -= paragraph.IndentationLeft;
+ indentation.indentRight -= paragraph.IndentationRight;
+ this.Add(table);
+ indentation.indentLeft += paragraph.IndentationLeft;
+ indentation.indentRight += paragraph.IndentationRight;
+ }
+ else {
+ line.SetExtraIndent(paragraph.FirstLineIndent);
+ element.Process(this);
+ CarriageReturn();
+ AddSpacing(paragraph.SpacingAfter, paragraph.TotalLeading, paragraph.Font);
+ }
+
+ if (pageEvent != null && !isSectionTitle)
+ pageEvent.OnParagraphEnd(writer, this, IndentTop - currentHeight);
+
+ alignment = Element.ALIGN_LEFT;
+ indentation.indentLeft -= paragraph.IndentationLeft;
+ indentation.indentRight -= paragraph.IndentationRight;
+ CarriageReturn();
+ leadingCount--;
+ break;
+ }
+ case Element.SECTION:
+ case Element.CHAPTER: {
+ // Chapters and Sections only differ in their constructor
+ // so we cast both to a Section
+ Section section = (Section) element;
+ IPdfPageEvent pageEvent = writer.PageEvent;
+
+ bool hasTitle = section.NotAddedYet && section.Title != null;
+
+ // if the section is a chapter, we begin a new page
+ if (section.TriggerNewPage) {
+ NewPage();
+ }
+
+ if (hasTitle) {
+ float fith = IndentTop - currentHeight;
+ int rotation = pageSize.Rotation;
+ if (rotation == 90 || rotation == 180)
+ fith = pageSize.Height - fith;
+ PdfDestination destination = new PdfDestination(PdfDestination.FITH, fith);
+ while (currentOutline.Level >= section.Depth) {
+ currentOutline = currentOutline.Parent;
+ }
+ PdfOutline outline = new PdfOutline(currentOutline, destination, section.GetBookmarkTitle(), section.BookmarkOpen);
+ currentOutline = outline;
+ }
+
+ // some values are set
+ CarriageReturn();
+ indentation.sectionIndentLeft += section.IndentationLeft;
+ indentation.sectionIndentRight += section.IndentationRight;
+ if (section.NotAddedYet && pageEvent != null)
+ if (element.Type == Element.CHAPTER)
+ pageEvent.OnChapter(writer, this, IndentTop - currentHeight, section.Title);
+ else
+ pageEvent.OnSection(writer, this, IndentTop - currentHeight, section.Depth, section.Title);
+
+ // the title of the section (if any has to be printed)
+ if (hasTitle) {
+ isSectionTitle = true;
+ Add(section.Title);
+ isSectionTitle = false;
+ }
+ indentation.sectionIndentLeft += section.Indentation;
+ // we process the section
+ element.Process(this);
+ // some parameters are set back to normal again
+ indentation.sectionIndentLeft -= (section.IndentationLeft + section.Indentation);
+ indentation.sectionIndentRight -= section.IndentationRight;
+
+ if (section.ElementComplete && pageEvent != null)
+ if (element.Type == Element.CHAPTER)
+ pageEvent.OnChapterEnd(writer, this, IndentTop - currentHeight);
+ else
+ pageEvent.OnSectionEnd(writer, this, IndentTop - currentHeight);
+
+ break;
+ }
+ case Element.LIST: {
+ // we cast the element to a List
+ List list = (List) element;
+ if (list.Alignindent) {
+ list.NormalizeIndentation();
+ }
+ // we adjust the document
+ indentation.listIndentLeft += list.IndentationLeft;
+ indentation.indentRight += list.IndentationRight;
+ // we process the items in the list
+ element.Process(this);
+ // some parameters are set back to normal again
+ indentation.listIndentLeft -= list.IndentationLeft;
+ indentation.indentRight -= list.IndentationRight;
+ CarriageReturn();
+ break;
+ }
+ case Element.LISTITEM: {
+ leadingCount++;
+ // we cast the element to a ListItem
+ ListItem listItem = (ListItem) element;
+
+ AddSpacing(listItem.SpacingBefore, leading, listItem.Font);
+
+ // we adjust the document
+ alignment = listItem.Alignment;
+ indentation.listIndentLeft += listItem.IndentationLeft;
+ indentation.indentRight += listItem.IndentationRight;
+ leading = listItem.TotalLeading;
+ CarriageReturn();
+ // we prepare the current line to be able to show us the listsymbol
+ line.ListItem = listItem;
+ // we process the item
+ element.Process(this);
+
+ AddSpacing(listItem.SpacingAfter, listItem.TotalLeading, listItem.Font);
+
+ // if the last line is justified, it should be aligned to the left
+ if (line.HasToBeJustified()) {
+ line.ResetAlignment();
+ }
+ // some parameters are set back to normal again
+ CarriageReturn();
+ indentation.listIndentLeft -= listItem.IndentationLeft;
+ indentation.indentRight -= listItem.IndentationRight;
+ leadingCount--;
+ break;
+ }
+ case Element.RECTANGLE: {
+ Rectangle rectangle = (Rectangle) element;
+ graphics.Rectangle(rectangle);
+ pageEmpty = false;
+ break;
+ }
+ case Element.PTABLE: {
+ PdfPTable ptable = (PdfPTable)element;
+ if (ptable.Size <= ptable.HeaderRows)
+ break; //nothing to do
+
+ // before every table, we add a new line and flush all lines
+ EnsureNewLine();
+ FlushLines();
+
+ AddPTable(ptable);
+ pageEmpty = false;
+ NewLine();
+ break;
+ }
+ case Element.MULTI_COLUMN_TEXT: {
+ EnsureNewLine();
+ FlushLines();
+ MultiColumnText multiText = (MultiColumnText) element;
+ float height = multiText.Write(writer.DirectContent, this, IndentTop - currentHeight);
+ currentHeight += height;
+ text.MoveText(0, -1f* height);
+ pageEmpty = false;
+ break;
+ }
+ case Element.TABLE : {
+ if (element is SimpleTable) {
+ PdfPTable ptable = ((SimpleTable)element).CreatePdfPTable();
+ if (ptable.Size <= ptable.HeaderRows)
+ break; //nothing to do
+
+ // before every table, we add a new line and flush all lines
+ EnsureNewLine();
+ FlushLines();
+ AddPTable(ptable);
+ pageEmpty = false;
+ break;
+ } else if (element is Table) {
+
+ try {
+ PdfPTable ptable = ((Table)element).CreatePdfPTable();
+ if (ptable.Size <= ptable.HeaderRows)
+ break; //nothing to do
+
+ // before every table, we add a new line and flush all lines
+ EnsureNewLine();
+ FlushLines();
+ AddPTable(ptable);
+ pageEmpty = false;
+ break;
+ }
+ catch (BadElementException) {
+ // constructing the PdfTable
+ // Before the table, add a blank line using offset or default leading
+ float offset = ((Table)element).Offset;
+ if (float.IsNaN(offset))
+ offset = leading;
+ CarriageReturn();
+ lines.Add(new PdfLine(IndentLeft, IndentRight, alignment, offset));
+ currentHeight += offset;
+ AddPdfTable((Table)element);
+ }
+ } else {
+ return false;
+ }
+ break;
+ }
+ case Element.JPEG:
+ case Element.JPEG2000:
+ case Element.IMGRAW:
+ case Element.IMGTEMPLATE: {
+ //carriageReturn(); suggestion by Marc Campforts
+ Add((Image) element);
+ break;
+ }
+ case Element.YMARK: {
+ IDrawInterface zh = (IDrawInterface)element;
+ zh.Draw(graphics, IndentLeft, IndentBottom, IndentRight, IndentTop, IndentTop - currentHeight - (leadingCount > 0 ? leading : 0));
+ pageEmpty = false;
+ break;
+ }
+ case Element.MARKED: {
+ MarkedObject mo;
+ if (element is MarkedSection) {
+ mo = ((MarkedSection)element).Title;
+ if (mo != null) {
+ mo.Process(this);
+ }
+ }
+ mo = (MarkedObject)element;
+ mo.Process(this);
+ break;
+ }
+ default:
+ return false;
+ }
+ lastElementType = element.Type;
+ return true;
+ }
+
+ // [L1] DocListener interface
+
+ /**
+ * Opens the document.
+ * PdfWriter
.
+ *
+ * @return a bool
+ * @throws DocumentException on error
+ */
+ public override bool NewPage() {
+ lastElementType = -1;
+ if (writer == null || (writer.DirectContent.Size == 0 && writer.DirectContentUnder.Size == 0 && (pageEmpty || writer.IsPaused()))) {
+ SetNewPageSizeAndMargins();
+ return false;
+ }
+ if (!open || close) {
+ throw new Exception("The document isn't open.");
+ }
+ IPdfPageEvent pageEvent = writer.PageEvent;
+ if (pageEvent != null)
+ pageEvent.OnEndPage(writer, this);
+
+ //Added to inform any listeners that we are moving to a new page (added by David Freels)
+ base.NewPage();
+
+ // the following 2 lines were added by Pelikan Stephan
+ indentation.imageIndentLeft = 0;
+ indentation.imageIndentRight = 0;
+
+ // we flush the arraylist with recently written lines
+ FlushLines();
+ // we prepare the elements of the page dictionary
+
+ // [U1] page size and rotation
+ int rotation = pageSize.Rotation;
+
+ // [C10]
+ if (writer.IsPdfX()) {
+ if (thisBoxSize.ContainsKey("art") && thisBoxSize.ContainsKey("trim"))
+ throw new PdfXConformanceException("Only one of ArtBox or TrimBox can exist in the page.");
+ if (!thisBoxSize.ContainsKey("art") && !thisBoxSize.ContainsKey("trim")) {
+ if (thisBoxSize.ContainsKey("crop"))
+ thisBoxSize["trim"] = thisBoxSize["crop"];
+ else
+ thisBoxSize["trim"] = new PdfRectangle(pageSize, pageSize.Rotation);
+ }
+ }
+
+ // [M1]
+ pageResources.AddDefaultColorDiff(writer.DefaultColorspace);
+ if (writer.RgbTransparencyBlending) {
+ PdfDictionary dcs = new PdfDictionary();
+ dcs.Put(PdfName.CS, PdfName.DEVICERGB);
+ pageResources.AddDefaultColorDiff(dcs);
+ }
+ PdfDictionary resources = pageResources.Resources;
+
+ // we create the page dictionary
+
+ PdfPage page = new PdfPage(new PdfRectangle(pageSize, rotation), thisBoxSize, resources, rotation);
+
+ // we complete the page dictionary
+
+ // [C9] if there is XMP data to add: add it
+ if (xmpMetadata != null) {
+ PdfStream xmp = new PdfStream(xmpMetadata);
+ xmp.Put(PdfName.TYPE, PdfName.METADATA);
+ xmp.Put(PdfName.SUBTYPE, PdfName.XML);
+ PdfEncryption crypto = writer.Encryption;
+ if (crypto != null && !crypto.IsMetadataEncrypted()) {
+ PdfArray ar = new PdfArray();
+ ar.Add(PdfName.CRYPT);
+ xmp.Put(PdfName.FILTER, ar);
+ }
+ page.Put(PdfName.METADATA, writer.AddToBody(xmp).IndirectReference);
+ }
+
+ // [U3] page actions: transition, duration, additional actions
+ if (this.transition!=null) {
+ page.Put(PdfName.TRANS, this.transition.TransitionDictionary);
+ transition = null;
+ }
+ if (this.duration>0) {
+ page.Put(PdfName.DUR,new PdfNumber(this.duration));
+ duration = 0;
+ }
+ if (pageAA != null) {
+ page.Put(PdfName.AA, writer.AddToBody(pageAA).IndirectReference);
+ pageAA = null;
+ }
+
+ // [U4] we add the thumbs
+ if (thumb != null) {
+ page.Put(PdfName.THUMB, thumb);
+ thumb = null;
+ }
+
+ // [U8] we check if the userunit is defined
+ if (writer.Userunit > 0f) {
+ page.Put(PdfName.USERUNIT, new PdfNumber(writer.Userunit));
+ }
+
+ // [C5] and [C8] we add the annotations
+ if (annotationsImp.HasUnusedAnnotations()) {
+ PdfArray array = annotationsImp.RotateAnnotations(writer, pageSize);
+ if (array.Size != 0)
+ page.Put(PdfName.ANNOTS, array);
+ }
+
+ // [F12] we add tag info
+ if (writer.IsTagged())
+ page.Put(PdfName.STRUCTPARENTS, new PdfNumber(writer.CurrentPageNumber - 1));
+
+ if (text.Size > textEmptySize)
+ text.EndText();
+ else
+ text = null;
+ writer.Add(page, new PdfContents(writer.DirectContentUnder, graphics, text, writer.DirectContent, pageSize));
+ // we initialize the new page
+ InitPage();
+ return true;
+ }
+
+ // [L4] DocListener interface
+
+ /**
+ * Sets the pagesize.
+ *
+ * @param pageSize the new pagesize
+ * @return true
if the page size was set
+ */
+ public override bool SetPageSize(Rectangle pageSize) {
+ if (writer != null && writer.IsPaused()) {
+ return false;
+ }
+ nextPageSize = new Rectangle(pageSize);
+ return true;
+ }
+
+
+ /** margin in x direction starting from the left. Will be valid in the next page */
+ protected float nextMarginLeft;
+
+ /** margin in x direction starting from the right. Will be valid in the next page */
+ protected float nextMarginRight;
+
+ /** margin in y direction starting from the top. Will be valid in the next page */
+ protected float nextMarginTop;
+
+ /** margin in y direction starting from the bottom. Will be valid in the next page */
+ protected float nextMarginBottom;
+
+ /**
+ * Sets the margins.
+ *
+ * @param marginLeft the margin on the left
+ * @param marginRight the margin on the right
+ * @param marginTop the margin on the top
+ * @param marginBottom the margin on the bottom
+ * @return a bool
+ */
+ public override bool SetMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) {
+ if (writer != null && writer.IsPaused()) {
+ return false;
+ }
+ nextMarginLeft = marginLeft;
+ nextMarginRight = marginRight;
+ nextMarginTop = marginTop;
+ nextMarginBottom = marginBottom;
+ return true;
+ }
+
+ // [L6] DocListener interface
+
+ /**
+ * @see com.lowagie.text.DocListener#setMarginMirroring(bool)
+ */
+ public override bool SetMarginMirroring(bool MarginMirroring) {
+ if (writer != null && writer.IsPaused()) {
+ return false;
+ }
+ return base.SetMarginMirroring(MarginMirroring);
+ }
+
+ // [L7] DocListener interface
+
+ /**
+ * Sets the page number.
+ *
+ * @param pageN the new page number
+ */
+ public override int PageCount {
+ set {
+ if (writer != null && writer.IsPaused()) {
+ return;
+ }
+ base.PageCount = value;
+ }
+ }
+
+ // [L8] DocListener interface
+
+ /**
+ * Sets the page number to 0.
+ */
+ public override void ResetPageCount() {
+ if (writer != null && writer.IsPaused()) {
+ return;
+ }
+ base.ResetPageCount();
+ }
+
+ /**
+ * Changes the header of this document.
+ *
+ * @param header the new header
+ */
+ public override HeaderFooter Header {
+ set {
+ if (writer != null && writer.IsPaused()) {
+ return;
+ }
+ base.Header = value;
+ }
+ }
+
+ /**
+ * Resets the header of this document.
+ */
+ public override void ResetHeader() {
+ if (writer != null && writer.IsPaused()) {
+ return;
+ }
+ base.ResetHeader();
+ }
+
+ /**
+ * Changes the footer of this document.
+ *
+ * @param footer the new footer
+ */
+ public override HeaderFooter Footer {
+ set {
+ if (writer != null && writer.IsPaused()) {
+ return;
+ }
+ base.Footer = value;
+ }
+ }
+
+ /**
+ * Resets the footer of this document.
+ */
+ public override void ResetFooter() {
+ if (writer != null && writer.IsPaused()) {
+ return;
+ }
+ base.ResetFooter();
+ }
+
+ // DOCLISTENER METHODS END
+
+ /** Signals that OnOpenDocument should be called. */
+ protected internal bool firstPageEvent = true;
+
+ /**
+ * Initializes a page.
+ * text
argument must be in text object scope (beginText()
).
+ * @param line the line to be written
+ * @param text the PdfContentByte
where the text will be written to
+ * @param graphics the PdfContentByte
where the graphics will be written to
+ * @param currentValues the current font and extra spacing values
+ * @param ratio
+ * @throws DocumentException on error
+ */
+ internal void WriteLineToContent(PdfLine line, PdfContentByte text, PdfContentByte graphics, Object[] currentValues, float ratio) {
+ PdfFont currentFont = (PdfFont)(currentValues[0]);
+ float lastBaseFactor = (float)currentValues[1];
+ //PdfChunk chunkz;
+ int numberOfSpaces;
+ int lineLen;
+ bool isJustified;
+ float hangingCorrection = 0;
+ float hScale = 1;
+ float lastHScale = float.NaN;
+ float baseWordSpacing = 0;
+ float baseCharacterSpacing = 0;
+ float glueWidth = 0;
+
+ numberOfSpaces = line.NumberOfSpaces;
+ lineLen = line.GetLineLengthUtf32();
+ // does the line need to be justified?
+ isJustified = line.HasToBeJustified() && (numberOfSpaces != 0 || lineLen > 1);
+ int separatorCount = line.GetSeparatorCount();
+ if (separatorCount > 0) {
+ glueWidth = line.WidthLeft / separatorCount;
+ }
+ else if (isJustified) {
+ if (line.NewlineSplit && line.WidthLeft >= (lastBaseFactor * (ratio * numberOfSpaces + lineLen - 1))) {
+ if (line.RTL) {
+ text.MoveText(line.WidthLeft - lastBaseFactor * (ratio * numberOfSpaces + lineLen - 1), 0);
+ }
+ baseWordSpacing = ratio * lastBaseFactor;
+ baseCharacterSpacing = lastBaseFactor;
+ }
+ else {
+ float width = line.WidthLeft;
+ PdfChunk last = line.GetChunk(line.Size - 1);
+ if (last != null) {
+ String s = last.ToString();
+ char c;
+ if (s.Length > 0 && hangingPunctuation.IndexOf((c = s[s.Length - 1])) >= 0) {
+ float oldWidth = width;
+ width += last.Font.Width(c) * 0.4f;
+ hangingCorrection = width - oldWidth;
+ }
+ }
+ float baseFactor = width / (ratio * numberOfSpaces + lineLen - 1);
+ baseWordSpacing = ratio * baseFactor;
+ baseCharacterSpacing = baseFactor;
+ lastBaseFactor = baseFactor;
+ }
+ }
+
+ int lastChunkStroke = line.LastStrokeChunk;
+ int chunkStrokeIdx = 0;
+ float xMarker = text.XTLM;
+ float baseXMarker = xMarker;
+ float yMarker = text.YTLM;
+ bool adjustMatrix = false;
+ float tabPosition = 0;
+
+ // looping over all the chunks in 1 line
+ foreach (PdfChunk chunk in line) {
+ Color color = chunk.Color;
+ hScale = 1;
+
+ if (chunkStrokeIdx <= lastChunkStroke) {
+ float width;
+ if (isJustified) {
+ width = chunk.GetWidthCorrected(baseCharacterSpacing, baseWordSpacing);
+ }
+ else {
+ width = chunk.Width;
+ }
+ if (chunk.IsStroked()) {
+ PdfChunk nextChunk = line.GetChunk(chunkStrokeIdx + 1);
+ if (chunk.IsSeparator()) {
+ width = glueWidth;
+ Object[] sep = (Object[])chunk.GetAttribute(Chunk.SEPARATOR);
+ IDrawInterface di = (IDrawInterface)sep[0];
+ bool vertical = (bool)sep[1];
+ float fontSize = chunk.Font.Size;
+ float ascender = chunk.Font.Font.GetFontDescriptor(BaseFont.ASCENT, fontSize);
+ float descender = chunk.Font.Font.GetFontDescriptor(BaseFont.DESCENT, fontSize);
+ if (vertical) {
+ di.Draw(graphics, baseXMarker, yMarker + descender, baseXMarker + line.OriginalWidth, ascender - descender, yMarker);
+ }
+ else {
+ di.Draw(graphics, xMarker, yMarker + descender, xMarker + width, ascender - descender, yMarker);
+ }
+ }
+ if (chunk.IsTab()) {
+ Object[] tab = (Object[])chunk.GetAttribute(Chunk.TAB);
+ IDrawInterface di = (IDrawInterface)tab[0];
+ tabPosition = (float)tab[1] + (float)tab[3];
+ float fontSize = chunk.Font.Size;
+ float ascender = chunk.Font.Font.GetFontDescriptor(BaseFont.ASCENT, fontSize);
+ float descender = chunk.Font.Font.GetFontDescriptor(BaseFont.DESCENT, fontSize);
+ if (tabPosition > xMarker) {
+ di.Draw(graphics, xMarker, yMarker + descender, tabPosition, ascender - descender, yMarker);
+ }
+ float tmp = xMarker;
+ xMarker = tabPosition;
+ tabPosition = tmp;
+ }
+ if (chunk.IsAttribute(Chunk.BACKGROUND)) {
+ float subtract = lastBaseFactor;
+ if (nextChunk != null && nextChunk.IsAttribute(Chunk.BACKGROUND))
+ subtract = 0;
+ if (nextChunk == null)
+ subtract += hangingCorrection;
+ float fontSize = chunk.Font.Size;
+ float ascender = chunk.Font.Font.GetFontDescriptor(BaseFont.ASCENT, fontSize);
+ float descender = chunk.Font.Font.GetFontDescriptor(BaseFont.DESCENT, fontSize);
+ Object[] bgr = (Object[])chunk.GetAttribute(Chunk.BACKGROUND);
+ graphics.SetColorFill((Color)bgr[0]);
+ float[] extra = (float[])bgr[1];
+ graphics.Rectangle(xMarker - extra[0],
+ yMarker + descender - extra[1] + chunk.TextRise,
+ width - subtract + extra[0] + extra[2],
+ ascender - descender + extra[1] + extra[3]);
+ graphics.Fill();
+ graphics.SetGrayFill(0);
+ }
+ if (chunk.IsAttribute(Chunk.UNDERLINE)) {
+ float subtract = lastBaseFactor;
+ if (nextChunk != null && nextChunk.IsAttribute(Chunk.UNDERLINE))
+ subtract = 0;
+ if (nextChunk == null)
+ subtract += hangingCorrection;
+ Object[][] unders = (Object[][])chunk.GetAttribute(Chunk.UNDERLINE);
+ Color scolor = null;
+ for (int k = 0; k < unders.Length; ++k) {
+ Object[] obj = unders[k];
+ scolor = (Color)obj[0];
+ float[] ps = (float[])obj[1];
+ if (scolor == null)
+ scolor = color;
+ if (scolor != null)
+ graphics.SetColorStroke(scolor);
+ float fsize = chunk.Font.Size;
+ graphics.SetLineWidth(ps[0] + fsize * ps[1]);
+ float shift = ps[2] + fsize * ps[3];
+ int cap2 = (int)ps[4];
+ if (cap2 != 0)
+ graphics.SetLineCap(cap2);
+ graphics.MoveTo(xMarker, yMarker + shift);
+ graphics.LineTo(xMarker + width - subtract, yMarker + shift);
+ graphics.Stroke();
+ if (scolor != null)
+ graphics.ResetGrayStroke();
+ if (cap2 != 0)
+ graphics.SetLineCap(0);
+ }
+ graphics.SetLineWidth(1);
+ }
+ if (chunk.IsAttribute(Chunk.ACTION)) {
+ float subtract = lastBaseFactor;
+ if (nextChunk != null && nextChunk.IsAttribute(Chunk.ACTION))
+ subtract = 0;
+ if (nextChunk == null)
+ subtract += hangingCorrection;
+ text.AddAnnotation(new PdfAnnotation(writer, xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.Font.Size, (PdfAction)chunk.GetAttribute(Chunk.ACTION)));
+ }
+ if (chunk.IsAttribute(Chunk.REMOTEGOTO)) {
+ float subtract = lastBaseFactor;
+ if (nextChunk != null && nextChunk.IsAttribute(Chunk.REMOTEGOTO))
+ subtract = 0;
+ if (nextChunk == null)
+ subtract += hangingCorrection;
+ Object[] obj = (Object[])chunk.GetAttribute(Chunk.REMOTEGOTO);
+ String filename = (String)obj[0];
+ if (obj[1] is String)
+ RemoteGoto(filename, (String)obj[1], xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.Font.Size);
+ else
+ RemoteGoto(filename, (int)obj[1], xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.Font.Size);
+ }
+ if (chunk.IsAttribute(Chunk.LOCALGOTO)) {
+ float subtract = lastBaseFactor;
+ if (nextChunk != null && nextChunk.IsAttribute(Chunk.LOCALGOTO))
+ subtract = 0;
+ if (nextChunk == null)
+ subtract += hangingCorrection;
+ LocalGoto((String)chunk.GetAttribute(Chunk.LOCALGOTO), xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.Font.Size);
+ }
+ if (chunk.IsAttribute(Chunk.LOCALDESTINATION)) {
+ float subtract = lastBaseFactor;
+ if (nextChunk != null && nextChunk.IsAttribute(Chunk.LOCALDESTINATION))
+ subtract = 0;
+ if (nextChunk == null)
+ subtract += hangingCorrection;
+ LocalDestination((String)chunk.GetAttribute(Chunk.LOCALDESTINATION), new PdfDestination(PdfDestination.XYZ, xMarker, yMarker + chunk.Font.Size, 0));
+ }
+ if (chunk.IsAttribute(Chunk.GENERICTAG)) {
+ float subtract = lastBaseFactor;
+ if (nextChunk != null && nextChunk.IsAttribute(Chunk.GENERICTAG))
+ subtract = 0;
+ if (nextChunk == null)
+ subtract += hangingCorrection;
+ Rectangle rect = new Rectangle(xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.Font.Size);
+ IPdfPageEvent pev = writer.PageEvent;
+ if (pev != null)
+ pev.OnGenericTag(writer, this, rect, (String)chunk.GetAttribute(Chunk.GENERICTAG));
+ }
+ if (chunk.IsAttribute(Chunk.PDFANNOTATION)) {
+ float subtract = lastBaseFactor;
+ if (nextChunk != null && nextChunk.IsAttribute(Chunk.PDFANNOTATION))
+ subtract = 0;
+ if (nextChunk == null)
+ subtract += hangingCorrection;
+ float fontSize = chunk.Font.Size;
+ float ascender = chunk.Font.Font.GetFontDescriptor(BaseFont.ASCENT, fontSize);
+ float descender = chunk.Font.Font.GetFontDescriptor(BaseFont.DESCENT, fontSize);
+ PdfAnnotation annot = PdfFormField.ShallowDuplicate((PdfAnnotation)chunk.GetAttribute(Chunk.PDFANNOTATION));
+ annot.Put(PdfName.RECT, new PdfRectangle(xMarker, yMarker + descender, xMarker + width - subtract, yMarker + ascender));
+ text.AddAnnotation(annot);
+ }
+ float[] paramsx = (float[])chunk.GetAttribute(Chunk.SKEW);
+ object hs = chunk.GetAttribute(Chunk.HSCALE);
+ if (paramsx != null || hs != null) {
+ float b = 0, c = 0;
+ if (paramsx != null) {
+ b = paramsx[0];
+ c = paramsx[1];
+ }
+ if (hs != null)
+ hScale = (float)hs;
+ text.SetTextMatrix(hScale, b, c, 1, xMarker, yMarker);
+ }
+ if (chunk.IsImage()) {
+ Image image = chunk.Image;
+ float[] matrix = image.Matrix;
+ matrix[Image.CX] = xMarker + chunk.ImageOffsetX - matrix[Image.CX];
+ matrix[Image.CY] = yMarker + chunk.ImageOffsetY - matrix[Image.CY];
+ graphics.AddImage(image, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
+ text.MoveText(xMarker + lastBaseFactor + image.ScaledWidth - text.XTLM, 0);
+ }
+ }
+ xMarker += width;
+ ++chunkStrokeIdx;
+ }
+
+ if (chunk.Font.CompareTo(currentFont) != 0) {
+ currentFont = chunk.Font;
+ text.SetFontAndSize(currentFont.Font, currentFont.Size);
+ }
+ float rise = 0;
+ Object[] textRender = (Object[])chunk.GetAttribute(Chunk.TEXTRENDERMODE);
+ int tr = 0;
+ float strokeWidth = 1;
+ Color strokeColor = null;
+ object fr = chunk.GetAttribute(Chunk.SUBSUPSCRIPT);
+ if (textRender != null) {
+ tr = (int)textRender[0] & 3;
+ if (tr != PdfContentByte.TEXT_RENDER_MODE_FILL)
+ text.SetTextRenderingMode(tr);
+ if (tr == PdfContentByte.TEXT_RENDER_MODE_STROKE || tr == PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE) {
+ strokeWidth = (float)textRender[1];
+ if (strokeWidth != 1)
+ text.SetLineWidth(strokeWidth);
+ strokeColor = (Color)textRender[2];
+ if (strokeColor == null)
+ strokeColor = color;
+ if (strokeColor != null)
+ text.SetColorStroke(strokeColor);
+ }
+ }
+ if (fr != null)
+ rise = (float)fr;
+ if (color != null)
+ text.SetColorFill(color);
+ if (rise != 0)
+ text.SetTextRise(rise);
+ if (chunk.IsImage()) {
+ adjustMatrix = true;
+ }
+ else if (chunk.IsHorizontalSeparator()) {
+ PdfTextArray array = new PdfTextArray();
+ array.Add(-glueWidth * 1000f / chunk.Font.Size / hScale);
+ text.ShowText(array);
+ }
+ else if (chunk.IsTab()) {
+ PdfTextArray array = new PdfTextArray();
+ array.Add((tabPosition - xMarker) * 1000f / chunk.Font.Size / hScale);
+ text.ShowText(array);
+ }
+ // If it is a CJK chunk or Unicode TTF we will have to simulate the
+ // space adjustment.
+ else if (isJustified && numberOfSpaces > 0 && chunk.IsSpecialEncoding()) {
+ if (hScale != lastHScale) {
+ lastHScale = hScale;
+ text.SetWordSpacing(baseWordSpacing / hScale);
+ text.SetCharacterSpacing(baseCharacterSpacing / hScale);
+ }
+ String s = chunk.ToString();
+ int idx = s.IndexOf(' ');
+ if (idx < 0)
+ text.ShowText(s);
+ else {
+ float spaceCorrection = - baseWordSpacing * 1000f / chunk.Font.Size / hScale;
+ PdfTextArray textArray = new PdfTextArray(s.Substring(0, idx));
+ int lastIdx = idx;
+ while ((idx = s.IndexOf(' ', lastIdx + 1)) >= 0) {
+ textArray.Add(spaceCorrection);
+ textArray.Add(s.Substring(lastIdx, idx - lastIdx));
+ lastIdx = idx;
+ }
+ textArray.Add(spaceCorrection);
+ textArray.Add(s.Substring(lastIdx));
+ text.ShowText(textArray);
+ }
+ }
+ else {
+ if (isJustified && hScale != lastHScale) {
+ lastHScale = hScale;
+ text.SetWordSpacing(baseWordSpacing / hScale);
+ text.SetCharacterSpacing(baseCharacterSpacing / hScale);
+ }
+ text.ShowText(chunk.ToString());
+ }
+
+ if (rise != 0)
+ text.SetTextRise(0);
+ if (color != null)
+ text.ResetRGBColorFill();
+ if (tr != PdfContentByte.TEXT_RENDER_MODE_FILL)
+ text.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
+ if (strokeColor != null)
+ text.ResetRGBColorStroke();
+ if (strokeWidth != 1)
+ text.SetLineWidth(1);
+ if (chunk.IsAttribute(Chunk.SKEW) || chunk.IsAttribute(Chunk.HSCALE)) {
+ adjustMatrix = true;
+ text.SetTextMatrix(xMarker, yMarker);
+ }
+ }
+ if (isJustified) {
+ text.SetWordSpacing(0);
+ text.SetCharacterSpacing(0);
+ if (line.NewlineSplit)
+ lastBaseFactor = 0;
+ }
+ if (adjustMatrix)
+ text.MoveText(baseXMarker - text.XTLM, 0);
+ currentValues[0] = currentFont;
+ currentValues[1] = lastBaseFactor;
+ }
+
+ protected internal Indentation indentation = new Indentation();
+ public class Indentation {
+ /** This represents the current indentation of the PDF Elements on the left side. */
+ internal float indentLeft = 0;
+
+ /** Indentation to the left caused by a section. */
+ internal float sectionIndentLeft = 0;
+
+ /** This represents the current indentation of the PDF Elements on the left side. */
+ internal float listIndentLeft = 0;
+
+ /** This is the indentation caused by an image on the left. */
+ internal float imageIndentLeft = 0;
+
+ /** This represents the current indentation of the PDF Elements on the right side. */
+ internal float indentRight = 0;
+
+ /** Indentation to the right caused by a section. */
+ internal float sectionIndentRight = 0;
+
+ /** This is the indentation caused by an image on the right. */
+ internal float imageIndentRight = 0;
+
+ /** This represents the current indentation of the PDF Elements on the top side. */
+ internal float indentTop = 0;
+
+ /** This represents the current indentation of the PDF Elements on the bottom side. */
+ internal float indentBottom = 0;
+ }
+
+ /**
+ * Gets the indentation on the left side.
+ *
+ * @return a margin
+ */
+
+ protected internal float IndentLeft {
+ get {
+ return GetLeft(indentation.indentLeft + indentation.listIndentLeft + indentation.imageIndentLeft + indentation.sectionIndentLeft);
+ }
+ }
+
+ /**
+ * Gets the indentation on the right side.
+ *
+ * @return a margin
+ */
+
+ protected internal float IndentRight {
+ get {
+ return GetRight(indentation.indentRight + indentation.sectionIndentRight + indentation.imageIndentRight);
+ }
+ }
+
+ /**
+ * Gets the indentation on the top side.
+ *
+ * @return a margin
+ */
+
+ protected internal float IndentTop {
+ get {
+ return GetTop(indentation.indentTop);
+ }
+ }
+
+ /**
+ * Gets the indentation on the bottom side.
+ *
+ * @return a margin
+ */
+
+ protected internal float IndentBottom {
+ get {
+ return GetBottom(indentation.indentBottom);
+ }
+ }
+
+ /**
+ * Adds extra space.
+ * This method should probably be rewritten.
+ */
+ protected internal void AddSpacing(float extraspace, float oldleading, Font f) {
+ if (extraspace == 0) return;
+ if (pageEmpty) return;
+ if (currentHeight + line.Height + leading > IndentTop - IndentBottom) return;
+ leading = extraspace;
+ CarriageReturn();
+ if (f.IsUnderlined() || f.IsStrikethru()) {
+ f = new Font(f);
+ int style = f.Style;
+ style &= ~Font.UNDERLINE;
+ style &= ~Font.STRIKETHRU;
+ f.SetStyle(Font.UNDEFINED);
+ f.SetStyle(style);
+ }
+ Chunk space = new Chunk(" ", f);
+ space.Process(this);
+ CarriageReturn();
+ leading = oldleading;
+ }
+
+ // Info Dictionary and Catalog
+
+ /** some meta information about the Document. */
+ protected internal PdfInfo info = new PdfInfo();
+
+ /**
+ * Gets the PdfInfo
-object.
+ *
+ * @return PdfInfo
+ */
+ internal PdfInfo Info {
+ get {
+ return info;
+ }
+ }
+
+ /**
+ * Gets the
byte array according
+ * to the font's encoding.
+ * @param text the PdfCatalog
-object.
+ *
+ * @param pages an indirect reference to this document pages
+ * @return PdfCatalog
+ */
+ internal PdfCatalog GetCatalog(PdfIndirectReference pages) {
+ PdfCatalog catalog = new PdfCatalog(pages, writer);
+
+ // [C1] outlines
+ if (rootOutline.Kids.Count > 0) {
+ catalog.Put(PdfName.PAGEMODE, PdfName.USEOUTLINES);
+ catalog.Put(PdfName.OUTLINES, rootOutline.IndirectReference);
+ }
+
+ // [C2] version
+ writer.GetPdfVersion().AddToCatalog(catalog);
+
+ // [C3] preferences
+ viewerPreferences.AddToCatalog(catalog);
+
+ // [C4] pagelabels
+ if (pageLabels != null) {
+ catalog.Put(PdfName.PAGELABELS, pageLabels.GetDictionary(writer));
+ }
+
+ // [C5] named objects
+ catalog.AddNames(localDestinations, GetDocumentLevelJS(), documentFileAttachment, writer);
+
+ // [C6] actions
+ if (openActionName != null) {
+ PdfAction action = GetLocalGotoAction(openActionName);
+ catalog.OpenAction = action;
+ }
+ else if (openActionAction != null)
+ catalog.OpenAction = openActionAction;
+ if (additionalActions != null) {
+ catalog.AdditionalActions = additionalActions;
+ }
+
+ // [C7] portable collections
+ if (collection != null) {
+ catalog.Put(PdfName.COLLECTION, collection);
+ }
+
+ // [C8] AcroForm
+ if (annotationsImp.HasValidAcroForm()) {
+ catalog.Put(PdfName.ACROFORM, writer.AddToBody(annotationsImp.AcroForm).IndirectReference);
+ }
+
+ return catalog;
+ }
+
+ // [C1] outlines
+
+ /** This is the root outline of the document. */
+ protected internal PdfOutline rootOutline;
+
+ /** This is the current PdfOutline
in the hierarchy of outlines. */
+ protected internal PdfOutline currentOutline;
+
+ /**
+ * Adds a named outline to the document .
+ * @param outline the outline to be added
+ * @param name the name of this local destination
+ */
+ internal void AddOutline(PdfOutline outline, String name) {
+ LocalDestination(name, outline.PdfDestination);
+ }
+
+ /**
+ * Gets the root outline. All the outlines must be created with a parent.
+ * The first level is created with this outline.
+ * @return the root outline
+ */
+ public PdfOutline RootOutline {
+ get {
+ return rootOutline;
+ }
+ }
+
+ internal void CalculateOutlineCount() {
+ if (rootOutline.Kids.Count == 0)
+ return;
+ TraverseOutlineCount(rootOutline);
+ }
+
+ internal void TraverseOutlineCount(PdfOutline outline) {
+ ArrayList kids = outline.Kids;
+ PdfOutline parent = outline.Parent;
+ if (kids.Count == 0) {
+ if (parent != null) {
+ parent.Count = parent.Count + 1;
+ }
+ }
+ else {
+ for (int k = 0; k < kids.Count; ++k) {
+ TraverseOutlineCount((PdfOutline)kids[k]);
+ }
+ if (parent != null) {
+ if (outline.Open) {
+ parent.Count = outline.Count + parent.Count + 1;
+ }
+ else {
+ parent.Count = parent.Count + 1;
+ outline.Count = -outline.Count;
+ }
+ }
+ }
+ }
+
+ internal void WriteOutlines() {
+ if (rootOutline.Kids.Count == 0)
+ return;
+ OutlineTree(rootOutline);
+ writer.AddToBody(rootOutline, rootOutline.IndirectReference);
+ }
+
+ internal void OutlineTree(PdfOutline outline) {
+ outline.IndirectReference = writer.PdfIndirectReference;
+ if (outline.Parent != null)
+ outline.Put(PdfName.PARENT, outline.Parent.IndirectReference);
+ ArrayList kids = outline.Kids;
+ int size = kids.Count;
+ for (int k = 0; k < size; ++k)
+ OutlineTree((PdfOutline)kids[k]);
+ for (int k = 0; k < size; ++k) {
+ if (k > 0)
+ ((PdfOutline)kids[k]).Put(PdfName.PREV, ((PdfOutline)kids[k - 1]).IndirectReference);
+ if (k < size - 1)
+ ((PdfOutline)kids[k]).Put(PdfName.NEXT, ((PdfOutline)kids[k + 1]).IndirectReference);
+ }
+ if (size > 0) {
+ outline.Put(PdfName.FIRST, ((PdfOutline)kids[0]).IndirectReference);
+ outline.Put(PdfName.LAST, ((PdfOutline)kids[size - 1]).IndirectReference);
+ }
+ for (int k = 0; k < size; ++k) {
+ PdfOutline kid = (PdfOutline)kids[k];
+ writer.AddToBody(kid, kid.IndirectReference);
+ }
+ }
+
+ // [C3] PdfViewerPreferences interface
+
+ /** Contains the Viewer preferences of this PDF document. */
+ protected PdfViewerPreferencesImp viewerPreferences = new PdfViewerPreferencesImp();
+ /** @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#setViewerPreferences(int) */
+ internal int ViewerPreferences {
+ set {
+ this.viewerPreferences.ViewerPreferences = value;
+ }
+ }
+
+ /** @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#addViewerPreference(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfObject) */
+ internal void AddViewerPreference(PdfName key, PdfObject value) {
+ this.viewerPreferences.AddViewerPreference(key, value);
+ }
+
+ // [C4] Page labels
+
+ protected internal PdfPageLabels pageLabels;
+
+ internal PdfPageLabels PageLabels {
+ set {
+ this.pageLabels = value;
+ }
+ }
+
+ // [C5] named objects: local destinations, javascript, embedded files
+
+ /**
+ * Implements a link to other part of the document. The jump will
+ * be made to a local destination with the same name, that must exist.
+ * @param name the name for this link
+ * @param llx the lower left x corner of the activation area
+ * @param lly the lower left y corner of the activation area
+ * @param urx the upper right x corner of the activation area
+ * @param ury the upper right y corner of the activation area
+ */
+ internal void LocalGoto(String name, float llx, float lly, float urx, float ury) {
+ PdfAction action = GetLocalGotoAction(name);
+ annotationsImp.AddPlainAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action));
+ }
+
+ /**
+ * Implements a link to another document.
+ * @param filename the filename for the remote document
+ * @param name the name to jump to
+ * @param llx the lower left x corner of the activation area
+ * @param lly the lower left y corner of the activation area
+ * @param urx the upper right x corner of the activation area
+ * @param ury the upper right y corner of the activation area
+ */
+ internal void RemoteGoto(String filename, String name, float llx, float lly, float urx, float ury) {
+ annotationsImp.AddPlainAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, new PdfAction(filename, name)));
+ }
+
+ /**
+ * Implements a link to another document.
+ * @param filename the filename for the remote document
+ * @param page the page to jump to
+ * @param llx the lower left x corner of the activation area
+ * @param lly the lower left y corner of the activation area
+ * @param urx the upper right x corner of the activation area
+ * @param ury the upper right y corner of the activation area
+ */
+ internal void RemoteGoto(String filename, int page, float llx, float lly, float urx, float ury) {
+ AddAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, new PdfAction(filename, page)));
+ }
+
+ /** Implements an action in an area.
+ * @param action the PdfAction
+ * @param llx the lower left x corner of the activation area
+ * @param lly the lower left y corner of the activation area
+ * @param urx the upper right x corner of the activation area
+ * @param ury the upper right y corner of the activation area
+ */
+ internal void SetAction(PdfAction action, float llx, float lly, float urx, float ury) {
+ AddAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action));
+ }
+
+ /**
+ * Stores the destinations keyed by name. Value is
+ * Object[]{PdfAction,PdfIndirectReference,PdfDestintion}
.
+ */
+ protected internal k_Tree localDestinations = new k_Tree();
+
+ internal PdfAction GetLocalGotoAction(String name) {
+ PdfAction action;
+ Object[] obj = (Object[])localDestinations[name];
+ if (obj == null)
+ obj = new Object[3];
+ if (obj[0] == null) {
+ if (obj[1] == null) {
+ obj[1] = writer.PdfIndirectReference;
+ }
+ action = new PdfAction((PdfIndirectReference)obj[1]);
+ obj[0] = action;
+ localDestinations[name] = obj;
+ }
+ else {
+ action = (PdfAction)obj[0];
+ }
+ return action;
+ }
+
+ /**
+ * The local destination to where a local goto with the same
+ * name will jump to.
+ * @param name the name of this local destination
+ * @param destination the PdfDestination
with the jump coordinates
+ * @return true
if the local destination was added,
+ * false
if a local destination with the same name
+ * already existed
+ */
+ internal bool LocalDestination(String name, PdfDestination destination) {
+ Object[] obj = (Object[])localDestinations[name];
+ if (obj == null)
+ obj = new Object[3];
+ if (obj[2] != null)
+ return false;
+ obj[2] = destination;
+ localDestinations[name] = obj;
+ destination.AddPage(writer.CurrentPage);
+ return true;
+ }
+
+ /**
+ * Stores a list of document level JavaScript actions.
+ */
+ private int jsCounter;
+ protected internal Hashtable documentLevelJS = new Hashtable();
+
+ internal void AddJavaScript(PdfAction js) {
+ if (js.Get(PdfName.JS) == null)
+ throw new ArgumentException("Only JavaScript actions are allowed.");
+ documentLevelJS[jsCounter.ToString().PadLeft(16, '0')] = writer.AddToBody(js).IndirectReference;
+ jsCounter++;
+ }
+
+ internal void AddJavaScript(String name, PdfAction js) {
+ if (js.Get(PdfName.JS) == null)
+ throw new ArgumentException("Only JavaScript actions are allowed.");
+ documentLevelJS[name] = writer.AddToBody(js).IndirectReference;
+ }
+
+ internal Hashtable GetDocumentLevelJS() {
+ return documentLevelJS;
+ }
+
+ protected internal Hashtable documentFileAttachment = new Hashtable();
+
+ internal void AddFileAttachment(String description, PdfFileSpecification fs) {
+ if (description == null) {
+ PdfString desc = (PdfString)fs.Get(PdfName.DESC);
+ if (desc == null) {
+ description = "";
+ }
+ else {
+ description = PdfEncodings.ConvertToString(desc.GetBytes(), null);
+ }
+ }
+ fs.AddDescription(description, true);
+ if (description.Length == 0)
+ description = "Unnamed";
+ String fn = PdfEncodings.ConvertToString(new PdfString(description, PdfObject.TEXT_UNICODE).GetBytes(), null);
+ int k = 0;
+ while (documentFileAttachment.ContainsKey(fn)) {
+ ++k;
+ fn = PdfEncodings.ConvertToString(new PdfString(description + " " + k, PdfObject.TEXT_UNICODE).GetBytes(), null);
+ }
+ documentFileAttachment[fn] = fs.Reference;
+ }
+
+ internal Hashtable GetDocumentFileAttachment() {
+ return documentFileAttachment;
+ }
+
+ // [C6] document level actions
+
+ protected internal String openActionName;
+
+ internal void SetOpenAction(String name) {
+ openActionName = name;
+ openActionAction = null;
+ }
+
+ protected internal PdfAction openActionAction;
+
+ internal void SetOpenAction(PdfAction action) {
+ openActionAction = action;
+ openActionName = null;
+ }
+
+ protected internal PdfDictionary additionalActions;
+
+ internal void AddAdditionalAction(PdfName actionType, PdfAction action) {
+ if (additionalActions == null) {
+ additionalActions = new PdfDictionary();
+ }
+ if (action == null)
+ additionalActions.Remove(actionType);
+ else
+ additionalActions.Put(actionType, action);
+ if (additionalActions.Size == 0)
+ additionalActions = null;
+ }
+
+ // [C7] portable collections
+
+ protected internal PdfCollection collection;
+
+ /**
+ * Sets the collection dictionary.
+ * @param collection a dictionary of type PdfCollection
+ */
+ public PdfCollection Collection {
+ set {
+ this.collection = value;
+ }
+ }
+
+ // [C8] AcroForm
+
+ internal PdfAnnotationsImp annotationsImp;
+
+ /**
+ * Gets the AcroForm object.
+ * @return the PdfAcroform object of the PdfDocument
+ */
+ public PdfAcroForm AcroForm {
+ get {
+ return annotationsImp.AcroForm;
+ }
+ }
+
+ internal int SigFlags {
+ set {
+ annotationsImp.SigFlags = value;
+ }
+ }
+
+ internal void AddCalculationOrder(PdfFormField formField) {
+ annotationsImp.AddCalculationOrder(formField);
+ }
+
+ internal void AddAnnotation(PdfAnnotation annot) {
+ pageEmpty = false;
+ annotationsImp.AddAnnotation(annot);
+ }
+
+ // [F12] tagged PDF
+
+ protected int markPoint;
+
+ internal int GetMarkPoint() {
+ return markPoint;
+ }
+
+ internal void IncMarkPoint() {
+ ++markPoint;
+ }
+
+ // [U1] page sizes
+
+ /** This is the size of the next page. */
+ protected Rectangle nextPageSize = null;
+
+ /** This is the size of the several boxes of the current Page. */
+ protected Hashtable thisBoxSize = new Hashtable();
+
+ /** This is the size of the several boxes that will be used in
+ * the next page. */
+ protected Hashtable boxSize = new Hashtable();
+
+ internal Rectangle CropBoxSize {
+ set {
+ SetBoxSize("crop", value);
+ }
+ }
+
+ internal void SetBoxSize(String boxName, Rectangle size) {
+ if (size == null)
+ boxSize.Remove(boxName);
+ else
+ boxSize[boxName] = new PdfRectangle(size);
+ }
+
+ protected internal void SetNewPageSizeAndMargins() {
+ pageSize = nextPageSize;
+ if (marginMirroring && (PageNumber & 1) == 0) {
+ marginRight = nextMarginLeft;
+ marginLeft = nextMarginRight;
+ }
+ else {
+ marginLeft = nextMarginLeft;
+ marginRight = nextMarginRight;
+ }
+ marginTop = nextMarginTop;
+ marginBottom = nextMarginBottom;
+ }
+
+ /**
+ * Gives the size of a trim, art, crop or bleed box, or null if not defined.
+ * @param boxName crop, trim, art or bleed
+ */
+ internal Rectangle GetBoxSize(String boxName) {
+ PdfRectangle r = (PdfRectangle)thisBoxSize[boxName];
+ if (r != null) return r.Rectangle;
+ return null;
+ }
+
+ // [U2] empty pages
+
+ /** This checks if the page is empty. */
+ protected internal bool pageEmpty = true;
+
+ internal bool PageEmpty {
+ set {
+ this.pageEmpty = value;
+ }
+ }
+
+
+ // [U3] page actions
+
+ /** The duration of the page */
+ protected int duration=-1; // negative values will indicate no duration
+
+ /** The page transition */
+ protected PdfTransition transition=null;
+
+ /**
+ * Sets the display duration for the page (for presentations)
+ * @param seconds the number of seconds to display the page
+ */
+ internal int Duration {
+ set {
+ if (value > 0)
+ this.duration=value;
+ else
+ this.duration=-1;
+ }
+ }
+
+ /**
+ * Sets the transition for the page
+ * @param transition the PdfTransition object
+ */
+ internal PdfTransition Transition {
+ set {
+ this.transition=value;
+ }
+ }
+
+ protected PdfDictionary pageAA = null;
+
+ internal void SetPageAction(PdfName actionType, PdfAction action) {
+ if (pageAA == null) {
+ pageAA = new PdfDictionary();
+ }
+ pageAA.Put(actionType, action);
+ }
+
+ // [U8] thumbnail images
+
+ protected internal PdfIndirectReference thumb;
+
+ internal Image Thumbnail {
+ set {
+ thumb = writer.GetImageReference(writer.AddDirectImageSimple(value));
+ }
+ }
+
+ // [M0] Page resources contain references to fonts, extgstate, images,...
+
+ /** This are the page resources of the current Page. */
+ protected internal PageResources pageResources;
+
+ internal PageResources PageResources {
+ get {
+ return pageResources;
+ }
+ }
+
+ // [M3] Images
+
+ /** Holds value of property strictImageSequence. */
+ protected internal bool strictImageSequence = false;
+
+ /** Setter for property strictImageSequence.
+ * @param strictImageSequence New value of property strictImageSequence.
+ *
+ */
+ internal bool StrictImageSequence {
+ set {
+ this.strictImageSequence = value;
+ }
+ get {
+ return strictImageSequence;
+ }
+ }
+
+ /** This is the position where the image ends. */
+ protected internal float imageEnd = -1;
+
+ /**
+ * Method added by Pelikan Stephan
+ * @see com.lowagie.text.DocListener#clearTextWrap()
+ */
+ public void ClearTextWrap() {
+ float tmpHeight = imageEnd - currentHeight;
+ if (line != null) {
+ tmpHeight += line.Height;
+ }
+ if ((imageEnd > -1) && (tmpHeight > 0)) {
+ CarriageReturn();
+ currentHeight += tmpHeight;
+ }
+ }
+
+ /** This is the image that could not be shown on a previous page. */
+ protected internal Image imageWait = null;
+
+ /**
+ * Adds an image to the document.
+ * @param image the Image
to add
+ * @throws PdfException on error
+ * @throws DocumentException on error
+ */
+ protected internal void Add(Image image) {
+
+ if (image.HasAbsolutePosition()) {
+ graphics.AddImage(image);
+ pageEmpty = false;
+ return;
+ }
+
+ // if there isn't enough room for the image on this page, save it for the next page
+ if (currentHeight != 0 && IndentTop - currentHeight - image.ScaledHeight < IndentBottom) {
+ if (!strictImageSequence && imageWait == null) {
+ imageWait = image;
+ return;
+ }
+ NewPage();
+ if (currentHeight != 0 && IndentTop - currentHeight - image.ScaledHeight < IndentBottom) {
+ imageWait = image;
+ return;
+ }
+ }
+ pageEmpty = false;
+ // avoid endless loops
+ if (image == imageWait)
+ imageWait = null;
+ bool textwrap = (image.Alignment & Image.TEXTWRAP) == Image.TEXTWRAP
+ && !((image.Alignment & Image.MIDDLE_ALIGN) == Image.MIDDLE_ALIGN);
+ bool underlying = (image.Alignment & Image.UNDERLYING) == Image.UNDERLYING;
+ float diff = leading / 2;
+ if (textwrap) {
+ diff += leading;
+ }
+ float lowerleft = IndentTop - currentHeight - image.ScaledHeight - diff;
+ float[] mt = image.Matrix;
+ float startPosition = IndentLeft - mt[4];
+ if ((image.Alignment & Image.RIGHT_ALIGN) == Image.RIGHT_ALIGN) startPosition = IndentRight - image.ScaledWidth - mt[4];
+ if ((image.Alignment & Image.MIDDLE_ALIGN) == Image.MIDDLE_ALIGN) startPosition = IndentLeft + ((IndentRight - IndentLeft - image.ScaledWidth) / 2) - mt[4];
+ if (image.HasAbsoluteX()) startPosition = image.AbsoluteX;
+ if (textwrap) {
+ if (imageEnd < 0 || imageEnd < currentHeight + image.ScaledHeight + diff) {
+ imageEnd = currentHeight + image.ScaledHeight + diff;
+ }
+ if ((image.Alignment & Image.RIGHT_ALIGN) == Image.RIGHT_ALIGN) {
+ // indentation suggested by Pelikan Stephan
+ indentation.imageIndentRight += image.ScaledWidth + image.IndentationLeft;
+ }
+ else {
+ // indentation suggested by Pelikan Stephan
+ indentation.imageIndentLeft += image.ScaledWidth + image.IndentationRight;
+ }
+ }
+ else {
+ if ((image.Alignment & Image.RIGHT_ALIGN) == Image.RIGHT_ALIGN) startPosition -= image.IndentationRight;
+ else if ((image.Alignment & Image.MIDDLE_ALIGN) == Image.MIDDLE_ALIGN) startPosition += image.IndentationLeft - image.IndentationRight;
+ else startPosition -= image.IndentationRight;
+ }
+ graphics.AddImage(image, mt[0], mt[1], mt[2], mt[3], startPosition, lowerleft - mt[5]);
+ if (!(textwrap || underlying)) {
+ currentHeight += image.ScaledHeight + diff;
+ FlushLines();
+ text.MoveText(0, - (image.ScaledHeight + diff));
+ NewLine();
+ }
+ }
+
+ // [M4] Adding a PdfPTable
+
+ /** Adds a PdfPTable
to the document.
+ * @param ptable the PdfPTable
to be added to the document.
+ * @throws DocumentException on error
+ */
+ internal void AddPTable(PdfPTable ptable) {
+ ColumnText ct = new ColumnText(writer.DirectContent);
+ if (currentHeight > 0) {
+ Paragraph p = new Paragraph();
+ p.Leading = 0;
+ ct.AddElement(p);
+ //if the table prefers to be on a single page, and it wouldn't
+ //fit on the current page, start a new page.
+ if (ptable.KeepTogether && !FitsPage(ptable, 0f))
+ NewPage();
+ }
+ ct.AddElement(ptable);
+ bool he = ptable.HeadersInEvent;
+ ptable.HeadersInEvent = true;
+ int loop = 0;
+ while (true) {
+ ct.SetSimpleColumn(IndentLeft, IndentBottom, IndentRight, IndentTop - currentHeight);
+ int status = ct.Go();
+ if ((status & ColumnText.NO_MORE_TEXT) != 0) {
+ text.MoveText(0, ct.YLine - IndentTop + currentHeight);
+ currentHeight = IndentTop - ct.YLine;
+ break;
+ }
+ if (IndentTop - currentHeight == ct.YLine)
+ ++loop;
+ else
+ loop = 0;
+ if (loop == 3) {
+ Add(new Paragraph("ERROR: Infinite table loop"));
+ break;
+ }
+ NewPage();
+ }
+ ptable.HeadersInEvent = he;
+ }
+
+ internal bool FitsPage(PdfPTable table, float margin) {
+ if (!table.LockedWidth) {
+ float totalWidth = (IndentRight - IndentLeft) * table.WidthPercentage / 100;
+ table.TotalWidth = totalWidth;
+ }
+ // ensuring that a new line has been started.
+ EnsureNewLine();
+ return table.TotalHeight <= IndentTop - currentHeight - IndentBottom - margin;
+ }
+
+ // [M4'] Adding a Table
+
+ protected internal class RenderingContext {
+ internal float pagetop = -1;
+ internal float oldHeight = -1;
+
+ internal PdfContentByte cellGraphics = null;
+
+ internal float lostTableBottom;
+
+ internal float maxCellBottom;
+ //internal float maxCellHeight;
+
+ internal Hashtable rowspanMap;
+ internal Hashtable pageMap = new Hashtable();
+ /**
+ * A PdfPTable
+ */
+ public PdfTable table;
+
+ /**
+ * Consumes the rowspan
+ * @param c
+ * @return a rowspan.
+ */
+ public int ConsumeRowspan(PdfCell c) {
+ if (c.Rowspan == 1) {
+ return 1;
+ }
+
+ object i = rowspanMap[c];
+ if (i == null) {
+ i = c.Rowspan;
+ }
+
+ i = (int)i - 1;
+ rowspanMap[c] = i;
+
+ if ((int)i < 1) {
+ return 1;
+ }
+ return (int)i;
+ }
+
+ /**
+ * Looks at the current rowspan.
+ * @param c
+ * @return the current rowspan
+ */
+ public int CurrentRowspan(PdfCell c) {
+ object i = rowspanMap[c];
+ if (i == null) {
+ return c.Rowspan;
+ } else {
+ return (int)i;
+ }
+ }
+
+ public int CellRendered(PdfCell cell, int pageNumber) {
+ object i = pageMap[cell];
+ if (i == null) {
+ i = 1;
+ } else {
+ i = (int)i + 1;
+ }
+ pageMap[cell] = i;
+
+ Hashtable seti = (Hashtable)pageMap[pageNumber];
+
+ if (seti == null) {
+ seti = new Hashtable();
+ pageMap[pageNumber] = seti;
+ }
+
+ seti[cell] = null;
+
+ return (int)i;
+ }
+
+ public int NumCellRendered(PdfCell cell) {
+ object i = pageMap[cell];
+ if (i == null) {
+ i = 0;
+ }
+ return (int)i;
+ }
+
+ public bool IsCellRenderedOnPage(PdfCell cell, int pageNumber) {
+ Hashtable seti = (Hashtable) pageMap[pageNumber];
+
+ if (seti != null) {
+ return seti.ContainsKey(cell);
+ }
+
+ return false;
+ }
+ };
+
+ /**
+ * Adds a new table to
+ * @param table Table to add. Rendered rows will be deleted after processing.
+ * @param onlyFirstPage Render only the first full page
+ * @throws DocumentException
+ */
+ private void AddPdfTable(Table t) {
+ // before every table, we flush all lines
+ FlushLines();
+
+ PdfTable table = new PdfTable(t, IndentLeft, IndentRight, IndentTop - currentHeight);
+ RenderingContext ctx = new RenderingContext();
+ ctx.pagetop = IndentTop;
+ ctx.oldHeight = currentHeight;
+ ctx.cellGraphics = new PdfContentByte(writer);
+ ctx.rowspanMap = new Hashtable();
+ ctx.table = table;
+
+ // initialisation of parameters
+ PdfCell cell;
+
+ // drawing the table
+ ArrayList headercells = table.HeaderCells;
+ ArrayList cells = table.Cells;
+ ArrayList rows = ExtractRows(cells, ctx);
+ bool isContinue = false;
+ while (cells.Count != 0) {
+ // initialisation of some extra parameters;
+ ctx.lostTableBottom = 0;
+
+ // loop over the cells
+ bool cellsShown = false;
+
+ // draw the cells (line by line)
+ ListIterator iterator = new ListIterator(rows);
+
+ bool atLeastOneFits = false;
+ while (iterator.HasNext()) {
+ ArrayList row = (ArrayList) iterator.Next();
+ AnalyzeRow(rows, ctx);
+ RenderCells(ctx, row, table.HasToFitPageCells() & atLeastOneFits);
+
+ if (!MayBeRemoved(row)) {
+ break;
+ }
+
+ ConsumeRowspan(row, ctx);
+ iterator.Remove();
+ atLeastOneFits = true;
+ }
+
+ // compose cells array list for subsequent code
+ cells.Clear();
+ Hashtable opt = new Hashtable();
+ foreach (ArrayList row in rows) {
+ foreach (PdfCell cellp in row) {
+ if (!opt.ContainsKey(cellp)) {
+ cells.Add(cellp);
+ opt[cellp] = null;
+ }
+ }
+ }
+ // we paint the graphics of the table after looping through all the cells
+ Rectangle tablerec = new Rectangle(table);
+ tablerec.Border = table.Border;
+ tablerec.BorderWidth = table.BorderWidth;
+ tablerec.BorderColor = table.BorderColor;
+ tablerec.BackgroundColor = table.BackgroundColor;
+ PdfContentByte under = writer.DirectContentUnder;
+ under.Rectangle(tablerec.GetRectangle(Top, IndentBottom));
+ under.Add(ctx.cellGraphics);
+ // bugfix by Gerald Fehringer: now again add the border for the table
+ // since it might have been covered by cell backgrounds
+ tablerec.BackgroundColor = null;
+ tablerec = tablerec.GetRectangle(Top, IndentBottom);
+ tablerec.Border = table.Border;
+ under.Rectangle(tablerec);
+ // end bugfix
+ ctx.cellGraphics = new PdfContentByte(null);
+ // if the table continues on the next page
+ if (rows.Count != 0) {
+ isContinue = true;
+ graphics.SetLineWidth(table.BorderWidth);
+ if (cellsShown && (table.Border & Rectangle.BOTTOM_BORDER) == Rectangle.BOTTOM_BORDER) {
+ // Draw the bottom line
+
+ // the color is set to the color of the element
+ Color tColor = table.BorderColor;
+ if (tColor != null) {
+ graphics.SetColorStroke(tColor);
+ }
+ graphics.MoveTo(table.Left, Math.Max(table.Bottom, IndentBottom));
+ graphics.LineTo(table.Right, Math.Max(table.Bottom, IndentBottom));
+ graphics.Stroke();
+ if (tColor != null) {
+ graphics.ResetRGBColorStroke();
+ }
+ }
+
+ // old page
+ pageEmpty = false;
+ float difference = ctx.lostTableBottom;
+
+ // new page
+ NewPage();
+ // G.F.: if something added in page event i.e. currentHeight > 0
+ float heightCorrection = 0;
+ bool somethingAdded = false;
+ if (currentHeight > 0) {
+ heightCorrection = 6;
+ currentHeight += heightCorrection;
+ somethingAdded = true;
+ NewLine();
+ FlushLines();
+ indentation.indentTop = currentHeight - leading;
+ currentHeight = 0;
+ }
+ else {
+ FlushLines();
+ }
+
+ // this part repeats the table headers (if any)
+ int size = headercells.Count;
+ if (size > 0) {
+ // this is the top of the headersection
+ cell = (PdfCell) headercells[0];
+ float oldTop = cell.GetTop(0);
+ // loop over all the cells of the table header
+ for (int ii = 0; ii < size; ii++) {
+ cell = (PdfCell) headercells[ii];
+ // calculation of the new cellpositions
+ cell.Top = IndentTop - oldTop + cell.GetTop(0);
+ cell.Bottom = IndentTop - oldTop + cell.GetBottom(0);
+ ctx.pagetop = cell.Bottom;
+ // we paint the borders of the cell
+ ctx.cellGraphics.Rectangle(cell.Rectangle(IndentTop, IndentBottom));
+ // we write the text of the cell
+ ArrayList images = cell.GetImages(IndentTop, IndentBottom);
+ foreach (Image image in images) {
+ cellsShown = true;
+ graphics.AddImage(image);
+ }
+ lines = cell.GetLines(IndentTop, IndentBottom);
+ float cellTop = cell.GetTop(IndentTop);
+ text.MoveText(0, cellTop-heightCorrection);
+ float cellDisplacement = FlushLines() - cellTop+heightCorrection;
+ text.MoveText(0, cellDisplacement);
+ }
+ currentHeight = IndentTop - ctx.pagetop + table.Cellspacing;
+ text.MoveText(0, ctx.pagetop - IndentTop - currentHeight);
+ }
+ else {
+ if (somethingAdded) {
+ ctx.pagetop = IndentTop;
+ text.MoveText(0, -table.Cellspacing);
+ }
+ }
+ ctx.oldHeight = currentHeight - heightCorrection;
+ // calculating the new positions of the table and the cells
+ size = Math.Min(cells.Count, table.Columns);
+ int i = 0;
+ while (i < size) {
+ cell = (PdfCell) cells[i];
+ if (cell.GetTop(-table.Cellspacing) > ctx.lostTableBottom) {
+ float newBottom = ctx.pagetop - difference + cell.Bottom;
+ float neededHeight = cell.RemainingHeight;
+ if (newBottom > ctx.pagetop - neededHeight) {
+ difference += newBottom - (ctx.pagetop - neededHeight);
+ }
+ }
+ i++;
+ }
+ size = cells.Count;
+ table.Top = IndentTop;
+ table.Bottom = ctx.pagetop - difference + table.GetBottom(table.Cellspacing);
+ for (i = 0; i < size; i++) {
+ cell = (PdfCell) cells[i];
+ float newBottom = ctx.pagetop - difference + cell.Bottom;
+ float newTop = ctx.pagetop - difference + cell.GetTop(-table.Cellspacing);
+ if (newTop > IndentTop - currentHeight) {
+ newTop = IndentTop - currentHeight;
+ }
+ cell.Top = newTop ;
+ cell.Bottom = newBottom ;
+ }
+ }
+ }
+
+ float tableHeight = table.Top - table.Bottom;
+ // bugfix by Adauto Martins when have more than two tables and more than one page
+ // If continuation of table in other page (bug report #1460051)
+ if (isContinue) {
+ currentHeight = tableHeight;
+ text.MoveText(0, -(tableHeight - (ctx.oldHeight * 2)));
+ }
+ else {
+ currentHeight = ctx.oldHeight + tableHeight;
+ text.MoveText(0, -tableHeight);
+ }
+ pageEmpty = false;
+ }
+
+ protected internal void AnalyzeRow(ArrayList rows, RenderingContext ctx) {
+ ctx.maxCellBottom = IndentBottom;
+
+ // determine whether Row(index) is in a rowspan
+ int rowIndex = 0;
+
+ ArrayList row = (ArrayList) rows[rowIndex];
+ int maxRowspan = 1;
+ foreach (PdfCell cell in row) {
+ maxRowspan = Math.Max(ctx.CurrentRowspan(cell), maxRowspan);
+ }
+ rowIndex += maxRowspan;
+
+ bool useTop = true;
+ if (rowIndex == rows.Count) {
+ rowIndex = rows.Count - 1;
+ useTop = false;
+ }
+
+ if (rowIndex < 0 || rowIndex >= rows.Count) return;
+
+ row = (ArrayList) rows[rowIndex];
+ foreach (PdfCell cell in row) {
+ Rectangle cellRect = cell.Rectangle(ctx.pagetop, IndentBottom);
+ if (useTop) {
+ ctx.maxCellBottom = Math.Max(ctx.maxCellBottom, cellRect.Top);
+ } else {
+ if (ctx.CurrentRowspan(cell) == 1) {
+ ctx.maxCellBottom = Math.Max(ctx.maxCellBottom, cellRect.Bottom);
+ }
+ }
+ }
+ }
+
+ protected internal bool MayBeRemoved(ArrayList row) {
+ bool mayBeRemoved = true;
+ foreach (PdfCell cell in row) {
+ mayBeRemoved &= cell.MayBeRemoved();
+ }
+ return mayBeRemoved;
+ }
+
+ protected internal void ConsumeRowspan(ArrayList row, RenderingContext ctx) {
+ foreach (PdfCell c in row) {
+ ctx.ConsumeRowspan(c);
+ }
+ }
+
+ protected internal ArrayList ExtractRows(ArrayList cells, RenderingContext ctx) {
+ PdfCell cell;
+ PdfCell previousCell = null;
+ ArrayList rows = new ArrayList();
+ ArrayList rowCells = new ArrayList();
+
+ ListIterator iterator = new ListIterator(cells);
+ while (iterator.HasNext()) {
+ cell = (PdfCell) iterator.Next();
+
+ bool isAdded = false;
+
+ bool isEndOfRow = !iterator.HasNext();
+ bool isCurrentCellPartOfRow = !iterator.HasNext();
+
+ if (previousCell != null) {
+ if (cell.Left <= previousCell.Left) {
+ isEndOfRow = true;
+ isCurrentCellPartOfRow = false;
+ }
+ }
+
+ if (isCurrentCellPartOfRow) {
+ rowCells.Add(cell);
+ isAdded = true;
+ }
+
+ if (isEndOfRow) {
+ if (rowCells.Count != 0) {
+ // add to rowlist
+ rows.Add(rowCells);
+ }
+
+ // start a new list for next line
+ rowCells = new ArrayList();
+ }
+
+ if (!isAdded) {
+ rowCells.Add(cell);
+ }
+
+ previousCell = cell;
+ }
+
+ if (rowCells.Count != 0) {
+ rows.Add(rowCells);
+ }
+
+ // fill row information with rowspan cells to get complete "scan lines"
+ for (int i = rows.Count - 1; i >= 0; i--) {
+ ArrayList row = (ArrayList) rows[i];
+
+ // iterator through row
+ for (int j = 0; j < row.Count; j++) {
+ PdfCell c = (PdfCell) row[j];
+ int rowspan = c.Rowspan;
+
+ // fill in missing rowspan cells to complete "scan line"
+ for (int k = 1; k < rowspan && rows.Count < i+k; k++) {
+ ArrayList spannedRow = ((ArrayList) rows[i + k]);
+ if (spannedRow.Count > j)
+ spannedRow.Insert(j, c);
+ }
+ }
+ }
+
+ return rows;
+ }
+
+ protected internal void RenderCells(RenderingContext ctx, ArrayList cells, bool hasToFit) {
+ if (hasToFit) {
+ foreach (PdfCell cell in cells) {
+ if (!cell.Header) {
+ if (cell.Bottom < IndentBottom) return;
+ }
+ }
+ }
+ foreach (PdfCell cell in cells) {
+ if (!ctx.IsCellRenderedOnPage(cell, PageNumber)) {
+
+ float correction = 0;
+ if (ctx.NumCellRendered(cell) >= 1) {
+ correction = 1.0f;
+ }
+
+ lines = cell.GetLines(ctx.pagetop, IndentBottom - correction);
+
+ // if there is still text to render we render it
+ if (lines != null && lines.Count > 0) {
+
+ // we write the text
+ float cellTop = cell.GetTop(ctx.pagetop - ctx.oldHeight);
+ text.MoveText(0, cellTop);
+ float cellDisplacement = FlushLines() - cellTop;
+
+ text.MoveText(0, cellDisplacement);
+ if (ctx.oldHeight + cellDisplacement > currentHeight) {
+ currentHeight = ctx.oldHeight + cellDisplacement;
+ }
+
+ ctx.CellRendered(cell, PageNumber);
+ }
+
+ float indentBottom = Math.Max(cell.Bottom, IndentBottom);
+
+ Rectangle tableRect = ctx.table.GetRectangle(ctx.pagetop, IndentBottom);
+
+ indentBottom = Math.Max(tableRect.Bottom, indentBottom);
+
+ // we paint the borders of the cells
+ Rectangle cellRect = cell.GetRectangle(tableRect.Top, indentBottom);
+ //cellRect.Bottom = cellRect.Bottom;
+ if (cellRect.Height > 0) {
+ ctx.lostTableBottom = indentBottom;
+ ctx.cellGraphics.Rectangle(cellRect);
+ }
+
+ // and additional graphics
+ ArrayList images = cell.GetImages(ctx.pagetop, IndentBottom);
+ foreach (Image image in images) {
+ graphics.AddImage(image);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the bottomvalue of a Table
if it were added to this document.
+ *
+ * @param table the table that may or may not be added to this document
+ * @return a bottom value
+ */
+ internal float GetBottom(Table table) {
+ // constructing a PdfTable
+ PdfTable tmp = new PdfTable(table, IndentLeft, IndentRight, IndentTop - currentHeight);
+ return tmp.Bottom;
+ }
+
+ // [M5] header/footer
+ protected internal void DoFooter() {
+ if (footer == null) return;
+ // Begin added by Edgar Leonardo Prieto Perilla
+ // Avoid footer identation
+ float tmpIndentLeft = indentation.indentLeft;
+ float tmpIndentRight = indentation.indentRight;
+ // Begin added: Bonf (Marc Schneider) 2003-07-29
+ float tmpListIndentLeft = indentation.listIndentLeft;
+ float tmpImageIndentLeft = indentation.imageIndentLeft;
+ float tmpImageIndentRight = indentation.imageIndentRight;
+ // End added: Bonf (Marc Schneider) 2003-07-29
+
+ indentation.indentLeft = indentation.indentRight = 0;
+ // Begin added: Bonf (Marc Schneider) 2003-07-29
+ indentation.listIndentLeft = 0;
+ indentation.imageIndentLeft = 0;
+ indentation.imageIndentRight = 0;
+ // End added: Bonf (Marc Schneider) 2003-07-29
+ // End Added by Edgar Leonardo Prieto Perilla
+ footer.PageNumber = pageN;
+ leading = footer.Paragraph.TotalLeading;
+ Add(footer.Paragraph);
+ // adding the footer limits the height
+ indentation.indentBottom = currentHeight;
+ text.MoveText(Left, IndentBottom);
+ FlushLines();
+ text.MoveText(-Left, -Bottom);
+ footer.Top = GetBottom(currentHeight);
+ footer.Bottom = Bottom - (0.75f * leading);
+ footer.Left = Left;
+ footer.Right = Right;
+ graphics.Rectangle(footer);
+ indentation.indentBottom = currentHeight + leading * 2;
+ currentHeight = 0;
+ // Begin added by Edgar Leonardo Prieto Perilla
+ indentation.indentLeft = tmpIndentLeft;
+ indentation.indentRight = tmpIndentRight;
+ // Begin added: Bonf (Marc Schneider) 2003-07-29
+ indentation.listIndentLeft = tmpListIndentLeft;
+ indentation.imageIndentLeft = tmpImageIndentLeft;
+ indentation.imageIndentRight = tmpImageIndentRight;
+ // End added: Bonf (Marc Schneider) 2003-07-29
+ // End added by Edgar Leonardo Prieto Perilla
+ }
+
+ protected internal void DoHeader() {
+ // if there is a header, the header = added
+ if (header == null) return;
+ // Begin added by Edgar Leonardo Prieto Perilla
+ // Avoid header identation
+ float tmpIndentLeft = indentation.indentLeft;
+ float tmpIndentRight = indentation.indentRight;
+ // Begin added: Bonf (Marc Schneider) 2003-07-29
+ float tmpListIndentLeft = indentation.listIndentLeft;
+ float tmpImageIndentLeft = indentation.imageIndentLeft;
+ float tmpImageIndentRight = indentation.imageIndentRight;
+ // End added: Bonf (Marc Schneider) 2003-07-29
+ indentation.indentLeft = indentation.indentRight = 0;
+ // Added: Bonf
+ indentation.listIndentLeft = 0;
+ indentation.imageIndentLeft = 0;
+ indentation.imageIndentRight = 0;
+ // End added: Bonf
+ // Begin added by Edgar Leonardo Prieto Perilla
+ header.PageNumber = pageN;
+ leading = header.Paragraph.TotalLeading;
+ text.MoveText(0, leading);
+ Add(header.Paragraph);
+ NewLine();
+ indentation.indentTop = currentHeight - leading;
+ header.Top = Top + leading;
+ header.Bottom = IndentTop + leading * 2 / 3;
+ header.Left = Left;
+ header.Right = Right;
+ graphics.Rectangle(header);
+ FlushLines();
+ currentHeight = 0;
+ // Begin added by Edgar Leonardo Prieto Perilla
+ // Restore identation
+ indentation.indentLeft = tmpIndentLeft;
+ indentation.indentRight = tmpIndentRight;
+ // Begin added: Bonf (Marc Schneider) 2003-07-29
+ indentation.listIndentLeft = tmpListIndentLeft;
+ indentation.imageIndentLeft = tmpImageIndentLeft;
+ indentation.imageIndentRight = tmpImageIndentRight;
+ // End added: Bonf (Marc Schneider) 2003-07-29
+ // End Added by Edgar Leonardo Prieto Perilla
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfEncodings.cs b/iTechSharp/iTextSharp/text/pdf/PdfEncodings.cs
new file mode 100644
index 0000000..e06fd12
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfEncodings.cs
@@ -0,0 +1,782 @@
+using System;
+using System.Collections;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.util;
+using iTextSharp.text.xml.simpleparser;
+
+/*
+ * Copyright 2002-2006 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+/** Supports fast encodings for winansi and PDFDocEncoding.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+public class PdfEncodings {
+
+ protected const int CIDNONE = 0;
+ protected const int CIDRANGE = 1;
+ protected const int CIDCHAR = 2;
+
+ internal static char[] winansiByteToChar = {
+ (char)0, (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10, (char)11, (char)12, (char)13, (char)14, (char)15,
+ (char)16, (char)17, (char)18, (char)19, (char)20, (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30, (char)31,
+ (char)32, (char)33, (char)34, (char)35, (char)36, (char)37, (char)38, (char)39, (char)40, (char)41, (char)42, (char)43, (char)44, (char)45, (char)46, (char)47,
+ (char)48, (char)49, (char)50, (char)51, (char)52, (char)53, (char)54, (char)55, (char)56, (char)57, (char)58, (char)59, (char)60, (char)61, (char)62, (char)63,
+ (char)64, (char)65, (char)66, (char)67, (char)68, (char)69, (char)70, (char)71, (char)72, (char)73, (char)74, (char)75, (char)76, (char)77, (char)78, (char)79,
+ (char)80, (char)81, (char)82, (char)83, (char)84, (char)85, (char)86, (char)87, (char)88, (char)89, (char)90, (char)91, (char)92, (char)93, (char)94, (char)95,
+ (char)96, (char)97, (char)98, (char)99, (char)100, (char)101, (char)102, (char)103, (char)104, (char)105, (char)106, (char)107, (char)108, (char)109, (char)110, (char)111,
+ (char)112, (char)113, (char)114, (char)115, (char)116, (char)117, (char)118, (char)119, (char)120, (char)121, (char)122, (char)123, (char)124, (char)125, (char)126, (char)127,
+ (char)8364, (char)65533, (char)8218, (char)402, (char)8222, (char)8230, (char)8224, (char)8225, (char)710, (char)8240, (char)352, (char)8249, (char)338, (char)65533, (char)381, (char)65533,
+ (char)65533, (char)8216, (char)8217, (char)8220, (char)8221, (char)8226, (char)8211, (char)8212, (char)732, (char)8482, (char)353, (char)8250, (char)339, (char)65533, (char)382, (char)376,
+ (char)160, (char)161, (char)162, (char)163, (char)164, (char)165, (char)166, (char)167, (char)168, (char)169, (char)170, (char)171, (char)172, (char)173, (char)174, (char)175,
+ (char)176, (char)177, (char)178, (char)179, (char)180, (char)181, (char)182, (char)183, (char)184, (char)185, (char)186, (char)187, (char)188, (char)189, (char)190, (char)191,
+ (char)192, (char)193, (char)194, (char)195, (char)196, (char)197, (char)198, (char)199, (char)200, (char)201, (char)202, (char)203, (char)204, (char)205, (char)206, (char)207,
+ (char)208, (char)209, (char)210, (char)211, (char)212, (char)213, (char)214, (char)215, (char)216, (char)217, (char)218, (char)219, (char)220, (char)221, (char)222, (char)223,
+ (char)224, (char)225, (char)226, (char)227, (char)228, (char)229, (char)230, (char)231, (char)232, (char)233, (char)234, (char)235, (char)236, (char)237, (char)238, (char)239,
+ (char)240, (char)241, (char)242, (char)243, (char)244, (char)245, (char)246, (char)247, (char)248, (char)249, (char)250, (char)251, (char)252, (char)253, (char)254, (char)255};
+
+ internal static char[] pdfEncodingByteToChar = {
+ (char)0, (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10, (char)11, (char)12, (char)13, (char)14, (char)15,
+ (char)16, (char)17, (char)18, (char)19, (char)20, (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30, (char)31,
+ (char)32, (char)33, (char)34, (char)35, (char)36, (char)37, (char)38, (char)39, (char)40, (char)41, (char)42, (char)43, (char)44, (char)45, (char)46, (char)47,
+ (char)48, (char)49, (char)50, (char)51, (char)52, (char)53, (char)54, (char)55, (char)56, (char)57, (char)58, (char)59, (char)60, (char)61, (char)62, (char)63,
+ (char)64, (char)65, (char)66, (char)67, (char)68, (char)69, (char)70, (char)71, (char)72, (char)73, (char)74, (char)75, (char)76, (char)77, (char)78, (char)79,
+ (char)80, (char)81, (char)82, (char)83, (char)84, (char)85, (char)86, (char)87, (char)88, (char)89, (char)90, (char)91, (char)92, (char)93, (char)94, (char)95,
+ (char)96, (char)97, (char)98, (char)99, (char)100, (char)101, (char)102, (char)103, (char)104, (char)105, (char)106, (char)107, (char)108, (char)109, (char)110, (char)111,
+ (char)112, (char)113, (char)114, (char)115, (char)116, (char)117, (char)118, (char)119, (char)120, (char)121, (char)122, (char)123, (char)124, (char)125, (char)126, (char)127,
+ (char)0x2022, (char)0x2020, (char)0x2021, (char)0x2026, (char)0x2014, (char)0x2013, (char)0x0192, (char)0x2044, (char)0x2039, (char)0x203a, (char)0x2212, (char)0x2030, (char)0x201e, (char)0x201c, (char)0x201d, (char)0x2018,
+ (char)0x2019, (char)0x201a, (char)0x2122, (char)0xfb01, (char)0xfb02, (char)0x0141, (char)0x0152, (char)0x0160, (char)0x0178, (char)0x017d, (char)0x0131, (char)0x0142, (char)0x0153, (char)0x0161, (char)0x017e, (char)65533,
+ (char)0x20ac, (char)161, (char)162, (char)163, (char)164, (char)165, (char)166, (char)167, (char)168, (char)169, (char)170, (char)171, (char)172, (char)173, (char)174, (char)175,
+ (char)176, (char)177, (char)178, (char)179, (char)180, (char)181, (char)182, (char)183, (char)184, (char)185, (char)186, (char)187, (char)188, (char)189, (char)190, (char)191,
+ (char)192, (char)193, (char)194, (char)195, (char)196, (char)197, (char)198, (char)199, (char)200, (char)201, (char)202, (char)203, (char)204, (char)205, (char)206, (char)207,
+ (char)208, (char)209, (char)210, (char)211, (char)212, (char)213, (char)214, (char)215, (char)216, (char)217, (char)218, (char)219, (char)220, (char)221, (char)222, (char)223,
+ (char)224, (char)225, (char)226, (char)227, (char)228, (char)229, (char)230, (char)231, (char)232, (char)233, (char)234, (char)235, (char)236, (char)237, (char)238, (char)239,
+ (char)240, (char)241, (char)242, (char)243, (char)244, (char)245, (char)246, (char)247, (char)248, (char)249, (char)250, (char)251, (char)252, (char)253, (char)254, (char)255};
+
+ internal static IntHashtable winansi = new IntHashtable();
+
+ internal static IntHashtable pdfEncoding = new IntHashtable();
+
+ internal static Hashtable extraEncodings = new Hashtable();
+
+ static PdfEncodings() {
+ for (int k = 128; k < 161; ++k) {
+ char c = winansiByteToChar[k];
+ if (c != 65533)
+ winansi[c] = k;
+ }
+
+ for (int k = 128; k < 161; ++k) {
+ char c = pdfEncodingByteToChar[k];
+ if (c != 65533)
+ pdfEncoding[c] = k;
+ }
+
+ AddExtraEncoding("Wingdings", new WingdingsConversion());
+ AddExtraEncoding("Symbol", new SymbolConversion(true));
+ AddExtraEncoding("ZapfDingbats", new SymbolConversion(false));
+ AddExtraEncoding("SymbolTT", new SymbolTTConversion());
+ AddExtraEncoding("Cp437", new Cp437Conversion());
+ }
+
+ /**
+ * Converts a string
to a string
to be converted
+ * @return an array of byte
representing the conversion according to the font's encoding
+ */
+ public static byte[] ConvertToBytes(string text, string encoding) {
+ if (text == null)
+ return new byte[0];
+ if (encoding == null || encoding.Length == 0) {
+ int len = text.Length;
+ byte[] b = new byte[len];
+ for (int k = 0; k < len; ++k)
+ b[k] = (byte)text[k];
+ return b;
+ }
+ IExtraEncoding extra = (IExtraEncoding)extraEncodings[encoding.ToLower(System.Globalization.CultureInfo.InvariantCulture)];
+ if (extra != null) {
+ byte[] b = extra.CharToByte(text, encoding);
+ if (b != null)
+ return b;
+ }
+ IntHashtable hash = null;
+ if (encoding.Equals(BaseFont.CP1252))
+ hash = winansi;
+ else if (encoding.Equals(PdfObject.TEXT_PDFDOCENCODING))
+ hash = pdfEncoding;
+ if (hash != null) {
+ char[] cc = text.ToCharArray();
+ int len = cc.Length;
+ int ptr = 0;
+ byte[] b = new byte[len];
+ int c = 0;
+ for (int k = 0; k < len; ++k) {
+ char char1 = cc[k];
+ if (char1 < 128 || (char1 > 160 && char1 <= 255))
+ c = char1;
+ else
+ c = hash[char1];
+ if (c != 0)
+ b[ptr++] = (byte)c;
+ }
+ if (ptr == len)
+ return b;
+ byte[] b2 = new byte[ptr];
+ Array.Copy(b, 0, b2, 0, ptr);
+ return b2;
+ }
+ Encoding encw = IanaEncodings.GetEncodingEncoding(encoding);
+ byte[] preamble = encw.GetPreamble();
+ if (preamble.Length == 0)
+ return encw.GetBytes(text);
+ byte[] encoded = encw.GetBytes(text);
+ byte[] total = new byte[encoded.Length + preamble.Length];
+ Array.Copy(preamble, 0, total, 0, preamble.Length);
+ Array.Copy(encoded, 0, total, preamble.Length, encoded.Length);
+ return total;
+ }
+
+ /** Converts a String
to a byte array according
+ * to the font's encoding.
+ * @return an array of byte
representing the conversion according to the font's encoding
+ * @param encoding the encoding
+ * @param char1 the char
to be converted
+ */
+ public static byte[] ConvertToBytes(char char1, String encoding) {
+ if (encoding == null || encoding.Length == 0)
+ return new byte[]{(byte)char1};
+ IExtraEncoding extra = (IExtraEncoding)extraEncodings[encoding.ToLower(System.Globalization.CultureInfo.InvariantCulture)];
+ if (extra != null) {
+ byte[] b = extra.CharToByte(char1, encoding);
+ if (b != null)
+ return b;
+ }
+ IntHashtable hash = null;
+ if (encoding.Equals(BaseFont.WINANSI))
+ hash = winansi;
+ else if (encoding.Equals(PdfObject.TEXT_PDFDOCENCODING))
+ hash = pdfEncoding;
+ if (hash != null) {
+ int c = 0;
+ if (char1 < 128 || (char1 > 160 && char1 <= 255))
+ c = char1;
+ else
+ c = hash[char1];
+ if (c != 0)
+ return new byte[]{(byte)c};
+ else
+ return new byte[0];
+ }
+ Encoding encw = IanaEncodings.GetEncodingEncoding(encoding);
+ byte[] preamble = encw.GetPreamble();
+ char[] text = new char[]{char1};
+ if (preamble.Length == 0)
+ return encw.GetBytes(text);
+ byte[] encoded = encw.GetBytes(text);
+ byte[] total = new byte[encoded.Length + preamble.Length];
+ Array.Copy(preamble, 0, total, 0, preamble.Length);
+ Array.Copy(encoded, 0, total, preamble.Length, encoded.Length);
+ return total;
+ }
+
+ public static string ConvertToString(byte[] bytes, string encoding) {
+ if (bytes == null)
+ return PdfObject.NOTHING;
+ if (encoding == null || encoding.Length == 0) {
+ char[] c = new char[bytes.Length];
+ for (int k = 0; k < bytes.Length; ++k)
+ c[k] = (char)(bytes[k] & 0xff);
+ return new String(c);
+ }
+ IExtraEncoding extra = (IExtraEncoding)extraEncodings[encoding.ToLower(System.Globalization.CultureInfo.InvariantCulture)];
+ if (extra != null) {
+ String text = extra.ByteToChar(bytes, encoding);
+ if (text != null)
+ return text;
+ }
+ char[] ch = null;
+ if (encoding.Equals(BaseFont.WINANSI))
+ ch = winansiByteToChar;
+ else if (encoding.Equals(PdfObject.TEXT_PDFDOCENCODING))
+ ch = pdfEncodingByteToChar;
+ if (ch != null) {
+ int len = bytes.Length;
+ char[] c = new char[len];
+ for (int k = 0; k < len; ++k) {
+ c[k] = ch[bytes[k] & 0xff];
+ }
+ return new String(c);
+ }
+ String nameU = encoding.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
+ bool marker = false;
+ bool big = false;
+ int offset = 0;
+ if (bytes.Length >= 2) {
+ if (bytes[0] == (byte)254 && bytes[1] == (byte)255) {
+ marker = true;
+ big = true;
+ offset = 2;
+ }
+ else if (bytes[0] == (byte)255 && bytes[1] == (byte)254) {
+ marker = true;
+ big = false;
+ offset = 2;
+ }
+ }
+ Encoding enc = null;
+ if (nameU.Equals("UNICODEBIGUNMARKED") || nameU.Equals("UNICODEBIG"))
+ enc = new UnicodeEncoding(marker ? big : true, false);
+ if (nameU.Equals("UNICODELITTLEUNMARKED") || nameU.Equals("UNICODELITTLE"))
+ enc = new UnicodeEncoding(marker ? big : false, false);
+ if (enc != null)
+ return enc.GetString(bytes, offset, bytes.Length - offset);
+ return IanaEncodings.GetEncodingEncoding(encoding).GetString(bytes);
+ }
+
+ /** Checks is text
only has PdfDocEncoding characters.
+ * @param text the String
to test
+ * @return true
if only PdfDocEncoding characters are present
+ */
+ public static bool IsPdfDocEncoding(String text) {
+ if (text == null)
+ return true;
+ int len = text.Length;
+ for (int k = 0; k < len; ++k) {
+ char char1 = text[k];
+ if (char1 < 128 || (char1 > 160 && char1 <= 255))
+ continue;
+ if (!pdfEncoding.ContainsKey(char1))
+ return false;
+ }
+ return true;
+ }
+
+ internal static Hashtable cmaps = new Hashtable();
+ /** Assumes that '\\n' and '\\r\\n' are the newline sequences. It may not work for
+ * all CJK encodings. To be used with LoadCmap().
+ */
+ public static byte[][] CRLF_CID_NEWLINE = new byte[][]{new byte[]{(byte)'\n'}, new byte[]{(byte)'\r', (byte)'\n'}};
+
+ /** Clears the CJK cmaps from the cache. If name
is the
+ * empty string then all the cache is cleared. Calling this method
+ * has no consequences other than the need to reload the cmap
+ * if needed.
+ * @param name the name of the cmap to clear or all the cmaps if the empty string
+ */
+ public static void ClearCmap(String name) {
+ lock (cmaps) {
+ if (name.Length == 0)
+ cmaps.Clear();
+ else
+ cmaps.Remove(name);
+ }
+ }
+
+ /** Loads a CJK cmap to the cache with the option of associating
+ * sequences to the newline.
+ * @param name the CJK cmap name
+ * @param newline the sequences to be replaced bi a newline in the resulting CID. See CRLF_CID_NEWLINE
+ */
+ public static void LoadCmap(String name, byte[][] newline) {
+ char[][] planes = null;
+ lock (cmaps) {
+ planes = (char[][])cmaps[name];
+ }
+ if (planes == null) {
+ planes = ReadCmap(name, newline);
+ lock (cmaps) {
+ cmaps[name] = planes;
+ }
+ }
+ }
+
+ /** Converts a byte
array encoded as name
+ * to a CID string. This is needed to reach some CJK characters
+ * that don't exist in 16 bit Unicode.byte
array to be decoded
+ * @return the CID string
+ */
+ public static String ConvertCmap(String name, byte[] seq) {
+ return ConvertCmap(name, seq, 0, seq.Length);
+ }
+
+ /** Converts a byte
array encoded as name
+ * to a CID string. This is needed to reach some CJK characters
+ * that don't exist in 16 bit Unicode.byte
array to be decoded
+ * @return the CID string
+ */
+ public static String ConvertCmap(String name, byte[] seq, int start, int length) {
+ char[][] planes = null;
+ lock (cmaps) {
+ planes = (char[][])cmaps[name];
+ }
+ if (planes == null) {
+ planes = ReadCmap(name, (byte[][])null);
+ lock (cmaps) {
+ cmaps[name] = planes;
+ }
+ }
+ return DecodeSequence(seq, start, length, planes);
+ }
+
+ internal static String DecodeSequence(byte[] seq, int start, int length, char[][] planes) {
+ StringBuilder buf = new StringBuilder();
+ int end = start + length;
+ int currentPlane = 0;
+ for (int k = start; k < end; ++k) {
+ int one = (int)seq[k] & 0xff;
+ char[] plane = planes[currentPlane];
+ int cid = plane[one];
+ if ((cid & 0x8000) == 0) {
+ buf.Append((char)cid);
+ currentPlane = 0;
+ }
+ else
+ currentPlane = cid & 0x7fff;
+ }
+ return buf.ToString();
+ }
+
+ internal static char[][] ReadCmap(String name, byte[][] newline) {
+ ArrayList planes = new ArrayList();
+ planes.Add(new char[256]);
+ ReadCmap(name, planes);
+ if (newline != null) {
+ for (int k = 0; k < newline.Length; ++k)
+ EncodeSequence(newline[k].Length, newline[k], BaseFont.CID_NEWLINE, planes);
+ }
+ char[][] ret = new char[planes.Count][];
+ planes.CopyTo(ret, 0);
+ return ret;
+ }
+
+ internal static void ReadCmap(String name, ArrayList planes) {
+ String fullName = BaseFont.RESOURCE_PATH + "cmaps." + name;
+ Stream inp = BaseFont.GetResourceStream(fullName);
+ if (inp == null)
+ throw new IOException("The Cmap " + name + " was not found.");
+ EncodeStream(inp, planes);
+ inp.Close();
+ }
+
+ internal static void EncodeStream(Stream inp, ArrayList planes) {
+ StreamReader rd = new StreamReader(inp, Encoding.ASCII);
+ String line = null;
+ int state = CIDNONE;
+ byte[] seqs = new byte[7];
+ while ((line = rd.ReadLine()) != null) {
+ if (line.Length < 6)
+ continue;
+ switch (state) {
+ case CIDNONE: {
+ if (line.IndexOf("begincidrange") >= 0)
+ state = CIDRANGE;
+ else if (line.IndexOf("begincidchar") >= 0)
+ state = CIDCHAR;
+ else if (line.IndexOf("usecmap") >= 0) {
+ StringTokenizer tk = new StringTokenizer(line);
+ String t = tk.NextToken();
+ ReadCmap(t.Substring(1), planes);
+ }
+ break;
+ }
+ case CIDRANGE: {
+ if (line.IndexOf("endcidrange") >= 0) {
+ state = CIDNONE;
+ break;
+ }
+ StringTokenizer tk = new StringTokenizer(line);
+ String t = tk.NextToken();
+ int size = t.Length / 2 - 1;
+ long start = long.Parse(t.Substring(1, t.Length - 2), NumberStyles.HexNumber);
+ t = tk.NextToken();
+ long end = long.Parse(t.Substring(1, t.Length - 2), NumberStyles.HexNumber);
+ t = tk.NextToken();
+ int cid = int.Parse(t);
+ for (long k = start; k <= end; ++k) {
+ BreakLong(k, size, seqs);
+ EncodeSequence(size, seqs, (char)cid, planes);
+ ++cid;
+ }
+ break;
+ }
+ case CIDCHAR: {
+ if (line.IndexOf("endcidchar") >= 0) {
+ state = CIDNONE;
+ break;
+ }
+ StringTokenizer tk = new StringTokenizer(line);
+ String t = tk.NextToken();
+ int size = t.Length / 2 - 1;
+ long start = long.Parse(t.Substring(1, t.Length - 2), NumberStyles.HexNumber);
+ t = tk.NextToken();
+ int cid = int.Parse(t);
+ BreakLong(start, size, seqs);
+ EncodeSequence(size, seqs, (char)cid, planes);
+ break;
+ }
+ }
+ }
+ }
+
+ internal static void BreakLong(long n, int size, byte[] seqs) {
+ for (int k = 0; k < size; ++k) {
+ seqs[k] = (byte)(n >> ((size - 1 - k) * 8));
+ }
+ }
+
+ internal static void EncodeSequence(int size, byte[] seqs, char cid, ArrayList planes) {
+ --size;
+ int nextPlane = 0;
+ char[] plane;
+ for (int idx = 0; idx < size; ++idx) {
+ plane = (char[])planes[nextPlane];
+ int one = (int)seqs[idx] & 0xff;
+ char c = plane[one];
+ if (c != 0 && (c & 0x8000) == 0)
+ throw new Exception("Inconsistent mapping.");
+ if (c == 0) {
+ planes.Add(new char[256]);
+ c = (char)((planes.Count - 1) | 0x8000);
+ plane[one] = c;
+ }
+ nextPlane = c & 0x7fff;
+ }
+ plane = (char[])planes[nextPlane];
+ int ones = (int)seqs[size] & 0xff;
+ char cc = plane[ones];
+ if ((cc & 0x8000) != 0)
+ throw new Exception("Inconsistent mapping.");
+ plane[ones] = cid;
+ }
+
+ /** Adds an extra encoding.
+ * @param name the name of the encoding. The encoding recognition is case insensitive
+ * @param enc the conversion class
+ */
+ public static void AddExtraEncoding(String name, IExtraEncoding enc) {
+ lock (extraEncodings) { // This serializes concurrent updates
+ Hashtable newEncodings = (Hashtable)extraEncodings.Clone();
+ newEncodings[name.ToLower(System.Globalization.CultureInfo.InvariantCulture)] = enc;
+ extraEncodings = newEncodings; // This swap does not require synchronization with reader
+ }
+ }
+
+ private class WingdingsConversion : IExtraEncoding {
+
+ public byte[] CharToByte(char char1, String encoding) {
+ if (char1 == ' ')
+ return new byte[]{(byte)char1};
+ else if (char1 >= '\u2701' && char1 <= '\u27BE') {
+ byte v = table[char1 - 0x2700];
+ if (v != 0)
+ return new byte[]{v};
+ }
+ return new byte[0];
+ }
+
+ public byte[] CharToByte(String text, String encoding) {
+ char[] cc = text.ToCharArray();
+ byte[] b = new byte[cc.Length];
+ int ptr = 0;
+ int len = cc.Length;
+ for (int k = 0; k < len; ++k) {
+ char c = cc[k];
+ if (c == ' ')
+ b[ptr++] = (byte)c;
+ else if (c >= '\u2701' && c <= '\u27BE') {
+ byte v = table[c - 0x2700];
+ if (v != 0)
+ b[ptr++] = v;
+ }
+ }
+ if (ptr == len)
+ return b;
+ byte[] b2 = new byte[ptr];
+ Array.Copy(b, 0, b2, 0, ptr);
+ return b2;
+ }
+
+ public String ByteToChar(byte[] b, String encoding) {
+ return null;
+ }
+
+ private static byte[] table = {
+ 0, 35, 34, 0, 0, 0, 41, 62, 81, 42,
+ 0, 0, 65, 63, 0, 0, 0, 0, 0, (byte)(256-4),
+ 0, 0, 0, (byte)(256-5), 0, 0, 0, 0, 0, 0,
+ 86, 0, 88, 89, 0, 0, 0, 0, 0, 0,
+ 0, 0, (byte)(256-75), 0, 0, 0, 0, 0, (byte)(256-74), 0,
+ 0, 0, (byte)(256-83), (byte)(256-81), (byte)(256-84), 0, 0, 0, 0, 0,
+ 0, 0, 0, 124, 123, 0, 0, 0, 84, 0,
+ 0, 0, 0, 0, 0, 0, 0, (byte)(256-90), 0, 0,
+ 0, 113, 114, 0, 0, 0, 117, 0, 0, 0,
+ 0, 0, 0, 125, 126, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, (byte)(256-116), (byte)(256-115),
+ (byte)(256-114), (byte)(256-113), (byte)(256-112), (byte)(256-111), (byte)(256-110), (byte)(256-109), (byte)(256-108), (byte)(256-107), (byte)(256-127), (byte)(256-126),
+ (byte)(256-125), (byte)(256-124), (byte)(256-123), (byte)(256-122), (byte)(256-121), (byte)(256-120), (byte)(256-119), (byte)(256-118), (byte)(256-116), (byte)(256-115),
+ (byte)(256-114), (byte)(256-113), (byte)(256-112), (byte)(256-111), (byte)(256-110), (byte)(256-109), (byte)(256-108), (byte)(256-107), (byte)(256-24), 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, (byte)(256-24), (byte)(256-40), 0, 0, (byte)(256-60), (byte)(256-58), 0, 0, (byte)(256-16),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte)(256-36),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+ };
+ }
+
+ private class Cp437Conversion : IExtraEncoding {
+ private static IntHashtable c2b = new IntHashtable();
+
+ public byte[] CharToByte(String text, String encoding) {
+ char[] cc = text.ToCharArray();
+ byte[] b = new byte[cc.Length];
+ int ptr = 0;
+ int len = cc.Length;
+ for (int k = 0; k < len; ++k) {
+ char c = cc[k];
+ if (c < 128)
+ b[ptr++] = (byte)c;
+ else {
+ byte v = (byte)c2b[c];
+ if (v != 0)
+ b[ptr++] = v;
+ }
+ }
+ if (ptr == len)
+ return b;
+ byte[] b2 = new byte[ptr];
+ Array.Copy(b, 0, b2, 0, ptr);
+ return b2;
+ }
+
+ public byte[] CharToByte(char char1, String encoding) {
+ if (char1 < 128)
+ return new byte[]{(byte)char1};
+ else {
+ byte v = (byte)c2b[char1];
+ if (v != 0)
+ return new byte[]{v};
+ else
+ return new byte[0];
+ }
+ }
+
+ public String ByteToChar(byte[] b, String encoding) {
+ int len = b.Length;
+ char[] cc = new char[len];
+ int ptr = 0;
+ for (int k = 0; k < len; ++k) {
+ int c = b[k] & 0xff;
+ if (c < ' ')
+ continue;
+ if (c < 128)
+ cc[ptr++] = (char)c;
+ else {
+ char v = table[c - 128];
+ cc[ptr++] = v;
+ }
+ }
+ return new String(cc, 0, ptr);
+ }
+
+ private static char[] table = {
+ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5',
+ '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', '\u00FF', '\u00D6', '\u00DC', '\u00A2', '\u00A3', '\u00A5', '\u20A7', '\u0192',
+ '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', '\u00AA', '\u00BA', '\u00BF', '\u2310', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB',
+ '\u2591', '\u2592', '\u2593', '\u2502', '\u2524', '\u2561', '\u2562', '\u2556', '\u2555', '\u2563', '\u2551', '\u2557', '\u255D', '\u255C', '\u255B', '\u2510',
+ '\u2514', '\u2534', '\u252C', '\u251C', '\u2500', '\u253C', '\u255E', '\u255F', '\u255A', '\u2554', '\u2569', '\u2566', '\u2560', '\u2550', '\u256C', '\u2567',
+ '\u2568', '\u2564', '\u2565', '\u2559', '\u2558', '\u2552', '\u2553', '\u256B', '\u256A', '\u2518', '\u250C', '\u2588', '\u2584', '\u258C', '\u2590', '\u2580',
+ '\u03B1', '\u00DF', '\u0393', '\u03C0', '\u03A3', '\u03C3', '\u00B5', '\u03C4', '\u03A6', '\u0398', '\u03A9', '\u03B4', '\u221E', '\u03C6', '\u03B5', '\u2229',
+ '\u2261', '\u00B1', '\u2265', '\u2264', '\u2320', '\u2321', '\u00F7', '\u2248', '\u00B0', '\u2219', '\u00B7', '\u221A', '\u207F', '\u00B2', '\u25A0', '\u00A0'
+ };
+
+ static Cp437Conversion() {
+ for (int k = 0; k < table.Length; ++k)
+ c2b[table[k]] = k + 128;
+ }
+ }
+
+ private class SymbolConversion : IExtraEncoding {
+
+ private static IntHashtable t1 = new IntHashtable();
+ private static IntHashtable t2 = new IntHashtable();
+ private IntHashtable translation;
+
+ internal SymbolConversion(bool symbol) {
+ if (symbol)
+ translation = t1;
+ else
+ translation = t2;
+ }
+
+ public byte[] CharToByte(String text, String encoding) {
+ char[] cc = text.ToCharArray();
+ byte[] b = new byte[cc.Length];
+ int ptr = 0;
+ int len = cc.Length;
+ for (int k = 0; k < len; ++k) {
+ char c = cc[k];
+ byte v = (byte)translation[(int)c];
+ if (v != 0)
+ b[ptr++] = v;
+ }
+ if (ptr == len)
+ return b;
+ byte[] b2 = new byte[ptr];
+ Array.Copy(b, 0, b2, 0, ptr);
+ return b2;
+ }
+
+ public byte[] CharToByte(char char1, String encoding) {
+ byte v = (byte)translation[(int)char1];
+ if (v != 0)
+ return new byte[]{v};
+ else
+ return new byte[0];
+ }
+
+ public String ByteToChar(byte[] b, String encoding) {
+ return null;
+ }
+
+ private static char[] table1 = {
+ ' ','!','\u2200','#','\u2203','%','&','\u220b','(',')','*','+',',','-','.','/',
+ '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?',
+ '\u2245','\u0391','\u0392','\u03a7','\u0394','\u0395','\u03a6','\u0393','\u0397','\u0399','\u03d1','\u039a','\u039b','\u039c','\u039d','\u039f',
+ '\u03a0','\u0398','\u03a1','\u03a3','\u03a4','\u03a5','\u03c2','\u03a9','\u039e','\u03a8','\u0396','[','\u2234',']','\u22a5','_',
+ '\u0305','\u03b1','\u03b2','\u03c7','\u03b4','\u03b5','\u03d5','\u03b3','\u03b7','\u03b9','\u03c6','\u03ba','\u03bb','\u03bc','\u03bd','\u03bf',
+ '\u03c0','\u03b8','\u03c1','\u03c3','\u03c4','\u03c5','\u03d6','\u03c9','\u03be','\u03c8','\u03b6','{','|','}','~','\0',
+ '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
+ '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
+ '\u20ac','\u03d2','\u2032','\u2264','\u2044','\u221e','\u0192','\u2663','\u2666','\u2665','\u2660','\u2194','\u2190','\u2191','\u2192','\u2193',
+ '\u00b0','\u00b1','\u2033','\u2265','\u00d7','\u221d','\u2202','\u2022','\u00f7','\u2260','\u2261','\u2248','\u2026','\u2502','\u2500','\u21b5',
+ '\u2135','\u2111','\u211c','\u2118','\u2297','\u2295','\u2205','\u2229','\u222a','\u2283','\u2287','\u2284','\u2282','\u2286','\u2208','\u2209',
+ '\u2220','\u2207','\u00ae','\u00a9','\u2122','\u220f','\u221a','\u2022','\u00ac','\u2227','\u2228','\u21d4','\u21d0','\u21d1','\u21d2','\u21d3',
+ '\u25ca','\u2329','\0','\0','\0','\u2211','\u239b','\u239c','\u239d','\u23a1','\u23a2','\u23a3','\u23a7','\u23a8','\u23a9','\u23aa',
+ '\0','\u232a','\u222b','\u2320','\u23ae','\u2321','\u239e','\u239f','\u23a0','\u23a4','\u23a5','\u23a6','\u23ab','\u23ac','\u23ad','\0'
+ };
+
+ private static char[] table2 = {
+ '\u0020','\u2701','\u2702','\u2703','\u2704','\u260e','\u2706','\u2707','\u2708','\u2709','\u261b','\u261e','\u270C','\u270D','\u270E','\u270F',
+ '\u2710','\u2711','\u2712','\u2713','\u2714','\u2715','\u2716','\u2717','\u2718','\u2719','\u271A','\u271B','\u271C','\u271D','\u271E','\u271F',
+ '\u2720','\u2721','\u2722','\u2723','\u2724','\u2725','\u2726','\u2727','\u2605','\u2729','\u272A','\u272B','\u272C','\u272D','\u272E','\u272F',
+ '\u2730','\u2731','\u2732','\u2733','\u2734','\u2735','\u2736','\u2737','\u2738','\u2739','\u273A','\u273B','\u273C','\u273D','\u273E','\u273F',
+ '\u2740','\u2741','\u2742','\u2743','\u2744','\u2745','\u2746','\u2747','\u2748','\u2749','\u274A','\u274B','\u25cf','\u274D','\u25a0','\u274F',
+ '\u2750','\u2751','\u2752','\u25b2','\u25bc','\u25c6','\u2756','\u25d7','\u2758','\u2759','\u275A','\u275B','\u275C','\u275D','\u275E','\u0000',
+ '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
+ '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
+ '\u0000','\u2761','\u2762','\u2763','\u2764','\u2765','\u2766','\u2767','\u2663','\u2666','\u2665','\u2660','\u2460','\u2461','\u2462','\u2463',
+ '\u2464','\u2465','\u2466','\u2467','\u2468','\u2469','\u2776','\u2777','\u2778','\u2779','\u277A','\u277B','\u277C','\u277D','\u277E','\u277F',
+ '\u2780','\u2781','\u2782','\u2783','\u2784','\u2785','\u2786','\u2787','\u2788','\u2789','\u278A','\u278B','\u278C','\u278D','\u278E','\u278F',
+ '\u2790','\u2791','\u2792','\u2793','\u2794','\u2192','\u2194','\u2195','\u2798','\u2799','\u279A','\u279B','\u279C','\u279D','\u279E','\u279F',
+ '\u27A0','\u27A1','\u27A2','\u27A3','\u27A4','\u27A5','\u27A6','\u27A7','\u27A8','\u27A9','\u27AA','\u27AB','\u27AC','\u27AD','\u27AE','\u27AF',
+ '\u0000','\u27B1','\u27B2','\u27B3','\u27B4','\u27B5','\u27B6','\u27B7','\u27B8','\u27B9','\u27BA','\u27BB','\u27BC','\u27BD','\u27BE','\u0000'
+ };
+
+ static SymbolConversion(){
+ for (int k = 0; k < table1.Length; ++k) {
+ int v = (int)table1[k];
+ if (v != 0)
+ t1[v] = k + 32;
+ }
+ for (int k = 0; k < table2.Length; ++k) {
+ int v = (int)table2[k];
+ if (v != 0)
+ t2[v] = k + 32;
+ }
+ }
+ }
+
+ private class SymbolTTConversion : IExtraEncoding {
+
+ public byte[] CharToByte(char char1, String encoding) {
+ if ((char1 & 0xff00) == 0 || (char1 & 0xff00) == 0xf000)
+ return new byte[]{(byte)char1};
+ else
+ return new byte[0];
+ }
+
+ public byte[] CharToByte(String text, String encoding) {
+ char[] ch = text.ToCharArray();
+ byte[] b = new byte[ch.Length];
+ int ptr = 0;
+ int len = ch.Length;
+ for (int k = 0; k < len; ++k) {
+ char c = ch[k];
+ if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000)
+ b[ptr++] = (byte)c;
+ }
+ if (ptr == len)
+ return b;
+ byte[] b2 = new byte[ptr];
+ Array.Copy(b, 0, b2, 0, ptr);
+ return b2;
+ }
+
+ public String ByteToChar(byte[] b, String encoding) {
+ return null;
+ }
+ }
+}
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfEncryption.cs b/iTechSharp/iTextSharp/text/pdf/PdfEncryption.cs
new file mode 100644
index 0000000..155e1d0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfEncryption.cs
@@ -0,0 +1,512 @@
+using System;
+using System.Collections;
+using System.Security.Cryptography;
+using System.Text;
+using System.IO;
+using iTextSharp.text.pdf.crypto;
+using Org.BouncyCastle.X509;
+
+/*
+ * $Id: PdfEncryption.cs,v 1.13 2007/06/14 20:01:48 psoares33 Exp $
+ *
+ * Copyright 2001-2006 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+/**
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+public class PdfEncryption {
+
+ public const int STANDARD_ENCRYPTION_40 = 2;
+ public const int STANDARD_ENCRYPTION_128 = 3;
+ public const int AES_128 = 4;
+
+ private static byte[] pad = {
+ (byte)0x28, (byte)0xBF, (byte)0x4E, (byte)0x5E, (byte)0x4E, (byte)0x75,
+ (byte)0x8A, (byte)0x41, (byte)0x64, (byte)0x00, (byte)0x4E, (byte)0x56,
+ (byte)0xFF, (byte)0xFA, (byte)0x01, (byte)0x08, (byte)0x2E, (byte)0x2E,
+ (byte)0x00, (byte)0xB6, (byte)0xD0, (byte)0x68, (byte)0x3E, (byte)0x80,
+ (byte)0x2F, (byte)0x0C, (byte)0xA9, (byte)0xFE, (byte)0x64, (byte)0x53,
+ (byte)0x69, (byte)0x7A};
+
+ private static readonly byte[] salt = {(byte)0x73, (byte)0x41, (byte)0x6c, (byte)0x54};
+ internal static readonly byte[] metadataPad = {(byte)255,(byte)255,(byte)255,(byte)255};
+ /** The encryption key for a particular object/generation */
+ internal byte[] key;
+ /** The encryption key length for a particular object/generation */
+ internal int keySize;
+ /** The global encryption key */
+ internal byte[] mkey;
+ /** Work area to prepare the object/generation bytes */
+ internal byte[] extra = new byte[5];
+ /** The message digest algorithm MD5 */
+ internal MD5 md5;
+ /** The encryption key for the owner */
+ internal byte[] ownerKey = new byte[32];
+ /** The encryption key for the user */
+ internal byte[] userKey = new byte[32];
+ /** The public key security handler for certificate encryption */
+ protected PdfPublicKeySecurityHandler publicKeyHandler = null;
+ internal int permissions;
+ internal byte[] documentID;
+ internal static long seq = DateTime.Now.Ticks + Environment.TickCount;
+ private int revision;
+ private ARCFOUREncryption rc4 = new ARCFOUREncryption();
+ /** The generic key length. It may be 40 or 128. */
+ private int keyLength;
+ private bool encryptMetadata;
+ private int cryptoMode;
+
+ public PdfEncryption() {
+ md5 = new MD5CryptoServiceProvider();
+ publicKeyHandler = new PdfPublicKeySecurityHandler();
+ }
+
+ public PdfEncryption(PdfEncryption enc) : this() {
+ mkey = (byte[])enc.mkey.Clone();
+ ownerKey = (byte[])enc.ownerKey.Clone();
+ userKey = (byte[])enc.userKey.Clone();
+ permissions = enc.permissions;
+ if (enc.documentID != null)
+ documentID = (byte[])enc.documentID.Clone();
+ revision = enc.revision;
+ keyLength = enc.keyLength;
+ encryptMetadata = enc.encryptMetadata;
+ publicKeyHandler = enc.publicKeyHandler;
+ }
+
+ public void SetCryptoMode(int mode, int kl) {
+ cryptoMode = mode;
+ encryptMetadata = (mode & PdfWriter.DO_NOT_ENCRYPT_METADATA) == 0;
+ mode &= PdfWriter.ENCRYPTION_MASK;
+ switch (mode) {
+ case PdfWriter.STANDARD_ENCRYPTION_40:
+ encryptMetadata = true;
+ keyLength = 40;
+ revision = STANDARD_ENCRYPTION_40;
+ break;
+ case PdfWriter.STANDARD_ENCRYPTION_128:
+ if (kl > 0)
+ keyLength = kl;
+ else
+ keyLength = 128;
+ revision = STANDARD_ENCRYPTION_128;
+ break;
+ case PdfWriter.ENCRYPTION_AES_128:
+ keyLength = 128;
+ revision = AES_128;
+ break;
+ default:
+ throw new ArgumentException("No valid encryption mode");
+ }
+ }
+
+ public int GetCryptoMode() {
+ return cryptoMode;
+ }
+
+ public bool IsMetadataEncrypted() {
+ return encryptMetadata;
+ }
+
+ private byte[] PadPassword(byte[] userPassword) {
+ byte[] userPad = new byte[32];
+ if (userPassword == null) {
+ Array.Copy(pad, 0, userPad, 0, 32);
+ }
+ else {
+ Array.Copy(userPassword, 0, userPad, 0, Math.Min(userPassword.Length, 32));
+ if (userPassword.Length < 32)
+ Array.Copy(pad, 0, userPad, userPassword.Length, 32 - userPassword.Length);
+ }
+
+ return userPad;
+ }
+
+ /**
+ */
+ private byte[] ComputeOwnerKey(byte[] userPad, byte[] ownerPad) {
+ byte[] ownerKey = new byte[32];
+
+ byte[] digest = md5.ComputeHash(ownerPad);
+ if (revision == STANDARD_ENCRYPTION_128 || revision == AES_128) {
+ byte[] mkey = new byte[keyLength / 8];
+ // only use for the input as many bit as the key consists of
+ for (int k = 0; k < 50; ++k)
+ Array.Copy(md5.ComputeHash(digest), 0, digest, 0, mkey.Length);
+ Array.Copy(userPad, 0, ownerKey, 0, 32);
+ for (int i = 0; i < 20; ++i) {
+ for (int j = 0; j < mkey.Length ; ++j)
+ mkey[j] = (byte)(digest[j] ^ i);
+ rc4.PrepareARCFOURKey(mkey);
+ rc4.EncryptARCFOUR(ownerKey);
+ }
+ }
+ else {
+ rc4.PrepareARCFOURKey(digest, 0, 5);
+ rc4.EncryptARCFOUR(userPad, ownerKey);
+ }
+
+ return ownerKey;
+ }
+
+ /**
+ *
+ * ownerKey, documentID must be setuped
+ */
+ private void SetupGlobalEncryptionKey(byte[] documentID, byte[] userPad, byte[] ownerKey, int permissions) {
+ this.documentID = documentID;
+ this.ownerKey = ownerKey;
+ this.permissions = permissions;
+ // use variable keylength
+ mkey = new byte[keyLength / 8];
+
+ //fixed by ujihara in order to follow PDF refrence
+ md5.Initialize();
+ md5.TransformBlock(userPad, 0, userPad.Length, userPad, 0);
+ md5.TransformBlock(ownerKey, 0, ownerKey.Length, ownerKey, 0);
+
+ byte[] ext = new byte[4];
+ ext[0] = (byte)permissions;
+ ext[1] = (byte)(permissions >> 8);
+ ext[2] = (byte)(permissions >> 16);
+ ext[3] = (byte)(permissions >> 24);
+ md5.TransformBlock(ext, 0, 4, ext, 0);
+ if (documentID != null)
+ md5.TransformBlock(documentID, 0, documentID.Length, documentID, 0);
+ if (!encryptMetadata)
+ md5.TransformBlock(metadataPad, 0, metadataPad.Length, metadataPad, 0);
+ md5.TransformFinalBlock(ext, 0, 0);
+
+ byte[] digest = new byte[mkey.Length];
+ Array.Copy(md5.Hash, 0, digest, 0, mkey.Length);
+
+
+ md5.Initialize();
+ // only use the really needed bits as input for the hash
+ if (revision == STANDARD_ENCRYPTION_128 || revision == AES_128) {
+ for (int k = 0; k < 50; ++k) {
+ Array.Copy(md5.ComputeHash(digest), 0, digest, 0, mkey.Length);
+ md5.Initialize();
+ }
+ }
+ Array.Copy(digest, 0, mkey, 0, mkey.Length);
+ }
+
+ /**
+ *
+ * mkey must be setuped
+ */
+ // use the revision to choose the setup method
+ private void SetupUserKey() {
+ if (revision == STANDARD_ENCRYPTION_128 || revision == AES_128) {
+ md5.TransformBlock(pad, 0, pad.Length, pad, 0);
+ md5.TransformFinalBlock(documentID, 0, documentID.Length);
+ byte[] digest = md5.Hash;
+ md5.Initialize();
+ Array.Copy(digest, 0, userKey, 0, 16);
+ for (int k = 16; k < 32; ++k)
+ userKey[k] = 0;
+ for (int i = 0; i < 20; ++i) {
+ for (int j = 0; j < mkey.Length; ++j)
+ digest[j] = (byte)(mkey[j] ^ i);
+ rc4.PrepareARCFOURKey(digest, 0, mkey.Length);
+ rc4.EncryptARCFOUR(userKey, 0, 16);
+ }
+ }
+ else {
+ rc4.PrepareARCFOURKey(mkey);
+ rc4.EncryptARCFOUR(pad, userKey);
+ }
+ }
+
+ // gets keylength and revision and uses revison to choose the initial values for permissions
+ public void SetupAllKeys(byte[] userPassword, byte[] ownerPassword, int permissions) {
+ if (ownerPassword == null || ownerPassword.Length == 0)
+ ownerPassword = md5.ComputeHash(CreateDocumentId());
+ md5.Initialize();
+ permissions |= (int)((revision == STANDARD_ENCRYPTION_128 || revision == AES_128) ? (uint)0xfffff0c0 : (uint)0xffffffc0);
+ permissions &= unchecked((int)0xfffffffc);
+ //PDF refrence 3.5.2 Standard Security Handler, Algorithum 3.3-1
+ //If there is no owner password, use the user password instead.
+ byte[] userPad = PadPassword(userPassword);
+ byte[] ownerPad = PadPassword(ownerPassword);
+
+ this.ownerKey = ComputeOwnerKey(userPad, ownerPad);
+ documentID = CreateDocumentId();
+ SetupByUserPad(this.documentID, userPad, this.ownerKey, permissions);
+ }
+
+ public static byte[] CreateDocumentId() {
+ MD5 md5 = new MD5CryptoServiceProvider();
+ long time = DateTime.Now.Ticks + Environment.TickCount;
+ long mem = GC.GetTotalMemory(false);
+ String s = time + "+" + mem + "+" + (seq++);
+ return md5.ComputeHash(Encoding.ASCII.GetBytes(s));
+ }
+
+ public void SetupByUserPassword(byte[] documentID, byte[] userPassword, byte[] ownerKey, int permissions) {
+ SetupByUserPad(documentID, PadPassword(userPassword), ownerKey, permissions);
+ }
+
+ /**
+ */
+ private void SetupByUserPad(byte[] documentID, byte[] userPad, byte[] ownerKey, int permissions) {
+ SetupGlobalEncryptionKey(documentID, userPad, ownerKey, permissions);
+ SetupUserKey();
+ }
+
+ /**
+ */
+ public void SetupByOwnerPassword(byte[] documentID, byte[] ownerPassword, byte[] userKey, byte[] ownerKey, int permissions) {
+ SetupByOwnerPad(documentID, PadPassword(ownerPassword), userKey, ownerKey, permissions);
+ }
+
+ private void SetupByOwnerPad(byte[] documentID, byte[] ownerPad, byte[] userKey, byte[] ownerKey, int permissions) {
+ byte[] userPad = ComputeOwnerKey(ownerKey, ownerPad); //userPad will be set in this.ownerKey
+ SetupGlobalEncryptionKey(documentID, userPad, ownerKey, permissions); //step 3
+ SetupUserKey();
+ }
+
+ public void SetupByEncryptionKey(byte[] key, int keylength) {
+ mkey = new byte[keylength/8];
+ System.Array.Copy(key, 0, mkey, 0, mkey.Length);
+ }
+
+ public void SetHashKey(int number, int generation) {
+ md5.Initialize(); //added by ujihara
+ extra[0] = (byte)number;
+ extra[1] = (byte)(number >> 8);
+ extra[2] = (byte)(number >> 16);
+ extra[3] = (byte)generation;
+ extra[4] = (byte)(generation >> 8);
+ md5.TransformBlock(mkey, 0, mkey.Length, mkey, 0);
+ md5.TransformBlock(extra, 0, extra.Length, extra, 0);
+ if (revision == AES_128)
+ md5.TransformBlock(salt, 0, salt.Length, salt, 0);
+ md5.TransformFinalBlock(extra, 0, 0);
+ key = md5.Hash;
+ md5.Initialize();
+ keySize = mkey.Length + 5;
+ if (keySize > 16)
+ keySize = 16;
+ }
+
+ public static PdfObject CreateInfoId(byte[] id) {
+ ByteBuffer buf = new ByteBuffer(90);
+ buf.Append('[').Append('<');
+ for (int k = 0; k < 16; ++k)
+ buf.AppendHex(id[k]);
+ buf.Append('>').Append('<');
+ id = CreateDocumentId();
+ for (int k = 0; k < 16; ++k)
+ buf.AppendHex(id[k]);
+ buf.Append('>').Append(']');
+ return new PdfLiteral(buf.ToByteArray());
+ }
+
+ public PdfDictionary GetEncryptionDictionary() {
+ PdfDictionary dic = new PdfDictionary();
+
+ if (publicKeyHandler.GetRecipientsSize() > 0) {
+ PdfArray recipients = null;
+
+ dic.Put(PdfName.FILTER, PdfName.PUBSEC);
+ dic.Put(PdfName.R, new PdfNumber(revision));
+
+ recipients = publicKeyHandler.GetEncodedRecipients();
+
+ if (revision == STANDARD_ENCRYPTION_40) {
+ dic.Put(PdfName.V, new PdfNumber(1));
+ dic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S4);
+ dic.Put(PdfName.RECIPIENTS, recipients);
+ }
+ else if (revision == STANDARD_ENCRYPTION_128 && encryptMetadata) {
+ dic.Put(PdfName.V, new PdfNumber(2));
+ dic.Put(PdfName.LENGTH, new PdfNumber(128));
+ dic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S4);
+ dic.Put(PdfName.RECIPIENTS, recipients);
+ }
+ else {
+ dic.Put(PdfName.R, new PdfNumber(AES_128));
+ dic.Put(PdfName.V, new PdfNumber(4));
+ dic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S5);
+
+ PdfDictionary stdcf = new PdfDictionary();
+ stdcf.Put(PdfName.RECIPIENTS, recipients);
+ if (!encryptMetadata)
+ stdcf.Put(PdfName.ENCRYPTMETADATA, PdfBoolean.PDFFALSE);
+
+ if (revision == AES_128)
+ stdcf.Put(PdfName.CFM, PdfName.AESV2);
+ else
+ stdcf.Put(PdfName.CFM, PdfName.V2);
+ PdfDictionary cf = new PdfDictionary();
+ cf.Put(PdfName.DEFAULTCRYPTFILER, stdcf);
+ dic.Put(PdfName.CF, cf);
+ dic.Put(PdfName.STRF, PdfName.DEFAULTCRYPTFILER);
+ dic.Put(PdfName.STMF, PdfName.DEFAULTCRYPTFILER);
+ }
+
+ SHA1 sh = new SHA1CryptoServiceProvider();
+ byte[] encodedRecipient = null;
+ byte[] seed = publicKeyHandler.GetSeed();
+ sh.TransformBlock(seed, 0, seed.Length, seed, 0);
+ for (int i=0; itrue
for 128 bit key length, false
for 40 bit key length
+ * @throws DocumentException on error
+ * @throws IOException on error */
+ public static void Encrypt(PdfReader reader, Stream os, byte[] userPassword, byte[] ownerPassword, int permissions, bool strength128Bits) {
+ PdfStamper stamper = new PdfStamper(reader, os);
+ stamper.SetEncryption(userPassword, ownerPassword, permissions, strength128Bits);
+ stamper.Close();
+ }
+
+ /** Entry point to encrypt a PDF document. The encryption parameters are the same as in
+ * PdfWriter
. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param reader the read PDF
+ * @param os the output destination
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param strength128Bits true
for 128 bit key length, false
for 40 bit key length
+ * @param newInfo an optional String
map to add or change
+ * the info dictionary. Entries with null
+ * values delete the key in the original info dictionary
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public static void Encrypt(PdfReader reader, Stream os, byte[] userPassword, byte[] ownerPassword, int permissions, bool strength128Bits, Hashtable newInfo) {
+ PdfStamper stamper = new PdfStamper(reader, os);
+ stamper.SetEncryption(userPassword, ownerPassword, permissions, strength128Bits);
+ stamper.MoreInfo = newInfo;
+ stamper.Close();
+ }
+
+ /** Entry point to encrypt a PDF document. The encryption parameters are the same as in
+ * PdfWriter
. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param reader the read PDF
+ * @param os the output destination
+ * @param strength true
for 128 bit key length, false
for 40 bit key length
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @throws DocumentException on error
+ * @throws IOException on error */
+ public static void Encrypt(PdfReader reader, Stream os, bool strength, String userPassword, String ownerPassword, int permissions) {
+ PdfStamper stamper = new PdfStamper(reader, os);
+ stamper.SetEncryption(strength, userPassword, ownerPassword, permissions);
+ stamper.Close();
+ }
+
+ /** Entry point to encrypt a PDF document. The encryption parameters are the same as in
+ * PdfWriter
. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param reader the read PDF
+ * @param os the output destination
+ * @param strength true
for 128 bit key length, false
for 40 bit key length
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param newInfo an optional String
map to add or change
+ * the info dictionary. Entries with null
+ * values delete the key in the original info dictionary
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public static void Encrypt(PdfReader reader, Stream os, bool strength, String userPassword, String ownerPassword, int permissions, Hashtable newInfo) {
+ PdfStamper stamper = new PdfStamper(reader, os);
+ stamper.SetEncryption(strength, userPassword, ownerPassword, permissions);
+ stamper.MoreInfo = newInfo;
+ stamper.Close();
+ }
+
+ /** Entry point to encrypt a PDF document. The encryption parameters are the same as in
+ * PdfWriter
. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param reader the read PDF
+ * @param os the output destination
+ * @param type the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param newInfo an optional String
map to add or change
+ * the info dictionary. Entries with null
+ * values delete the key in the original info dictionary
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public static void Encrypt(PdfReader reader, Stream os, int type, String userPassword, String ownerPassword, int permissions, Hashtable newInfo) {
+ PdfStamper stamper = new PdfStamper(reader, os);
+ stamper.SetEncryption(type, userPassword, ownerPassword, permissions);
+ stamper.MoreInfo = newInfo;
+ stamper.Close();
+ }
+
+ /** Entry point to encrypt a PDF document. The encryption parameters are the same as in
+ * PdfWriter
. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param reader the read PDF
+ * @param os the output destination
+ * @param type the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * values delete the key in the original info dictionary
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public static void Encrypt(PdfReader reader, Stream os, int type, String userPassword, String ownerPassword, int permissions) {
+ PdfStamper stamper = new PdfStamper(reader, os);
+ stamper.SetEncryption(type, userPassword, ownerPassword, permissions);
+ stamper.Close();
+ }
+
+ /**
+ * Give you a verbose analysis of the permissions.
+ * @param permissions the permissions value of a PDF file
+ * @return a String that explains the meaning of the permissions value
+ */
+ public static String GetPermissionsVerbose(int permissions) {
+ StringBuilder buf = new StringBuilder("Allowed:");
+ if ((PdfWriter.ALLOW_PRINTING & permissions) == PdfWriter.ALLOW_PRINTING) buf.Append(" Printing");
+ if ((PdfWriter.ALLOW_MODIFY_CONTENTS & permissions) == PdfWriter.ALLOW_MODIFY_CONTENTS) buf.Append(" Modify contents");
+ if ((PdfWriter.ALLOW_COPY & permissions) == PdfWriter.ALLOW_COPY) buf.Append(" Copy");
+ if ((PdfWriter.ALLOW_MODIFY_ANNOTATIONS & permissions) == PdfWriter.ALLOW_MODIFY_ANNOTATIONS) buf.Append(" Modify annotations");
+ if ((PdfWriter.ALLOW_FILL_IN & permissions) == PdfWriter.ALLOW_FILL_IN) buf.Append(" Fill in");
+ if ((PdfWriter.ALLOW_SCREENREADERS & permissions) == PdfWriter.ALLOW_SCREENREADERS) buf.Append(" Screen readers");
+ if ((PdfWriter.ALLOW_ASSEMBLY & permissions) == PdfWriter.ALLOW_ASSEMBLY) buf.Append(" Assembly");
+ if ((PdfWriter.ALLOW_DEGRADED_PRINTING & permissions) == PdfWriter.ALLOW_DEGRADED_PRINTING) buf.Append(" Degraded printing");
+ return buf.ToString();
+ }
+
+ /**
+ * Tells you if printing is allowed.
+ * @param permissions the permissions value of a PDF file
+ * @return true if printing is allowed
+ *
+ * @since 2.0.7
+ */
+ public static bool IsPrintingAllowed(int permissions) {
+ return (PdfWriter.ALLOW_PRINTING & permissions) == PdfWriter.ALLOW_PRINTING;
+ }
+
+ /**
+ * Tells you if modifying content is allowed.
+ * @param permissions the permissions value of a PDF file
+ * @return true if modifying content is allowed
+ *
+ * @since 2.0.7
+ */
+ public static bool IsModifyContentsAllowed(int permissions) {
+ return (PdfWriter.ALLOW_MODIFY_CONTENTS & permissions) == PdfWriter.ALLOW_MODIFY_CONTENTS;
+ }
+
+ /**
+ * Tells you if copying is allowed.
+ * @param permissions the permissions value of a PDF file
+ * @return true if copying is allowed
+ *
+ * @since 2.0.7
+ */
+ public static bool IsCopyAllowed(int permissions) {
+ return (PdfWriter.ALLOW_COPY & permissions) == PdfWriter.ALLOW_COPY;
+ }
+
+ /**
+ * Tells you if modifying annotations is allowed.
+ * @param permissions the permissions value of a PDF file
+ * @return true if modifying annotations is allowed
+ *
+ * @since 2.0.7
+ */
+ public static bool IsModifyAnnotationsAllowed(int permissions) {
+ return (PdfWriter.ALLOW_MODIFY_ANNOTATIONS & permissions) == PdfWriter.ALLOW_MODIFY_ANNOTATIONS;
+ }
+
+ /**
+ * Tells you if filling in fields is allowed.
+ * @param permissions the permissions value of a PDF file
+ * @return true if filling in fields is allowed
+ *
+ * @since 2.0.7
+ */
+ public static bool IsFillInAllowed(int permissions) {
+ return (PdfWriter.ALLOW_FILL_IN & permissions) == PdfWriter.ALLOW_FILL_IN;
+ }
+
+ /**
+ * Tells you if repurposing for screenreaders is allowed.
+ * @param permissions the permissions value of a PDF file
+ * @return true if repurposing for screenreaders is allowed
+ *
+ * @since 2.0.7
+ */
+ public static bool IsScreenReadersAllowed(int permissions) {
+ return (PdfWriter.ALLOW_SCREENREADERS & permissions) == PdfWriter.ALLOW_SCREENREADERS;
+ }
+
+ /**
+ * Tells you if document assembly is allowed.
+ * @param permissions the permissions value of a PDF file
+ * @return true if document assembly is allowed
+ *
+ * @since 2.0.7
+ */
+ public static bool IsAssemblyAllowed(int permissions) {
+ return (PdfWriter.ALLOW_ASSEMBLY & permissions) == PdfWriter.ALLOW_ASSEMBLY;
+ }
+
+ /**
+ * Tells you if degraded printing is allowed.
+ * @param permissions the permissions value of a PDF file
+ * @return true if degraded printing is allowed
+ *
+ * @since 2.0.7
+ */
+ public static bool IsDegradedPrintingAllowed(int permissions) {
+ return (PdfWriter.ALLOW_DEGRADED_PRINTING & permissions) == PdfWriter.ALLOW_DEGRADED_PRINTING;
+ }
+}
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfException.cs b/iTechSharp/iTextSharp/text/pdf/PdfException.cs
new file mode 100644
index 0000000..a31ac47
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfException.cs
@@ -0,0 +1,68 @@
+using System;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfException.cs,v 1.3 2008/05/13 11:25:20 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * Signals that an unspecified problem while constructing a PDF document.
+ *
+ * @see BadPdfFormatException
+ */
+
+ public class PdfException : DocumentException {
+ public PdfException() : base() {}
+
+ public PdfException(string message) : base(message) {}
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfFileSpecification.cs b/iTechSharp/iTextSharp/text/pdf/PdfFileSpecification.cs
new file mode 100644
index 0000000..d6e77d5
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfFileSpecification.cs
@@ -0,0 +1,261 @@
+using System;
+using System.IO;
+using System.Net;
+using iTextSharp.text.pdf.collection;
+/*
+ * Copyright 2003 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except inp compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added inp the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), inp which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed inp 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** Specifies a file or an URL. The file can be extern or embedded.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfFileSpecification : PdfDictionary {
+ protected PdfWriter writer;
+ protected PdfIndirectReference refi;
+
+ /** Creates a new instance of PdfFileSpecification. The static methods are preferred. */
+ public PdfFileSpecification() : base(PdfName.FILESPEC) {
+ }
+
+ /**
+ * Creates a file specification of type URL.
+ * @param writer the PdfWriter
+ * @param url the URL
+ * @return the file specification
+ */
+ public static PdfFileSpecification Url(PdfWriter writer, String url) {
+ PdfFileSpecification fs = new PdfFileSpecification();
+ fs.writer = writer;
+ fs.Put(PdfName.FS, PdfName.URL);
+ fs.Put(PdfName.F, new PdfString(url));
+ return fs;
+ }
+
+ /**
+ * Creates a file specification with the file embedded. The file may
+ * come from the file system or from a byte array. The data is flate compressed.
+ * @param writer the PdfWriter
+ * @param filePath the file path
+ * @param fileDisplay the file information that is presented to the user
+ * @param fileStore the byte array with the file. If it is not null
+ * it takes precedence over filePath
+ * @throws IOException on error
+ * @return the file specification
+ */
+ public static PdfFileSpecification FileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte[] fileStore) {
+ return FileEmbedded(writer, filePath, fileDisplay, fileStore, true);
+ }
+
+
+ /**
+ * Creates a file specification with the file embedded. The file may
+ * come from the file system or from a byte array.
+ * @param writer the PdfWriter
+ * @param filePath the file path
+ * @param fileDisplay the file information that is presented to the user
+ * @param fileStore the byte array with the file. If it is not null
+ * it takes precedence over filePath
+ * @param compress sets the compression on the data. Multimedia content will benefit little
+ * from compression
+ * @throws IOException on error
+ * @return the file specification
+ */
+ public static PdfFileSpecification FileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte[] fileStore, bool compress) {
+ return FileEmbedded(writer, filePath, fileDisplay, fileStore, compress, null, null);
+ }
+
+ /**
+ * Creates a file specification with the file embedded. The file may
+ * come from the file system or from a byte array.
+ * @param writer the PdfWriter
+ * @param filePath the file path
+ * @param fileDisplay the file information that is presented to the user
+ * @param fileStore the byte array with the file. If it is not null
+ * it takes precedence over filePath
+ * @param compress sets the compression on the data. Multimedia content will benefit little
+ * from compression
+ * @param mimeType the optional mimeType
+ * @param fileParameter the optional extra file parameters such as the creation or modification date
+ * @throws IOException on error
+ * @return the file specification
+ */
+ public static PdfFileSpecification FileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte[] fileStore, bool compress, String mimeType, PdfDictionary fileParameter) {
+ PdfFileSpecification fs = new PdfFileSpecification();
+ fs.writer = writer;
+ fs.Put(PdfName.F, new PdfString(fileDisplay));
+ PdfStream stream;
+ Stream inp = null;
+ PdfIndirectReference refi;
+ PdfIndirectReference refFileLength;
+ try {
+ refFileLength = writer.PdfIndirectReference;
+ if (fileStore == null) {
+ if (File.Exists(filePath)) {
+ inp = new FileStream(filePath, FileMode.Open, FileAccess.Read);
+ }
+ else {
+ if (filePath.StartsWith("file:/") || filePath.StartsWith("http://") || filePath.StartsWith("https://")) {
+ WebRequest w = WebRequest.Create(filePath);
+ inp = w.GetResponse().GetResponseStream();
+ }
+ else {
+ inp = BaseFont.GetResourceStream(filePath);
+ if (inp == null)
+ throw new IOException(filePath + " not found as file or resource.");
+ }
+ }
+ stream = new PdfStream(inp, writer);
+ }
+ else
+ stream = new PdfStream(fileStore);
+ stream.Put(PdfName.TYPE, PdfName.EMBEDDEDFILE);
+ if (compress)
+ stream.FlateCompress();
+ stream.Put(PdfName.PARAMS, refFileLength);
+ if (mimeType != null)
+ stream.Put(PdfName.SUBTYPE, new PdfName(mimeType));
+ refi = writer.AddToBody(stream).IndirectReference;
+ if (fileStore == null) {
+ stream.WriteLength();
+ }
+ PdfDictionary param = new PdfDictionary();
+ if (fileParameter != null)
+ param.Merge(fileParameter);
+ param.Put(PdfName.SIZE, new PdfNumber(stream.RawLength));
+ writer.AddToBody(param, refFileLength);
+ }
+ finally {
+ if (inp != null)
+ try{inp.Close();}catch{}
+ }
+ PdfDictionary f = new PdfDictionary();
+ f.Put(PdfName.F, refi);
+ fs.Put(PdfName.EF, f);
+ return fs;
+ }
+
+ /**
+ * Creates a file specification for an external file.
+ * @param writer the PdfWriter
+ * @param filePath the file path
+ * @return the file specification
+ */
+ public static PdfFileSpecification FileExtern(PdfWriter writer, String filePath) {
+ PdfFileSpecification fs = new PdfFileSpecification();
+ fs.writer = writer;
+ fs.Put(PdfName.F, new PdfString(filePath));
+ return fs;
+ }
+
+ /**
+ * Gets the indirect reference to this file specification.
+ * Multiple invocations will retrieve the same value.
+ * @throws IOException on error
+ * @return the indirect reference
+ */
+ public PdfIndirectReference Reference {
+ get {
+ if (refi != null)
+ return refi;
+ refi = writer.AddToBody(this).IndirectReference;
+ return refi;
+ }
+ }
+
+ /**
+ * Sets the file name (the key /F) string as an hex representation
+ * to support multi byte file names. The name must have the slash and
+ * backslash escaped according to the file specification rules
+ * @param fileName the file name as a byte array
+ */
+ public byte[] MultiByteFileName {
+ set {
+ Put(PdfName.F, new PdfString(value).SetHexWriting(true));
+ }
+ }
+
+ /**
+ * Adds the unicode file name (the key /UF). This entry was introduced
+ * in PDF 1.7. The filename must have the slash and backslash escaped
+ * according to the file specification rules.
+ * @param filename the filename
+ * @param unicode if true, the filename is UTF-16BE encoded; otherwise PDFDocEncoding is used;
+ */
+ public void SetUnicodeFileName(String filename, bool unicode) {
+ Put(PdfName.UF, new PdfString(filename, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING));
+ }
+
+ /**
+ * Sets a flag that indicates whether an external file referenced by the file
+ * specification is volatile. If the value is true, applications should never
+ * cache a copy of the file.
+ * @param volatile_file if true, the external file should not be cached
+ */
+ public bool Volatile {
+ set {
+ Put(PdfName.V, new PdfBoolean(value));
+ }
+ }
+
+ /**
+ * Adds a description for the file that is specified here.
+ * @param description some text
+ * @param unicode if true, the text is added as a unicode string
+ */
+ public void AddDescription(String description, bool unicode) {
+ Put(PdfName.DESC, new PdfString(description, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING));
+ }
+
+ /**
+ * Adds the Collection item dictionary.
+ */
+ public void AddCollectionItem(PdfCollectionItem ci) {
+ Put(PdfName.CI, ci);
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfFont.cs b/iTechSharp/iTextSharp/text/pdf/PdfFont.cs
new file mode 100644
index 0000000..c4649b6
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfFont.cs
@@ -0,0 +1,193 @@
+using System;
+using iTextSharp.text;
+/*
+ * $Id: PdfFont.cs,v 1.4 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfFont
is the Pdf Font object.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 7.7 (page 198-203).
+ *
+ * @see PdfName
+ * @see PdfDictionary
+ * @see BadPdfFormatException
+ */
+
+ public class PdfFont : IComparable {
+
+
+ /** the font metrics. */
+ private BaseFont font;
+
+ /** the size. */
+ private float size;
+
+ /** an image. */
+ protected Image image;
+
+ protected float hScale = 1;
+
+ // constructors
+
+ internal PdfFont(BaseFont bf, float size) {
+ this.size = size;
+ font = bf;
+ }
+
+ // methods
+
+ /**
+ * Compares this PdfFont
with another
+ *
+ * @param object the other PdfFont
+ * @return a value
+ */
+
+ public int CompareTo(Object obj) {
+ if (image != null)
+ return 0;
+ if (obj == null) {
+ return -1;
+ }
+ PdfFont pdfFont;
+ try {
+ pdfFont = (PdfFont) obj;
+ if (font != pdfFont.font) {
+ return 1;
+ }
+ if (this.Size != pdfFont.Size) {
+ return 2;
+ }
+ return 0;
+ }
+ catch (InvalidCastException) {
+ return -2;
+ }
+ }
+
+ /**
+ * Returns the size of this font.
+ *
+ * @return a size
+ */
+
+ internal float Size {
+ get {
+ if (image == null)
+ return size;
+ else {
+ return image.ScaledHeight;
+ }
+ }
+ }
+
+ /**
+ * Returns the approximative width of 1 character of this font.
+ *
+ * @return a width in Text Space
+ */
+
+ internal float Width() {
+ return Width(' ');
+ }
+
+ /**
+ * Returns the width of a certain character of this font.
+ *
+ * @param character a certain character
+ * @return a width in Text Space
+ */
+
+ internal float Width(int character) {
+ if (image == null)
+ return font.GetWidthPoint(character, size) * hScale;
+ else
+ return image.ScaledWidth;
+ }
+
+ internal float Width(String s) {
+ if (image == null)
+ return font.GetWidthPoint(s, size) * hScale;
+ else
+ return image.ScaledWidth;
+ }
+
+ internal BaseFont Font {
+ get {
+ return font;
+ }
+ }
+
+ internal Image Image {
+ set {
+ this.image = value;
+ }
+ }
+
+ internal static PdfFont DefaultFont {
+ get {
+ BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, false);
+ return new PdfFont(bf, 12);
+ }
+ }
+
+ internal float HorizontalScaling {
+ set {
+ this.hScale = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfFormField.cs b/iTechSharp/iTextSharp/text/pdf/PdfFormField.cs
new file mode 100644
index 0000000..d0cd5e4
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfFormField.cs
@@ -0,0 +1,353 @@
+using System;
+using System.Drawing;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * Copyright 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Implements form fields.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfFormField : PdfAnnotation {
+
+ public const int FF_READ_ONLY = 1;
+ public const int FF_REQUIRED = 2;
+ public const int FF_NO_EXPORT = 4;
+ public const int FF_NO_TOGGLE_TO_OFF = 16384;
+ public const int FF_RADIO = 32768;
+ public const int FF_PUSHBUTTON = 65536;
+ public const int FF_MULTILINE = 4096;
+ public const int FF_PASSWORD = 8192;
+ public const int FF_COMBO = 131072;
+ public const int FF_EDIT = 262144;
+ public const int FF_FILESELECT = 1048576;
+ public const int FF_MULTISELECT = 2097152;
+ public const int FF_DONOTSPELLCHECK = 4194304;
+ public const int FF_DONOTSCROLL = 8388608;
+ public const int FF_COMB = 16777216;
+ public const int FF_RADIOSINUNISON = 1 << 25;
+ public const int Q_LEFT = 0;
+ public const int Q_CENTER = 1;
+ public const int Q_RIGHT = 2;
+ public const int MK_NO_ICON = 0;
+ public const int MK_NO_CAPTION = 1;
+ public const int MK_CAPTION_BELOW = 2;
+ public const int MK_CAPTION_ABOVE = 3;
+ public const int MK_CAPTION_RIGHT = 4;
+ public const int MK_CAPTION_LEFT = 5;
+ public const int MK_CAPTION_OVERLAID = 6;
+ public static readonly PdfName IF_SCALE_ALWAYS = PdfName.A;
+ public static readonly PdfName IF_SCALE_BIGGER = PdfName.B;
+ public static readonly PdfName IF_SCALE_SMALLER = PdfName.S;
+ public static readonly PdfName IF_SCALE_NEVER = PdfName.N;
+ public static readonly PdfName IF_SCALE_ANAMORPHIC = PdfName.A;
+ public static readonly PdfName IF_SCALE_PROPORTIONAL = PdfName.P;
+ public const bool MULTILINE = true;
+ public const bool SINGLELINE = false;
+ public const bool PLAINTEXT = false;
+ public const bool PASSWORD = true;
+ public static PdfName[] mergeTarget = {PdfName.FONT, PdfName.XOBJECT, PdfName.COLORSPACE, PdfName.PATTERN};
+
+ /** Holds value of property parent. */
+ internal PdfFormField parent;
+
+ internal ArrayList kids;
+
+ /**
+ * Constructs a new PdfAnnotation
of subtype link (Action).
+ */
+
+ public PdfFormField(PdfWriter writer, float llx, float lly, float urx, float ury, PdfAction action) : base(writer, llx, lly, urx, ury, action) {
+ Put(PdfName.TYPE, PdfName.ANNOT);
+ Put(PdfName.SUBTYPE, PdfName.WIDGET);
+ annotation = true;
+ }
+
+ /** Creates new PdfFormField */
+ internal PdfFormField(PdfWriter writer) : base(writer, null) {
+ form = true;
+ annotation = false;
+ }
+
+ public void SetWidget(Rectangle rect, PdfName highlight) {
+ Put(PdfName.TYPE, PdfName.ANNOT);
+ Put(PdfName.SUBTYPE, PdfName.WIDGET);
+ Put(PdfName.RECT, new PdfRectangle(rect));
+ annotation = true;
+ if (highlight != null && !highlight.Equals(HIGHLIGHT_INVERT))
+ Put(PdfName.H, highlight);
+ }
+
+ public static PdfFormField CreateEmpty(PdfWriter writer) {
+ PdfFormField field = new PdfFormField(writer);
+ return field;
+ }
+
+ public int Button {
+ set {
+ Put(PdfName.FT, PdfName.BTN);
+ if (value != 0)
+ Put(PdfName.FF, new PdfNumber(value));
+ }
+ }
+
+ protected static PdfFormField CreateButton(PdfWriter writer, int flags) {
+ PdfFormField field = new PdfFormField(writer);
+ field.Button = flags;
+ return field;
+ }
+
+ public static PdfFormField CreatePushButton(PdfWriter writer) {
+ return CreateButton(writer, FF_PUSHBUTTON);
+ }
+
+ public static PdfFormField CreateCheckBox(PdfWriter writer) {
+ return CreateButton(writer, 0);
+ }
+
+ public static PdfFormField CreateRadioButton(PdfWriter writer, bool noToggleToOff) {
+ return CreateButton(writer, FF_RADIO + (noToggleToOff ? FF_NO_TOGGLE_TO_OFF : 0));
+ }
+
+ public static PdfFormField CreateTextField(PdfWriter writer, bool multiline, bool password, int maxLen) {
+ PdfFormField field = new PdfFormField(writer);
+ field.Put(PdfName.FT, PdfName.TX);
+ int flags = (multiline ? FF_MULTILINE : 0);
+ flags += (password ? FF_PASSWORD : 0);
+ field.Put(PdfName.FF, new PdfNumber(flags));
+ if (maxLen > 0)
+ field.Put(PdfName.MAXLEN, new PdfNumber(maxLen));
+ return field;
+ }
+
+ protected static PdfFormField CreateChoice(PdfWriter writer, int flags, PdfArray options, int topIndex) {
+ PdfFormField field = new PdfFormField(writer);
+ field.Put(PdfName.FT, PdfName.CH);
+ field.Put(PdfName.FF, new PdfNumber(flags));
+ field.Put(PdfName.OPT, options);
+ if (topIndex > 0)
+ field.Put(PdfName.TI, new PdfNumber(topIndex));
+ return field;
+ }
+
+ public static PdfFormField CreateList(PdfWriter writer, String[] options, int topIndex) {
+ return CreateChoice(writer, 0, ProcessOptions(options), topIndex);
+ }
+
+ public static PdfFormField CreateList(PdfWriter writer, String[,] options, int topIndex) {
+ return CreateChoice(writer, 0, ProcessOptions(options), topIndex);
+ }
+
+ public static PdfFormField CreateCombo(PdfWriter writer, bool edit, String[] options, int topIndex) {
+ return CreateChoice(writer, FF_COMBO + (edit ? FF_EDIT : 0), ProcessOptions(options), topIndex);
+ }
+
+ public static PdfFormField CreateCombo(PdfWriter writer, bool edit, String[,] options, int topIndex) {
+ return CreateChoice(writer, FF_COMBO + (edit ? FF_EDIT : 0), ProcessOptions(options), topIndex);
+ }
+
+ protected static PdfArray ProcessOptions(String[] options) {
+ PdfArray array = new PdfArray();
+ for (int k = 0; k < options.Length; ++k) {
+ array.Add(new PdfString(options[k], PdfObject.TEXT_UNICODE));
+ }
+ return array;
+ }
+
+ protected static PdfArray ProcessOptions(String[,] options) {
+ PdfArray array = new PdfArray();
+ for (int k = 0; k < options.GetLength(0); ++k) {
+ PdfArray ar2 = new PdfArray(new PdfString(options[k, 0], PdfObject.TEXT_UNICODE));
+ ar2.Add(new PdfString(options[k, 1], PdfObject.TEXT_UNICODE));
+ array.Add(ar2);
+ }
+ return array;
+ }
+
+ public static PdfFormField CreateSignature(PdfWriter writer) {
+ PdfFormField field = new PdfFormField(writer);
+ field.Put(PdfName.FT, PdfName.SIG);
+ return field;
+ }
+
+ /** Getter for property parent.
+ * @return Value of property parent.
+ */
+ public PdfFormField Parent {
+ get {
+ return parent;
+ }
+ }
+
+ public void AddKid(PdfFormField field) {
+ field.parent = this;
+ if (kids == null)
+ kids = new ArrayList();
+ kids.Add(field);
+ }
+
+ public ArrayList Kids {
+ get {
+ return kids;
+ }
+ }
+
+ public int SetFieldFlags(int flags) {
+ PdfNumber obj = (PdfNumber)Get(PdfName.FF);
+ int old;
+ if (obj == null)
+ old = 0;
+ else
+ old = obj.IntValue;
+ int v = old | flags;
+ Put(PdfName.FF, new PdfNumber(v));
+ return old;
+ }
+
+ public string ValueAsString {
+ set {
+ Put(PdfName.V, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public string ValueAsName {
+ set {
+ Put(PdfName.V, new PdfName(value));
+ }
+ }
+
+ public PdfSignature ValueAsSig {
+ set {
+ Put(PdfName.V, value);
+ }
+ }
+
+ public string DefaultValueAsString {
+ set {
+ Put(PdfName.DV, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public string DefaultValueAsName {
+ set {
+ Put(PdfName.DV, new PdfName(value));
+ }
+ }
+
+ public string FieldName {
+ set {
+ if (value != null)
+ Put(PdfName.T, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public string UserName {
+ set {
+ Put(PdfName.TU, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public string MappingName {
+ set {
+ Put(PdfName.TM, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public int Quadding {
+ set {
+ Put(PdfName.Q, new PdfNumber(value));
+ }
+ }
+
+ internal static void MergeResources(PdfDictionary result, PdfDictionary source, PdfStamperImp writer) {
+ PdfDictionary dic = null;
+ PdfDictionary res = null;
+ PdfName target = null;
+ for (int k = 0; k < mergeTarget.Length; ++k) {
+ target = mergeTarget[k];
+ PdfDictionary pdfDict = (PdfDictionary)PdfReader.GetPdfObject(source.Get(target));
+ if ((dic = pdfDict) != null) {
+ if ((res = (PdfDictionary)PdfReader.GetPdfObject(result.Get(target), result)) == null) {
+ res = new PdfDictionary();
+ }
+ res.MergeDifferent(dic);
+ result.Put(target, res);
+ if (writer != null)
+ writer.MarkUsed(res);
+ }
+ }
+ }
+
+ internal static void MergeResources(PdfDictionary result, PdfDictionary source) {
+ MergeResources(result, source, null);
+ }
+
+ public override void SetUsed() {
+ used = true;
+ if (parent != null)
+ Put(PdfName.PARENT, parent.IndirectReference);
+ if (kids != null) {
+ PdfArray array = new PdfArray();
+ for (int k = 0; k < kids.Count; ++k)
+ array.Add(((PdfFormField)kids[k]).IndirectReference);
+ Put(PdfName.KIDS, array);
+ }
+ if (templates == null)
+ return;
+ PdfDictionary dic = new PdfDictionary();
+ foreach (PdfTemplate template in templates.Keys) {
+ MergeResources(dic, (PdfDictionary)template.Resources);
+ }
+ Put(PdfName.DR, dic);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfFormXObject.cs b/iTechSharp/iTextSharp/text/pdf/PdfFormXObject.cs
new file mode 100644
index 0000000..fc9916a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfFormXObject.cs
@@ -0,0 +1,104 @@
+using System;
+
+/*
+ * $Id: PdfFormXObject.cs,v 1.3 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfFormObject
is a type of XObject containing a template-object.
+ */
+
+ public class PdfFormXObject : PdfStream {
+
+ // public static variables
+
+ /** This is a PdfNumber representing 0. */
+ public static PdfNumber ZERO = new PdfNumber(0);
+
+ /** This is a PdfNumber representing 1. */
+ public static PdfNumber ONE = new PdfNumber(1);
+
+ /** This is the 1 - matrix. */
+ public static PdfLiteral MATRIX = new PdfLiteral("[1 0 0 1 0 0]");
+
+ // membervariables
+
+
+ // constructor
+
+ /**
+ * Constructs a PdfFormXObject
-object.
+ *
+ * @param template the template
+ */
+
+ internal PdfFormXObject(PdfTemplate template) : base() {
+ Put(PdfName.TYPE, PdfName.XOBJECT);
+ Put(PdfName.SUBTYPE, PdfName.FORM);
+ Put(PdfName.RESOURCES, template.Resources);
+ Put(PdfName.BBOX, new PdfRectangle(template.BoundingBox));
+ Put(PdfName.FORMTYPE, ONE);
+ PdfArray matrix = template.Matrix;
+ if (template.Layer != null)
+ Put(PdfName.OC, template.Layer.Ref);
+ if (template.Group != null)
+ Put(PdfName.GROUP, template.Group);
+ if (matrix == null)
+ Put(PdfName.MATRIX, MATRIX);
+ else
+ Put(PdfName.MATRIX, matrix);
+ bytes = template.ToPdf(null);
+ Put(PdfName.LENGTH, new PdfNumber(bytes.Length));
+ FlateCompress();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfFunction.cs b/iTechSharp/iTextSharp/text/pdf/PdfFunction.cs
new file mode 100644
index 0000000..ad484ec
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfFunction.cs
@@ -0,0 +1,141 @@
+using System;
+using System.IO;
+
+/*
+ * Copyright 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /** Implements PDF functions.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfFunction {
+
+ protected PdfWriter writer;
+
+ protected PdfIndirectReference reference;
+
+ protected PdfDictionary dictionary;
+
+ /** Creates new PdfFunction */
+ protected PdfFunction(PdfWriter writer) {
+ this.writer = writer;
+ }
+
+ internal PdfIndirectReference Reference {
+ get {
+ if (reference == null) {
+ reference = writer.AddToBody(dictionary).IndirectReference;
+ }
+ return reference;
+ }
+ }
+
+ public static PdfFunction Type0(PdfWriter writer, float[] domain, float[] range, int[] size,
+ int bitsPerSample, int order, float[] encode, float[] decode, byte[] stream) {
+ PdfFunction func = new PdfFunction(writer);
+ func.dictionary = new PdfStream(stream);
+ ((PdfStream)func.dictionary).FlateCompress();
+ func.dictionary.Put(PdfName.FUNCTIONTYPE, new PdfNumber(0));
+ func.dictionary.Put(PdfName.DOMAIN, new PdfArray(domain));
+ func.dictionary.Put(PdfName.RANGE, new PdfArray(range));
+ func.dictionary.Put(PdfName.SIZE, new PdfArray(size));
+ func.dictionary.Put(PdfName.BITSPERSAMPLE, new PdfNumber(bitsPerSample));
+ if (order != 1)
+ func.dictionary.Put(PdfName.ORDER, new PdfNumber(order));
+ if (encode != null)
+ func.dictionary.Put(PdfName.ENCODE, new PdfArray(encode));
+ if (decode != null)
+ func.dictionary.Put(PdfName.DECODE, new PdfArray(decode));
+ return func;
+ }
+
+ public static PdfFunction Type2(PdfWriter writer, float[] domain, float[] range, float[] c0, float[] c1, float n) {
+ PdfFunction func = new PdfFunction(writer);
+ func.dictionary = new PdfDictionary();
+ func.dictionary.Put(PdfName.FUNCTIONTYPE, new PdfNumber(2));
+ func.dictionary.Put(PdfName.DOMAIN, new PdfArray(domain));
+ if (range != null)
+ func.dictionary.Put(PdfName.RANGE, new PdfArray(range));
+ if (c0 != null)
+ func.dictionary.Put(PdfName.C0, new PdfArray(c0));
+ if (c1 != null)
+ func.dictionary.Put(PdfName.C1, new PdfArray(c1));
+ func.dictionary.Put(PdfName.N, new PdfNumber(n));
+ return func;
+ }
+
+ public static PdfFunction Type3(PdfWriter writer, float[] domain, float[] range, PdfFunction[] functions, float[] bounds, float[] encode) {
+ PdfFunction func = new PdfFunction(writer);
+ func.dictionary = new PdfDictionary();
+ func.dictionary.Put(PdfName.FUNCTIONTYPE, new PdfNumber(3));
+ func.dictionary.Put(PdfName.DOMAIN, new PdfArray(domain));
+ if (range != null)
+ func.dictionary.Put(PdfName.RANGE, new PdfArray(range));
+ PdfArray array = new PdfArray();
+ for (int k = 0; k < functions.Length; ++k)
+ array.Add(functions[k].Reference);
+ func.dictionary.Put(PdfName.FUNCTIONS, array);
+ func.dictionary.Put(PdfName.BOUNDS, new PdfArray(bounds));
+ func.dictionary.Put(PdfName.ENCODE, new PdfArray(encode));
+ return func;
+ }
+
+ public static PdfFunction Type4(PdfWriter writer, float[] domain, float[] range, string postscript) {
+ byte[] b = new byte[postscript.Length];
+ for (int k = 0; k < b.Length; ++k)
+ b[k] = (byte)postscript[k];
+ PdfFunction func = new PdfFunction(writer);
+ func.dictionary = new PdfStream(b);
+ ((PdfStream)func.dictionary).FlateCompress();
+ func.dictionary.Put(PdfName.FUNCTIONTYPE, new PdfNumber(4));
+ func.dictionary.Put(PdfName.DOMAIN, new PdfArray(domain));
+ func.dictionary.Put(PdfName.RANGE, new PdfArray(range));
+ return func;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfGState.cs b/iTechSharp/iTextSharp/text/pdf/PdfGState.cs
new file mode 100644
index 0000000..f9f81e8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfGState.cs
@@ -0,0 +1,170 @@
+using System;
+/*
+ * Copyright 2003 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** The graphic state dictionary.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfGState : PdfDictionary {
+ /** A possible blend mode */
+ public static PdfName BM_NORMAL = new PdfName("Normal");
+ /** A possible blend mode */
+ public static PdfName BM_COMPATIBLE = new PdfName("Compatible");
+ /** A possible blend mode */
+ public static PdfName BM_MULTIPLY = new PdfName("Multiply");
+ /** A possible blend mode */
+ public static PdfName BM_SCREEN = new PdfName("Screen");
+ /** A possible blend mode */
+ public static PdfName BM_OVERLAY = new PdfName("Overlay");
+ /** A possible blend mode */
+ public static PdfName BM_DARKEN = new PdfName("Darken");
+ /** A possible blend mode */
+ public static PdfName BM_LIGHTEN = new PdfName("Lighten");
+ /** A possible blend mode */
+ public static PdfName BM_COLORDODGE = new PdfName("ColorDodge");
+ /** A possible blend mode */
+ public static PdfName BM_COLORBURN = new PdfName("ColorBurn");
+ /** A possible blend mode */
+ public static PdfName BM_HARDLIGHT = new PdfName("HardLight");
+ /** A possible blend mode */
+ public static PdfName BM_SOFTLIGHT = new PdfName("SoftLight");
+ /** A possible blend mode */
+ public static PdfName BM_DIFFERENCE = new PdfName("Difference");
+ /** A possible blend mode */
+ public static PdfName BM_EXCLUSION = new PdfName("Exclusion");
+
+ /**
+ * Sets the flag whether to apply overprint for stroking.
+ * @param ov
+ */
+ public bool OverPrintStroking {
+ set {
+ Put(PdfName.OP, value ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE);
+ }
+ }
+
+ /**
+ * Sets the flag whether to apply overprint for non stroking painting operations.
+ * @param ov
+ */
+ public bool OverPrintNonStroking {
+ set {
+ Put(PdfName.op_, value ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE);
+ }
+ }
+
+ /**
+ * Sets the flag whether to toggle knockout behavior for overprinted objects.
+ * @param ov - accepts 0 or 1
+ */
+ public int OverPrintMode {
+ set {
+ Put(PdfName.OPM, new PdfNumber(value == 0 ? 0 : 1));
+ }
+ }
+
+ /**
+ * Sets the current stroking alpha constant, specifying the constant shape or
+ * constant opacity value to be used for stroking operations in the transparent
+ * imaging model.
+ * @param n
+ */
+ public float StrokeOpacity {
+ set {
+ Put(PdfName.CA, new PdfNumber(value));
+ }
+ }
+
+ /**
+ * Sets the current stroking alpha constant, specifying the constant shape or
+ * constant opacity value to be used for nonstroking operations in the transparent
+ * imaging model.
+ * @param n
+ */
+ public float FillOpacity {
+ set {
+ Put(PdfName.ca_, new PdfNumber(value));
+ }
+ }
+
+ /**
+ * The alpha source flag specifying whether the current soft mask
+ * and alpha constant are to be interpreted as shape values (true)
+ * or opacity values (false).
+ * @param v
+ */
+ public bool AlphaIsShape {
+ set {
+ Put(PdfName.AIS, value ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE);
+ }
+ }
+
+ /**
+ * Determines the behaviour of overlapping glyphs within a text object
+ * in the transparent imaging model.
+ * @param v
+ */
+ public bool TextKnockout {
+ set {
+ Put(PdfName.TK, value ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE);
+ }
+ }
+
+ /**
+ * The current blend mode to be used in the transparent imaging model.
+ * @param bm
+ */
+ public PdfName BlendMode {
+ set {
+ Put(PdfName.BM, value);
+ }
+ }
+
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfICCBased.cs b/iTechSharp/iTextSharp/text/pdf/PdfICCBased.cs
new file mode 100644
index 0000000..fdcc782
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfICCBased.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfICCBased
defines a ColorSpace
+ *
+ * @see PdfStream
+ */
+
+ public class PdfICCBased : PdfStream {
+
+ public PdfICCBased(ICC_Profile profile) {
+ int numberOfComponents = profile.NumComponents;
+ switch (numberOfComponents) {
+ case 1:
+ Put(PdfName.ALTERNATE, PdfName.DEVICEGRAY);
+ break;
+ case 3:
+ Put(PdfName.ALTERNATE, PdfName.DEVICERGB);
+ break;
+ case 4:
+ Put(PdfName.ALTERNATE, PdfName.DEVICECMYK);
+ break;
+ default:
+ throw new PdfException(numberOfComponents + " Component(s) is not supported in iText");
+ }
+ Put(PdfName.N, new PdfNumber(numberOfComponents));
+ bytes = profile.Data;
+ FlateCompress();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfImage.cs b/iTechSharp/iTextSharp/text/pdf/PdfImage.cs
new file mode 100644
index 0000000..68b80f8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfImage.cs
@@ -0,0 +1,281 @@
+using System;
+using System.IO;
+using System.Net;
+using iTextSharp.text;
+/*
+ * $Id: PdfImage.cs,v 1.6 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfImage
is a PdfStream
containing an image-Dictionary
and -stream.
+ */
+
+ public class PdfImage : PdfStream {
+
+ internal const int TRANSFERSIZE = 4096;
+ // membervariables
+
+ /** This is the PdfName
of the image. */
+ protected PdfName name = null;
+
+ // constructor
+
+ /**
+ * Constructs a PdfImage
-object.
+ *
+ * @param image the Image
-object
+ * @param name the PdfName
for this image
+ * @throws BadPdfFormatException on error
+ */
+
+ public PdfImage(Image image, String name, PdfIndirectReference maskRef) {
+ this.name = new PdfName(name);
+ Put(PdfName.TYPE, PdfName.XOBJECT);
+ Put(PdfName.SUBTYPE, PdfName.IMAGE);
+ Put(PdfName.WIDTH, new PdfNumber(image.Width));
+ Put(PdfName.HEIGHT, new PdfNumber(image.Height));
+ if (image.Layer != null)
+ Put(PdfName.OC, image.Layer.Ref);
+ if (image.IsMask() && (image.Bpc == 1 || image.Bpc > 0xff))
+ Put(PdfName.IMAGEMASK, PdfBoolean.PDFTRUE);
+ if (maskRef != null) {
+ if (image.Smask)
+ Put(PdfName.SMASK, maskRef);
+ else
+ Put(PdfName.MASK, maskRef);
+ }
+ if (image.IsMask() && image.Inverted)
+ Put(PdfName.DECODE, new PdfLiteral("[1 0]"));
+ if (image.Interpolation)
+ Put(PdfName.INTERPOLATE, PdfBoolean.PDFTRUE);
+ Stream isp = null;
+ try {
+ // Raw Image data
+ if (image.IsImgRaw()) {
+ // will also have the CCITT parameters
+ int colorspace = image.Colorspace;
+ int[] transparency = image.Transparency;
+ if (transparency != null && !image.IsMask() && maskRef == null) {
+ String s = "[";
+ for (int k = 0; k < transparency.Length; ++k)
+ s += transparency[k] + " ";
+ s += "]";
+ Put(PdfName.MASK, new PdfLiteral(s));
+ }
+ bytes = image.RawData;
+ Put(PdfName.LENGTH, new PdfNumber(bytes.Length));
+ int bpc = image.Bpc;
+ if (bpc > 0xff) {
+ if (!image.IsMask())
+ Put(PdfName.COLORSPACE, PdfName.DEVICEGRAY);
+ Put(PdfName.BITSPERCOMPONENT, new PdfNumber(1));
+ Put(PdfName.FILTER, PdfName.CCITTFAXDECODE);
+ int k = bpc - Image.CCITTG3_1D;
+ PdfDictionary decodeparms = new PdfDictionary();
+ if (k != 0)
+ decodeparms.Put(PdfName.K, new PdfNumber(k));
+ if ((colorspace & Image.CCITT_BLACKIS1) != 0)
+ decodeparms.Put(PdfName.BLACKIS1, PdfBoolean.PDFTRUE);
+ if ((colorspace & Image.CCITT_ENCODEDBYTEALIGN) != 0)
+ decodeparms.Put(PdfName.ENCODEDBYTEALIGN, PdfBoolean.PDFTRUE);
+ if ((colorspace & Image.CCITT_ENDOFLINE) != 0)
+ decodeparms.Put(PdfName.ENDOFLINE, PdfBoolean.PDFTRUE);
+ if ((colorspace & Image.CCITT_ENDOFBLOCK) != 0)
+ decodeparms.Put(PdfName.ENDOFBLOCK, PdfBoolean.PDFFALSE);
+ decodeparms.Put(PdfName.COLUMNS, new PdfNumber(image.Width));
+ decodeparms.Put(PdfName.ROWS, new PdfNumber(image.Height));
+ Put(PdfName.DECODEPARMS, decodeparms);
+ }
+ else {
+ switch (colorspace) {
+ case 1:
+ Put(PdfName.COLORSPACE, PdfName.DEVICEGRAY);
+ if (image.Inverted)
+ Put(PdfName.DECODE, new PdfLiteral("[1 0]"));
+ break;
+ case 3:
+ Put(PdfName.COLORSPACE, PdfName.DEVICERGB);
+ if (image.Inverted)
+ Put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0]"));
+ break;
+ case 4:
+ default:
+ Put(PdfName.COLORSPACE, PdfName.DEVICECMYK);
+ if (image.Inverted)
+ Put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0 1 0]"));
+ break;
+ }
+ PdfDictionary additional = image.Additional;
+ if (additional != null)
+ Merge(additional);
+ if (image.IsMask() && (image.Bpc == 1 || image.Bpc > 8))
+ Remove(PdfName.COLORSPACE);
+ Put(PdfName.BITSPERCOMPONENT, new PdfNumber(image.Bpc));
+ if (image.Deflated)
+ Put(PdfName.FILTER, PdfName.FLATEDECODE);
+ else {
+ FlateCompress();
+ }
+ }
+ return;
+ }
+
+ // GIF, JPEG or PNG
+ String errorID;
+ if (image.RawData == null){
+ isp = WebRequest.Create(image.Url).GetResponse().GetResponseStream();
+ errorID = image.Url.ToString();
+ }
+ else{
+ isp = new MemoryStream(image.RawData);
+ errorID = "Byte array";
+ }
+ switch (image.Type) {
+ case Image.JPEG:
+ Put(PdfName.FILTER, PdfName.DCTDECODE);
+ switch (image.Colorspace) {
+ case 1:
+ Put(PdfName.COLORSPACE, PdfName.DEVICEGRAY);
+ break;
+ case 3:
+ Put(PdfName.COLORSPACE, PdfName.DEVICERGB);
+ break;
+ default:
+ Put(PdfName.COLORSPACE, PdfName.DEVICECMYK);
+ if (image.Inverted) {
+ Put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0 1 0]"));
+ }
+ break;
+ }
+ Put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
+ if (image.RawData != null){
+ bytes = image.RawData;
+ Put(PdfName.LENGTH, new PdfNumber(bytes.Length));
+ return;
+ }
+ streamBytes = new MemoryStream();
+ TransferBytes(isp, streamBytes, -1);
+ break;
+ case Image.JPEG2000:
+ Put(PdfName.FILTER, PdfName.JPXDECODE);
+ if (image.Colorspace > 0) {
+ switch (image.Colorspace) {
+ case 1:
+ Put(PdfName.COLORSPACE, PdfName.DEVICEGRAY);
+ break;
+ case 3:
+ Put(PdfName.COLORSPACE, PdfName.DEVICERGB);
+ break;
+ default:
+ Put(PdfName.COLORSPACE, PdfName.DEVICECMYK);
+ break;
+ }
+ Put(PdfName.BITSPERCOMPONENT, new PdfNumber(image.Bpc));
+ }
+ if (image.RawData != null){
+ bytes = image.RawData;
+ Put(PdfName.LENGTH, new PdfNumber(bytes.Length));
+ return;
+ }
+ streamBytes = new MemoryStream();
+ TransferBytes(isp, streamBytes, -1);
+ break;
+ default:
+ throw new IOException(errorID + " is an unknown Image format.");
+ }
+ Put(PdfName.LENGTH, new PdfNumber(streamBytes.Length));
+ }
+ finally {
+ if (isp != null) {
+ try{
+ isp.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the PdfName
of the image.
+ *
+ * @return the name
+ */
+
+ public PdfName Name {
+ get {
+ return name;
+ }
+ }
+
+ internal static void TransferBytes(Stream inp, Stream outp, int len) {
+ byte[] buffer = new byte[TRANSFERSIZE];
+ if (len < 0)
+ len = 0x7ffffff;
+ int size;
+ while (len != 0) {
+ size = inp.Read(buffer, 0, Math.Min(len, TRANSFERSIZE));
+ if (size <= 0)
+ return;
+ outp.Write(buffer, 0, size);
+ len -= size;
+ }
+ }
+
+ protected void ImportAll(PdfImage dup) {
+ name = dup.name;
+ compressed = dup.compressed;
+ streamBytes = dup.streamBytes;
+ bytes = dup.bytes;
+ hashMap = dup.hashMap;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfImportedPage.cs b/iTechSharp/iTextSharp/text/pdf/PdfImportedPage.cs
new file mode 100644
index 0000000..4b12b79
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfImportedPage.cs
@@ -0,0 +1,162 @@
+using System;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfImportedPage.cs,v 1.3 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Represents an imported page.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfImportedPage : PdfTemplate {
+
+ internal PdfReaderInstance readerInstance;
+ internal int pageNumber;
+
+ internal PdfImportedPage(PdfReaderInstance readerInstance, PdfWriter writer, int pageNumber) {
+ this.readerInstance = readerInstance;
+ this.pageNumber = pageNumber;
+ thisReference = writer.PdfIndirectReference;
+ bBox = readerInstance.Reader.GetPageSize(pageNumber);
+ type = TYPE_IMPORTED;
+ }
+
+ /** Reads the content from this PdfImportedPage
-object from a reader.
+ *
+ * @return self
+ *
+ */
+ public PdfImportedPage FromReader {
+ get {
+ return this;
+ }
+ }
+
+ public int PageNumber {
+ get {
+ return pageNumber;
+ }
+ }
+
+ /** Always throws an error. This operation is not allowed.
+ * @param image dummy
+ * @param a dummy
+ * @param b dummy
+ * @param c dummy
+ * @param d dummy
+ * @param e dummy
+ * @param f dummy
+ * @throws DocumentException dummy */
+ public override void AddImage(Image image, float a, float b, float c, float d, float e, float f) {
+ ThrowError();
+ }
+
+ /** Always throws an error. This operation is not allowed.
+ * @param template dummy
+ * @param a dummy
+ * @param b dummy
+ * @param c dummy
+ * @param d dummy
+ * @param e dummy
+ * @param f dummy */
+ public override void AddTemplate(PdfTemplate template, float a, float b, float c, float d, float e, float f) {
+ ThrowError();
+ }
+
+ /** Always throws an error. This operation is not allowed.
+ * @return dummy */
+ public override PdfContentByte Duplicate {
+ get {
+ ThrowError();
+ return null;
+ }
+ }
+
+ internal override PdfStream FormXObject {
+ get {
+ return readerInstance.GetFormXObject(pageNumber);
+ }
+ }
+
+ public override void SetColorFill(PdfSpotColor sp, float tint) {
+ ThrowError();
+ }
+
+ public override void SetColorStroke(PdfSpotColor sp, float tint) {
+ ThrowError();
+ }
+
+ internal override PdfObject Resources {
+ get {
+ return readerInstance.GetResources(pageNumber);
+ }
+ }
+
+ /** Always throws an error. This operation is not allowed.
+ * @param bf dummy
+ * @param size dummy */
+ public override void SetFontAndSize(BaseFont bf, float size) {
+ ThrowError();
+ }
+
+ internal void ThrowError() {
+ throw new Exception("Content can not be added to a PdfImportedPage.");
+ }
+
+ internal PdfReaderInstance PdfReaderInstance {
+ get {
+ return readerInstance;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfIndirectObject.cs b/iTechSharp/iTextSharp/text/pdf/PdfIndirectObject.cs
new file mode 100644
index 0000000..ec01fc6
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfIndirectObject.cs
@@ -0,0 +1,157 @@
+using System;
+using System.IO;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfIndirectObject.cs,v 1.3 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+/**
+ * PdfIndirectObject
is the Pdf indirect object.
+ * PdfObject
may be labeled as an indirect object.
+ * An indirect object consists of an object identifier, a direct object, and the endobj
+ * keyword. The object identifier consists of an integer object number, an integer
+ * generation number, and the obj keyword.
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.10 (page 53).
+ *
+ * @see PdfObject
+ * @see PdfIndirectReference
+ */
+
+public class PdfIndirectObject {
+
+ // membervariables
+
+ /** The object number */
+ protected int number;
+
+ /** the generation number */
+ protected int generation = 0;
+
+ internal static byte[] STARTOBJ = DocWriter.GetISOBytes(" obj");
+ internal static byte[] ENDOBJ = DocWriter.GetISOBytes("\nendobj\n");
+ internal static int SIZEOBJ = STARTOBJ.Length + ENDOBJ.Length;
+ internal PdfObject objecti;
+ internal PdfWriter writer;
+
+ // constructors
+
+ /**
+ * Constructs a PdfIndirectObject
.
+ *
+ * @param number the objecti number
+ * @param objecti the direct objecti
+ */
+
+ internal PdfIndirectObject(int number, PdfObject objecti, PdfWriter writer) : this(number, 0, objecti, writer) {
+ }
+
+ internal PdfIndirectObject(PdfIndirectReference refi, PdfObject objecti, PdfWriter writer) : this(refi.Number,refi.Generation,objecti,writer) {
+ }
+ /**
+ * Constructs a PdfIndirectObject
.
+ *
+ * @param number the objecti number
+ * @param generation the generation number
+ * @param objecti the direct objecti
+ */
+
+ internal PdfIndirectObject(int number, int generation, PdfObject objecti, PdfWriter writer) {
+ this.writer = writer;
+ this.number = number;
+ this.generation = generation;
+ this.objecti = objecti;
+ PdfEncryption crypto = null;
+ if (writer != null)
+ crypto = writer.Encryption;
+ if (crypto != null) {
+ crypto.SetHashKey(number, generation);
+ }
+ }
+
+ // methods
+
+ /**
+ * Returns a PdfIndirectReference
to this PdfIndirectObject
.
+ *
+ * @return a PdfIndirectReference
+ */
+
+ public PdfIndirectReference IndirectReference {
+ get {
+ return new PdfIndirectReference(objecti.Type, number, generation);
+ }
+ }
+
+ /**
+ * Writes eficiently to a stream
+ *
+ * @param os the stream to write to
+ * @throws IOException on write error
+ */
+ internal void WriteTo(Stream os) {
+ byte[] tmp = DocWriter.GetISOBytes(number.ToString());
+ os.Write(tmp, 0, tmp.Length);
+ os.WriteByte((byte)' ');
+ tmp = DocWriter.GetISOBytes(generation.ToString());
+ os.Write(tmp, 0, tmp.Length);
+ os.Write(STARTOBJ, 0, STARTOBJ.Length);
+ int type = objecti.Type;
+ if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING)
+ os.WriteByte((byte)' ');
+ objecti.ToPdf(writer, os);
+ os.Write(ENDOBJ, 0, ENDOBJ.Length);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfIndirectReference.cs b/iTechSharp/iTextSharp/text/pdf/PdfIndirectReference.cs
new file mode 100644
index 0000000..443751a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfIndirectReference.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Text;
+
+/*
+ * $Id: PdfIndirectReference.cs,v 1.5 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfIndirectReference
contains a reference to a PdfIndirectObject
.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.11 (page 54).
+ *
+ * @see PdfObject
+ * @see PdfIndirectObject
+ */
+
+ public class PdfIndirectReference : PdfObject {
+
+ // membervariables
+
+ /** the object number */
+ protected int number;
+
+ /** the generation number */
+ protected int generation = 0;
+
+ // constructors
+
+ protected PdfIndirectReference() : base(0) {
+ }
+
+ /**
+ * Constructs a PdfIndirectReference
.
+ *
+ * @param type the type of the PdfObject
that is referenced to
+ * @param number the object number.
+ * @param generation the generation number.
+ */
+
+ internal PdfIndirectReference(int type, int number, int generation) : base(0, new StringBuilder().Append(number).Append(' ').Append(generation).Append(" R").ToString()) {
+ this.number = number;
+ this.generation = generation;
+ }
+
+ /**
+ * Constructs a PdfIndirectReference
.
+ *
+ * @param type the type of the PdfObject
that is referenced to
+ * @param number the object number.
+ */
+
+ internal PdfIndirectReference(int type, int number) : this(type, number, 0) {}
+
+ // methods
+
+ /**
+ * Returns the number of the object.
+ *
+ * @return a number.
+ */
+
+ public int Number {
+ get {
+ return number;
+ }
+ }
+
+ /**
+ * Returns the generation of the object.
+ *
+ * @return a number.
+ */
+
+ public int Generation {
+ get {
+ return generation;
+ }
+ }
+
+ public override String ToString() {
+ return new StringBuilder().Append(number).Append(' ').Append(generation).Append(" R").ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfLayer.cs b/iTechSharp/iTextSharp/text/pdf/PdfLayer.cs
new file mode 100644
index 0000000..4cb3f39
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfLayer.cs
@@ -0,0 +1,321 @@
+using System;
+using System.Collections;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * An optional content group is a dictionary representing a collection of graphics
+ * that can be made visible or invisible dynamically by users of viewer applications.
+ * In iText they are referenced as layers.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfLayer : PdfDictionary, IPdfOCG {
+ protected PdfIndirectReference refi;
+ protected ArrayList children;
+ protected PdfLayer parent;
+ protected String title;
+
+ /**
+ * Holds value of property on.
+ */
+ private bool on = true;
+
+ /**
+ * Holds value of property onPanel.
+ */
+ private bool onPanel = true;
+
+ internal PdfLayer(String title) {
+ this.title = title;
+ }
+
+ /**
+ * Creates a title layer. A title layer is not really a layer but a collection of layers
+ * under the same title heading.
+ * @param title the title text
+ * @param writer the PdfWriter
+ * @return the title layer
+ */
+ public static PdfLayer CreateTitle(String title, PdfWriter writer) {
+ if (title == null)
+ throw new ArgumentNullException("Title cannot be null.");
+ PdfLayer layer = new PdfLayer(title);
+ writer.RegisterLayer(layer);
+ return layer;
+ }
+ /**
+ * Creates a new layer.
+ * @param name the name of the layer
+ * @param writer the writer
+ */
+ public PdfLayer(String name, PdfWriter writer) : base(PdfName.OCG) {
+ Name = name;
+ refi = writer.PdfIndirectReference;
+ writer.RegisterLayer(this);
+ }
+
+ internal String Title {
+ get {
+ return title;
+ }
+ }
+
+ /**
+ * Adds a child layer. Nested layers can only have one parent.
+ * @param child the child layer
+ */
+ public void AddChild(PdfLayer child) {
+ if (child.parent != null)
+ throw new ArgumentException("The layer '" + ((PdfString)child.Get(PdfName.NAME)).ToUnicodeString() + "' already has a parent.");
+ child.parent = this;
+ if (children == null)
+ children = new ArrayList();
+ children.Add(child);
+ }
+
+
+ /**
+ * Gets the parent layer.
+ * @return the parent layer or null
if the layer has no parent
+ */
+ public PdfLayer Parent {
+ get {
+ return parent;
+ }
+ }
+
+ /**
+ * Gets the children layers.
+ * @return the children layers or null
if the layer has no children
+ */
+ public ArrayList Children {
+ get {
+ return children;
+ }
+ }
+
+ /**
+ * Gets the PdfIndirectReference
that represents this layer.
+ * @return the PdfIndirectReference
that represents this layer
+ */
+ public PdfIndirectReference Ref {
+ get {
+ return refi;
+ }
+ set {
+ refi = value;
+ }
+ }
+
+ /**
+ * Sets the name of this layer.
+ * @param name the name of this layer
+ */
+ public string Name {
+ set {
+ Put(PdfName.NAME, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ /**
+ * Gets the dictionary representing the layer. It just returns this
.
+ * @return the dictionary representing the layer
+ */
+ public PdfObject PdfObject {
+ get {
+ return this;
+ }
+ }
+
+ /**
+ * Gets the initial visibility of the layer.
+ * @return the initial visibility of the layer
+ */
+ public bool On {
+ get {
+ return this.on;
+ }
+ set {
+ on = value;
+ }
+ }
+
+
+ private PdfDictionary Usage {
+ get {
+ PdfDictionary usage = (PdfDictionary)Get(PdfName.USAGE);
+ if (usage == null) {
+ usage = new PdfDictionary();
+ Put(PdfName.USAGE, usage);
+ }
+ return usage;
+ }
+ }
+
+ /**
+ * Used by the creating application to store application-specific
+ * data associated with this optional content group.
+ * @param creator a text string specifying the application that created the group
+ * @param subtype a string defining the type of content controlled by the group. Suggested
+ * values include but are not limited to Artwork, for graphic-design or publishing
+ * applications, and Technical, for technical designs such as building plans or
+ * schematics
+ */
+ public void SetCreatorInfo(String creator, String subtype) {
+ PdfDictionary usage = Usage;
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.CREATOR, new PdfString(creator, PdfObject.TEXT_UNICODE));
+ dic.Put(PdfName.SUBTYPE, new PdfName(subtype));
+ usage.Put(PdfName.CREATORINFO, dic);
+ }
+
+ /**
+ * Specifies the language of the content controlled by this
+ * optional content group
+ * @param lang a language string which specifies a language and possibly a locale
+ * (for example, es-MX represents Mexican Spanish)
+ * @param preferred used by viewer applications when there is a partial match but no exact
+ * match between the system language and the language strings in all usage dictionaries
+ */
+ public void SetLanguage(String lang, bool preferred) {
+ PdfDictionary usage = Usage;
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.LANG, new PdfString(lang, PdfObject.TEXT_UNICODE));
+ if (preferred)
+ dic.Put(PdfName.PREFERRED, PdfName.ON);
+ usage.Put(PdfName.LANGUAGE, dic);
+ }
+
+ /**
+ * Specifies the recommended state for content in this
+ * group when the document (or part of it) is saved by a viewer application to a format
+ * that does not support optional content (for example, an earlier version of
+ * PDF or a raster image format).
+ * @param export the export state
+ */
+ public bool Export {
+ set {
+ PdfDictionary usage = Usage;
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.EXPORTSTATE, value ? PdfName.ON : PdfName.OFF);
+ usage.Put(PdfName.EXPORT, dic);
+ }
+ }
+
+ /**
+ * Specifies a range of magnifications at which the content
+ * in this optional content group is best viewed.
+ * @param min the minimum recommended magnification factors at which the group
+ * should be ON. A negative value will set the default to 0
+ * @param max the maximum recommended magnification factor at which the group
+ * should be ON. A negative value will set the largest possible magnification supported by the
+ * viewer application
+ */
+ public void SetZoom(float min, float max) {
+ if (min <= 0 && max < 0)
+ return;
+ PdfDictionary usage = Usage;
+ PdfDictionary dic = new PdfDictionary();
+ if (min > 0)
+ dic.Put(PdfName.MIN, new PdfNumber(min));
+ if (max >= 0)
+ dic.Put(PdfName.MAX, new PdfNumber(max));
+ usage.Put(PdfName.ZOOM, dic);
+ }
+
+ /**
+ * Specifies that the content in this group is intended for
+ * use in printing
+ * @param subtype a name specifying the kind of content controlled by the group;
+ * for example, Trapping, PrintersMarks and Watermark
+ * @param printstate indicates that the group should be
+ * set to that state when the document is printed from a viewer application
+ */
+ public void SetPrint(String subtype, bool printstate) {
+ PdfDictionary usage = Usage;
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.SUBTYPE, new PdfName(subtype));
+ dic.Put(PdfName.PRINTSTATE, printstate ? PdfName.ON : PdfName.OFF);
+ usage.Put(PdfName.PRINT, dic);
+ }
+
+ /**
+ * Indicates that the group should be set to that state when the
+ * document is opened in a viewer application.
+ * @param view the view state
+ */
+ public bool View {
+ set {
+ PdfDictionary usage = Usage;
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.VIEWSTATE, value ? PdfName.ON : PdfName.OFF);
+ usage.Put(PdfName.VIEW, dic);
+ }
+ }
+
+ /**
+ * Gets the layer visibility in Acrobat's layer panel
+ * @return the layer visibility in Acrobat's layer panel
+ */
+ /**
+ * Sets the visibility of the layer in Acrobat's layer panel. If false
+ * the layer cannot be directly manipulated by the user. Note that any children layers will
+ * also be absent from the panel.
+ * @param onPanel the visibility of the layer in Acrobat's layer panel
+ */
+ public bool OnPanel {
+ get {
+ return this.onPanel;
+ }
+ set {
+ onPanel = value;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfLayerMembership.cs b/iTechSharp/iTextSharp/text/pdf/PdfLayerMembership.cs
new file mode 100644
index 0000000..c7130cb
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfLayerMembership.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Content typically belongs to a single optional content group,
+ * and is visible when the group is ON and invisible when it is OFF. To express more
+ * complex visibility policies, content should not declare itself to belong to an optional
+ * content group directly, but rather to an optional content membership dictionary
+ * represented by this class.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfLayerMembership : PdfDictionary, IPdfOCG {
+
+ /**
+ * Visible only if all of the entries are ON.
+ */
+ public static readonly PdfName ALLON = new PdfName("AllOn");
+ /**
+ * Visible if any of the entries are ON.
+ */
+ public static readonly PdfName ANYON = new PdfName("AnyOn");
+ /**
+ * Visible if any of the entries are OFF.
+ */
+ public static readonly PdfName ANYOFF = new PdfName("AnyOff");
+ /**
+ * Visible only if all of the entries are OFF.
+ */
+ public static readonly PdfName ALLOFF = new PdfName("AllOff");
+
+ internal PdfIndirectReference refi;
+ internal PdfArray members = new PdfArray();
+ internal Hashtable layers = new Hashtable();
+
+ /**
+ * Creates a new, empty, membership layer.
+ * @param writer the writer
+ */
+ public PdfLayerMembership(PdfWriter writer) : base(PdfName.OCMD) {
+ Put(PdfName.OCGS, members);
+ refi = writer.PdfIndirectReference;
+ }
+
+ /**
+ * Gets the PdfIndirectReference
that represents this membership layer.
+ * @return the PdfIndirectReference
that represents this layer
+ */
+ public PdfIndirectReference Ref {
+ get {
+ return refi;
+ }
+ }
+
+ /**
+ * Adds a new member to the layer.
+ * @param layer the new member to the layer
+ */
+ public void AddMember(PdfLayer layer) {
+ if (!layers.ContainsKey(layer)) {
+ members.Add(layer.Ref);
+ layers[layer] = null;
+ }
+ }
+
+ /**
+ * Gets the member layers.
+ * @return the member layers
+ */
+ public ICollection Layers {
+ get {
+ return layers.Keys;
+ }
+ }
+
+ /**
+ * Sets the visibility policy for content belonging to this
+ * membership dictionary. Possible values are ALLON, ANYON, ANYOFF and ALLOFF.
+ * The default value is ANYON.
+ * @param type the visibility policy
+ */
+ public PdfName VisibilityPolicy {
+ set {
+ Put(PdfName.P, value);
+ }
+ }
+
+ /**
+ * Gets the dictionary representing the membership layer. It just returns this
.
+ * @return the dictionary representing the layer
+ */
+ public PdfObject PdfObject {
+ get {
+ return this;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfLine.cs b/iTechSharp/iTextSharp/text/pdf/PdfLine.cs
new file mode 100644
index 0000000..8d0ef90
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfLine.cs
@@ -0,0 +1,539 @@
+using System;
+using System.Text;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfLine.cs,v 1.7 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfLine
defines an array with PdfChunk
-objects
+ * that fit into 1 line.
+ */
+
+ public class PdfLine {
+
+ // membervariables
+
+ /** The arraylist containing the chunks. */
+ protected internal ArrayList line;
+
+ /** The left indentation of the line. */
+ protected internal float left;
+
+ /** The width of the line. */
+ protected internal float width;
+
+ /** The alignment of the line. */
+ protected internal int alignment;
+
+ /** The heigth of the line. */
+ protected internal float height;
+
+ /** The listsymbol (if necessary). */
+ protected internal Chunk listSymbol = null;
+
+ /** The listsymbol (if necessary). */
+ protected internal float symbolIndent;
+
+ /** true
if the chunk splitting was caused by a newline. */
+ protected internal bool newlineSplit = false;
+
+ /** The original width. */
+ protected internal float originalWidth;
+
+ protected internal bool isRTL = false;
+
+ // constructors
+
+ /**
+ * Constructs a new PdfLine
-object.
+ *
+ * @param left the limit of the line at the left
+ * @param right the limit of the line at the right
+ * @param alignment the alignment of the line
+ * @param height the height of the line
+ */
+
+ internal PdfLine(float left, float right, int alignment, float height) {
+ this.left = left;
+ this.width = right - left;
+ this.originalWidth = this.width;
+ this.alignment = alignment;
+ this.height = height;
+ this.line = new ArrayList();
+ }
+
+ /**
+ * Creates a PdfLine object.
+ * @param left the left offset
+ * @param originalWidth the original width of the line
+ * @param remainingWidth bigger than 0 if the line isn't completely filled
+ * @param alignment the alignment of the line
+ * @param newlineSplit was the line splitted (or does the paragraph end with this line)
+ * @param line an array of PdfChunk objects
+ * @param isRTL do you have to read the line from Right to Left?
+ */
+ internal PdfLine(float left, float originalWidth, float remainingWidth, int alignment, bool newlineSplit, ArrayList line, bool isRTL) {
+ this.left = left;
+ this.originalWidth = originalWidth;
+ this.width = remainingWidth;
+ this.alignment = alignment;
+ this.line = line;
+ this.newlineSplit = newlineSplit;
+ this.isRTL = isRTL;
+ }
+
+ // methods
+
+ /**
+ * Adds a PdfChunk
to the PdfLine
.
+ *
+ * @param chunk the PdfChunk
to add
+ * @return null
if the chunk could be added completely; if not
+ * a PdfChunk
containing the part of the chunk that could
+ * not be added is returned
+ */
+
+ internal PdfChunk Add(PdfChunk chunk) {
+ // nothing happens if the chunk is null.
+ if (chunk == null || chunk.ToString().Equals("")) {
+ return null;
+ }
+
+ // we split the chunk to be added
+ PdfChunk overflow = chunk.Split(width);
+ newlineSplit = (chunk.IsNewlineSplit() || overflow == null);
+ // if (chunk.IsNewlineSplit() && alignment == Element.ALIGN_JUSTIFIED)
+ // alignment = Element.ALIGN_LEFT;
+ if (chunk.IsTab()) {
+ Object[] tab = (Object[])chunk.GetAttribute(Chunk.TAB);
+ float tabPosition = (float)tab[1];
+ bool newline = (bool)tab[2];
+ if (newline && tabPosition < originalWidth - width) {
+ return chunk;
+ }
+ width = originalWidth - tabPosition;
+ chunk.AdjustLeft(left);
+ AddToLine(chunk);
+ }
+ // if the length of the chunk > 0 we add it to the line
+ else if (chunk.Length > 0) {
+ if (overflow != null)
+ chunk.TrimLastSpace();
+ width -= chunk.Width;
+ AddToLine(chunk);
+ }
+
+ // if the length == 0 and there were no other chunks added to the line yet,
+ // we risk to end up in an endless loop trying endlessly to add the same chunk
+ else if (line.Count < 1) {
+ chunk = overflow;
+ overflow = chunk.Truncate(width);
+ width -= chunk.Width;
+ if (chunk.Length > 0) {
+ AddToLine(chunk);
+ return overflow;
+ }
+ // if the chunck couldn't even be truncated, we add everything, so be it
+ else {
+ if (overflow != null)
+ AddToLine(chunk);
+ return null;
+ }
+ }
+ else {
+ width += ((PdfChunk)(line[line.Count - 1])).TrimLastSpace();
+ }
+ return overflow;
+ }
+
+ private void AddToLine(PdfChunk chunk) {
+ if (chunk.ChangeLeading && chunk.IsImage()) {
+ float f = chunk.Image.ScaledHeight + chunk.ImageOffsetY;
+ if (f > height) height = f;
+ }
+ line.Add(chunk);
+ }
+
+ // methods to retrieve information
+
+ /**
+ * Returns the number of chunks in the line.
+ *
+ * @return a value
+ */
+
+ public int Size {
+ get {
+ return line.Count;
+ }
+ }
+
+ /**
+ * Returns an iterator of PdfChunk
s.
+ *
+ * @return an Iterator
+ */
+
+ public IEnumerator GetEnumerator() {
+ return line.GetEnumerator();
+ }
+
+ /**
+ * Returns the height of the line.
+ *
+ * @return a value
+ */
+
+ internal float Height {
+ get {
+ return height;
+ }
+ }
+
+ /**
+ * Returns the left indentation of the line taking the alignment of the line into account.
+ *
+ * @return a value
+ */
+
+ internal float IndentLeft {
+ get {
+ if (isRTL) {
+ switch (alignment) {
+ case Element.ALIGN_LEFT:
+ return left + width;
+ case Element.ALIGN_CENTER:
+ return left + (width / 2f);
+ default:
+ return left;
+ }
+ }
+ else {
+ switch (alignment) {
+ case Element.ALIGN_RIGHT:
+ return left + width;
+ case Element.ALIGN_CENTER:
+ return left + (width / 2f);
+ default:
+ return left;
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if this line has to be justified.
+ *
+ * @return true
if the alignment equals ALIGN_JUSTIFIED and there is some width left.
+ */
+
+ public bool HasToBeJustified() {
+ return ((alignment == Element.ALIGN_JUSTIFIED || alignment == Element.ALIGN_JUSTIFIED_ALL) && width != 0);
+ }
+
+ /**
+ * Resets the alignment of this line.
+ * Paragraph
+ * that has to be justified, has to be reset to ALIGN_LEFT.
+ */
+
+ public void ResetAlignment() {
+ if (alignment == Element.ALIGN_JUSTIFIED) {
+ alignment = Element.ALIGN_LEFT;
+ }
+ }
+
+ /** Adds extra indentation to the left (for Paragraph.setFirstLineIndent). */
+ internal void SetExtraIndent(float extra) {
+ left += extra;
+ width -= extra;
+ }
+
+ /**
+ * Returns the width that is left, after a maximum of characters is added to the line.
+ *
+ * @return a value
+ */
+
+ internal float WidthLeft {
+ get {
+ return width;
+ }
+ }
+
+ /**
+ * Returns the number of space-characters in this line.
+ *
+ * @return a value
+ */
+
+ internal int NumberOfSpaces {
+ get {
+ string str = ToString();
+ int length = str.Length;
+ int numberOfSpaces = 0;
+ for (int i = 0; i < length; i++) {
+ if (str[i] == ' ') {
+ numberOfSpaces++;
+ }
+ }
+ return numberOfSpaces;
+ }
+ }
+
+ /**
+ * Sets the listsymbol of this line.
+ * ListItem
.
+ *
+ * @param listItem the list symbol
+ */
+
+ public ListItem ListItem {
+ set {
+ this.listSymbol = value.ListSymbol;
+ this.symbolIndent = value.IndentationLeft;
+ }
+ }
+
+ /**
+ * Returns the listsymbol of this line.
+ *
+ * @return a PdfChunk
if the line has a listsymbol; null
otherwise
+ */
+
+ public Chunk ListSymbol {
+ get {
+ return listSymbol;
+ }
+ }
+
+ /**
+ * Return the indentation needed to show the listsymbol.
+ *
+ * @return a value
+ */
+
+ public float ListIndent {
+ get {
+ return symbolIndent;
+ }
+ }
+
+ /**
+ * Get the string representation of what is in this line.
+ *
+ * @return a string
+ */
+
+ public override string ToString() {
+ StringBuilder tmp = new StringBuilder();
+ foreach (PdfChunk c in line) {
+ tmp.Append(c.ToString());
+ }
+ return tmp.ToString();
+ }
+
+ public int GetLineLengthUtf32() {
+ int total = 0;
+ foreach (PdfChunk c in line) {
+ total += c.LengthUtf32;
+ }
+ return total;
+ }
+
+ /**
+ * Checks if a newline caused the line split.
+ * @return true
if a newline caused the line split
+ */
+ public bool NewlineSplit {
+ get {
+ return newlineSplit && (alignment != Element.ALIGN_JUSTIFIED_ALL);
+ }
+ }
+
+ /**
+ * Gets the index of the last PdfChunk
with metric attributes
+ * @return the last PdfChunk
with metric attributes
+ */
+ public int LastStrokeChunk {
+ get {
+ int lastIdx = line.Count - 1;
+ for (; lastIdx >= 0; --lastIdx) {
+ PdfChunk chunk = (PdfChunk)line[lastIdx];
+ if (chunk.IsStroked())
+ break;
+ }
+ return lastIdx;
+ }
+ }
+
+ /**
+ * Gets a PdfChunk
by index.
+ * @param idx the index
+ * @return the PdfChunk
or null if beyond the array
+ */
+ public PdfChunk GetChunk(int idx) {
+ if (idx < 0 || idx >= line.Count)
+ return null;
+ return (PdfChunk)line[idx];
+ }
+
+ /**
+ * Gets the original width of the line.
+ * @return the original width of the line
+ */
+ public float OriginalWidth {
+ get {
+ return originalWidth;
+ }
+ }
+
+ /**
+ * Gets the maximum size of all the fonts used in this line
+ * including images.
+ * @return maximum size of all the fonts used in this line
+ */
+ internal float MaxSizeSimple {
+ get {
+ float maxSize = 0;
+ for (int k = 0; k < line.Count; ++k) {
+ PdfChunk chunk = (PdfChunk)line[k];
+ if (!chunk.IsImage()) {
+ maxSize = Math.Max(chunk.Font.Size, maxSize);
+ }
+ else {
+ maxSize = Math.Max(chunk.Image.ScaledHeight + chunk.ImageOffsetY , maxSize);
+ }
+ }
+ return maxSize;
+ }
+ }
+
+ internal bool RTL {
+ get {
+ return isRTL;
+ }
+ }
+
+ /**
+ * Gets the number of separators in the line.
+ * @return the number of separators in the line
+ * @since 2.1.2
+ */
+ internal int GetSeparatorCount() {
+ int s = 0;
+ foreach (PdfChunk ck in line) {
+ if (ck.IsTab()) {
+ return 0;
+ }
+ if (ck.IsHorizontalSeparator()) {
+ s++;
+ }
+ }
+ return s;
+ }
+
+ public float GetWidthCorrected(float charSpacing, float wordSpacing) {
+ float total = 0;
+ for (int k = 0; k < line.Count; ++k) {
+ PdfChunk ck = (PdfChunk)line[k];
+ total += ck.GetWidthCorrected(charSpacing, wordSpacing);
+ }
+ return total;
+ }
+
+ /**
+ * Gets the maximum size of the ascender for all the fonts used
+ * in this line.
+ * @return maximum size of all the ascenders used in this line
+ */
+ public float Ascender {
+ get {
+ float ascender = 0;
+ foreach (PdfChunk ck in line) {
+ if (ck.IsImage())
+ ascender = Math.Max(ascender, ck.Image.ScaledHeight + ck.ImageOffsetY);
+ else {
+ PdfFont font = ck.Font;
+ ascender = Math.Max(ascender, font.Font.GetFontDescriptor(BaseFont.ASCENT, font.Size));
+ }
+ }
+ return ascender;
+ }
+ }
+
+ /**
+ * Gets the biggest descender for all the fonts used
+ * in this line. Note that this is a negative number.
+ * @return maximum size of all the ascenders used in this line
+ */
+ public float Descender {
+ get {
+ float descender = 0;
+ foreach (PdfChunk ck in line) {
+ if (ck.IsImage())
+ descender = Math.Min(descender, ck.ImageOffsetY);
+ else {
+ PdfFont font = ck.Font;
+ descender = Math.Min(descender, font.Font.GetFontDescriptor(BaseFont.DESCENT, font.Size));
+ }
+ }
+ return descender;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfLiteral.cs b/iTechSharp/iTextSharp/text/pdf/PdfLiteral.cs
new file mode 100644
index 0000000..4e70fa7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfLiteral.cs
@@ -0,0 +1,101 @@
+using System;
+using System.IO;
+
+/*
+ * $Id: PdfLiteral.cs,v 1.3 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf
+{
+
+ /**
+ * a Literal
+ */
+
+ public class PdfLiteral : PdfObject {
+
+ private int position;
+
+ public PdfLiteral(string text) : base(0, text) {}
+
+ public PdfLiteral(byte[] b) : base(0, b) {}
+
+ public PdfLiteral(int type, string text) : base(type, text) {}
+
+ public PdfLiteral(int type, byte[] b) : base(type, b) {}
+
+ public PdfLiteral(int size) : base(0, (byte[])null) {
+ bytes = new byte[size];
+ for (int k = 0; k < size; ++k) {
+ bytes[k] = 32;
+ }
+ }
+
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ if (os is OutputStreamCounter)
+ position = ((OutputStreamCounter)os).Counter;
+ base.ToPdf(writer, os);
+ }
+
+ public int Position {
+ get {
+ return position;
+ }
+ }
+
+ public int PosLength {
+ get {
+ if (bytes != null)
+ return bytes.Length;
+ else
+ return 0;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfMediaClipData.cs b/iTechSharp/iTextSharp/text/pdf/PdfMediaClipData.cs
new file mode 100644
index 0000000..66d1abd
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfMediaClipData.cs
@@ -0,0 +1,63 @@
+using System;
+/*
+ * Copyright 2003 Galo Gimenez
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ public class PdfMediaClipData : PdfDictionary {
+
+ internal PdfMediaClipData(String file, PdfFileSpecification fs, String mimeType) {
+ Put(PdfName.TYPE,new PdfName("MediaClip"));
+ Put(PdfName.S, new PdfName("MCD"));
+ Put(PdfName.N, new PdfString("Media clip for "+file));
+ Put(new PdfName("CT"), new PdfString(mimeType));
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(new PdfName("TF"), new PdfString("TEMPACCESS"));
+ Put(new PdfName("P"), dic);
+ Put(PdfName.D, fs.Reference);
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfName.cs b/iTechSharp/iTextSharp/text/pdf/PdfName.cs
new file mode 100644
index 0000000..1a0951b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfName.cs
@@ -0,0 +1,1257 @@
+using System;
+using System.Text;
+
+/*
+ * $Id: PdfName.cs,v 1.31 2008/05/24 18:41:23 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfName
is an object that can be used as a name in a PDF-file.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.5 (page 39-40).
+ * PdfName
. The name length will be checked.
+ * @param name the new name
+ */
+ public PdfName(String name) : this(name, true) {
+ }
+
+ /**
+ * Constructs a new PdfName
.
+ * @param name the new name
+ * @param lengthCheck if true
check the lenght validity, if false
the name can
+ * have any length
+ */
+ public PdfName(string name, bool lengthCheck) : base(PdfObject.NAME) {
+ // The minimum number of characters in a name is 0, the maximum is 127 (the '/' not included)
+ int length = name.Length;
+ if (lengthCheck && length > 127) {
+ throw new ArgumentException("The name '" + name + "' is too long (" + length + " characters).");
+ }
+ // every special character has to be substituted
+ ByteBuffer pdfName = new ByteBuffer(length + 20);
+ pdfName.Append('/');
+ char[] chars = name.ToCharArray();
+ char character;
+ // loop over all the characters
+ foreach (char cc in chars) {
+ character = (char)(cc & 0xff);
+ // special characters are escaped (reference manual p.39)
+ switch (character) {
+ case ' ':
+ case '%':
+ case '(':
+ case ')':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ case '/':
+ case '#':
+ pdfName.Append('#');
+ pdfName.Append(System.Convert.ToString(character, 16));
+ break;
+ default:
+ if (character > 126 || character < 32) {
+ pdfName.Append('#');
+ if (character < 16)
+ pdfName.Append('0');
+ pdfName.Append(System.Convert.ToString(character, 16));
+ }
+ else
+ pdfName.Append(character);
+ break;
+ }
+ }
+ bytes = pdfName.ToByteArray();
+ }
+
+ public PdfName(byte[] bytes) : base(PdfObject.NAME, bytes) {
+ }
+
+ // methods
+
+ /**
+ * Compares this object with the specified object for order. Returns a
+ * negative int, zero, or a positive int as this object is less
+ * than, equal to, or greater than the specified object.true
if this object is the same as the obj
+ * argument; false
otherwise.
+ */
+ public override bool Equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj is PdfName)
+ return CompareTo(obj) == 0;
+ return false;
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * java.util.Hashtable
.
+ *
+ * @return a hash code value for this object.
+ */
+ public override int GetHashCode() {
+ int h = hash;
+ if (h == 0) {
+ int ptr = 0;
+ int len = bytes.Length;
+
+ for (int i = 0; i < len; i++)
+ h = 31*h + (bytes[ptr++] & 0xff);
+ hash = h;
+ }
+ return h;
+ }
+
+ /** Decodes an escaped name in the form "/AB#20CD" into "AB CD".
+ * @param name the name to decode
+ * @return the decoded name
+ */
+ public static string DecodeName(string name) {
+ StringBuilder buf = new StringBuilder();
+ int len = name.Length;
+ for (int k = 1; k < len; ++k) {
+ char c = name[k];
+ if (c == '#') {
+ c = (char)((PRTokeniser.GetHex(name[k + 1]) << 4) + PRTokeniser.GetHex(name[k + 2]));
+ k += 2;
+ }
+ buf.Append(c);
+ }
+ return buf.ToString();
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfNameTree.cs b/iTechSharp/iTextSharp/text/pdf/PdfNameTree.cs
new file mode 100644
index 0000000..a7617ef
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfNameTree.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Collections;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Creates a name tree.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfNameTree {
+
+ private const int leafSize = 64;
+
+ /**
+ * Creates a name tree.
+ * @param items the item of the name tree. The key is a String
+ * and the value is a PdfObject
. Note that although the
+ * keys are strings only the lower byte is used and no check is made for chars
+ * with the same lower byte and different upper byte. This will generate a wrong
+ * tree name.
+ * @param writer the writer
+ * @throws IOException on error
+ * @return the dictionary with the name tree. This dictionary is the one
+ * generally pointed to by the key /Dests, for example
+ */
+ public static PdfDictionary WriteTree(Hashtable items, PdfWriter writer) {
+ if (items.Count == 0)
+ return null;
+ String[] names = new String[items.Count];
+ items.Keys.CopyTo(names, 0);
+ Array.Sort(names);
+ if (names.Length <= leafSize) {
+ PdfDictionary dic = new PdfDictionary();
+ PdfArray ar = new PdfArray();
+ for (int k = 0; k < names.Length; ++k) {
+ ar.Add(new PdfString(names[k], null));
+ ar.Add((PdfObject)items[names[k]]);
+ }
+ dic.Put(PdfName.NAMES, ar);
+ return dic;
+ }
+ int skip = leafSize;
+ PdfIndirectReference[] kids = new PdfIndirectReference[(names.Length + leafSize - 1) / leafSize];
+ for (int k = 0; k < kids.Length; ++k) {
+ int offset = k * leafSize;
+ int end = Math.Min(offset + leafSize, names.Length);
+ PdfDictionary dic = new PdfDictionary();
+ PdfArray arr = new PdfArray();
+ arr.Add(new PdfString(names[offset], null));
+ arr.Add(new PdfString(names[end - 1], null));
+ dic.Put(PdfName.LIMITS, arr);
+ arr = new PdfArray();
+ for (; offset < end; ++offset) {
+ arr.Add(new PdfString(names[offset], null));
+ arr.Add((PdfObject)items[names[offset]]);
+ }
+ dic.Put(PdfName.NAMES, arr);
+ kids[k] = writer.AddToBody(dic).IndirectReference;
+ }
+ int top = kids.Length;
+ while (true) {
+ if (top <= leafSize) {
+ PdfArray arr = new PdfArray();
+ for (int k = 0; k < top; ++k)
+ arr.Add(kids[k]);
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.KIDS, arr);
+ return dic;
+ }
+ skip *= leafSize;
+ int tt = (names.Length + skip - 1 )/ skip;
+ for (int k = 0; k < tt; ++k) {
+ int offset = k * leafSize;
+ int end = Math.Min(offset + leafSize, top);
+ PdfDictionary dic = new PdfDictionary();
+ PdfArray arr = new PdfArray();
+ arr.Add(new PdfString(names[k * skip], null));
+ arr.Add(new PdfString(names[Math.Min((k + 1) * skip, names.Length) - 1], null));
+ dic.Put(PdfName.LIMITS, arr);
+ arr = new PdfArray();
+ for (; offset < end; ++offset) {
+ arr.Add(kids[offset]);
+ }
+ dic.Put(PdfName.KIDS, arr);
+ kids[k] = writer.AddToBody(dic).IndirectReference;
+ }
+ top = tt;
+ }
+ }
+
+ private static void IterateItems(PdfDictionary dic, Hashtable items) {
+ PdfArray nn = (PdfArray)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.NAMES));
+ if (nn != null) {
+ ArrayList arr = nn.ArrayList;
+ for (int k = 0; k < arr.Count; ++k) {
+ PdfString s = (PdfString)PdfReader.GetPdfObjectRelease((PdfObject)arr[k++]);
+ items[PdfEncodings.ConvertToString(s.GetBytes(), null)] = arr[k];
+ }
+ }
+ else if ((nn = (PdfArray)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.KIDS))) != null) {
+ ArrayList arr = nn.ArrayList;
+ for (int k = 0; k < arr.Count; ++k) {
+ PdfDictionary kid = (PdfDictionary)PdfReader.GetPdfObjectRelease((PdfObject)arr[k]);
+ IterateItems(kid, items);
+ }
+ }
+ }
+
+ public static Hashtable ReadTree(PdfDictionary dic) {
+ Hashtable items = new Hashtable();
+ if (dic != null)
+ IterateItems(dic, items);
+ return items;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfNull.cs b/iTechSharp/iTextSharp/text/pdf/PdfNull.cs
new file mode 100644
index 0000000..8e066a9
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfNull.cs
@@ -0,0 +1,85 @@
+using System;
+
+/*
+ * $Id: PdfNull.cs,v 1.4 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfNull
is the Null object represented by the keyword null.
+ * PdfNull
-object. */
+ public static PdfNull PDFNULL = new PdfNull();
+
+ // constructors
+
+ /**
+ * Constructs a PdfNull
-object.
+ * PdfNumber
provides two types of numbers, int and real.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.3 (page 37).
+ *
+ * @see PdfObject
+ * @see BadPdfFormatException
+ */
+
+ public class PdfNumber : PdfObject {
+
+ /** actual value of this PdfNumber
, represented as a double
*/
+ private double value;
+
+ // constructors
+
+ /**
+ * Constructs a PdfNumber
-object.
+ *
+ * @param content value of the new PdfNumber
-object
+ */
+
+ public PdfNumber(string content) : base(NUMBER) {
+ try {
+ value = Double.Parse(content.Trim(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ this.Content = content;
+ }
+ catch (Exception nfe){
+ throw new Exception(content + " is not a valid number - " + nfe.ToString());
+ }
+ }
+
+ /**
+ * Constructs a new int PdfNumber
-object.
+ *
+ * @param value value of the new PdfNumber
-object
+ */
+
+ public PdfNumber(int value) : base(NUMBER) {
+ this.value = value;
+ this.Content = value.ToString();
+ }
+
+ /**
+ * Constructs a new REAL PdfNumber
-object.
+ *
+ * @param value value of the new PdfNumber
-object
+ */
+
+ public PdfNumber(double value) : base(NUMBER) {
+ this.value = value;
+ Content = ByteBuffer.FormatDouble(value);
+ }
+
+ /**
+ * Constructs a new REAL PdfNumber
-object.
+ *
+ * @param value value of the new PdfNumber
-object
+ */
+
+ public PdfNumber(float value) : this((double)value) {}
+
+ // methods returning the value of this object
+
+ /**
+ * Returns the primitive int
value of this object.
+ *
+ * @return a value
+ */
+
+ public int IntValue {
+ get {
+ return (int) value;
+ }
+ }
+
+ /**
+ * Returns the primitive double
value of this object.
+ *
+ * @return a value
+ */
+
+ public double DoubleValue {
+ get {
+ return value;
+ }
+ }
+
+ public float FloatValue {
+ get {
+ return (float)value;
+ }
+ }
+
+ // other methods
+
+ /**
+ * Increments the value of the PdfNumber
-object with 1.
+ */
+
+ public void Increment() {
+ value += 1.0;
+ Content = ByteBuffer.FormatDouble(value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfNumberTree.cs b/iTechSharp/iTextSharp/text/pdf/PdfNumberTree.cs
new file mode 100644
index 0000000..d41c1af
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfNumberTree.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections;
+/*
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Creates a number tree.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfNumberTree {
+
+ private const int leafSize = 64;
+
+ /**
+ * Creates a number tree.
+ * @param items the item of the number tree. The key is an Integer
+ * and the value is a PdfObject
.
+ * @param writer the writer
+ * @throws IOException on error
+ * @return the dictionary with the number tree.
+ */
+ public static PdfDictionary WriteTree(Hashtable items, PdfWriter writer) {
+ if (items.Count == 0)
+ return null;
+ int[] numbers = new int[items.Count];
+ items.Keys.CopyTo(numbers, 0);
+ Array.Sort(numbers);
+ if (numbers.Length <= leafSize) {
+ PdfDictionary dic = new PdfDictionary();
+ PdfArray ar = new PdfArray();
+ for (int k = 0; k < numbers.Length; ++k) {
+ ar.Add(new PdfNumber(numbers[k]));
+ ar.Add((PdfObject)items[numbers[k]]);
+ }
+ dic.Put(PdfName.NUMS, ar);
+ return dic;
+ }
+ int skip = leafSize;
+ PdfIndirectReference[] kids = new PdfIndirectReference[(numbers.Length + leafSize - 1) / leafSize];
+ for (int k = 0; k < kids.Length; ++k) {
+ int offset = k * leafSize;
+ int end = Math.Min(offset + leafSize, numbers.Length);
+ PdfDictionary dic = new PdfDictionary();
+ PdfArray arr = new PdfArray();
+ arr.Add(new PdfNumber(numbers[offset]));
+ arr.Add(new PdfNumber(numbers[end - 1]));
+ dic.Put(PdfName.LIMITS, arr);
+ arr = new PdfArray();
+ for (; offset < end; ++offset) {
+ arr.Add(new PdfNumber(numbers[offset]));
+ arr.Add((PdfObject)items[numbers[offset]]);
+ }
+ dic.Put(PdfName.NUMS, arr);
+ kids[k] = writer.AddToBody(dic).IndirectReference;
+ }
+ int top = kids.Length;
+ while (true) {
+ if (top <= leafSize) {
+ PdfArray arr = new PdfArray();
+ for (int k = 0; k < top; ++k)
+ arr.Add(kids[k]);
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.KIDS, arr);
+ return dic;
+ }
+ skip *= leafSize;
+ int tt = (numbers.Length + skip - 1 )/ skip;
+ for (int k = 0; k < tt; ++k) {
+ int offset = k * leafSize;
+ int end = Math.Min(offset + leafSize, top);
+ PdfDictionary dic = new PdfDictionary();
+ PdfArray arr = new PdfArray();
+ arr.Add(new PdfNumber(numbers[k * skip]));
+ arr.Add(new PdfNumber(numbers[Math.Min((k + 1) * skip, numbers.Length) - 1]));
+ dic.Put(PdfName.LIMITS, arr);
+ arr = new PdfArray();
+ for (; offset < end; ++offset) {
+ arr.Add(kids[offset]);
+ }
+ dic.Put(PdfName.KIDS, arr);
+ kids[k] = writer.AddToBody(dic).IndirectReference;
+ }
+ top = tt;
+ }
+ }
+
+ private static void IterateItems(PdfDictionary dic, Hashtable items) {
+ PdfArray nn = (PdfArray)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.NUMS));
+ if (nn != null) {
+ ArrayList arr = nn.ArrayList;
+ for (int k = 0; k < arr.Count; ++k) {
+ PdfNumber s = (PdfNumber)PdfReader.GetPdfObjectRelease((PdfObject)arr[k++]);
+ items[s.IntValue] = arr[k];
+ }
+ }
+ else if ((nn = (PdfArray)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.KIDS))) != null) {
+ ArrayList arr = nn.ArrayList;
+ for (int k = 0; k < arr.Count; ++k) {
+ PdfDictionary kid = (PdfDictionary)PdfReader.GetPdfObjectRelease((PdfObject)arr[k]);
+ IterateItems(kid, items);
+ }
+ }
+ }
+
+ public static Hashtable ReadTree(PdfDictionary dic) {
+ Hashtable items = new Hashtable();
+ if (dic != null)
+ IterateItems(dic, items);
+ return items;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfOCProperties.cs b/iTechSharp/iTextSharp/text/pdf/PdfOCProperties.cs
new file mode 100644
index 0000000..0b5de68
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfOCProperties.cs
@@ -0,0 +1,52 @@
+using System;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ public class PdfOCProperties : PdfDictionary {
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfObject.cs b/iTechSharp/iTextSharp/text/pdf/PdfObject.cs
new file mode 100644
index 0000000..f08296d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfObject.cs
@@ -0,0 +1,369 @@
+/*
+ * $Id: PdfObject.cs,v 1.3 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+using System;
+using System.IO;
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfObject
is the abstract baseclass of all PDF objects.
+ *
+ * All these basic PDF objects are described in the 'Portable Document Format
+ * Reference Manual version 1.3' Chapter 4 (pages 37-54).
+ *
+ * @see PdfNull
+ * @see Pdfbool
+ * @see PdfNumber
+ * @see PdfString
+ * @see PdfName
+ * @see PdfArray
+ * @see PdfDictionary
+ * @see PdfStream
+ * @see PdfIndirectReference
+ */
+
+ public abstract class PdfObject {
+
+ // static membervariables (all the possible types of a PdfObject)
+
+ /** a possible type of PdfObject
*/
+ public const int BOOLEAN = 1;
+
+ /** a possible type of PdfObject
*/
+ public const int NUMBER = 2;
+
+ /** a possible type of PdfObject
*/
+ public const int STRING = 3;
+
+ /** a possible type of PdfObject
*/
+ public const int NAME = 4;
+
+ /** a possible type of PdfObject
*/
+ public const int ARRAY = 5;
+
+ /** a possible type of PdfObject
*/
+ public const int DICTIONARY = 6;
+
+ /** a possible type of PdfObject
*/
+ public const int STREAM = 7;
+
+ /** a possible type of PdfObject
*/
+ public const int NULL = 8;
+
+ /** a possible type of PdfObject
*/
+ public const int INDIRECT = 10;
+
+ /** This is an empty string used for the PdfNull
-object and for an empty PdfString
-object. */
+ public const string NOTHING = "";
+
+ /** This is the default encoding to be used for converting strings into bytes and vice versa.
+ * The default encoding is PdfDocEcoding.
+ */
+ public const string TEXT_PDFDOCENCODING = "PDF";
+
+ /** This is the encoding to be used to output text in Unicode. */
+ public const string TEXT_UNICODE = "UnicodeBig";
+
+ // membervariables
+
+ /** the content of this PdfObject
*/
+ protected byte[] bytes;
+
+ /** the type of this PdfObject
*/
+ protected int type;
+
+ /**
+ * Holds value of property indRef.
+ */
+ protected PRIndirectReference indRef;
+
+ // constructors
+
+ /**
+ * Constructs a PdfObject
of a certain type without any content.
+ *
+ * @param type type of the new PdfObject
+ */
+
+ protected PdfObject(int type) {
+ this.type = type;
+ }
+
+ /**
+ * Constructs a PdfObject
of a certain type with a certain content.
+ *
+ * @param type type of the new PdfObject
+ * @param content content of the new PdfObject
as a String
.
+ */
+
+ protected PdfObject(int type, string content) {
+ this.type = type;
+ bytes = PdfEncodings.ConvertToBytes(content, null);
+ }
+
+ /**
+ * Constructs a PdfObject
of a certain type with a certain content.
+ *
+ * @param type type of the new PdfObject
+ * @param bytes content of the new PdfObject
as an array of byte
.
+ */
+
+ protected PdfObject(int type, byte[] bytes) {
+ this.bytes = bytes;
+ this.type = type;
+ }
+
+ // methods dealing with the content of this object
+
+ /**
+ * Writes the PDF representation of this PdfObject
as an array of byte
s to the writer.
+ * @param writer for backwards compatibility
+ * @param os the outputstream to write the bytes to.
+ * @throws IOException
+ */
+
+ public virtual void ToPdf(PdfWriter writer, Stream os) {
+ if (bytes != null)
+ os.Write(bytes, 0, bytes.Length);
+ }
+
+ /**
+ * Gets the presentation of this object in a byte array
+ * @return a byte array
+ */
+ public virtual byte[] GetBytes() {
+ return bytes;
+ }
+
+ /**
+ * Can this object be in an object stream?
+ * @return true if this object can be in an object stream.
+ */
+ public bool CanBeInObjStm() {
+ return (type >= 1 && type <= 6) || type == 8;
+ }
+
+ /**
+ * Returns the length of the PDF representation of the PdfObject
.
+ * PdfString
and PdfStream
,
+ * this method differs from the method length
because length
+ * returns the length of the actual content of the PdfObject
.String
-representation of this PdfObject
.
+ *
+ * @return a String
+ */
+
+ public override string ToString() {
+ if (bytes == null)
+ return "";
+ else
+ return PdfEncodings.ConvertToString(bytes, null);
+ }
+
+ /**
+ * Returns the length of the actual content of the PdfObject
.
+ * PdfString
and PdfStream
,
+ * this method differs from the method pdfLength
because pdfLength
+ * returns the length of the PDF representation of the object, not of the actual content
+ * as does the method length
.PdfObject
.
+ *
+ * @param content the new content of this PdfObject
+ */
+
+ protected string Content {
+ set {
+ bytes = PdfEncodings.ConvertToBytes(value, null);
+ }
+ }
+
+ // methods dealing with the type of this object
+
+ /**
+ * Returns the type of this PdfObject
.
+ *
+ * @return a type
+ */
+
+ public int Type {
+ get {
+ return type;
+ }
+ }
+
+ /**
+ * Checks if this PdfObject
is of the type PdfNull
.
+ *
+ * @return true
or false
+ */
+
+ public bool IsNull() {
+ return (this.type == NULL);
+ }
+
+ /**
+ * Checks if this PdfObject
is of the type PdfBoolean
.
+ *
+ * @return true
or false
+ */
+
+ public bool IsBoolean() {
+ return (this.type == BOOLEAN);
+ }
+
+ /**
+ * Checks if this PdfObject
is of the type PdfNumber
.
+ *
+ * @return true
or false
+ */
+
+ public bool IsNumber() {
+ return (this.type == NUMBER);
+ }
+
+ /**
+ * Checks if this PdfObject
is of the type PdfString
.
+ *
+ * @return true
or false
+ */
+
+ public bool IsString() {
+ return (this.type == STRING);
+ }
+
+ /**
+ * Checks if this PdfObject
is of the type PdfName
.
+ *
+ * @return true
or false
+ */
+
+ public bool IsName() {
+ return (this.type == NAME);
+ }
+
+ /**
+ * Checks if this PdfObject
is of the type PdfArray
.
+ *
+ * @return true
or false
+ */
+
+ public bool IsArray() {
+ return (this.type == ARRAY);
+ }
+
+ /**
+ * Checks if this PdfObject
is of the type PdfDictionary
.
+ *
+ * @return true
or false
+ */
+
+ public bool IsDictionary() {
+ return (this.type == DICTIONARY);
+ }
+
+ /**
+ * Checks if this PdfObject
is of the type PdfStream
.
+ *
+ * @return true
or false
+ */
+
+ public bool IsStream() {
+ return (this.type == STREAM);
+ }
+
+ /**
+ * Checks if this is an indirect object.
+ * @return true if this is an indirect object
+ */
+ public bool IsIndirect() {
+ return (this.type == INDIRECT);
+ }
+
+ public PRIndirectReference IndRef {
+ get {
+ return indRef;
+ }
+ set {
+ indRef = value;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfOutline.cs b/iTechSharp/iTextSharp/text/pdf/PdfOutline.cs
new file mode 100644
index 0000000..2061f4a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfOutline.cs
@@ -0,0 +1,485 @@
+using System;
+using System.Text;
+using System.IO;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfOutline.cs,v 1.5 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfOutline
is an object that represents a PDF outline entry.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 6.7 (page 104-106)
+ *
+ * @see PdfDictionary
+ */
+
+ public class PdfOutline : PdfDictionary {
+
+ // membervariables
+
+ /** the PdfIndirectReference
of this object */
+ private PdfIndirectReference reference;
+
+ /** value of the Count-key */
+ private int count = 0;
+
+ /** value of the Parent-key */
+ private PdfOutline parent;
+
+ /** value of the Destination-key */
+ private PdfDestination destination;
+
+ /** The PdfAction
for this outline.
+ */
+ private PdfAction action;
+
+ protected ArrayList kids = new ArrayList();
+
+ protected PdfWriter writer;
+
+ /** Holds value of property tag. */
+ private string tag;
+
+ /** Holds value of property open. */
+ private bool open;
+
+ /** Holds value of property color. */
+ private Color color;
+
+ /** Holds value of property style. */
+ private int style = 0;
+
+ // constructors
+
+ /**
+ * Constructs a PdfOutline
.
+ * outlines object
.
+ */
+
+ internal PdfOutline(PdfWriter writer) : base(OUTLINES) {
+ open = true;
+ parent = null;
+ this.writer = writer;
+ }
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
. The open mode is
+ * true
.
+ *
+ * @param parent the parent of this outline item
+ * @param action the PdfAction
for this outline item
+ * @param title the title of this outline item
+ */
+
+ public PdfOutline(PdfOutline parent, PdfAction action, string title) : this(parent, action, title, true) {}
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
.
+ *
+ * @param parent the parent of this outline item
+ * @param action the PdfAction
for this outline item
+ * @param title the title of this outline item
+ * @param open true
if the children are visible
+ */
+ public PdfOutline(PdfOutline parent, PdfAction action, string title, bool open) : base() {
+ this.action = action;
+ InitOutline(parent, title, open);
+ }
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
. The open mode is
+ * true
.
+ *
+ * @param parent the parent of this outline item
+ * @param destination the destination for this outline item
+ * @param title the title of this outline item
+ */
+
+ public PdfOutline(PdfOutline parent, PdfDestination destination, string title) : this(parent, destination, title, true) {}
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
.
+ *
+ * @param parent the parent of this outline item
+ * @param destination the destination for this outline item
+ * @param title the title of this outline item
+ * @param open true
if the children are visible
+ */
+ public PdfOutline(PdfOutline parent, PdfDestination destination, string title, bool open) : base() {
+ this.destination = destination;
+ InitOutline(parent, title, open);
+ }
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
. The open mode is
+ * true
.
+ *
+ * @param parent the parent of this outline item
+ * @param action the PdfAction
for this outline item
+ * @param title the title of this outline item
+ */
+ public PdfOutline(PdfOutline parent, PdfAction action, PdfString title) : this(parent, action, title, true) {}
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
.
+ *
+ * @param parent the parent of this outline item
+ * @param action the PdfAction
for this outline item
+ * @param title the title of this outline item
+ * @param open true
if the children are visible
+ */
+ public PdfOutline(PdfOutline parent, PdfAction action, PdfString title, bool open) : this(parent, action, title.ToString(), open) {}
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
. The open mode is
+ * true
.
+ *
+ * @param parent the parent of this outline item
+ * @param destination the destination for this outline item
+ * @param title the title of this outline item
+ */
+
+ public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title) : this(parent, destination, title, true) {}
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
.
+ *
+ * @param parent the parent of this outline item
+ * @param destination the destination for this outline item
+ * @param title the title of this outline item
+ * @param open true
if the children are visible
+ */
+ public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title, bool open) : this(parent, destination, title.ToString(), true) {}
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
. The open mode is
+ * true
.
+ *
+ * @param parent the parent of this outline item
+ * @param action the PdfAction
for this outline item
+ * @param title the title of this outline item
+ */
+
+ public PdfOutline(PdfOutline parent, PdfAction action, Paragraph title) : this(parent, action, title, true) {}
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
.
+ *
+ * @param parent the parent of this outline item
+ * @param action the PdfAction
for this outline item
+ * @param title the title of this outline item
+ * @param open true
if the children are visible
+ */
+ public PdfOutline(PdfOutline parent, PdfAction action, Paragraph title, bool open) : base() {
+ StringBuilder buf = new StringBuilder();
+ foreach (Chunk chunk in title.Chunks) {
+ buf.Append(chunk.Content);
+ }
+ this.action = action;
+ InitOutline(parent, buf.ToString(), open);
+ }
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
. The open mode is
+ * true
.
+ *
+ * @param parent the parent of this outline item
+ * @param destination the destination for this outline item
+ * @param title the title of this outline item
+ */
+
+ public PdfOutline(PdfOutline parent, PdfDestination destination, Paragraph title) : this(parent, destination, title, true) {}
+
+ /**
+ * Constructs a PdfOutline
.
+ * outline entry
.
+ *
+ * @param parent the parent of this outline item
+ * @param destination the destination for this outline item
+ * @param title the title of this outline item
+ * @param open true
if the children are visible
+ */
+ public PdfOutline(PdfOutline parent, PdfDestination destination, Paragraph title, bool open) : base() {
+ StringBuilder buf = new StringBuilder();
+ foreach (Chunk chunk in title.Chunks) {
+ buf.Append(chunk.Content);
+ }
+ this.destination = destination;
+ InitOutline(parent, buf.ToString(), open);
+ }
+
+
+ // methods
+
+ /** Helper for the constructors.
+ * @param parent the parent outline
+ * @param title the title for this outline
+ * @param open true
if the children are visible
+ */
+ internal void InitOutline(PdfOutline parent, string title, bool open) {
+ this.open = open;
+ this.parent = parent;
+ writer = parent.writer;
+ Put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE));
+ parent.AddKid(this);
+ if (destination != null && !destination.HasPage()) // bugfix Finn Bock
+ SetDestinationPage(writer.CurrentPage);
+ }
+
+ /**
+ * Gets the indirect reference of this PdfOutline
.
+ *
+ * @return the PdfIndirectReference
to this outline.
+ */
+
+ public PdfIndirectReference IndirectReference {
+ get {
+ return reference;
+ }
+
+ set {
+ this.reference = value;
+ }
+ }
+
+ /**
+ * Gets the parent of this PdfOutline
.
+ *
+ * @return the PdfOutline
that is the parent of this outline.
+ */
+
+ public PdfOutline Parent {
+ get {
+ return parent;
+ }
+ }
+
+ /**
+ * Set the page of the PdfDestination
-object.
+ *
+ * @param pageReference indirect reference to the page
+ * @return true
if this page was set as the PdfDestination
-page.
+ */
+
+ public bool SetDestinationPage(PdfIndirectReference pageReference) {
+ if (destination == null) {
+ return false;
+ }
+ return destination.AddPage(pageReference);
+ }
+
+ /**
+ * Gets the destination for this outline.
+ * @return the destination
+ */
+ public PdfDestination PdfDestination {
+ get {
+ return destination;
+ }
+ }
+
+ internal int Count {
+ get {
+ return count;
+ }
+
+ set {
+ this.count = value;
+ }
+ }
+
+ /**
+ * returns the level of this outline.
+ *
+ * @return a level
+ */
+
+ public int Level {
+ get {
+ if (parent == null) {
+ return 0;
+ }
+ return (parent.Level + 1);
+ }
+ }
+
+ /**
+ * Returns the PDF representation of this PdfOutline
.
+ *
+ * @param writer the encryption information
+ * @param os
+ * @throws IOException
+ */
+
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ if (color != null && !color.Equals(Color.BLACK)) {
+ Put(PdfName.C, new PdfArray(new float[]{color.R/255f,color.G/255f,color.B/255f}));
+ }
+ int flag = 0;
+ if ((style & Font.BOLD) != 0)
+ flag |= 2;
+ if ((style & Font.ITALIC) != 0)
+ flag |= 1;
+ if (flag != 0)
+ Put(PdfName.F, new PdfNumber(flag));
+ if (parent != null) {
+ Put(PdfName.PARENT, parent.IndirectReference);
+ }
+ if (destination != null && destination.HasPage()) {
+ Put(PdfName.DEST, destination);
+ }
+ if (action != null)
+ Put(PdfName.A, action);
+ if (count != 0) {
+ Put(PdfName.COUNT, new PdfNumber(count));
+ }
+ base.ToPdf(writer, os);
+ }
+
+ public void AddKid(PdfOutline outline) {
+ kids.Add(outline);
+ }
+
+ public ArrayList Kids {
+ get {
+ return kids;
+ }
+
+ set {
+ this.kids = value;
+ }
+ }
+
+ /** Getter for property tag.
+ * @return Value of property tag.
+ */
+ public string Tag {
+ get {
+ return tag;
+ }
+
+ set {
+ this.tag = value;
+ }
+ }
+
+ public string Title {
+ get {
+ PdfString title = (PdfString)Get(PdfName.TITLE);
+ return title.ToString();
+ }
+
+ set {
+ Put(PdfName.TITLE, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ /** Setter for property open.
+ * @param open New value of property open.
+ */
+ public bool Open {
+ set {
+ this.open = value;
+ }
+ get {
+ return open;
+ }
+ }
+
+ public Color Color {
+ get {
+ return color;
+ }
+ set {
+ color = value;
+ }
+ }
+
+ public int Style {
+ get {
+ return style;
+ }
+ set {
+ style = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPCell.cs b/iTechSharp/iTextSharp/text/pdf/PdfPCell.cs
new file mode 100644
index 0000000..7bd36ae
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPCell.cs
@@ -0,0 +1,696 @@
+using System;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.pdf.events;
+
+/*
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** A cell in a PdfPTable.
+ */
+
+ public class PdfPCell : Rectangle{
+
+ private ColumnText column = new ColumnText(null);
+
+ /** Holds value of property verticalAlignment. */
+ private int verticalAlignment = Element.ALIGN_TOP;
+
+ /** Holds value of property paddingLeft. */
+ private float paddingLeft = 2;
+
+ /** Holds value of property paddingLeft. */
+ private float paddingRight = 2;
+
+ /** Holds value of property paddingTop. */
+ private float paddingTop = 2;
+
+ /** Holds value of property paddingBottom. */
+ private float paddingBottom = 2;
+
+ /** Holds value of property fixedHeight. */
+ private float fixedHeight = 0;
+
+ /** Holds value of property noWrap. */
+ private bool noWrap = false;
+
+ /** Holds value of property table. */
+ private PdfPTable table;
+
+ /** Holds value of property minimumHeight. */
+ private float minimumHeight;
+
+ /** Holds value of property colspan. */
+ private int colspan = 1;
+
+ /** Holds value of property image. */
+ private Image image;
+
+ /** Holds value of property cellEvent. */
+ private IPdfPCellEvent cellEvent;
+
+ /** Holds value of property useDescender. */
+ private bool useDescender;
+
+ /** Increases padding to include border if true */
+ private bool useBorderPadding = false;
+
+
+ /** The text in the cell. */
+ protected Phrase phrase;
+
+ /** Constructs an empty PdfPCell
.
+ * The default padding is 2.
+ */
+ public PdfPCell() : base(0, 0, 0, 0) {
+ borderWidth = 0.5f;
+ border = BOX;
+ column.SetLeading(0, 1);
+ }
+
+ /** Constructs a PdfPCell
with a Phrase
.
+ * The default padding is 2.
+ * @param phrase the text
+ */
+ public PdfPCell(Phrase phrase) : base(0, 0, 0, 0) {
+ borderWidth = 0.5f;
+ border = BOX;
+ column.AddText(this.phrase = phrase);
+ column.SetLeading(0, 1);
+ }
+
+ /** Constructs a PdfPCell
with an Image
.
+ * The default padding is 0.
+ * @param image the Image
+ */
+ public PdfPCell(Image image) : this(image, false) {
+ }
+
+ /** Constructs a PdfPCell
with an Image
.
+ * The default padding is 0.25 for a border width of 0.5.
+ * @param image the Image
+ * @param fit true
to fit the image to the cell
+ */
+ public PdfPCell(Image image, bool fit) : base(0, 0, 0, 0) {
+ if (fit) {
+ borderWidth = 0.5f;
+ border = BOX;
+ this.image = image;
+ column.SetLeading(0, 1);
+ Padding = borderWidth / 2;
+ }
+ else {
+ borderWidth = 0.5f;
+ border = BOX;
+ column.AddText(this.phrase = new Phrase(new Chunk(image, 0, 0)));
+ column.SetLeading(0, 1);
+ Padding = 0;
+ }
+ }
+
+ /** Constructs a PdfPCell
with a PdfPtable
.
+ * This constructor allows nested tables.
+ * The default padding is 0.
+ * @param table The PdfPTable
+ */
+ public PdfPCell(PdfPTable table) : this(table, null) {
+ }
+
+ /** Constructs a PdfPCell
with a PdfPtable
.
+ * This constructor allows nested tables.
+ *
+ * @param table The PdfPTable
+ * @param style The style to apply to the cell (you could use getDefaultCell())
+ * @since 2.1.0
+ */
+ public PdfPCell(PdfPTable table, PdfPCell style) : base(0, 0, 0, 0) {
+ borderWidth = 0.5f;
+ border = BOX;
+ column.SetLeading(0, 1);
+ this.table = table;
+ table.WidthPercentage = 100;
+ table.ExtendLastRow = true;
+ column.AddElement(table);
+ if (style != null) {
+ CloneNonPositionParameters(style);
+ verticalAlignment = style.verticalAlignment;
+ paddingLeft = style.paddingLeft;
+ paddingRight = style.paddingRight;
+ paddingTop = style.paddingTop;
+ paddingBottom = style.paddingBottom;
+ colspan = style.colspan;
+ cellEvent = style.cellEvent;
+ useDescender = style.useDescender;
+ useBorderPadding = style.useBorderPadding;
+ rotation = style.rotation;
+ }
+ else {
+ Padding = 0;
+ }
+ }
+
+ /** Constructs a deep copy of a PdfPCell
.
+ * @param cell the PdfPCell
to duplicate
+ */
+ public PdfPCell(PdfPCell cell) : base(cell.llx, cell.lly, cell.urx, cell.ury) {
+ CloneNonPositionParameters(cell);
+ verticalAlignment = cell.verticalAlignment;
+ paddingLeft = cell.paddingLeft;
+ paddingRight = cell.paddingRight;
+ paddingTop = cell.paddingTop;
+ paddingBottom = cell.paddingBottom;
+ phrase = cell.phrase;
+ fixedHeight = cell.fixedHeight;
+ minimumHeight = cell.minimumHeight;
+ noWrap = cell.noWrap;
+ colspan = cell.colspan;
+ if (cell.table != null)
+ table = new PdfPTable(cell.table);
+ image = Image.GetInstance(cell.image);
+ cellEvent = cell.cellEvent;
+ useDescender = cell.useDescender;
+ column = ColumnText.Duplicate(cell.column);
+ useBorderPadding = cell.useBorderPadding;
+ rotation = cell.rotation;
+ }
+
+ /**
+ * Adds an iText element to the cell.
+ * @param element
+ */
+ public void AddElement(IElement element) {
+ if (table != null) {
+ table = null;
+ column.SetText(null);
+ }
+ column.AddElement(element);
+ }
+
+ /** Gets the Phrase
from this cell.
+ * @return the Phrase
+ */
+ public Phrase Phrase {
+ get {
+ return phrase;
+ }
+ set {
+ table = null;
+ image = null;
+ column.SetText(this.phrase = value);
+ }
+ }
+
+ /** Gets the horizontal alignment for the cell.
+ * @return the horizontal alignment for the cell
+ */
+ public int HorizontalAlignment {
+ get {
+ return column.Alignment;
+ }
+ set {
+ column.Alignment = value;
+ }
+ }
+
+ /** Gets the vertical alignment for the cell.
+ * @return the vertical alignment for the cell
+ */
+ public int VerticalAlignment {
+ get {
+ return verticalAlignment;
+ }
+ set {
+ verticalAlignment = value;
+ if (table != null)
+ table.ExtendLastRow = (verticalAlignment == Element.ALIGN_TOP);
+ }
+ }
+
+ /** Gets the effective left padding. This will include
+ * the left border width if {@link #UseBorderPadding} is true.
+ * @return effective value of property paddingLeft.
+ */
+ public float EffectivePaddingLeft {
+ get {
+ return paddingLeft + (UseBorderPadding ? (BorderWidthLeft/(UseVariableBorders?1f:2f)) : 0);
+ }
+ }
+
+ /**
+ * @return Value of property paddingLeft.
+ */
+ public float PaddingLeft {
+ get {
+ return paddingLeft;
+ }
+ set {
+ paddingLeft = value;
+ }
+ }
+
+ /** Gets the effective right padding. This will include
+ * the right border width if {@link #UseBorderPadding} is true.
+ * @return effective value of property paddingRight.
+ */
+ public float EffectivePaddingRight {
+ get {
+ return paddingRight + (UseBorderPadding ? (BorderWidthRight/(UseVariableBorders?1f:2f)) : 0);
+ }
+ }
+
+ /**
+ * Getter for property paddingRight.
+ * @return Value of property paddingRight.
+ */
+ public float PaddingRight {
+ get {
+ return paddingRight;
+ }
+ set {
+ paddingRight = value;
+ }
+ }
+
+ /** Gets the effective top padding. This will include
+ * the top border width if {@link #isUseBorderPadding()} is true.
+ * @return effective value of property paddingTop.
+ */
+ public float EffectivePaddingTop {
+ get {
+ return paddingTop + (UseBorderPadding ? (BorderWidthTop/(UseVariableBorders?1f:2f)) : 0);
+ }
+ }
+
+ /**
+ * Getter for property paddingTop.
+ * @return Value of property paddingTop.
+ */
+ public float PaddingTop {
+ get {
+ return paddingTop;
+ }
+ set {
+ paddingTop = value;
+ }
+ }
+
+ /**
+ /** Gets the effective bottom padding. This will include
+ * the bottom border width if {@link #UseBorderPadding} is true.
+ * @return effective value of property paddingBottom.
+ */
+ public float EffectivePaddingBottom {
+ get {
+ return paddingBottom + (UseBorderPadding ? (BorderWidthBottom/(UseVariableBorders?1f:2f)) : 0);
+ }
+ }
+
+ /**
+ * Getter for property paddingBottom.
+ * @return Value of property paddingBottom.
+ */
+ public float PaddingBottom {
+ get {
+ return paddingBottom;
+ }
+ set {
+ paddingBottom = value;
+ }
+ }
+
+ /**
+ * Sets the padding of the contents in the cell (space between content and border).
+ * @param padding
+ */
+ public float Padding {
+ set {
+ paddingBottom = value;
+ paddingTop = value;
+ paddingLeft = value;
+ paddingRight = value;
+ }
+ }
+
+ /**
+ * Adjusts effective padding to include border widths.
+ * @param use adjust effective padding if true
+ */
+ public bool UseBorderPadding {
+ set {
+ useBorderPadding = value;
+ }
+ get {
+ return useBorderPadding;
+ }
+ }
+
+ /**
+ * Sets the leading fixed and variable. The resultant leading will be
+ * fixedLeading+multipliedLeading*maxFontSize where maxFontSize is the
+ * size of the bigest font in the line.
+ * @param fixedLeading the fixed leading
+ * @param multipliedLeading the variable leading
+ */
+ public void SetLeading(float fixedLeading, float multipliedLeading) {
+ column.SetLeading(fixedLeading, multipliedLeading);
+ }
+
+ /**
+ * Gets the fixed leading
+ * @return the leading
+ */
+ public float Leading {
+ get {
+ return column.Leading;
+ }
+ }
+
+ /**
+ * Gets the variable leading
+ * @return the leading
+ */
+ public float MultipliedLeading {
+ get {
+ return column.MultipliedLeading;
+ }
+ }
+
+ /**
+ * Gets the first paragraph line indent.
+ * @return the indent
+ */
+ public float Indent {
+ get {
+ return column.Indent;
+ }
+ set {
+ column.Indent = value;
+ }
+ }
+
+ /**
+ * Gets the extra space between paragraphs.
+ * @return the extra space between paragraphs
+ */
+ public float ExtraParagraphSpace {
+ get {
+ return column.ExtraParagraphSpace;
+ }
+ set {
+ column.ExtraParagraphSpace = value;
+ }
+ }
+
+ /**
+ * Getter for property fixedHeight.
+ * @return Value of property fixedHeight.
+ */
+ public float FixedHeight {
+ get {
+ return fixedHeight;
+ }
+ set {
+ fixedHeight = value;
+ minimumHeight = 0;
+ }
+ }
+
+ /**
+ * Setter for property noWrap.
+ * @param noWrap New value of property noWrap.
+ */
+ public bool NoWrap {
+ set {
+ noWrap = value;
+ }
+ get {
+ return noWrap;
+ }
+ }
+
+ /**
+ * Getter for property table.
+ * @return Value of property table.
+ */
+ internal PdfPTable Table {
+ get {
+ return table;
+ }
+ set {
+ table = value;
+ column.SetText(null);
+ image = null;
+ if (table != null) {
+ table.ExtendLastRow = (verticalAlignment == Element.ALIGN_TOP);
+ column.AddElement(table);
+ table.WidthPercentage = 100;
+ }
+ }
+ }
+
+ /** Getter for property minimumHeight.
+ * @return Value of property minimumHeight.
+ */
+ public float MinimumHeight {
+ get {
+ return minimumHeight;
+ }
+ set {
+ this.minimumHeight = value;
+ fixedHeight = 0;
+ }
+ }
+
+ /** Getter for property colspan.
+ * @return Value of property colspan.
+ */
+ public int Colspan {
+ get {
+ return colspan;
+ }
+ set {
+ colspan = value;
+ }
+ }
+
+ /**
+ * Gets the following paragraph lines indent.
+ * @return the indent
+ */
+ public float FollowingIndent {
+ get {
+ return column.FollowingIndent;
+ }
+ set {
+ column.FollowingIndent = value;
+ }
+ }
+
+ /**
+ * Gets the right paragraph lines indent.
+ * @return the indent
+ */
+ public float RightIndent {
+ get {
+ return column.RightIndent;
+ }
+ set {
+ column.RightIndent = value;
+ }
+ }
+
+ /** Gets the space/character extra spacing ratio for
+ * fully justified text.
+ * @return the space/character extra spacing ratio
+ */
+ public float SpaceCharRatio {
+ get {
+ return column.SpaceCharRatio;
+ }
+ set {
+ column.SpaceCharRatio = value;
+ }
+ }
+
+ /**
+ * Gets the run direction of the text content in the cell
+ * @return One of the following values: PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL.
+ */
+ public int RunDirection {
+ get {
+ return column.RunDirection;
+ }
+ set {
+ column.RunDirection = value;
+ }
+ }
+
+ /** Getter for property image.
+ * @return Value of property image.
+ *
+ */
+ public Image Image {
+ get {
+ return this.image;
+ }
+ set {
+ column.SetText(null);
+ table = null;
+ this.image = value;
+ }
+ }
+
+ /** Gets the cell event for this cell.
+ * @return the cell event
+ *
+ */
+ public IPdfPCellEvent CellEvent {
+ get {
+ return this.cellEvent;
+ }
+ set {
+ if (value == null) this.cellEvent = null;
+ else if (this.cellEvent == null) this.cellEvent = value;
+ else if (this.cellEvent is PdfPCellEventForwarder) ((PdfPCellEventForwarder)this.cellEvent).AddCellEvent(value);
+ else {
+ PdfPCellEventForwarder forward = new PdfPCellEventForwarder();
+ forward.AddCellEvent(this.cellEvent);
+ forward.AddCellEvent(value);
+ this.cellEvent = forward;
+ }
+ }
+ }
+
+ /** Gets the arabic shaping options.
+ * @return the arabic shaping options
+ */
+ public int ArabicOptions {
+ get {
+ return column.ArabicOptions;
+ }
+ set {
+ column.ArabicOptions = value;
+ }
+ }
+
+ /** Gets state of first line height based on max ascender
+ * @return true if an ascender is to be used.
+ */
+ public bool UseAscender {
+ get {
+ return column.UseAscender;
+ }
+ set {
+ column.UseAscender = value;
+ }
+ }
+
+ /** Getter for property useDescender.
+ * @return Value of property useDescender.
+ *
+ */
+ public bool UseDescender {
+ get {
+ return this.useDescender;
+ }
+ set {
+ useDescender = value;
+ }
+ }
+
+ /**
+ * Gets the ColumnText with the content of the cell.
+ * @return a columntext object
+ */
+ public ColumnText Column {
+ get {
+ return column;
+ }
+ set {
+ column = value;
+ }
+ }
+
+ /**
+ * Returns the list of composite elements of the column.
+ * @return a List object.
+ * @since 2.1.1
+ */
+ public ArrayList CompositeElements {
+ get {
+ return column.compositeElements;
+ }
+ }
+
+ /**
+ * The rotation of the cell. Possible values are
+ * 0, 90, 180 and 270.
+ */
+ private new int rotation;
+
+ /**
+ * Sets the rotation of the cell. Possible values are
+ * 0, 90, 180 and 270.
+ * @param rotation the rotation of the cell
+ */
+ public new int Rotation {
+ set {
+ int rot = value % 360;
+ if (rot < 0)
+ rot += 360;
+ if ((rot % 90) != 0)
+ throw new ArgumentException("Rotation must be a multiple of 90.");
+ rotation = rot;
+ }
+ get {
+ return rotation;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPKCS7.cs b/iTechSharp/iTextSharp/text/pdf/PdfPKCS7.cs
new file mode 100644
index 0000000..7949d85
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPKCS7.cs
@@ -0,0 +1,1170 @@
+using System;
+using System.Collections;
+using System.Text;
+using System.IO;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Utilities;
+
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+ /**
+ * This class does all the processing related to signing and verifying a PKCS#7
+ * signature.
+ * null
for the default provider
+ * @throws SecurityException on error
+ * @throws CRLException on error
+ * @throws InvalidKeyException on error
+ * @throws CertificateException on error
+ * @throws NoSuchProviderException on error
+ * @throws NoSuchAlgorithmException on error
+ * @throws IOException on error
+ */
+ public PdfPKCS7(byte[] contentsKey, byte[] certsKey) {
+
+ X509CertificateParser cf = new X509CertificateParser();
+ certs = new ArrayList();
+ foreach (X509Certificate cc in cf.ReadCertificates(certsKey)) {
+ certs.Add(cc);
+ }
+ signCert = (X509Certificate)certs[0];
+ crls = new ArrayList();
+ Asn1InputStream inp = new Asn1InputStream(new MemoryStream(contentsKey));
+ digest = ((DerOctetString)inp.ReadObject()).GetOctets();
+ sig = SignerUtilities.GetSigner("SHA1withRSA");
+ sig.Init(false, signCert.GetPublicKey());
+ }
+
+ /**
+ * Verifies a signature using the sub-filter adbe.pkcs7.detached or
+ * adbe.pkcs7.sha1.
+ * @param contentsKey the /Contents key
+ * @param provider the provider or null
for the default provider
+ * @throws SecurityException on error
+ * @throws CRLException on error
+ * @throws InvalidKeyException on error
+ * @throws CertificateException on error
+ * @throws NoSuchProviderException on error
+ * @throws NoSuchAlgorithmException on error
+ */
+ public PdfPKCS7(byte[] contentsKey) {
+ Asn1InputStream din = new Asn1InputStream(new MemoryStream(contentsKey));
+
+ //
+ // Basic checks to make sure it's a PKCS#7 SignedData Object
+ //
+ Asn1Object pkcs;
+
+ try {
+ pkcs = din.ReadObject();
+ }
+ catch {
+ throw new ArgumentException("can't decode PKCS7SignedData object");
+ }
+ if (!(pkcs is Asn1Sequence)) {
+ throw new ArgumentException("Not a valid PKCS#7 object - not a sequence");
+ }
+ Asn1Sequence signedData = (Asn1Sequence)pkcs;
+ DerObjectIdentifier objId = (DerObjectIdentifier)signedData[0];
+ if (!objId.Id.Equals(ID_PKCS7_SIGNED_DATA))
+ throw new ArgumentException("Not a valid PKCS#7 object - not signed data");
+ Asn1Sequence content = (Asn1Sequence)((DerTaggedObject)signedData[1]).GetObject();
+ // the positions that we care are:
+ // 0 - version
+ // 1 - digestAlgorithms
+ // 2 - possible ID_PKCS7_DATA
+ // (the certificates and crls are taken out by other means)
+ // last - signerInfos
+
+ // the version
+ version = ((DerInteger)content[0]).Value.IntValue;
+
+ // the digestAlgorithms
+ digestalgos = new Hashtable();
+ IEnumerator e = ((Asn1Set)content[1]).GetEnumerator();
+ while (e.MoveNext())
+ {
+ Asn1Sequence s = (Asn1Sequence)e.Current;
+ DerObjectIdentifier o = (DerObjectIdentifier)s[0];
+ digestalgos[o.Id] = null;
+ }
+
+ // the certificates and crls
+ X509CertificateParser cf = new X509CertificateParser();
+ certs = new ArrayList();
+ foreach (X509Certificate cc in cf.ReadCertificates(contentsKey)) {
+ certs.Add(cc);
+ }
+ crls = new ArrayList();
+
+ // the possible ID_PKCS7_DATA
+ Asn1Sequence rsaData = (Asn1Sequence)content[2];
+ if (rsaData.Count > 1) {
+ DerOctetString rsaDataContent = (DerOctetString)((DerTaggedObject)rsaData[1]).GetObject();
+ RSAdata = rsaDataContent.GetOctets();
+ }
+
+ // the signerInfos
+ int next = 3;
+ while (content[next] is DerTaggedObject)
+ ++next;
+ Asn1Set signerInfos = (Asn1Set)content[next];
+ if (signerInfos.Count != 1)
+ throw new ArgumentException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time");
+ Asn1Sequence signerInfo = (Asn1Sequence)signerInfos[0];
+ // the positions that we care are
+ // 0 - version
+ // 1 - the signing certificate serial number
+ // 2 - the digest algorithm
+ // 3 or 4 - digestEncryptionAlgorithm
+ // 4 or 5 - encryptedDigest
+ signerversion = ((DerInteger)signerInfo[0]).Value.IntValue;
+ // Get the signing certificate
+ Asn1Sequence issuerAndSerialNumber = (Asn1Sequence)signerInfo[1];
+ BigInteger serialNumber = ((DerInteger)issuerAndSerialNumber[1]).Value;
+ foreach (X509Certificate cert in certs) {
+ if (serialNumber.Equals(cert.SerialNumber)) {
+ signCert = cert;
+ break;
+ }
+ }
+ if (signCert == null) {
+ throw new ArgumentException("Can't find signing certificate with serial " + serialNumber.ToString(16));
+ }
+ digestAlgorithm = ((DerObjectIdentifier)((Asn1Sequence)signerInfo[2])[0]).Id;
+ next = 3;
+ if (signerInfo[next] is Asn1TaggedObject) {
+ Asn1TaggedObject tagsig = (Asn1TaggedObject)signerInfo[next];
+ Asn1Sequence sseq = (Asn1Sequence)tagsig.GetObject();
+ MemoryStream bOut = new MemoryStream();
+ Asn1OutputStream dout = new Asn1OutputStream(bOut);
+ try {
+ Asn1EncodableVector attribute = new Asn1EncodableVector();
+ for (int k = 0; k < sseq.Count; ++k) {
+ attribute.Add(sseq[k]);
+ }
+ dout.WriteObject(new DerSet(attribute));
+ dout.Close();
+ }
+ catch (IOException){}
+ sigAttr = bOut.ToArray();
+
+ for (int k = 0; k < sseq.Count; ++k) {
+ Asn1Sequence seq2 = (Asn1Sequence)sseq[k];
+ if (((DerObjectIdentifier)seq2[0]).Id.Equals(ID_MESSAGE_DIGEST)) {
+ Asn1Set sset = (Asn1Set)seq2[1];
+ digestAttr = ((DerOctetString)sset[0]).GetOctets();
+ break;
+ }
+ }
+ if (digestAttr == null)
+ throw new ArgumentException("Authenticated attribute is missing the digest.");
+ ++next;
+ }
+ digestEncryptionAlgorithm = ((DerObjectIdentifier)((Asn1Sequence)signerInfo[next++])[0]).Id;
+ digest = ((DerOctetString)signerInfo[next]).GetOctets();
+ if (RSAdata != null || digestAttr != null) {
+ messageDigest = GetHashClass();
+ }
+ sig = SignerUtilities.GetSigner(GetDigestAlgorithm());
+ sig.Init(false, signCert.GetPublicKey());
+ }
+
+ /**
+ * Generates a signature.
+ * @param privKey the private key
+ * @param certChain the certificate chain
+ * @param crlList the certificate revocation list
+ * @param hashAlgorithm the hash algorithm
+ * @param provider the provider or null
for the default provider
+ * @param hasRSAdata true
if the sub-filter is adbe.pkcs7.sha1
+ * @throws SecurityException on error
+ * @throws InvalidKeyException on error
+ * @throws NoSuchProviderException on error
+ * @throws NoSuchAlgorithmException on error
+ */
+ public PdfPKCS7(ICipherParameters privKey, X509Certificate[] certChain, object[] crlList,
+ String hashAlgorithm, bool hasRSAdata) {
+ this.privKey = privKey;
+
+ if (hashAlgorithm.Equals("MD5")) {
+ digestAlgorithm = ID_MD5;
+ }
+ else if (hashAlgorithm.Equals("MD2")) {
+ digestAlgorithm = ID_MD2;
+ }
+ else if (hashAlgorithm.Equals("SHA")) {
+ digestAlgorithm = ID_SHA1;
+ }
+ else if (hashAlgorithm.Equals("SHA1")) {
+ digestAlgorithm = ID_SHA1;
+ }
+ else {
+ throw new ArgumentException("Unknown Hash Algorithm "+hashAlgorithm);
+ }
+
+ version = signerversion = 1;
+ certs = new ArrayList();
+ crls = new ArrayList();
+ digestalgos = new Hashtable();
+ digestalgos[digestAlgorithm] = null;
+
+ //
+ // Copy in the certificates and crls used to sign the private key.
+ //
+ signCert = certChain[0];
+ for (int i = 0;i < certChain.Length;i++) {
+ certs.Add(certChain[i]);
+ }
+
+// if (crlList != null) {
+// for (int i = 0;i < crlList.length;i++) {
+// crls.Add(crlList[i]);
+// }
+// }
+
+ if (privKey != null) {
+ //
+ // Now we have private key, find out what the digestEncryptionAlgorithm is.
+ //
+ if (privKey is RsaKeyParameters)
+ digestEncryptionAlgorithm = ID_RSA;
+ else if (privKey is DsaKeyParameters)
+ digestEncryptionAlgorithm = ID_DSA;
+ else
+ throw new ArgumentException("Unknown Key Algorithm "+privKey.ToString());
+
+ }
+ if (hasRSAdata) {
+ RSAdata = new byte[0];
+ messageDigest = GetHashClass();
+ }
+
+ if (privKey != null) {
+ sig = SignerUtilities.GetSigner(GetDigestAlgorithm());
+ sig.Init(true, privKey);
+ }
+ }
+
+ /**
+ * Update the digest with the specified bytes. This method is used both for signing and verifying
+ * @param buf the data buffer
+ * @param off the offset in the data buffer
+ * @param len the data length
+ * @throws SignatureException on error
+ */
+ public void Update(byte[] buf, int off, int len) {
+ if (RSAdata != null || digestAttr != null)
+ messageDigest.BlockUpdate(buf, off, len);
+ else
+ sig.BlockUpdate(buf, off, len);
+ }
+
+ /**
+ * Verify the digest.
+ * @throws SignatureException on error
+ * @return true
if the signature checks out, false
otherwise
+ */
+ public bool Verify() {
+ if (verified)
+ return verifyResult;
+ if (sigAttr != null) {
+ byte[] msd = new byte[messageDigest.GetDigestSize()];
+ sig.BlockUpdate(sigAttr, 0, sigAttr.Length);
+ if (RSAdata != null) {
+ messageDigest.DoFinal(msd, 0);
+ messageDigest.BlockUpdate(msd, 0, msd.Length);
+ }
+ messageDigest.DoFinal(msd, 0);
+ verifyResult = (Arrays.AreEqual(msd, digestAttr) && sig.VerifySignature(digest));
+ }
+ else {
+ if (RSAdata != null){
+ byte[] msd = new byte[messageDigest.GetDigestSize()];
+ messageDigest.DoFinal(msd, 0);
+ sig.BlockUpdate(msd, 0, msd.Length);
+ }
+ verifyResult = sig.VerifySignature(digest);
+ }
+ verified = true;
+ return verifyResult;
+ }
+
+ /**
+ * Get the X.509 certificates associated with this PKCS#7 object
+ * @return the X.509 certificates associated with this PKCS#7 object
+ */
+ public X509Certificate[] Certificates {
+ get {
+ X509Certificate[] c = new X509Certificate[certs.Count];
+ certs.CopyTo(c);
+ return c;
+ }
+ }
+
+ /**
+ * Get the X.509 certificate revocation lists associated with this PKCS#7 object
+ * @return the X.509 certificate revocation lists associated with this PKCS#7 object
+ */
+ public ArrayList CRLs {
+ get {
+ return crls;
+ }
+ }
+
+ /**
+ * Get the X.509 certificate actually used to sign the digest.
+ * @return the X.509 certificate actually used to sign the digest
+ */
+ public X509Certificate SigningCertificate {
+ get {
+ return signCert;
+ }
+ }
+
+ /**
+ * Get the version of the PKCS#7 object. Always 1
+ * @return the version of the PKCS#7 object. Always 1
+ */
+ public int Version {
+ get {
+ return version;
+ }
+ }
+
+ /**
+ * Get the version of the PKCS#7 "SignerInfo" object. Always 1
+ * @return the version of the PKCS#7 "SignerInfo" object. Always 1
+ */
+ public int SigningInfoVersion {
+ get {
+ return signerversion;
+ }
+ }
+
+ /**
+ * Get the algorithm used to calculate the message digest
+ * @return the algorithm used to calculate the message digest
+ */
+ public String GetDigestAlgorithm() {
+ String dea = digestEncryptionAlgorithm;
+
+ if (digestEncryptionAlgorithm.Equals(ID_RSA) || digestEncryptionAlgorithm.Equals(ID_MD5RSA)
+ || digestEncryptionAlgorithm.Equals(ID_MD2RSA) || digestEncryptionAlgorithm.Equals(ID_SHA1RSA)) {
+ dea = "RSA";
+ }
+ else if (digestEncryptionAlgorithm.Equals(ID_DSA)) {
+ dea = "DSA";
+ }
+
+ return GetHashAlgorithm() + "with" + dea;
+ }
+
+ /**
+ * Returns the algorithm.
+ * @return the digest algorithm
+ */
+ public String GetHashAlgorithm() {
+ String da = digestAlgorithm;
+
+ if (digestAlgorithm.Equals(ID_MD5) || digestAlgorithm.Equals(ID_MD5RSA)) {
+ da = "MD5";
+ }
+ else if (digestAlgorithm.Equals(ID_MD2) || digestAlgorithm.Equals(ID_MD2RSA)) {
+ da = "MD2";
+ }
+ else if (digestAlgorithm.Equals(ID_SHA1) || digestAlgorithm.Equals(ID_SHA1RSA)) {
+ da = "SHA1";
+ }
+ return da;
+ }
+
+ public IDigest GetHashClass() {
+ if (digestAlgorithm.Equals(ID_MD5) || digestAlgorithm.Equals(ID_MD5RSA)) {
+ return new MD5Digest();
+ }
+ else if (digestAlgorithm.Equals(ID_MD2) || digestAlgorithm.Equals(ID_MD2RSA)) {
+ return new MD2Digest();
+ }
+ else if (digestAlgorithm.Equals(ID_SHA1) || digestAlgorithm.Equals(ID_SHA1RSA)) {
+ return new Sha1Digest();
+ }
+ return null;
+ }
+
+ /**
+ * Loads the default root certificates at <java.home>/lib/security/cacerts
+ * with the default provider.
+ * @return a KeyStore
+ */
+// public static KeyStore LoadCacertsKeyStore() {
+// return LoadCacertsKeyStore(null);
+// }
+
+ /**
+ * Loads the default root certificates at <java.home>/lib/security/cacerts.
+ * @param provider the provider or null
for the default provider
+ * @return a KeyStore
+ */
+// public static KeyStore LoadCacertsKeyStore(String provider) {
+// File file = new File(System.GetProperty("java.home"), "lib");
+// file = new File(file, "security");
+// file = new File(file, "cacerts");
+// FileInputStream fin = null;
+// try {
+// fin = new FileInputStream(file);
+// KeyStore k;
+// if (provider == null)
+// k = KeyStore.GetInstance("JKS");
+// else
+// k = KeyStore.GetInstance("JKS", provider);
+// k.Load(fin, null);
+// return k;
+// }
+// catch (Exception e) {
+// throw new ExceptionConverter(e);
+// }
+// finally {
+// try{fin.Close();}catch(Exception ex){}
+// }
+// }
+
+ /**
+ * Verifies a single certificate.
+ * @param cert the certificate to verify
+ * @param crls the certificate revocation list or null
+ * @param calendar the date or null
for the current date
+ * @return a String
with the error description or null
+ * if no error
+ */
+ public static String VerifyCertificate(X509Certificate cert, object[] crls, DateTime calendar) {
+ try {
+ if (!cert.IsValid(calendar))
+ return "The certificate has expired or is not yet valid";
+ }
+ catch (Exception e) {
+ return e.ToString();
+ }
+ return null;
+ }
+
+ /**
+ * Verifies a certificate chain against a KeyStore.
+ * @param certs the certificate chain
+ * @param keystore the KeyStore
+ * @param crls the certificate revocation list or null
+ * @param calendar the date or null
for the current date
+ * @return null
if the certificate chain could be validade or a
+ * Object[]{cert,error}
where cert
is the
+ * failed certificate and error
is the error message
+ */
+ public static Object[] VerifyCertificates(X509Certificate[] certs, ArrayList keystore, object[] crls, DateTime calendar) {
+ for (int k = 0; k < certs.Length; ++k) {
+ X509Certificate cert = certs[k];
+ String err = VerifyCertificate(cert, crls, calendar);
+ if (err != null)
+ return new Object[]{cert, err};
+ foreach (X509Certificate certStoreX509 in keystore) {
+ try {
+ if (VerifyCertificate(certStoreX509, crls, calendar) != null)
+ continue;
+ try {
+ cert.Verify(certStoreX509.GetPublicKey());
+ return null;
+ }
+ catch {
+ continue;
+ }
+ }
+ catch {
+ }
+ }
+ int j;
+ for (j = 0; j < certs.Length; ++j) {
+ if (j == k)
+ continue;
+ X509Certificate certNext = certs[j];
+ try {
+ cert.Verify(certNext.GetPublicKey());
+ break;
+ }
+ catch {
+ }
+ }
+ if (j == certs.Length)
+ return new Object[]{cert, "Cannot be verified against the KeyStore or the certificate chain"};
+ }
+ return new Object[]{null, "Invalid state. Possible circular certificate chain"};
+ }
+
+ /**
+ * Get the "issuer" from the TBSCertificate bytes that are passed in
+ * @param enc a TBSCertificate in a byte array
+ * @return a DERObject
+ */
+ private static Asn1Object GetIssuer(byte[] enc) {
+ Asn1InputStream inp = new Asn1InputStream(new MemoryStream(enc));
+ Asn1Sequence seq = (Asn1Sequence)inp.ReadObject();
+ return (Asn1Object)seq[seq[0] is DerTaggedObject ? 3 : 2];
+ }
+
+ /**
+ * Get the "subject" from the TBSCertificate bytes that are passed in
+ * @param enc A TBSCertificate in a byte array
+ * @return a DERObject
+ */
+ private static Asn1Object GetSubject(byte[] enc) {
+ Asn1InputStream inp = new Asn1InputStream(new MemoryStream(enc));
+ Asn1Sequence seq = (Asn1Sequence)inp.ReadObject();
+ return (Asn1Object)seq[seq[0] is DerTaggedObject ? 5 : 4];
+ }
+
+ /**
+ * Get the issuer fields from an X509 Certificate
+ * @param cert an X509Certificate
+ * @return an X509Name
+ */
+ public static X509Name GetIssuerFields(X509Certificate cert) {
+ return new X509Name((Asn1Sequence)GetIssuer(cert.GetTbsCertificate()));
+ }
+
+ /**
+ * Get the subject fields from an X509 Certificate
+ * @param cert an X509Certificate
+ * @return an X509Name
+ */
+ public static X509Name GetSubjectFields(X509Certificate cert) {
+ return new X509Name((Asn1Sequence)GetSubject(cert.GetTbsCertificate()));
+ }
+
+ /**
+ * Gets the bytes for the PKCS#1 object.
+ * @return a byte array
+ */
+ public byte[] GetEncodedPKCS1() {
+ if (externalDigest != null)
+ digest = externalDigest;
+ else
+ digest = sig.GenerateSignature();
+ MemoryStream bOut = new MemoryStream();
+
+ Asn1OutputStream dout = new Asn1OutputStream(bOut);
+ dout.WriteObject(new DerOctetString(digest));
+ dout.Close();
+
+ return bOut.ToArray();
+ }
+
+ /**
+ * Sets the digest/signature to an external calculated value.
+ * @param digest the digest. This is the actual signature
+ * @param RSAdata the extra data that goes into the data tag in PKCS#7
+ * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null
if the digest
+ * is also null
. If the digest
is not null
+ * then it may be "RSA" or "DSA"
+ */
+ public void SetExternalDigest(byte[] digest, byte[] RSAdata, String digestEncryptionAlgorithm) {
+ externalDigest = digest;
+ externalRSAdata = RSAdata;
+ if (digestEncryptionAlgorithm != null) {
+ if (digestEncryptionAlgorithm.Equals("RSA")) {
+ this.digestEncryptionAlgorithm = ID_RSA;
+ }
+ else if (digestEncryptionAlgorithm.Equals("DSA")) {
+ this.digestEncryptionAlgorithm = ID_DSA;
+ }
+ else
+ throw new ArgumentException("Unknown Key Algorithm "+digestEncryptionAlgorithm);
+ }
+ }
+
+ /**
+ * Gets the bytes for the PKCS7SignedData object.
+ * @return the bytes for the PKCS7SignedData object
+ */
+ public byte[] GetEncodedPKCS7() {
+ return GetEncodedPKCS7(null, DateTime.Now);
+ }
+
+ /**
+ * Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes
+ * in the signerInfo can also be set. If either of the parameters is null
, none will be used.
+ * @param secondDigest the digest in the authenticatedAttributes
+ * @param signingTime the signing time in the authenticatedAttributes
+ * @return the bytes for the PKCS7SignedData object
+ */
+ public byte[] GetEncodedPKCS7(byte[] secondDigest, DateTime signingTime) {
+ if (externalDigest != null) {
+ digest = externalDigest;
+ if (RSAdata != null)
+ RSAdata = externalRSAdata;
+ }
+ else if (externalRSAdata != null && RSAdata != null) {
+ RSAdata = externalRSAdata;
+ sig.BlockUpdate(RSAdata, 0, RSAdata.Length);
+ digest = sig.GenerateSignature();
+ }
+ else {
+ if (RSAdata != null) {
+ RSAdata = new byte[messageDigest.GetDigestSize()];
+ messageDigest.DoFinal(RSAdata, 0);
+ sig.BlockUpdate(RSAdata, 0, RSAdata.Length);
+ }
+ digest = sig.GenerateSignature();
+ }
+
+ // Create the set of Hash algorithms
+ Asn1EncodableVector digestAlgorithms = new Asn1EncodableVector();
+ foreach (string dal in digestalgos.Keys) {
+ Asn1EncodableVector algos = new Asn1EncodableVector();
+ algos.Add(new DerObjectIdentifier(dal));
+ algos.Add(DerNull.Instance);
+ digestAlgorithms.Add(new DerSequence(algos));
+ }
+
+ // Create the contentInfo.
+ Asn1EncodableVector v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(ID_PKCS7_DATA));
+ if (RSAdata != null)
+ v.Add(new DerTaggedObject(0, new DerOctetString(RSAdata)));
+ DerSequence contentinfo = new DerSequence(v);
+
+ // Get all the certificates
+ //
+ v = new Asn1EncodableVector();
+ foreach (X509Certificate xcert in certs) {
+ Asn1InputStream tempstream = new Asn1InputStream(new MemoryStream(xcert.GetEncoded()));
+ v.Add(tempstream.ReadObject());
+ }
+
+ DerSet dercertificates = new DerSet(v);
+
+ // Create signerinfo structure.
+ //
+ Asn1EncodableVector signerinfo = new Asn1EncodableVector();
+
+ // Add the signerInfo version
+ //
+ signerinfo.Add(new DerInteger(signerversion));
+
+ v = new Asn1EncodableVector();
+ v.Add(GetIssuer(signCert.GetTbsCertificate()));
+ v.Add(new DerInteger(signCert.SerialNumber));
+ signerinfo.Add(new DerSequence(v));
+
+ // Add the digestAlgorithm
+ v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(digestAlgorithm));
+ v.Add(DerNull.Instance);
+ signerinfo.Add(new DerSequence(v));
+
+ // add the authenticated attribute if present
+ if (secondDigest != null /*&& signingTime != null*/) {
+ Asn1EncodableVector attribute = new Asn1EncodableVector();
+ v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(ID_CONTENT_TYPE));
+ v.Add(new DerSet(new DerObjectIdentifier(ID_PKCS7_DATA)));
+ attribute.Add(new DerSequence(v));
+ v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(ID_SIGNING_TIME));
+ v.Add(new DerSet(new DerUtcTime(signingTime)));
+ attribute.Add(new DerSequence(v));
+ v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(ID_MESSAGE_DIGEST));
+ v.Add(new DerSet(new DerOctetString(secondDigest)));
+ attribute.Add(new DerSequence(v));
+ signerinfo.Add(new DerTaggedObject(false, 0, new DerSet(attribute)));
+ }
+ // Add the digestEncryptionAlgorithm
+ v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(digestEncryptionAlgorithm));
+ v.Add(DerNull.Instance);
+ signerinfo.Add(new DerSequence(v));
+
+ // Add the digest
+ signerinfo.Add(new DerOctetString(digest));
+
+
+ // Finally build the body out of all the components above
+ Asn1EncodableVector body = new Asn1EncodableVector();
+ body.Add(new DerInteger(version));
+ body.Add(new DerSet(digestAlgorithms));
+ body.Add(contentinfo);
+ body.Add(new DerTaggedObject(false, 0, dercertificates));
+
+// if (crls.Count > 0) {
+// v = new Asn1EncodableVector();
+// for (Iterator i = crls.Iterator();i.HasNext();) {
+// Asn1InputStream t = new Asn1InputStream(new ByteArrayInputStream((((X509CRL)i.Next()).GetEncoded())));
+// v.Add(t.ReadObject());
+// }
+// DERSet dercrls = new DERSet(v);
+// body.Add(new DERTaggedObject(false, 1, dercrls));
+// }
+
+ // Only allow one signerInfo
+ body.Add(new DerSet(new DerSequence(signerinfo)));
+
+ // Now we have the body, wrap it in it's PKCS7Signed shell
+ // and return it
+ //
+ Asn1EncodableVector whole = new Asn1EncodableVector();
+ whole.Add(new DerObjectIdentifier(ID_PKCS7_SIGNED_DATA));
+ whole.Add(new DerTaggedObject(0, new DerSequence(body)));
+
+ MemoryStream bOut = new MemoryStream();
+
+ Asn1OutputStream dout = new Asn1OutputStream(bOut);
+ dout.WriteObject(new DerSequence(whole));
+ dout.Close();
+
+ return bOut.ToArray();
+ }
+
+
+ /**
+ * When using authenticatedAttributes the authentication process is different.
+ * The document digest is generated and put inside the attribute. The signing is done over the DER encoded
+ * authenticatedAttributes. This method provides that encoding and the parameters must be
+ * exactly the same as in {@link #getEncodedPKCS7(byte[],Calendar)}.
+ *
+ * Calendar cal = Calendar.GetInstance();
+ * PdfPKCS7 pk7 = new PdfPKCS7(key, chain, null, "SHA1", null, false);
+ * MessageDigest messageDigest = MessageDigest.GetInstance("SHA1");
+ * byte buf[] = new byte[8192];
+ * int n;
+ * Stream inp = sap.GetRangeStream();
+ * while ((n = inp.Read(buf)) > 0) {
+ * messageDigest.Update(buf, 0, n);
+ * }
+ * byte hash[] = messageDigest.Digest();
+ * byte sh[] = pk7.GetAuthenticatedAttributeBytes(hash, cal);
+ * pk7.Update(sh, 0, sh.length);
+ * byte sg[] = pk7.GetEncodedPKCS7(hash, cal);
+ *
+ * @param secondDigest the content digest
+ * @param signingTime the signing time
+ * @return the byte array representation of the authenticatedAttributes ready to be signed
+ */
+ public byte[] GetAuthenticatedAttributeBytes(byte[] secondDigest, DateTime signingTime) {
+ Asn1EncodableVector attribute = new Asn1EncodableVector();
+ Asn1EncodableVector v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(ID_CONTENT_TYPE));
+ v.Add(new DerSet(new DerObjectIdentifier(ID_PKCS7_DATA)));
+ attribute.Add(new DerSequence(v));
+ v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(ID_SIGNING_TIME));
+ v.Add(new DerSet(new DerUtcTime(signingTime)));
+ attribute.Add(new DerSequence(v));
+ v = new Asn1EncodableVector();
+ v.Add(new DerObjectIdentifier(ID_MESSAGE_DIGEST));
+ v.Add(new DerSet(new DerOctetString(secondDigest)));
+ attribute.Add(new DerSequence(v));
+ MemoryStream bOut = new MemoryStream();
+
+ Asn1OutputStream dout = new Asn1OutputStream(bOut);
+ dout.WriteObject(new DerSet(attribute));
+ dout.Close();
+
+ return bOut.ToArray();
+ }
+
+
+ public string Reason {
+ get {
+ return reason;
+ }
+ set {
+ reason = value;
+ }
+ }
+
+
+ public string Location {
+ get {
+ return location;
+ }
+ set {
+ location = value;
+ }
+ }
+
+
+ public DateTime SignDate {
+ get {
+ return signDate;
+ }
+ set {
+ signDate = value;
+ }
+ }
+
+
+ public string SignName {
+ get {
+ return signName;
+ }
+ set {
+ signName = value;
+ }
+ }
+
+ /**
+ * a class that holds an X509 name
+ */
+ public class X509Name {
+ /**
+ * country code - StringType(SIZE(2))
+ */
+ public static DerObjectIdentifier C = new DerObjectIdentifier("2.5.4.6");
+
+ /**
+ * organization - StringType(SIZE(1..64))
+ */
+ public static DerObjectIdentifier O = new DerObjectIdentifier("2.5.4.10");
+
+ /**
+ * organizational unit name - StringType(SIZE(1..64))
+ */
+ public static DerObjectIdentifier OU = new DerObjectIdentifier("2.5.4.11");
+
+ /**
+ * Title
+ */
+ public static DerObjectIdentifier T = new DerObjectIdentifier("2.5.4.12");
+
+ /**
+ * common name - StringType(SIZE(1..64))
+ */
+ public static DerObjectIdentifier CN = new DerObjectIdentifier("2.5.4.3");
+
+ /**
+ * device serial number name - StringType(SIZE(1..64))
+ */
+ public static DerObjectIdentifier SN = new DerObjectIdentifier("2.5.4.5");
+
+ /**
+ * locality name - StringType(SIZE(1..64))
+ */
+ public static DerObjectIdentifier L = new DerObjectIdentifier("2.5.4.7");
+
+ /**
+ * state, or province name - StringType(SIZE(1..64))
+ */
+ public static DerObjectIdentifier ST = new DerObjectIdentifier("2.5.4.8");
+
+ /** Naming attribute of type X520name */
+ public static DerObjectIdentifier SURNAME = new DerObjectIdentifier("2.5.4.4");
+ /** Naming attribute of type X520name */
+ public static DerObjectIdentifier GIVENNAME = new DerObjectIdentifier("2.5.4.42");
+ /** Naming attribute of type X520name */
+ public static DerObjectIdentifier INITIALS = new DerObjectIdentifier("2.5.4.43");
+ /** Naming attribute of type X520name */
+ public static DerObjectIdentifier GENERATION = new DerObjectIdentifier("2.5.4.44");
+ /** Naming attribute of type X520name */
+ public static DerObjectIdentifier UNIQUE_IDENTIFIER = new DerObjectIdentifier("2.5.4.45");
+
+ /**
+ * Email address (RSA PKCS#9 extension) - IA5String.
+ * PdfPSXObject
. All
+ * the members are copied by reference but the buffer stays different.
+ * @return a copy of this PdfPSXObject
+ */
+
+ public override PdfContentByte Duplicate {
+ get {
+ PdfPSXObject tpl = new PdfPSXObject();
+ tpl.writer = writer;
+ tpl.pdf = pdf;
+ tpl.thisReference = thisReference;
+ tpl.pageResources = pageResources;
+ tpl.separator = separator;
+ return tpl;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPTable.cs b/iTechSharp/iTextSharp/text/pdf/PdfPTable.cs
new file mode 100644
index 0000000..3f82101
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPTable.cs
@@ -0,0 +1,1050 @@
+using System;
+using System.Collections;
+
+using iTextSharp.text;
+using iTextSharp.text.pdf.events;
+
+/*
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** This is a table that can be put at an absolute position but can also
+ * be added to the document as the class Table
.
+ * In the last case when crossing pages the table always break at full rows; if a
+ * row is bigger than the page it is dropped silently to avoid infinite loops.
+ * PdfcontentByte
.
+ */
+ public const int BASECANVAS = 0;
+ /** The index of the duplicate PdfContentByte
where the background will be drawn.
+ */
+ public const int BACKGROUNDCANVAS = 1;
+ /** The index of the duplicate PdfContentByte
where the border lines will be drawn.
+ */
+ public const int LINECANVAS = 2;
+ /** The index of the duplicate PdfContentByte
where the text will be drawn.
+ */
+ public const int TEXTCANVAS = 3;
+
+ protected ArrayList rows = new ArrayList();
+ protected float totalHeight = 0;
+ protected PdfPCell[] currentRow;
+ protected int currentRowIdx = 0;
+ protected PdfPCell defaultCell = new PdfPCell((Phrase)null);
+ protected float totalWidth = 0;
+ protected float[] relativeWidths;
+ protected float[] absoluteWidths;
+ protected IPdfPTableEvent tableEvent;
+
+ /** Holds value of property headerRows. */
+ protected int headerRows;
+
+ /** Holds value of property widthPercentage. */
+ protected float widthPercentage = 80;
+
+ /** Holds value of property horizontalAlignment. */
+ private int horizontalAlignment = Element.ALIGN_CENTER;
+
+ /** Holds value of property skipFirstHeader. */
+ private bool skipFirstHeader = false;
+
+ protected bool isColspan = false;
+
+ protected int runDirection = PdfWriter.RUN_DIRECTION_DEFAULT;
+
+ /**
+ * Holds value of property lockedWidth.
+ */
+ private bool lockedWidth = false;
+
+ /**
+ * Holds value of property splitRows.
+ */
+ private bool splitRows = true;
+
+ /** The spacing before the table. */
+ protected float spacingBefore;
+
+ /** The spacing after the table. */
+ protected float spacingAfter;
+
+ /**
+ * Holds value of property extendLastRow.
+ */
+ private bool extendLastRow;
+
+ /**
+ * Holds value of property headersInEvent.
+ */
+ private bool headersInEvent;
+
+ /**
+ * Holds value of property splitLate.
+ */
+ private bool splitLate = true;
+
+ /**
+ * Defines if the table should be kept
+ * on one page if possible
+ */
+ private bool keepTogether;
+
+ /**
+ * Indicates if the PdfPTable is complete once added to the document.
+ * @since iText 2.0.8
+ */
+ protected bool complete = true;
+
+ private int footerRows;
+
+ protected PdfPTable() {
+ }
+
+ /** Constructs a PdfPTable
with the relative column widths.
+ * @param relativeWidths the relative column widths
+ */
+ public PdfPTable(float[] relativeWidths) {
+ if (relativeWidths == null)
+ throw new ArgumentNullException("The widths array in PdfPTable constructor can not be null.");
+ if (relativeWidths.Length == 0)
+ throw new ArgumentException("The widths array in PdfPTable constructor can not have zero length.");
+ this.relativeWidths = new float[relativeWidths.Length];
+ Array.Copy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.Length);
+ absoluteWidths = new float[relativeWidths.Length];
+ CalculateWidths();
+ currentRow = new PdfPCell[absoluteWidths.Length];
+ keepTogether = false;
+ }
+
+ /** Constructs a PdfPTable
with numColumns
columns.
+ * @param numColumns the number of columns
+ */
+ public PdfPTable(int numColumns) {
+ if (numColumns <= 0)
+ throw new ArgumentException("The number of columns in PdfPTable constructor must be greater than zero.");
+ relativeWidths = new float[numColumns];
+ for (int k = 0; k < numColumns; ++k)
+ relativeWidths[k] = 1;
+ absoluteWidths = new float[relativeWidths.Length];
+ CalculateWidths();
+ currentRow = new PdfPCell[absoluteWidths.Length];
+ keepTogether = false;
+ }
+
+ /** Constructs a copy of a PdfPTable
.
+ * @param table the PdfPTable
to be copied
+ */
+ public PdfPTable(PdfPTable table) {
+ CopyFormat(table);
+ for (int k = 0; k < currentRow.Length; ++k) {
+ if (table.currentRow[k] == null)
+ break;
+ currentRow[k] = new PdfPCell(table.currentRow[k]);
+ }
+ for (int k = 0; k < table.rows.Count; ++k) {
+ PdfPRow row = (PdfPRow)(table.rows[k]);
+ if (row != null)
+ row = new PdfPRow(row);
+ rows.Add(row);
+ }
+ }
+
+ /**
+ * Makes a shallow copy of a table (format without content).
+ * @param table
+ * @return a shallow copy of the table
+ */
+ public static PdfPTable ShallowCopy(PdfPTable table) {
+ PdfPTable nt = new PdfPTable();
+ nt.CopyFormat(table);
+ return nt;
+ }
+
+ /**
+ * Copies the format of the sourceTable without copying the content.
+ * @param sourceTable
+ */
+ private void CopyFormat(PdfPTable sourceTable) {
+ relativeWidths = new float[sourceTable.relativeWidths.Length];
+ absoluteWidths = new float[sourceTable.relativeWidths.Length];
+ Array.Copy(sourceTable.relativeWidths, 0, relativeWidths, 0, relativeWidths.Length);
+ Array.Copy(sourceTable.absoluteWidths, 0, absoluteWidths, 0, relativeWidths.Length);
+ totalWidth = sourceTable.totalWidth;
+ totalHeight = sourceTable.totalHeight;
+ currentRowIdx = 0;
+ tableEvent = sourceTable.tableEvent;
+ runDirection = sourceTable.runDirection;
+ defaultCell = new PdfPCell(sourceTable.defaultCell);
+ currentRow = new PdfPCell[sourceTable.currentRow.Length];
+ isColspan = sourceTable.isColspan;
+ splitRows = sourceTable.splitRows;
+ spacingAfter = sourceTable.spacingAfter;
+ spacingBefore = sourceTable.spacingBefore;
+ headerRows = sourceTable.headerRows;
+ footerRows = sourceTable.footerRows;
+ lockedWidth = sourceTable.lockedWidth;
+ extendLastRow = sourceTable.extendLastRow;
+ headersInEvent = sourceTable.headersInEvent;
+ widthPercentage = sourceTable.widthPercentage;
+ splitLate = sourceTable.splitLate;
+ skipFirstHeader = sourceTable.skipFirstHeader;
+ horizontalAlignment = sourceTable.horizontalAlignment;
+ keepTogether = sourceTable.keepTogether;
+ complete = sourceTable.complete;
+ }
+
+ /** Sets the relative widths of the table.
+ * @param relativeWidths the relative widths of the table.
+ * @throws DocumentException if the number of widths is different than the number
+ * of columns
+ */
+ public void SetWidths(float[] relativeWidths) {
+ if (relativeWidths.Length != this.relativeWidths.Length)
+ throw new DocumentException("Wrong number of columns.");
+ this.relativeWidths = new float[relativeWidths.Length];
+ Array.Copy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.Length);
+ absoluteWidths = new float[relativeWidths.Length];
+ totalHeight = 0;
+ CalculateWidths();
+ CalculateHeights();
+ }
+
+ /** Sets the relative widths of the table.
+ * @param relativeWidths the relative widths of the table.
+ * @throws DocumentException if the number of widths is different than the number
+ * of columns
+ */
+ public void SetWidths(int[] relativeWidths) {
+ float[] tb = new float[relativeWidths.Length];
+ for (int k = 0; k < relativeWidths.Length; ++k)
+ tb[k] = relativeWidths[k];
+ SetWidths(tb);
+ }
+
+ private void CalculateWidths() {
+ if (totalWidth <= 0)
+ return;
+ float total = 0;
+ for (int k = 0; k < absoluteWidths.Length; ++k) {
+ total += relativeWidths[k];
+ }
+ for (int k = 0; k < absoluteWidths.Length; ++k) {
+ absoluteWidths[k] = totalWidth * relativeWidths[k] / total;
+ }
+ }
+
+ /** Sets the full width of the table from the absolute column width.
+ * @param columnWidth the absolute width of each column
+ * @throws DocumentException if the number of widths is different than the number
+ * of columns
+ */
+ public void SetTotalWidth(float[] columnWidth) {
+ if (columnWidth.Length != this.relativeWidths.Length)
+ throw new DocumentException("Wrong number of columns.");
+ totalWidth = 0;
+ for (int k = 0; k < columnWidth.Length; ++k)
+ totalWidth += columnWidth[k];
+ SetWidths(columnWidth);
+ }
+
+ /** Sets the percentage width of the table from the absolute column width.
+ * @param columnWidth the absolute width of each column
+ * @param pageSize the page size
+ * @throws DocumentException
+ */
+ public void SetWidthPercentage(float[] columnWidth, Rectangle pageSize) {
+ if (columnWidth.Length != this.relativeWidths.Length)
+ throw new ArgumentException("Wrong number of columns.");
+ float totalWidth = 0;
+ for (int k = 0; k < columnWidth.Length; ++k)
+ totalWidth += columnWidth[k];
+ widthPercentage = totalWidth / (pageSize.Right - pageSize.Left) * 100f;
+ SetWidths(columnWidth);
+ }
+
+ /** Gets the full width of the table.
+ * @return the full width of the table
+ */
+ public float TotalWidth {
+ get {
+ return totalWidth;
+ }
+ set {
+ if (this.totalWidth == value)
+ return;
+ this.totalWidth = value;
+ totalHeight = 0;
+ CalculateWidths();
+ CalculateHeights();
+ }
+ }
+
+ internal void CalculateHeights() {
+ if (totalWidth <= 0)
+ return;
+ totalHeight = 0;
+ for (int k = 0; k < rows.Count; ++k) {
+ PdfPRow row = (PdfPRow)rows[k];
+ if (row != null) {
+ row.SetWidths(absoluteWidths);
+ totalHeight += row.MaxHeights;
+ }
+ }
+ }
+
+ /**
+ * Calculates the heights of the table.
+ */
+ public void CalculateHeightsFast() {
+ if (totalWidth <= 0)
+ return;
+ totalHeight = 0;
+ for (int k = 0; k < rows.Count; ++k) {
+ PdfPRow row = (PdfPRow)rows[k];
+ if (row != null)
+ totalHeight += row.MaxHeights;
+ }
+ }
+
+ /** Gets the default PdfPCell
that will be used as
+ * reference for all the addCell
methods except
+ * addCell(PdfPCell)
.
+ * @return default PdfPCell
+ */
+ public PdfPCell DefaultCell {
+ get {
+ return defaultCell;
+ }
+ }
+
+ /** Adds a cell element.
+ * @param cell the cell element
+ */
+ public void AddCell(PdfPCell cell) {
+ PdfPCell ncell = new PdfPCell(cell);
+ int colspan = ncell.Colspan;
+ colspan = Math.Max(colspan, 1);
+ colspan = Math.Min(colspan, currentRow.Length - currentRowIdx);
+ ncell.Colspan = colspan;
+ if (colspan != 1)
+ isColspan = true;
+ int rdir = ncell.RunDirection;
+ if (rdir == PdfWriter.RUN_DIRECTION_DEFAULT)
+ ncell.RunDirection = runDirection;
+ currentRow[currentRowIdx] = ncell;
+ currentRowIdx += colspan;
+ if (currentRowIdx >= currentRow.Length) {
+ if (runDirection == PdfWriter.RUN_DIRECTION_RTL) {
+ PdfPCell[] rtlRow = new PdfPCell[absoluteWidths.Length];
+ int rev = currentRow.Length;
+ for (int k = 0; k < currentRow.Length; ++k) {
+ PdfPCell rcell = currentRow[k];
+ int cspan = rcell.Colspan;
+ rev -= cspan;
+ rtlRow[rev] = rcell;
+ k += cspan - 1;
+ }
+ currentRow = rtlRow;
+ }
+ PdfPRow row = new PdfPRow(currentRow);
+ if (totalWidth > 0) {
+ row.SetWidths(absoluteWidths);
+ totalHeight += row.MaxHeights;
+ }
+ rows.Add(row);
+ currentRow = new PdfPCell[absoluteWidths.Length];
+ currentRowIdx = 0;
+ }
+ }
+
+ /** Adds a cell element.
+ * @param text the text for the cell
+ */
+ public void AddCell(String text) {
+ AddCell(new Phrase(text));
+ }
+
+ /**
+ * Adds a nested table.
+ * @param table the table to be added to the cell
+ */
+ public void AddCell(PdfPTable table) {
+ defaultCell.Table = table;
+ AddCell(defaultCell);
+ defaultCell.Table = null;
+ }
+
+ /**
+ * Adds an Image as Cell.
+ * @param image the Image
to add to the table. This image will fit in the cell
+ */
+ public void AddCell(Image image) {
+ defaultCell.Image = image;
+ AddCell(defaultCell);
+ defaultCell.Image = null;
+ }
+
+ /**
+ * Adds a cell element.
+ * @param phrase the Phrase
to be added to the cell
+ */
+ public void AddCell(Phrase phrase) {
+ defaultCell.Phrase = phrase;
+ AddCell(defaultCell);
+ defaultCell.Phrase = null;
+ }
+
+ /**
+ * Writes the selected rows to the document.
+ * canvases
is obtained from beginWritingRows()
.
+ * @param rowStart the first row to be written, zero index
+ * @param rowEnd the last row to be written + 1. If it is -1 all the
+ * rows to the end are written
+ * @param xPos the x write coodinate
+ * @param yPos the y write coodinate
+ * @param canvases an array of 4 PdfContentByte
obtained from
+ * beginWrittingRows()
+ * @return the y coordinate position of the bottom of the last row
+ * @see #beginWritingRows(com.lowagie.text.pdf.PdfContentByte)
+ */
+ public float WriteSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) {
+ return WriteSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvases);
+ }
+
+ /** Writes the selected rows and columns to the document.
+ * This method does not clip the columns; this is only important
+ * if there are columns with colspan at boundaries.
+ * canvases
is obtained from beginWritingRows()
.
+ * PdfContentByte
obtained from
+ * beginWrittingRows()
+ * @return the y coordinate position of the bottom of the last row
+ * @see #beginWritingRows(com.lowagie.text.pdf.PdfContentByte)
+ */
+ public float WriteSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) {
+ if (totalWidth <= 0)
+ throw new ArgumentException("The table width must be greater than zero.");
+ int size = rows.Count;
+ if (rowEnd < 0)
+ rowEnd = size;
+ rowEnd = Math.Min(rowEnd, size);
+ if (rowStart < 0)
+ rowStart = 0;
+ if (rowStart >= rowEnd)
+ return yPos;
+ if (colEnd < 0)
+ colEnd = absoluteWidths.Length;
+ colEnd = Math.Min(colEnd, absoluteWidths.Length);
+ if (colStart < 0)
+ colStart = 0;
+ colStart = Math.Min(colStart, absoluteWidths.Length);
+ float yPosStart = yPos;
+ for (int k = rowStart; k < rowEnd; ++k) {
+ PdfPRow row = (PdfPRow)rows[k];
+ if (row != null) {
+ row.WriteCells(colStart, colEnd, xPos, yPos, canvases);
+ yPos -= row.MaxHeights;
+ }
+ }
+ if (tableEvent != null && colStart == 0 && colEnd == absoluteWidths.Length) {
+ float[] heights = new float[rowEnd - rowStart + 1];
+ heights[0] = yPosStart;
+ for (int k = rowStart; k < rowEnd; ++k) {
+ PdfPRow row = (PdfPRow)rows[k];
+ float hr = 0;
+ if (row != null)
+ hr = row.MaxHeights;
+ heights[k - rowStart + 1] = heights[k - rowStart] - hr;
+ }
+ tableEvent.TableLayout(this, GetEventWidths(xPos, rowStart, rowEnd, headersInEvent), heights, headersInEvent ? headerRows : 0, rowStart, canvases);
+ }
+ return yPos;
+ }
+
+ /**
+ * Writes the selected rows to the document.
+ *
+ * @param rowStart the first row to be written, zero index
+ * @param rowEnd the last row to be written + 1. If it is -1 all the
+ * rows to the end are written
+ * @param xPos the x write coodinate
+ * @param yPos the y write coodinate
+ * @param canvas the PdfContentByte
where the rows will
+ * be written to
+ * @return the y coordinate position of the bottom of the last row
+ */
+ public float WriteSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) {
+ return WriteSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvas);
+ }
+
+ /**
+ * Writes the selected rows to the document.
+ * This method clips the columns; this is only important
+ * if there are columns with colspan at boundaries.
+ * PdfContentByte
where the rows will
+ * be written to
+ * @return the y coordinate position of the bottom of the last row
+ */
+ public float WriteSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) {
+ if (colEnd < 0)
+ colEnd = absoluteWidths.Length;
+ colEnd = Math.Min(colEnd, absoluteWidths.Length);
+ if (colStart < 0)
+ colStart = 0;
+ colStart = Math.Min(colStart, absoluteWidths.Length);
+ if (colStart != 0 || colEnd != absoluteWidths.Length) {
+ float w = 0;
+ for (int k = colStart; k < colEnd; ++k)
+ w += absoluteWidths[k];
+ canvas.SaveState();
+ float lx = 0;
+ float rx = 0;
+ if (colStart == 0)
+ lx = 10000;
+ if (colEnd == absoluteWidths.Length)
+ rx = 10000;
+ canvas.Rectangle(xPos - lx, -10000, w + lx + rx, 20000);
+ canvas.Clip();
+ canvas.NewPath();
+ }
+ PdfContentByte[] canvases = BeginWritingRows(canvas);
+ float y = WriteSelectedRows(colStart, colEnd, rowStart, rowEnd, xPos, yPos, canvases);
+ EndWritingRows(canvases);
+ if (colStart != 0 || colEnd != absoluteWidths.Length)
+ canvas.RestoreState();
+ return y;
+ }
+
+ /** Gets and initializes the 4 layers where the table is written to. The text or graphics are added to
+ * one of the 4 PdfContentByte
returned with the following order:
+ *
PdfPtable.BASECANVAS
- the original PdfContentByte
. Anything placed here
+ * will be under the table.
+ * PdfPtable.BACKGROUNDCANVAS
- the layer where the background goes to.
+ * PdfPtable.LINECANVAS
- the layer where the lines go to.
+ * PdfPtable.TEXTCANVAS
- the layer where the text go to. Anything placed here
+ * will be over the table.
+ * PdfContentByte
where the rows will
+ * be written to
+ * @return an array of 4 PdfContentByte
+ * @see #writeSelectedRows(int, int, float, float, PdfContentByte[])
+ */
+ public static PdfContentByte[] BeginWritingRows(PdfContentByte canvas) {
+ return new PdfContentByte[]{
+ canvas,
+ canvas.Duplicate,
+ canvas.Duplicate,
+ canvas.Duplicate,
+ };
+ }
+
+ /** Finishes writing the table.
+ * @param canvases the array returned by beginWritingRows()
+ */
+ public static void EndWritingRows(PdfContentByte[] canvases) {
+ PdfContentByte canvas = canvases[BASECANVAS];
+ canvas.SaveState();
+ canvas.Add(canvases[BACKGROUNDCANVAS]);
+ canvas.RestoreState();
+ canvas.SaveState();
+ canvas.SetLineCap(2);
+ canvas.ResetRGBColorStroke();
+ canvas.Add(canvases[LINECANVAS]);
+ canvas.RestoreState();
+ canvas.Add(canvases[TEXTCANVAS]);
+ }
+
+ /** Gets the number of rows in this table.
+ * @return the number of rows in this table
+ */
+ public int Size {
+ get {
+ return rows.Count;
+ }
+ }
+
+ /** Gets the total height of the table.
+ * @return the total height of the table
+ */
+ public float TotalHeight {
+ get {
+ return totalHeight;
+ }
+ }
+
+ /** Gets the height of a particular row.
+ * @param idx the row index (starts at 0)
+ * @return the height of a particular row
+ */
+ public float GetRowHeight(int idx) {
+ if (totalWidth <= 0 || idx < 0 || idx >= rows.Count)
+ return 0;
+ PdfPRow row = (PdfPRow)rows[idx];
+ if (row == null)
+ return 0;
+ return row.MaxHeights;
+ }
+
+ /** Gets the height of the rows that constitute the header as defined by
+ * setHeaderRows()
.
+ * @return the height of the rows that constitute the header and footer
+ */
+ public float HeaderHeight {
+ get {
+ float total = 0;
+ int size = Math.Min(rows.Count, headerRows);
+ for (int k = 0; k < size; ++k) {
+ PdfPRow row = (PdfPRow)rows[k];
+ if (row != null)
+ total += row.MaxHeights;
+ }
+ return total;
+ }
+ }
+
+ /** Gets the height of the rows that constitute the header as defined by
+ * setFooterRows()
.
+ * @return the height of the rows that constitute the footer
+ * @since 2.1.1
+ */
+ public float FooterHeight {
+ get {
+ float total = 0;
+ int start = Math.Min(0, headerRows - footerRows);
+ int size = Math.Min(rows.Count, footerRows);
+ for (int k = start; k < size; ++k) {
+ PdfPRow row = (PdfPRow)rows[k];
+ if (row != null)
+ total += row.MaxHeights;
+ }
+ return total;
+ }
+ }
+
+ /** Deletes a row from the table.
+ * @param rowNumber the row to be deleted
+ * @return true
if the row was deleted
+ */
+ public bool DeleteRow(int rowNumber) {
+ if (rowNumber < 0 || rowNumber >= rows.Count) {
+ return false;
+ }
+ if (totalWidth > 0) {
+ PdfPRow row = (PdfPRow)rows[rowNumber];
+ if (row != null)
+ totalHeight -= row.MaxHeights;
+ }
+ rows.RemoveAt(rowNumber);
+ return true;
+ }
+
+ /** Deletes the last row in the table.
+ * @return true
if the last row was deleted
+ */
+ public bool DeleteLastRow() {
+ return DeleteRow(rows.Count - 1);
+ }
+
+ /**
+ * Removes all of the rows except headers
+ */
+ public void DeleteBodyRows() {
+ ArrayList rows2 = new ArrayList();
+ for (int k = 0; k < headerRows; ++k)
+ rows2.Add(rows[k]);
+ rows = rows2;
+ totalHeight = 0;
+ if (totalWidth > 0)
+ totalHeight = HeaderHeight;
+ }
+
+ /** Returns the number of columns.
+ * @return the number of columns.
+ * @since 2.1.1
+ */
+ public int NumberOfColumns {
+ get {
+ return relativeWidths.Length;
+ }
+ }
+ public int HeaderRows {
+ get {
+ return headerRows;
+ }
+ set {
+ headerRows = value;
+ if (headerRows < 0)
+ headerRows = 0;
+ }
+ }
+
+ public int FooterRows {
+ get {
+ return footerRows;
+ }
+ set {
+ footerRows = value;
+ if (footerRows < 0)
+ footerRows = 0;
+ }
+ }
+
+ /**
+ * Gets all the chunks in this element.
+ *
+ * @return an ArrayList
+ */
+ public ArrayList Chunks {
+ get {
+ return new ArrayList();
+ }
+ }
+
+ /**
+ * Gets the type of the text element.
+ *
+ * @return a type
+ */
+ public int Type {
+ get {
+ return Element.PTABLE;
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.Element#isContent()
+ * @since iText 2.0.8
+ */
+ public bool IsContent() {
+ return true;
+ }
+
+ /**
+ * @see com.lowagie.text.Element#isNestable()
+ * @since iText 2.0.8
+ */
+ public bool IsNestable() {
+ return true;
+ }
+
+ /**
+ * Processes the element by adding it (or the different parts) to an
+ * ElementListener
.
+ *
+ * @param listener an ElementListener
+ * @return true
if the element was processed successfully
+ */
+ public bool Process(IElementListener listener) {
+ try {
+ return listener.Add(this);
+ }
+ catch (DocumentException) {
+ return false;
+ }
+ }
+
+ public float WidthPercentage {
+ get {
+ return widthPercentage;
+ }
+ set {
+ widthPercentage = value;
+ }
+ }
+
+ public int HorizontalAlignment {
+ get {
+ return horizontalAlignment;
+ }
+ set {
+ horizontalAlignment = value;
+ }
+ }
+
+ /**
+ * Gets a row with a given index
+ * (added by Jin-Hsia Yang).
+ * @param idx
+ * @return the row at position idx
+ */
+ public PdfPRow GetRow(int idx) {
+ return (PdfPRow)rows[idx];
+ }
+
+ /**
+ * Gets an arraylist with all the rows in the table.
+ * @return an arraylist
+ */
+ public ArrayList Rows {
+ get {
+ return rows;
+ }
+ }
+
+ public IPdfPTableEvent TableEvent {
+ get {
+ return tableEvent;
+ }
+ set {
+ if (value == null) this.tableEvent = null;
+ else if (this.tableEvent == null) this.tableEvent = value;
+ else if (this.tableEvent is PdfPTableEventForwarder) ((PdfPTableEventForwarder)this.tableEvent).AddTableEvent(value);
+ else {
+ PdfPTableEventForwarder forward = new PdfPTableEventForwarder();
+ forward.AddTableEvent(this.tableEvent);
+ forward.AddTableEvent(value);
+ this.tableEvent = forward;
+ }
+ }
+ }
+
+ /** Gets the absolute sizes of each column width.
+ * @return he absolute sizes of each column width
+ */
+ public float[] AbsoluteWidths {
+ get {
+ return absoluteWidths;
+ }
+ }
+
+ internal float [][] GetEventWidths(float xPos, int firstRow, int lastRow, bool includeHeaders) {
+ if (includeHeaders) {
+ firstRow = Math.Max(firstRow, headerRows);
+ lastRow = Math.Max(lastRow, headerRows);
+ }
+ float[][] widths = new float[(includeHeaders ? headerRows : 0) + lastRow - firstRow][];
+ if (isColspan) {
+ int n = 0;
+ if (includeHeaders) {
+ for (int k = 0; k < headerRows; ++k) {
+ PdfPRow row = (PdfPRow)rows[k];
+ if (row == null)
+ ++n;
+ else
+ widths[n++] = row.GetEventWidth(xPos);
+ }
+ }
+ for (; firstRow < lastRow; ++firstRow) {
+ PdfPRow row = (PdfPRow)rows[firstRow];
+ if (row == null)
+ ++n;
+ else
+ widths[n++] = row.GetEventWidth(xPos);
+ }
+ }
+ else {
+ float[] width = new float[absoluteWidths.Length + 1];
+ width[0] = xPos;
+ for (int k = 0; k < absoluteWidths.Length; ++k)
+ width[k + 1] = width[k] + absoluteWidths[k];
+ for (int k = 0; k < widths.Length; ++k)
+ widths[k] = width;
+ }
+ return widths;
+ }
+
+ public bool SkipFirstHeader {
+ get {
+ return skipFirstHeader;
+ }
+ set {
+ skipFirstHeader = value;
+ }
+ }
+
+ public int RunDirection {
+ get {
+ return runDirection;
+ }
+ set {
+ if (value < PdfWriter.RUN_DIRECTION_DEFAULT || value > PdfWriter.RUN_DIRECTION_RTL)
+ throw new ArgumentException("Invalid run direction: " + value);
+ runDirection = value;
+ }
+ }
+
+ public bool LockedWidth {
+ get {
+ return lockedWidth;
+ }
+ set {
+ lockedWidth = value;
+ }
+ }
+
+ public bool SplitRows {
+ get {
+ return splitRows;
+ }
+ set {
+ splitRows = value;
+ }
+ }
+
+ public float SpacingBefore {
+ get {
+ return spacingBefore;
+ }
+ set {
+ spacingBefore = value;
+ }
+ }
+
+ public float SpacingAfter {
+ get {
+ return spacingAfter;
+ }
+ set {
+ spacingAfter = value;
+ }
+ }
+
+ public bool ExtendLastRow {
+ get {
+ return extendLastRow;
+ }
+ set {
+ extendLastRow = value;
+ }
+ }
+
+ public bool HeadersInEvent {
+ get {
+ return headersInEvent;
+ }
+ set {
+ headersInEvent = value;
+ }
+ }
+ public bool SplitLate {
+ get {
+ return splitLate;
+ }
+ set {
+ splitLate = value;
+ }
+ }
+
+ /**
+ * If true the table will be kept on one page if it fits, by forcing a
+ * new page if it doesn't fit on the current page. The default is to
+ * split the table over multiple pages.
+ *
+ * @param p_KeepTogether whether to try to keep the table on one page
+ */
+ public bool KeepTogether {
+ set {
+ keepTogether = value;
+ }
+ get {
+ return keepTogether;
+ }
+ }
+
+ /**
+ * Completes the current row with the default cell. An incomplete row will be dropped
+ * but calling this method will make sure that it will be present in the table.
+ */
+ public void CompleteRow() {
+ while (currentRowIdx > 0) {
+ AddCell(defaultCell);
+ }
+ }
+
+ /**
+ * @since iText 2.0.8
+ * @see com.lowagie.text.LargeElement#flushContent()
+ */
+ public void FlushContent() {
+ DeleteBodyRows();
+ SkipFirstHeader = true;
+ }
+
+ /**
+ * @since iText 2.0.8
+ * @see com.lowagie.text.LargeElement#isComplete()
+ */
+ public bool ElementComplete {
+ get {
+ return complete;
+ }
+ set {
+ complete = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPage.cs b/iTechSharp/iTextSharp/text/pdf/PdfPage.cs
new file mode 100644
index 0000000..a32fd29
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPage.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfPage.cs,v 1.3 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfPage
is the PDF Page-object.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 6.4 (page 73-81)
+ *
+ * @see PdfPageElement
+ * @see PdfPages
+ */
+
+ public class PdfPage : PdfDictionary {
+
+ // membervariables
+ private static String[] boxStrings = {"crop", "trim", "art", "bleed"};
+ private static PdfName[] boxNames = {PdfName.CROPBOX, PdfName.TRIMBOX, PdfName.ARTBOX, PdfName.BLEEDBOX};
+
+ /** value of the Rotate key for a page in PORTRAIT */
+ public static PdfNumber PORTRAIT = new PdfNumber(0);
+
+ /** value of the Rotate key for a page in LANDSCAPE */
+ public static PdfNumber LANDSCAPE = new PdfNumber(90);
+
+ /** value of the Rotate key for a page in INVERTEDPORTRAIT */
+ public static PdfNumber INVERTEDPORTRAIT = new PdfNumber(180);
+
+ /** value of the Rotate key for a page in SEASCAPE */
+ public static PdfNumber SEASCAPE = new PdfNumber(270);
+
+ /** value of the MediaBox key */
+ PdfRectangle mediaBox;
+
+ // constructors
+
+ /**
+ * Constructs a PdfPage
.
+ *
+ * @param mediaBox a value for the MediaBox key
+ * @param resources an indirect reference to a PdfResources
-object
+ * @param rotate a value for the Rotate key
+ */
+
+ internal PdfPage(PdfRectangle mediaBox, Hashtable boxSize, PdfDictionary resources, int rotate) : base(PAGE) {
+ this.mediaBox = mediaBox;
+ Put(PdfName.MEDIABOX, mediaBox);
+ Put(PdfName.RESOURCES, resources);
+ if (rotate != 0) {
+ Put(PdfName.ROTATE, new PdfNumber(rotate));
+ }
+ for (int k = 0; k < boxStrings.Length; ++k) {
+ PdfObject rect = (PdfObject)boxSize[boxStrings[k]];
+ if (rect != null)
+ Put(boxNames[k], rect);
+ }
+ }
+
+ /**
+ * Constructs a PdfPage
.
+ *
+ * @param mediaBox a value for the MediaBox key
+ * @param resources an indirect reference to a PdfResources
-object
+ */
+
+ internal PdfPage(PdfRectangle mediaBox, Hashtable boxSize, PdfDictionary resources) : this(mediaBox, boxSize, resources, 0) {
+ }
+
+ /**
+ * Checks if this page element is a tree of pages.
+ * false
.
+ *
+ * @return false
because this is a single page
+ */
+
+ public bool IsParent() {
+ return false;
+ }
+
+ // methods
+
+ /**
+ * Adds an indirect reference pointing to a PdfContents
-object.
+ *
+ * @param contents an indirect reference to a PdfContents
-object
+ */
+
+ internal void Add(PdfIndirectReference contents) {
+ Put(PdfName.CONTENTS, contents);
+ }
+
+ /**
+ * Rotates the mediabox, but not the text in it.
+ *
+ * @return a PdfRectangle
+ */
+
+ internal PdfRectangle RotateMediaBox() {
+ this.mediaBox = mediaBox.Rotate;
+ Put(PdfName.MEDIABOX, this.mediaBox);
+ return this.mediaBox;
+ }
+
+ /**
+ * Returns the MediaBox of this Page.
+ *
+ * @return a PdfRectangle
+ */
+
+ internal PdfRectangle MediaBox {
+ get {
+ return mediaBox;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPageEventHelper.cs b/iTechSharp/iTextSharp/text/pdf/PdfPageEventHelper.cs
new file mode 100644
index 0000000..28afb85
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPageEventHelper.cs
@@ -0,0 +1,202 @@
+using System;
+
+using iTextSharp.text;
+
+/*
+ * $Id: PdfPageEventHelper.cs,v 1.3 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * Helps the use of PdfPageEvent
by implementing all the interface methods.
+ * A class can extend PdfPageEventHelper
and only implement the
+ * needed methods.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+
+ public class PdfPageEventHelper : IPdfPageEvent {
+
+ /**
+ * Called when the document is opened.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ */
+ public virtual void OnOpenDocument(PdfWriter writer,Document document) {
+ }
+
+ /**
+ * Called when a page is initialized.
+ * onEndPage
to avoid
+ * infinite loops.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ */
+ public virtual void OnStartPage(PdfWriter writer,Document document) {
+ }
+
+ /**
+ * Called when a page is finished, just before being written to the document.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ */
+ public virtual void OnEndPage(PdfWriter writer,Document document) {
+ }
+
+ /**
+ * Called when the document is closed.
+ * PdfWriter
for this document
+ * @param document the document
+ */
+ public virtual void OnCloseDocument(PdfWriter writer,Document document) {
+ }
+
+ /**
+ * Called when a Paragraph is written.
+ * paragraphPosition
will hold the height at which the
+ * paragraph will be written to. This is useful to insert bookmarks with
+ * more control.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position the paragraph will be written to
+ */
+ public virtual void OnParagraph(PdfWriter writer,Document document,float paragraphPosition) {
+ }
+
+ /**
+ * Called when a Paragraph is written.
+ * paragraphPosition
will hold the height of the end of the paragraph.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position of the end of the paragraph
+ */
+ public virtual void OnParagraphEnd(PdfWriter writer,Document document,float paragraphPosition) {
+ }
+
+ /**
+ * Called when a Chapter is written.
+ * position
will hold the height at which the
+ * chapter will be written to.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position the chapter will be written to
+ * @param title the title of the Chapter
+ */
+ public virtual void OnChapter(PdfWriter writer,Document document,float paragraphPosition,Paragraph title) {
+ }
+
+ /**
+ * Called when the end of a Chapter is reached.
+ * position
will hold the height of the end of the chapter.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param position the position of the end of the chapter.
+ */
+ public virtual void OnChapterEnd(PdfWriter writer,Document document,float position) {
+ }
+
+ /**
+ * Called when a Section is written.
+ * position
will hold the height at which the
+ * section will be written to.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param paragraphPosition the position the chapter will be written to
+ * @param title the title of the Chapter
+ */
+ public virtual void OnSection(PdfWriter writer,Document document,float paragraphPosition,int depth,Paragraph title) {
+ }
+
+ /**
+ * Called when the end of a Section is reached.
+ * position
will hold the height of the section end.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param position the position of the end of the section
+ */
+ public virtual void OnSectionEnd(PdfWriter writer,Document document,float position) {
+ }
+
+ /**
+ * Called when a Chunk
with a generic tag is written.
+ * Chunk
location to generate
+ * bookmarks, for example.
+ *
+ * @param writer the PdfWriter
for this document
+ * @param document the document
+ * @param rect the Rectangle
containing the Chunk
+ * @param text the text of the tag
+ */
+ public virtual void OnGenericTag(PdfWriter writer,Document document,Rectangle rect,string text) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPageLabels.cs b/iTechSharp/iTextSharp/text/pdf/PdfPageLabels.cs
new file mode 100644
index 0000000..e8c76b7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPageLabels.cs
@@ -0,0 +1,289 @@
+using System;
+using System.Collections;
+using System.util;
+using iTextSharp.text;
+using iTextSharp.text.factories;
+
+/*
+ * $Id: PdfPageLabels.cs,v 1.9 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Page labels are used to identify each
+ * page visually on the screen or in print.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfPageLabels {
+
+ /** Logical pages will have the form 1,2,3,...
+ */
+ public const int DECIMAL_ARABIC_NUMERALS = 0;
+ /** Logical pages will have the form I,II,III,IV,...
+ */
+ public const int UPPERCASE_ROMAN_NUMERALS = 1;
+ /** Logical pages will have the form i,ii,iii,iv,...
+ */
+ public const int LOWERCASE_ROMAN_NUMERALS = 2;
+ /** Logical pages will have the form of uppercase letters
+ * (A to Z for the first 26 pages, AA to ZZ for the next 26, and so on)
+ */
+ public const int UPPERCASE_LETTERS = 3;
+ /** Logical pages will have the form of uppercase letters
+ * (a to z for the first 26 pages, aa to zz for the next 26, and so on)
+ */
+ public const int LOWERCASE_LETTERS = 4;
+ /** No logical page numbers are generated but fixed text may
+ * still exist
+ */
+ public const int EMPTY = 5;
+ /** Dictionary values to set the logical page styles
+ */
+ internal static PdfName[] numberingStyle = {PdfName.D, PdfName.R,
+ new PdfName("r"), PdfName.A, new PdfName("a")};
+ /** The sequence of logical pages. Will contain at least a value for page 1
+ */
+ internal Hashtable map;
+
+ /** Creates a new PdfPageLabel with a default logical page 1
+ */
+ public PdfPageLabels() {
+ map = new Hashtable();
+ AddPageLabel(1, DECIMAL_ARABIC_NUMERALS, null, 1);
+ }
+
+ /** Adds or replaces a page label.
+ * @param page the real page to start the numbering. First page is 1
+ * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS
+ * @param text the text to prefix the number. Can be null
or empty
+ * @param firstPage the first logical page number
+ */
+ public void AddPageLabel(int page, int numberStyle, string text, int firstPage) {
+ if (page < 1 || firstPage < 1)
+ throw new ArgumentException("In a page label the page numbers must be greater or equal to 1.");
+ PdfDictionary dic = new PdfDictionary();
+ if (numberStyle >= 0 && numberStyle < numberingStyle.Length)
+ dic.Put(PdfName.S, numberingStyle[numberStyle]);
+ if (text != null)
+ dic.Put(PdfName.P, new PdfString(text, PdfObject.TEXT_UNICODE));
+ if (firstPage != 1)
+ dic.Put(PdfName.ST, new PdfNumber(firstPage));
+ map[page - 1] = dic;
+ }
+
+ /** Adds or replaces a page label. The first logical page has the default
+ * of 1.
+ * @param page the real page to start the numbering. First page is 1
+ * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS
+ * @param text the text to prefix the number. Can be null
or empty
+ */
+ public void AddPageLabel(int page, int numberStyle, string text) {
+ AddPageLabel(page, numberStyle, text, 1);
+ }
+
+ /** Adds or replaces a page label. There is no text prefix and the first
+ * logical page has the default of 1.
+ * @param page the real page to start the numbering. First page is 1
+ * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS
+ */
+ public void AddPageLabel(int page, int numberStyle) {
+ AddPageLabel(page, numberStyle, null, 1);
+ }
+
+ /** Adds or replaces a page label.
+ */
+ public void AddPageLabel(PdfPageLabelFormat format) {
+ AddPageLabel(format.physicalPage, format.numberStyle, format.prefix, format.logicalPage);
+ }
+
+ /** Removes a page label. The first page lagel can not be removed, only changed.
+ * @param page the real page to remove
+ */
+ public void RemovePageLabel(int page) {
+ if (page <= 1)
+ return;
+ map.Remove(page - 1);
+ }
+
+ /** Gets the page label dictionary to insert into the document.
+ * @return the page label dictionary
+ */
+ internal PdfDictionary GetDictionary(PdfWriter writer) {
+ return PdfNumberTree.WriteTree(map, writer);
+ }
+
+ /**
+ * Retrieves the page labels from a PDF as an array of String objects.
+ * @param reader a PdfReader object that has the page labels you want to retrieve
+ * @return a String array or null
if no page labels are present
+ */
+ public static String[] GetPageLabels(PdfReader reader) {
+
+ int n = reader.NumberOfPages;
+
+ PdfDictionary dict = reader.Catalog;
+ PdfDictionary labels = (PdfDictionary)PdfReader.GetPdfObjectRelease(dict.Get(PdfName.PAGELABELS));
+ if (labels == null)
+ return null;
+
+ String[] labelstrings = new String[n];
+ Hashtable numberTree = PdfNumberTree.ReadTree(labels);
+
+ int pagecount = 1;
+ String prefix = "";
+ char type = 'D';
+ for (int i = 0; i < n; i++) {
+ if (numberTree.ContainsKey(i)) {
+ PdfDictionary d = (PdfDictionary)PdfReader.GetPdfObjectRelease((PdfObject)numberTree[i]);
+ if (d.Contains(PdfName.ST)) {
+ pagecount = ((PdfNumber)d.Get(PdfName.ST)).IntValue;
+ }
+ else {
+ pagecount = 1;
+ }
+ if (d.Contains(PdfName.P)) {
+ prefix = ((PdfString)d.Get(PdfName.P)).ToUnicodeString();
+ }
+ if (d.Contains(PdfName.S)) {
+ type = ((PdfName)d.Get(PdfName.S)).ToString()[1];
+ }
+ }
+ switch (type) {
+ default:
+ labelstrings[i] = prefix + pagecount;
+ break;
+ case 'R':
+ labelstrings[i] = prefix + RomanNumberFactory.GetUpperCaseString(pagecount);
+ break;
+ case 'r':
+ labelstrings[i] = prefix + RomanNumberFactory.GetLowerCaseString(pagecount);
+ break;
+ case 'A':
+ labelstrings[i] = prefix + RomanAlphabetFactory.GetUpperCaseString(pagecount);
+ break;
+ case 'a':
+ labelstrings[i] = prefix + RomanAlphabetFactory.GetLowerCaseString(pagecount);
+ break;
+ }
+ pagecount++;
+ }
+ return labelstrings;
+ }
+
+ /**
+ * Retrieves the page labels from a PDF as an array of {@link PdfPageLabelFormat} objects.
+ * @param reader a PdfReader object that has the page labels you want to retrieve
+ * @return a PdfPageLabelEntry array, containing an entry for each format change
+ * or null
if no page labels are present
+ */
+ public static PdfPageLabelFormat[] GetPageLabelFormats(PdfReader reader) {
+ PdfDictionary dict = reader.Catalog;
+ PdfDictionary labels = (PdfDictionary)PdfReader.GetPdfObjectRelease(dict.Get(PdfName.PAGELABELS));
+ if (labels == null)
+ return null;
+ Hashtable numberTree = PdfNumberTree.ReadTree(labels);
+ int[] numbers = new int[numberTree.Count];
+ numberTree.Keys.CopyTo(numbers, 0);
+ Array.Sort(numbers);
+ PdfPageLabelFormat[] formats = new PdfPageLabelFormat[numberTree.Count];
+ String prefix;
+ int numberStyle;
+ int pagecount;
+ for (int k = 0; k < numbers.Length; ++k) {
+ int key = numbers[k];
+ PdfDictionary d = (PdfDictionary)PdfReader.GetPdfObjectRelease((PdfObject)numberTree[key]);
+ if (d.Contains(PdfName.ST)) {
+ pagecount = ((PdfNumber)d.Get(PdfName.ST)).IntValue;
+ } else {
+ pagecount = 1;
+ }
+ if (d.Contains(PdfName.P)) {
+ prefix = ((PdfString)d.Get(PdfName.P)).ToUnicodeString();
+ } else {
+ prefix = "";
+ }
+ if (d.Contains(PdfName.S)) {
+ char type = ((PdfName)d.Get(PdfName.S)).ToString()[1];
+ switch (type) {
+ case 'R': numberStyle = UPPERCASE_ROMAN_NUMERALS; break;
+ case 'r': numberStyle = LOWERCASE_ROMAN_NUMERALS; break;
+ case 'A': numberStyle = UPPERCASE_LETTERS; break;
+ case 'a': numberStyle = LOWERCASE_LETTERS; break;
+ default: numberStyle = DECIMAL_ARABIC_NUMERALS; break;
+ }
+ } else {
+ numberStyle = EMPTY;
+ }
+ formats[k] = new PdfPageLabelFormat(key + 1, numberStyle, prefix, pagecount);
+ }
+ return formats;
+ }
+
+ public class PdfPageLabelFormat {
+
+ public int physicalPage;
+ public int numberStyle;
+ public String prefix;
+ public int logicalPage;
+
+ /** Creates a page label format.
+ * @param physicalPage the real page to start the numbering. First page is 1
+ * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS
+ * @param prefix the text to prefix the number. Can be null
or empty
+ * @param logicalPage the first logical page number
+ */
+ public PdfPageLabelFormat(int physicalPage, int numberStyle, String prefix, int logicalPage) {
+ this.physicalPage = physicalPage;
+ this.numberStyle = numberStyle;
+ this.prefix = prefix;
+ this.logicalPage = logicalPage;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPages.cs b/iTechSharp/iTextSharp/text/pdf/PdfPages.cs
new file mode 100644
index 0000000..2634da6
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPages.cs
@@ -0,0 +1,195 @@
+using System;
+using System.Collections;
+using System.IO;
+/*
+ * $Id: PdfPages.cs,v 1.3 2008/05/13 11:25:21 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfPages
is the PDF Pages-object.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 6.3 (page 71-73)
+ *
+ * @see PdfPageElement
+ * @see PdfPage
+ */
+
+ public class PdfPages {
+
+ private ArrayList pages = new ArrayList();
+ private ArrayList parents = new ArrayList();
+ private int leafSize = 10;
+ private PdfWriter writer;
+ private PdfIndirectReference topParent;
+
+ // constructors
+
+ /**
+ * Constructs a PdfPages
-object.
+ */
+
+ internal PdfPages(PdfWriter writer) {
+ this.writer = writer;
+ }
+
+ internal void AddPage(PdfDictionary page) {
+ if ((pages.Count % leafSize) == 0)
+ parents.Add(writer.PdfIndirectReference);
+ PdfIndirectReference parent = (PdfIndirectReference)parents[parents.Count - 1];
+ page.Put(PdfName.PARENT, parent);
+ PdfIndirectReference current = writer.CurrentPage;
+ writer.AddToBody(page, current);
+ pages.Add(current);
+ }
+
+ internal PdfIndirectReference AddPageRef(PdfIndirectReference pageRef) {
+ if ((pages.Count % leafSize) == 0)
+ parents.Add(writer.PdfIndirectReference);
+ pages.Add(pageRef);
+ return (PdfIndirectReference)parents[parents.Count - 1];
+ }
+
+ // returns the top parent to include in the catalog
+ internal PdfIndirectReference WritePageTree() {
+ if (pages.Count == 0)
+ throw new IOException("The document has no pages.");
+ int leaf = 1;
+ ArrayList tParents = parents;
+ ArrayList tPages = pages;
+ ArrayList nextParents = new ArrayList();
+ while (true) {
+ leaf *= leafSize;
+ int stdCount = leafSize;
+ int rightCount = tPages.Count % leafSize;
+ if (rightCount == 0)
+ rightCount = leafSize;
+ for (int p = 0; p < tParents.Count; ++p) {
+ int count;
+ int thisLeaf = leaf;
+ if (p == tParents.Count - 1) {
+ count = rightCount;
+ thisLeaf = pages.Count % leaf;
+ if (thisLeaf == 0)
+ thisLeaf = leaf;
+ }
+ else
+ count = stdCount;
+ PdfDictionary top = new PdfDictionary(PdfName.PAGES);
+ top.Put(PdfName.COUNT, new PdfNumber(thisLeaf));
+ PdfArray kids = new PdfArray();
+ ArrayList intern = kids.ArrayList;
+ intern.AddRange(tPages.GetRange(p * stdCount, count));
+ top.Put(PdfName.KIDS, kids);
+ if (tParents.Count > 1) {
+ if ((p % leafSize) == 0)
+ nextParents.Add(writer.PdfIndirectReference);
+ top.Put(PdfName.PARENT, (PdfIndirectReference)nextParents[p / leafSize]);
+ }
+ writer.AddToBody(top, (PdfIndirectReference)tParents[p]);
+ }
+ if (tParents.Count == 1) {
+ topParent = (PdfIndirectReference)tParents[0];
+ return topParent;
+ }
+ tPages = tParents;
+ tParents = nextParents;
+ nextParents = new ArrayList();
+ }
+ }
+
+ internal PdfIndirectReference TopParent {
+ get {
+ return topParent;
+ }
+ }
+
+ internal void SetLinearMode(PdfIndirectReference topParent) {
+ if (parents.Count > 1)
+ throw new Exception("Linear page mode can only be called with a single parent.");
+ if (topParent != null) {
+ this.topParent = topParent;
+ parents.Clear();
+ parents.Add(topParent);
+ }
+ leafSize = 10000000;
+ }
+
+ internal void AddPage(PdfIndirectReference page) {
+ pages.Add(page);
+ }
+
+ internal int ReorderPages(int[] order) {
+ if (order == null)
+ return pages.Count;
+ if (parents.Count > 1)
+ throw new DocumentException("Page reordering requires a single parent in the page tree. Call PdfWriter.SetLinearMode() after open.");
+ if (order.Length != pages.Count)
+ throw new DocumentException("Page reordering requires an array with the same size as the number of pages.");
+ int max = pages.Count;
+ bool[] temp = new bool[max];
+ for (int k = 0; k < max; ++k) {
+ int p = order[k];
+ if (p < 1 || p > max)
+ throw new DocumentException("Page reordering requires pages between 1 and " + max + ". Found " + p + ".");
+ if (temp[p - 1])
+ throw new DocumentException("Page reordering requires no page repetition. Page " + p + " is repeated.");
+ temp[p - 1] = true;
+ }
+ Object[] copy = pages.ToArray();
+ for (int k = 0; k < max; ++k) {
+ pages[k] = copy[order[k] - 1];
+ }
+ return max;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPattern.cs b/iTechSharp/iTextSharp/text/pdf/PdfPattern.cs
new file mode 100644
index 0000000..1f1917d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPattern.cs
@@ -0,0 +1,79 @@
+using System;
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfPattern
defines a ColorSpace
+ *
+ * @see PdfStream
+ */
+
+ public class PdfPattern : PdfStream {
+
+ internal PdfPattern(PdfPatternPainter painter) : base() {
+ PdfNumber one = new PdfNumber(1);
+ PdfArray matrix = painter.Matrix;
+ if ( matrix != null ) {
+ Put(PdfName.MATRIX, matrix);
+ }
+ Put(PdfName.TYPE, PdfName.PATTERN);
+ Put(PdfName.BBOX, new PdfRectangle(painter.BoundingBox));
+ Put(PdfName.RESOURCES, painter.Resources);
+ Put(PdfName.TILINGTYPE, one);
+ Put(PdfName.PATTERNTYPE, one);
+ if (painter.IsStencil())
+ Put(PdfName.PAINTTYPE, new PdfNumber(2));
+ else
+ Put(PdfName.PAINTTYPE, one);
+ Put(PdfName.XSTEP, new PdfNumber(painter.XStep));
+ Put(PdfName.YSTEP, new PdfNumber(painter.YStep));
+ bytes = painter.ToPdf(null);
+ Put(PdfName.LENGTH, new PdfNumber(bytes.Length));
+ FlateCompress();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPatternPainter.cs b/iTechSharp/iTextSharp/text/pdf/PdfPatternPainter.cs
new file mode 100644
index 0000000..6172575
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPatternPainter.cs
@@ -0,0 +1,360 @@
+using System;
+using iTextSharp.text;
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * Implements the pattern.
+ */
+
+ public sealed class PdfPatternPainter : PdfTemplate {
+
+ internal float xstep, ystep;
+ internal bool stencil = false;
+ internal Color defaultColor;
+
+ /**
+ *Creates a PdfPattern
.
+ */
+
+ private PdfPatternPainter() : base() {
+ type = TYPE_PATTERN;
+ }
+
+ /**
+ * Creates new PdfPattern
+ *
+ * @param wr the PdfWriter
+ */
+
+ internal PdfPatternPainter(PdfWriter wr) : base(wr) {
+ type = TYPE_PATTERN;
+ }
+
+ internal PdfPatternPainter(PdfWriter wr, Color defaultColor) : this(wr) {
+ stencil = true;
+ if (defaultColor == null)
+ this.defaultColor = new Color(System.Drawing.Color.Gray);
+ else
+ this.defaultColor = defaultColor;
+ }
+
+ public float XStep {
+ get {
+ return this.xstep;
+ }
+
+ set {
+ this.xstep = value;
+ }
+ }
+
+ public float YStep {
+ get {
+ return this.ystep;
+ }
+
+ set {
+ this.ystep = value;
+ }
+ }
+
+ public bool IsStencil() {
+ return stencil;
+ }
+
+ public void SetPatternMatrix(float a, float b, float c, float d, float e, float f) {
+ SetMatrix(a, b, c, d, e, f);
+ }
+ /**
+ * Gets the stream representing this pattern
+ *
+ * @return the stream representing this pattern
+ */
+
+ internal PdfPattern Pattern {
+ get {
+ return new PdfPattern(this);
+ }
+ }
+
+ /**
+ * Gets a duplicate of this PdfPatternPainter
. All
+ * the members are copied by reference but the buffer stays different.
+ * @return a copy of this PdfPatternPainter
+ */
+
+ public override PdfContentByte Duplicate {
+ get {
+ PdfPatternPainter tpl = new PdfPatternPainter();
+ tpl.writer = writer;
+ tpl.pdf = pdf;
+ tpl.thisReference = thisReference;
+ tpl.pageResources = pageResources;
+ tpl.bBox = new Rectangle(bBox);
+ tpl.xstep = xstep;
+ tpl.ystep = ystep;
+ tpl.matrix = matrix;
+ tpl.stencil = stencil;
+ tpl.defaultColor = defaultColor;
+ return tpl;
+ }
+ }
+
+ public Color DefaultColor {
+ get {
+ return defaultColor;
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setGrayFill(float)
+ */
+ public override void SetGrayFill(float gray) {
+ CheckNoColor();
+ base.SetGrayFill(gray);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#resetGrayFill()
+ */
+ public override void ResetGrayFill() {
+ CheckNoColor();
+ base.ResetGrayFill();
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setGrayStroke(float)
+ */
+ public override void SetGrayStroke(float gray) {
+ CheckNoColor();
+ base.SetGrayStroke(gray);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#resetGrayStroke()
+ */
+ public override void ResetGrayStroke() {
+ CheckNoColor();
+ base.ResetGrayStroke();
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorFillF(float, float, float)
+ */
+ public override void SetRGBColorFillF(float red, float green, float blue) {
+ CheckNoColor();
+ base.SetRGBColorFillF(red, green, blue);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#resetRGBColorFill()
+ */
+ public override void ResetRGBColorFill() {
+ CheckNoColor();
+ base.ResetRGBColorFill();
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorStrokeF(float, float, float)
+ */
+ public override void SetRGBColorStrokeF(float red, float green, float blue) {
+ CheckNoColor();
+ base.SetRGBColorStrokeF(red, green, blue);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#resetRGBColorStroke()
+ */
+ public override void ResetRGBColorStroke() {
+ CheckNoColor();
+ base.ResetRGBColorStroke();
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorFillF(float, float, float, float)
+ */
+ public override void SetCMYKColorFillF(float cyan, float magenta, float yellow, float black) {
+ CheckNoColor();
+ base.SetCMYKColorFillF(cyan, magenta, yellow, black);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#resetCMYKColorFill()
+ */
+ public override void ResetCMYKColorFill() {
+ CheckNoColor();
+ base.ResetCMYKColorFill();
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorStrokeF(float, float, float, float)
+ */
+ public override void SetCMYKColorStrokeF(float cyan, float magenta, float yellow, float black) {
+ CheckNoColor();
+ base.SetCMYKColorStrokeF(cyan, magenta, yellow, black);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#resetCMYKColorStroke()
+ */
+ public override void ResetCMYKColorStroke() {
+ CheckNoColor();
+ base.ResetCMYKColorStroke();
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#addImage(com.lowagie.text.Image, float, float, float, float, float, float)
+ */
+ public override void AddImage(Image image, float a, float b, float c, float d, float e, float f) {
+ if (stencil && !image.IsMask())
+ CheckNoColor();
+ base.AddImage(image, a, b, c, d, e, f);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorFill(int, int, int, int)
+ */
+ public override void SetCMYKColorFill(int cyan, int magenta, int yellow, int black) {
+ CheckNoColor();
+ base.SetCMYKColorFill(cyan, magenta, yellow, black);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorStroke(int, int, int, int)
+ */
+ public override void SetCMYKColorStroke(int cyan, int magenta, int yellow, int black) {
+ CheckNoColor();
+ base.SetCMYKColorStroke(cyan, magenta, yellow, black);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorFill(int, int, int)
+ */
+ public override void SetRGBColorFill(int red, int green, int blue) {
+ CheckNoColor();
+ base.SetRGBColorFill(red, green, blue);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorStroke(int, int, int)
+ */
+ public override void SetRGBColorStroke(int red, int green, int blue) {
+ CheckNoColor();
+ base.SetRGBColorStroke(red, green, blue);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setColorStroke(java.awt.Color)
+ */
+ public override void SetColorStroke(Color color) {
+ CheckNoColor();
+ base.SetColorStroke(color);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setColorFill(java.awt.Color)
+ */
+ public override void SetColorFill(Color color) {
+ CheckNoColor();
+ base.SetColorFill(color);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setColorFill(com.lowagie.text.pdf.PdfSpotColor, float)
+ */
+ public override void SetColorFill(PdfSpotColor sp, float tint) {
+ CheckNoColor();
+ base.SetColorFill(sp, tint);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setColorStroke(com.lowagie.text.pdf.PdfSpotColor, float)
+ */
+ public override void SetColorStroke(PdfSpotColor sp, float tint) {
+ CheckNoColor();
+ base.SetColorStroke(sp, tint);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setPatternFill(com.lowagie.text.pdf.PdfPatternPainter)
+ */
+ public override void SetPatternFill(PdfPatternPainter p) {
+ CheckNoColor();
+ base.SetPatternFill(p);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setPatternFill(com.lowagie.text.pdf.PdfPatternPainter, java.awt.Color, float)
+ */
+ public override void SetPatternFill(PdfPatternPainter p, Color color, float tint) {
+ CheckNoColor();
+ base.SetPatternFill(p, color, tint);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setPatternStroke(com.lowagie.text.pdf.PdfPatternPainter, java.awt.Color, float)
+ */
+ public override void SetPatternStroke(PdfPatternPainter p, Color color, float tint) {
+ CheckNoColor();
+ base.SetPatternStroke(p, color, tint);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfContentByte#setPatternStroke(com.lowagie.text.pdf.PdfPatternPainter)
+ */
+ public override void SetPatternStroke(PdfPatternPainter p) {
+ CheckNoColor();
+ base.SetPatternStroke(p);
+ }
+
+ internal void CheckNoColor() {
+ if (stencil)
+ throw new ArgumentException("Colors are not allowed in uncolored tile patterns.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPublicKeyRecipient.cs b/iTechSharp/iTextSharp/text/pdf/PdfPublicKeyRecipient.cs
new file mode 100644
index 0000000..5febe94
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPublicKeyRecipient.cs
@@ -0,0 +1,41 @@
+using System;
+using Org.BouncyCastle.X509;
+
+
+namespace iTextSharp.text.pdf {
+
+ public class PdfPublicKeyRecipient {
+
+ private X509Certificate certificate = null;
+
+ private int permission = 0;
+
+ protected byte[] cms = null;
+
+ public PdfPublicKeyRecipient(X509Certificate certificate, int permission) {
+ this.certificate = certificate;
+ this.permission = permission;
+ }
+
+ public X509Certificate Certificate {
+ get {
+ return certificate;
+ }
+ }
+
+ public int Permission {
+ get {
+ return permission;
+ }
+ }
+
+ protected internal byte[] Cms {
+ set {
+ cms = value;
+ }
+ get {
+ return cms;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfPublicKeySecurityHandler.cs b/iTechSharp/iTextSharp/text/pdf/PdfPublicKeySecurityHandler.cs
new file mode 100644
index 0000000..3cbcb98
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfPublicKeySecurityHandler.cs
@@ -0,0 +1,197 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text.pdf.crypto;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Security;
+
+
+/**
+ * The below 2 methods are from pdfbox.
+ *
+ * private DERObject CreateDERForRecipient(byte[] in, X509Certificate cert) ;
+ * private KeyTransRecipientInfo ComputeRecipientInfo(X509Certificate x509certificate, byte[] abyte0);
+ *
+ * 2006-11-22 Aiken Sam.
+ */
+
+/**
+ * Copyright (c) 2003-2006, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * @author Aiken Sam (aikensam@ieee.org)
+ */
+ public class PdfPublicKeySecurityHandler {
+
+ private const int SEED_LENGTH = 20;
+
+ private ArrayList recipients = null;
+
+ private byte[] seed;
+
+ public PdfPublicKeySecurityHandler() {
+ seed = IVGenerator.GetIV(SEED_LENGTH);
+ recipients = new ArrayList();
+ }
+
+
+ public void AddRecipient(PdfPublicKeyRecipient recipient) {
+ recipients.Add(recipient);
+ }
+
+ protected internal byte[] GetSeed() {
+ return (byte[])seed.Clone();
+ }
+
+ public int GetRecipientsSize() {
+ return recipients.Count;
+ }
+
+ public byte[] GetEncodedRecipient(int index) {
+ //Certificate certificate = recipient.GetX509();
+ PdfPublicKeyRecipient recipient = (PdfPublicKeyRecipient)recipients[index];
+ byte[] cms = recipient.Cms;
+
+ if (cms != null) return cms;
+
+ X509Certificate certificate = recipient.Certificate;
+ int permission = recipient.Permission;//PdfWriter.AllowCopy | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders | PdfWriter.AllowAssembly;
+ int revision = 3;
+
+ permission |= (int)(revision==3 ? (uint)0xfffff0c0 : (uint)0xffffffc0);
+ permission &= unchecked((int)0xfffffffc);
+ permission += 1;
+
+ byte[] pkcs7input = new byte[24];
+
+ byte one = (byte)(permission);
+ byte two = (byte)(permission >> 8);
+ byte three = (byte)(permission >> 16);
+ byte four = (byte)(permission >> 24);
+
+ System.Array.Copy(seed, 0, pkcs7input, 0, 20); // put this seed in the pkcs7 input
+
+ pkcs7input[20] = four;
+ pkcs7input[21] = three;
+ pkcs7input[22] = two;
+ pkcs7input[23] = one;
+
+ Asn1Object obj = CreateDERForRecipient(pkcs7input, certificate);
+
+ MemoryStream baos = new MemoryStream();
+
+ DerOutputStream k = new DerOutputStream(baos);
+
+ k.WriteObject(obj);
+
+ cms = baos.ToArray();
+
+ recipient.Cms = cms;
+
+ return cms;
+ }
+
+ public PdfArray GetEncodedRecipients() {
+ PdfArray EncodedRecipients = new PdfArray();
+ byte[] cms = null;
+ for (int i=0; iInputStream
containing the document. The stream is read to the
+ * end but is not closed
+ * @param ownerPassword the password to read the document
+ * @throws IOException on error
+ */
+ public PdfReader(Stream isp, byte[] ownerPassword) {
+ password = ownerPassword;
+ tokens = new PRTokeniser(new RandomAccessFileOrArray(isp));
+ ReadPdf();
+ }
+
+ /**
+ * Reads and parses a PDF document.
+ * @param isp the InputStream
containing the document. The stream is read to the
+ * end but is not closed
+ * @throws IOException on error
+ */
+ public PdfReader(Stream isp) : this(isp, null) {
+ }
+
+ /**
+ * Reads and parses a pdf document. Contrary to the other constructors only the xref is read
+ * into memory. The reader is said to be working in "partial" mode as only parts of the pdf
+ * are read as needed. The pdf is left open but may be closed at any time with
+ * PdfReader.Close()
, reopen is automatic.
+ * @param raf the document location
+ * @param ownerPassword the password or null
for no password
+ * @throws IOException on error
+ */
+ public PdfReader(RandomAccessFileOrArray raf, byte[] ownerPassword) {
+ password = ownerPassword;
+ partial = true;
+ tokens = new PRTokeniser(raf);
+ ReadPdfPartial();
+ }
+
+ /** Creates an independent duplicate.
+ * @param reader the PdfReader
to duplicate
+ */
+ public PdfReader(PdfReader reader) {
+ this.appendable = reader.appendable;
+ this.consolidateNamedDestinations = reader.consolidateNamedDestinations;
+ this.encrypted = reader.encrypted;
+ this.rebuilt = reader.rebuilt;
+ this.sharedStreams = reader.sharedStreams;
+ this.tampered = reader.tampered;
+ this.password = reader.password;
+ this.pdfVersion = reader.pdfVersion;
+ this.eofPos = reader.eofPos;
+ this.freeXref = reader.freeXref;
+ this.lastXref = reader.lastXref;
+ this.tokens = new PRTokeniser(reader.tokens.SafeFile);
+ if (reader.decrypt != null)
+ this.decrypt = new PdfEncryption(reader.decrypt);
+ this.pValue = reader.pValue;
+ this.rValue = reader.rValue;
+ this.xrefObj = new ArrayList(reader.xrefObj);
+ for (int k = 0; k < reader.xrefObj.Count; ++k) {
+ this.xrefObj[k] = DuplicatePdfObject((PdfObject)reader.xrefObj[k], this);
+ }
+ this.pageRefs = new PageRefs(reader.pageRefs, this);
+ this.trailer = (PdfDictionary)DuplicatePdfObject(reader.trailer, this);
+ this.catalog = (PdfDictionary)GetPdfObject(trailer.Get(PdfName.ROOT));
+ this.rootPages = (PdfDictionary)GetPdfObject(catalog.Get(PdfName.PAGES));
+ this.fileLength = reader.fileLength;
+ this.partial = reader.partial;
+ this.hybridXref = reader.hybridXref;
+ this.objStmToOffset = reader.objStmToOffset;
+ this.xref = reader.xref;
+ this.cryptoRef = (PRIndirectReference)DuplicatePdfObject(reader.cryptoRef, this);
+ this.ownerPasswordUsed = reader.ownerPasswordUsed;
+ }
+
+ /** Gets a new file instance of the original PDF
+ * document.
+ * @return a new file instance of the original PDF document
+ */
+ public RandomAccessFileOrArray SafeFile {
+ get {
+ return tokens.SafeFile;
+ }
+ }
+
+ protected internal PdfReaderInstance GetPdfReaderInstance(PdfWriter writer) {
+ return new PdfReaderInstance(this, writer);
+ }
+
+ /** Gets the number of pages in the document.
+ * @return the number of pages in the document
+ */
+ public int NumberOfPages {
+ get {
+ return pageRefs.Size;
+ }
+ }
+
+ /** Returns the document's catalog. This dictionary is not a copy,
+ * any changes will be reflected in the catalog.
+ * @return the document's catalog
+ */
+ public PdfDictionary Catalog {
+ get {
+ return catalog;
+ }
+ }
+
+ /** Returns the document's acroform, if it has one.
+ * @return the document's acroform
+ */
+ public PRAcroForm AcroForm {
+ get {
+ if (!acroFormParsed) {
+ acroFormParsed = true;
+ PdfObject form = catalog.Get(PdfName.ACROFORM);
+ if (form != null) {
+ try {
+ acroForm = new PRAcroForm(this);
+ acroForm.ReadAcroForm((PdfDictionary)GetPdfObject(form));
+ }
+ catch {
+ acroForm = null;
+ }
+ }
+ }
+ return acroForm;
+ }
+ }
+ /**
+ * Gets the page rotation. This value can be 0, 90, 180 or 270.
+ * @param index the page number. The first page is 1
+ * @return the page rotation
+ */
+ public int GetPageRotation(int index) {
+ return GetPageRotation(pageRefs.GetPageNRelease(index));
+ }
+
+ internal int GetPageRotation(PdfDictionary page) {
+ PdfNumber rotate = (PdfNumber)GetPdfObject(page.Get(PdfName.ROTATE));
+ if (rotate == null)
+ return 0;
+ else {
+ int n = rotate.IntValue;
+ n %= 360;
+ return n < 0 ? n + 360 : n;
+ }
+ }
+ /** Gets the page size, taking rotation into account. This
+ * is a Rectangle
with the value of the /MediaBox and the /Rotate key.
+ * @param index the page number. The first page is 1
+ * @return a Rectangle
+ */
+ public Rectangle GetPageSizeWithRotation(int index) {
+ return GetPageSizeWithRotation(pageRefs.GetPageNRelease(index));
+ }
+
+ /**
+ * Gets the rotated page from a page dictionary.
+ * @param page the page dictionary
+ * @return the rotated page
+ */
+ public Rectangle GetPageSizeWithRotation(PdfDictionary page) {
+ Rectangle rect = GetPageSize(page);
+ int rotation = GetPageRotation(page);
+ while (rotation > 0) {
+ rect = rect.Rotate();
+ rotation -= 90;
+ }
+ return rect;
+ }
+
+ /** Gets the page size without taking rotation into account. This
+ * is the value of the /MediaBox key.
+ * @param index the page number. The first page is 1
+ * @return the page size
+ */
+ public Rectangle GetPageSize(int index) {
+ return GetPageSize(pageRefs.GetPageNRelease(index));
+ }
+
+ /**
+ * Gets the page from a page dictionary
+ * @param page the page dictionary
+ * @return the page
+ */
+ public Rectangle GetPageSize(PdfDictionary page) {
+ PdfArray mediaBox = (PdfArray)GetPdfObject(page.Get(PdfName.MEDIABOX));
+ return GetNormalizedRectangle(mediaBox);
+ }
+
+ /** Gets the crop box without taking rotation into account. This
+ * is the value of the /CropBox key. The crop box is the part
+ * of the document to be displayed or printed. It usually is the same
+ * as the media box but may be smaller. If the page doesn't have a crop
+ * box the page size will be returned.
+ * @param index the page number. The first page is 1
+ * @return the crop box
+ */
+ public Rectangle GetCropBox(int index) {
+ PdfDictionary page = pageRefs.GetPageNRelease(index);
+ PdfArray cropBox = (PdfArray)GetPdfObjectRelease(page.Get(PdfName.CROPBOX));
+ if (cropBox == null)
+ return GetPageSize(page);
+ return GetNormalizedRectangle(cropBox);
+ }
+
+ /** Gets the box size. Allowed names are: "crop", "trim", "art", "bleed" and "media".
+ * @param index the page number. The first page is 1
+ * @param boxName the box name
+ * @return the box rectangle or null
+ */
+ public Rectangle GetBoxSize(int index, String boxName) {
+ PdfDictionary page = pageRefs.GetPageNRelease(index);
+ PdfArray box = null;
+ if (boxName.Equals("trim"))
+ box = (PdfArray)GetPdfObjectRelease(page.Get(PdfName.TRIMBOX));
+ else if (boxName.Equals("art"))
+ box = (PdfArray)GetPdfObjectRelease(page.Get(PdfName.ARTBOX));
+ else if (boxName.Equals("bleed"))
+ box = (PdfArray)GetPdfObjectRelease(page.Get(PdfName.BLEEDBOX));
+ else if (boxName.Equals("crop"))
+ box = (PdfArray)GetPdfObjectRelease(page.Get(PdfName.CROPBOX));
+ else if (boxName.Equals("media"))
+ box = (PdfArray)GetPdfObjectRelease(page.Get(PdfName.MEDIABOX));
+ if (box == null)
+ return null;
+ return GetNormalizedRectangle(box);
+ }
+
+ /** Returns the content of the document information dictionary as a Hashtable
+ * of String
.
+ * @return content of the document information dictionary
+ */
+ public Hashtable Info {
+ get {
+ Hashtable map = new Hashtable();
+ PdfDictionary info = (PdfDictionary)GetPdfObject(trailer.Get(PdfName.INFO));
+ if (info == null)
+ return map;
+ foreach (PdfName key in info.Keys) {
+ PdfObject obj = GetPdfObject(info.Get(key));
+ if (obj == null)
+ continue;
+ String value = obj.ToString();
+ switch (obj.Type) {
+ case PdfObject.STRING: {
+ value = ((PdfString)obj).ToUnicodeString();
+ break;
+ }
+ case PdfObject.NAME: {
+ value = PdfName.DecodeName(value);
+ break;
+ }
+ }
+ map[PdfName.DecodeName(key.ToString())] = value;
+ }
+ return map;
+ }
+ }
+
+ /** Normalizes a Rectangle
so that llx and lly are smaller than urx and ury.
+ * @param box the original rectangle
+ * @return a normalized Rectangle
+ */
+ public static Rectangle GetNormalizedRectangle(PdfArray box) {
+ ArrayList rect = box.ArrayList;
+ float llx = ((PdfNumber)GetPdfObjectRelease((PdfObject)rect[0])).FloatValue;
+ float lly = ((PdfNumber)GetPdfObjectRelease((PdfObject)rect[1])).FloatValue;
+ float urx = ((PdfNumber)GetPdfObjectRelease((PdfObject)rect[2])).FloatValue;
+ float ury = ((PdfNumber)GetPdfObjectRelease((PdfObject)rect[3])).FloatValue;
+ return new Rectangle(Math.Min(llx, urx), Math.Min(lly, ury),
+ Math.Max(llx, urx), Math.Max(lly, ury));
+ }
+
+ protected internal virtual void ReadPdf() {
+ try {
+ fileLength = tokens.File.Length;
+ pdfVersion = tokens.CheckPdfHeader();
+ try {
+ ReadXref();
+ }
+ catch (Exception e) {
+ try {
+ rebuilt = true;
+ RebuildXref();
+ lastXref = -1;
+ }
+ catch (Exception ne) {
+ throw new IOException("Rebuild failed: " + ne.Message + "; Original message: " + e.Message);
+ }
+ }
+ try {
+ ReadDocObj();
+ }
+ catch (Exception ne) {
+ if (rebuilt || encryptionError)
+ throw ne;
+ rebuilt = true;
+ encrypted = false;
+ RebuildXref();
+ lastXref = -1;
+ ReadDocObj();
+ }
+
+ strings.Clear();
+ ReadPages();
+ EliminateSharedStreams();
+ RemoveUnusedObjects();
+ }
+ finally {
+ try {
+ tokens.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+
+ protected internal void ReadPdfPartial() {
+ try {
+ fileLength = tokens.File.Length;
+ pdfVersion = tokens.CheckPdfHeader();
+ try {
+ ReadXref();
+ }
+ catch (Exception e) {
+ try {
+ rebuilt = true;
+ RebuildXref();
+ lastXref = -1;
+ }
+ catch (Exception ne) {
+ throw new IOException("Rebuild failed: " + ne.Message + "; Original message: " + e.Message);
+ }
+ }
+ ReadDocObjPartial();
+ ReadPages();
+ }
+ catch (IOException e) {
+ try{tokens.Close();}catch{}
+ throw e;
+ }
+ }
+
+ private bool EqualsArray(byte[] ar1, byte[] ar2, int size) {
+ for (int k = 0; k < size; ++k) {
+ if (ar1[k] != ar2[k])
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @throws IOException
+ */
+ private void ReadDecryptedDocObj() {
+ if (encrypted)
+ return;
+ PdfObject encDic = trailer.Get(PdfName.ENCRYPT);
+ if (encDic == null || encDic.ToString().Equals("null"))
+ return;
+ encryptionError = true;
+ byte[] encryptionKey = null;
+
+ encrypted = true;
+ PdfDictionary enc = (PdfDictionary)GetPdfObject(encDic);
+
+ String s;
+ PdfObject o;
+
+ PdfArray documentIDs = (PdfArray)GetPdfObject(trailer.Get(PdfName.ID));
+ byte[] documentID = null;
+ if (documentIDs != null) {
+ o = (PdfObject)documentIDs.ArrayList[0];
+ strings.Remove(o);
+ s = o.ToString();
+ documentID = DocWriter.GetISOBytes(s);
+ if (documentIDs.Size > 1)
+ strings.Remove(documentIDs.ArrayList[1]);
+ }
+ // just in case we have a broken producer
+ if (documentID == null)
+ documentID = new byte[0];
+
+ byte[] uValue = null;
+ byte[] oValue = null;
+ int cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40;
+ int lengthValue = 0;
+
+ PdfObject filter = GetPdfObjectRelease(enc.Get(PdfName.FILTER));
+
+ if (filter.Equals(PdfName.STANDARD)) {
+ s = enc.Get(PdfName.U).ToString();
+ strings.Remove(enc.Get(PdfName.U));
+ uValue = DocWriter.GetISOBytes(s);
+ s = enc.Get(PdfName.O).ToString();
+ strings.Remove(enc.Get(PdfName.O));
+ oValue = DocWriter.GetISOBytes(s);
+
+ o = enc.Get(PdfName.R);
+ if (!o.IsNumber()) throw new IOException("Illegal R value.");
+ rValue = ((PdfNumber)o).IntValue;
+ if (rValue != 2 && rValue != 3 && rValue != 4) throw new IOException("Unknown encryption type (" + rValue + ")");
+
+ o = enc.Get(PdfName.P);
+ if (!o.IsNumber()) throw new IOException("Illegal P value.");
+ pValue = ((PdfNumber)o).IntValue;
+
+ if ( rValue == 3 ){
+ o = enc.Get(PdfName.LENGTH);
+ if (!o.IsNumber())
+ throw new IOException("Illegal Length value.");
+ lengthValue = ((PdfNumber)o).IntValue;
+ if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0)
+ throw new IOException("Illegal Length value.");
+ cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
+ }
+ else if (rValue == 4) {
+ lengthValue = 128;
+ PdfDictionary dic = (PdfDictionary)enc.Get(PdfName.CF);
+ if (dic == null)
+ throw new IOException("/CF not found (encryption)");
+ dic = (PdfDictionary)dic.Get(PdfName.STDCF);
+ if (dic == null)
+ throw new IOException("/StdCF not found (encryption)");
+ if (PdfName.V2.Equals(dic.Get(PdfName.CFM)))
+ cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
+ else if (PdfName.AESV2.Equals(dic.Get(PdfName.CFM)))
+ cryptoMode = PdfWriter.ENCRYPTION_AES_128;
+ else
+ throw new IOException("No compatible encryption found");
+ PdfObject em = enc.Get(PdfName.ENCRYPTMETADATA);
+ if (em != null && em.ToString().Equals("false"))
+ cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA;
+ } else {
+ cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40;
+ }
+ } else if (filter.Equals(PdfName.PUBSEC)) {
+ bool foundRecipient = false;
+ byte[] envelopedData = null;
+ PdfArray recipients = null;
+
+ o = enc.Get(PdfName.V);
+ if (!o.IsNumber()) throw new IOException("Illegal V value.");
+ int vValue = ((PdfNumber)o).IntValue;
+ if (vValue != 1 && vValue != 2 && vValue != 4)
+ throw new IOException("Unknown encryption type V = " + rValue);
+
+ if ( vValue == 2 ){
+ o = enc.Get(PdfName.LENGTH);
+ if (!o.IsNumber())
+ throw new IOException("Illegal Length value.");
+ lengthValue = ((PdfNumber)o).IntValue;
+ if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0)
+ throw new IOException("Illegal Length value.");
+ cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
+ recipients = (PdfArray)enc.Get(PdfName.RECIPIENTS);
+ } else if (vValue == 4) {
+ PdfDictionary dic = (PdfDictionary)enc.Get(PdfName.CF);
+ if (dic == null)
+ throw new IOException("/CF not found (encryption)");
+ dic = (PdfDictionary)dic.Get(PdfName.DEFAULTCRYPTFILER);
+ if (dic == null)
+ throw new IOException("/DefaultCryptFilter not found (encryption)");
+ if (PdfName.V2.Equals(dic.Get(PdfName.CFM)))
+ {
+ cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
+ lengthValue = 128;
+ }
+ else if (PdfName.AESV2.Equals(dic.Get(PdfName.CFM)))
+ {
+ cryptoMode = PdfWriter.ENCRYPTION_AES_128;
+ lengthValue = 128;
+ }
+ else
+ throw new IOException("No compatible encryption found");
+ PdfObject em = dic.Get(PdfName.ENCRYPTMETADATA);
+ if (em != null && em.ToString().Equals("false"))
+ cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA;
+
+ recipients = (PdfArray)dic.Get(PdfName.RECIPIENTS);
+ } else {
+ cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40;
+ lengthValue = 40;
+ recipients = (PdfArray)enc.Get(PdfName.RECIPIENTS);
+ }
+
+ for (int i = 0; iPdfObject
to read
+ * @return the resolved PdfObject
+ */
+ public static PdfObject GetPdfObject(PdfObject obj) {
+ if (obj == null)
+ return null;
+ if (!obj.IsIndirect())
+ return obj;
+ PRIndirectReference refi = (PRIndirectReference)obj;
+ int idx = refi.Number;
+ bool appendable = refi.Reader.appendable;
+ obj = refi.Reader.GetPdfObject(idx);
+ if (obj == null) {
+ return null;
+ }
+ else {
+ if (appendable) {
+ switch (obj.Type) {
+ case PdfObject.NULL:
+ obj = new PdfNull();
+ break;
+ case PdfObject.BOOLEAN:
+ obj = new PdfBoolean(((PdfBoolean)obj).BooleanValue);
+ break;
+ case PdfObject.NAME:
+ obj = new PdfName(obj.GetBytes());
+ break;
+ }
+ obj.IndRef = refi;
+ }
+ return obj;
+ }
+ }
+
+ /**
+ * Reads a PdfObject
resolving an indirect reference
+ * if needed. If the reader was opened in partial mode the object will be released
+ * to save memory.
+ * @param obj the PdfObject
to read
+ * @param parent
+ * @return a PdfObject
+ */
+ public static PdfObject GetPdfObjectRelease(PdfObject obj, PdfObject parent) {
+ PdfObject obj2 = GetPdfObject(obj, parent);
+ ReleaseLastXrefPartial(obj);
+ return obj2;
+ }
+
+ /**
+ * @param obj
+ * @param parent
+ * @return a PdfObject
+ */
+ public static PdfObject GetPdfObject(PdfObject obj, PdfObject parent) {
+ if (obj == null)
+ return null;
+ if (!obj.IsIndirect()) {
+ PRIndirectReference refi = null;
+ if (parent != null && (refi = parent.IndRef) != null && refi.Reader.Appendable) {
+ switch (obj.Type) {
+ case PdfObject.NULL:
+ obj = new PdfNull();
+ break;
+ case PdfObject.BOOLEAN:
+ obj = new PdfBoolean(((PdfBoolean)obj).BooleanValue);
+ break;
+ case PdfObject.NAME:
+ obj = new PdfName(obj.GetBytes());
+ break;
+ }
+ obj.IndRef = refi;
+ }
+ return obj;
+ }
+ return GetPdfObject(obj);
+ }
+
+ /**
+ * @param idx
+ * @return a PdfObject
+ */
+ public PdfObject GetPdfObjectRelease(int idx) {
+ PdfObject obj = GetPdfObject(idx);
+ ReleaseLastXrefPartial();
+ return obj;
+ }
+
+ /**
+ * @param idx
+ * @return aPdfObject
+ */
+ public PdfObject GetPdfObject(int idx) {
+ lastXrefPartial = -1;
+ if (idx < 0 || idx >= xrefObj.Count)
+ return null;
+ PdfObject obj = (PdfObject)xrefObj[idx];
+ if (!partial || obj != null)
+ return obj;
+ if (idx * 2 >= xref.Length)
+ return null;
+ obj = ReadSingleObject(idx);
+ lastXrefPartial = -1;
+ if (obj != null)
+ lastXrefPartial = idx;
+ return obj;
+ }
+
+ /**
+ *
+ */
+ public void ResetLastXrefPartial() {
+ lastXrefPartial = -1;
+ }
+
+ /**
+ *
+ */
+ public void ReleaseLastXrefPartial() {
+ if (partial && lastXrefPartial != -1) {
+ xrefObj[lastXrefPartial] = null;
+ lastXrefPartial = -1;
+ }
+ }
+
+ /**
+ * @param obj
+ */
+ public static void ReleaseLastXrefPartial(PdfObject obj) {
+ if (obj == null)
+ return;
+ if (!obj.IsIndirect())
+ return;
+ PRIndirectReference refi = (PRIndirectReference)obj;
+ PdfReader reader = refi.Reader;
+ if (reader.partial && reader.lastXrefPartial != -1 && reader.lastXrefPartial == refi.Number) {
+ reader.xrefObj[reader.lastXrefPartial] = null;
+ }
+ reader.lastXrefPartial = -1;
+ }
+
+ private void SetXrefPartialObject(int idx, PdfObject obj) {
+ if (!partial || idx < 0)
+ return;
+ xrefObj[idx] = obj;
+ }
+
+ /**
+ * @param obj
+ * @return an indirect reference
+ */
+ public PRIndirectReference AddPdfObject(PdfObject obj) {
+ xrefObj.Add(obj);
+ return new PRIndirectReference(this, xrefObj.Count - 1);
+ }
+
+ protected internal void ReadPages() {
+ catalog = (PdfDictionary)GetPdfObject(trailer.Get(PdfName.ROOT));
+ rootPages = (PdfDictionary)GetPdfObject(catalog.Get(PdfName.PAGES));
+ pageRefs = new PageRefs(this);
+ }
+
+ protected internal void ReadDocObjPartial() {
+ xrefObj = ArrayList.Repeat(null, xref.Length / 2);
+ ReadDecryptedDocObj();
+ if (objStmToOffset != null) {
+ int[] keys = objStmToOffset.GetKeys();
+ for (int k = 0; k < keys.Length; ++k) {
+ int n = keys[k];
+ objStmToOffset[n] = xref[n * 2];
+ xref[n * 2] = -1;
+ }
+ }
+ }
+
+ protected internal PdfObject ReadSingleObject(int k) {
+ strings.Clear();
+ int k2 = k * 2;
+ int pos = xref[k2];
+ if (pos < 0)
+ return null;
+ if (xref[k2 + 1] > 0)
+ pos = objStmToOffset[xref[k2 + 1]];
+ if (pos == 0)
+ return null;
+ tokens.Seek(pos);
+ tokens.NextValidToken();
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER)
+ tokens.ThrowError("Invalid object number.");
+ objNum = tokens.IntValue;
+ tokens.NextValidToken();
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER)
+ tokens.ThrowError("Invalid generation number.");
+ objGen = tokens.IntValue;
+ tokens.NextValidToken();
+ if (!tokens.StringValue.Equals("obj"))
+ tokens.ThrowError("Token 'obj' expected.");
+ PdfObject obj;
+ try {
+ obj = ReadPRObject();
+ for (int j = 0; j < strings.Count; ++j) {
+ PdfString str = (PdfString)strings[j];
+ str.Decrypt(this);
+ }
+ if (obj.IsStream()) {
+ CheckPRStreamLength((PRStream)obj);
+ }
+ }
+ catch {
+ obj = null;
+ }
+ if (xref[k2 + 1] > 0) {
+ obj = ReadOneObjStm((PRStream)obj, xref[k2]);
+ }
+ xrefObj[k] = obj;
+ return obj;
+ }
+
+ protected internal PdfObject ReadOneObjStm(PRStream stream, int idx) {
+ int first = ((PdfNumber)GetPdfObject(stream.Get(PdfName.FIRST))).IntValue;
+ byte[] b = GetStreamBytes(stream, tokens.File);
+ PRTokeniser saveTokens = tokens;
+ tokens = new PRTokeniser(b);
+ try {
+ int address = 0;
+ bool ok = true;
+ ++idx;
+ for (int k = 0; k < idx; ++k) {
+ ok = tokens.NextToken();
+ if (!ok)
+ break;
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER) {
+ ok = false;
+ break;
+ }
+ ok = tokens.NextToken();
+ if (!ok)
+ break;
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER) {
+ ok = false;
+ break;
+ }
+ address = tokens.IntValue + first;
+ }
+ if (!ok)
+ throw new IOException("Error reading ObjStm");
+ tokens.Seek(address);
+ return ReadPRObject();
+ }
+ finally {
+ tokens = saveTokens;
+ }
+ }
+
+ /**
+ * @return the percentage of the cross reference table that has been read
+ */
+ public double DumpPerc() {
+ int total = 0;
+ for (int k = 0; k < xrefObj.Count; ++k) {
+ if (xrefObj[k] != null)
+ ++total;
+ }
+ return (total * 100.0 / xrefObj.Count);
+ }
+
+ protected internal void ReadDocObj() {
+ ArrayList streams = new ArrayList();
+ xrefObj = ArrayList.Repeat(null, xref.Length / 2);
+ for (int k = 2; k < xref.Length; k += 2) {
+ int pos = xref[k];
+ if (pos <= 0 || xref[k + 1] > 0)
+ continue;
+ tokens.Seek(pos);
+ tokens.NextValidToken();
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER)
+ tokens.ThrowError("Invalid object number.");
+ objNum = tokens.IntValue;
+ tokens.NextValidToken();
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER)
+ tokens.ThrowError("Invalid generation number.");
+ objGen = tokens.IntValue;
+ tokens.NextValidToken();
+ if (!tokens.StringValue.Equals("obj"))
+ tokens.ThrowError("Token 'obj' expected.");
+ PdfObject obj;
+ try {
+ obj = ReadPRObject();
+ if (obj.IsStream()) {
+ streams.Add(obj);
+ }
+ }
+ catch {
+ obj = null;
+ }
+ xrefObj[k / 2] = obj;
+ }
+ for (int k = 0; k < streams.Count; ++k) {
+ CheckPRStreamLength((PRStream)streams[k]);
+ }
+ ReadDecryptedDocObj();
+ if (objStmMark != null) {
+ foreach (DictionaryEntry entry in objStmMark) {
+ int n = (int)entry.Key;
+ IntHashtable h = (IntHashtable)entry.Value;
+ ReadObjStm((PRStream)xrefObj[n], h);
+ xrefObj[n] = null;
+ }
+ objStmMark = null;
+ }
+ xref = null;
+ }
+
+ private void CheckPRStreamLength(PRStream stream) {
+ int fileLength = tokens.Length;
+ int start = stream.Offset;
+ bool calc = false;
+ int streamLength = 0;
+ PdfObject obj = GetPdfObjectRelease(stream.Get(PdfName.LENGTH));
+ if (obj != null && obj.Type == PdfObject.NUMBER) {
+ streamLength = ((PdfNumber)obj).IntValue;
+ if (streamLength + start > fileLength - 20)
+ calc = true;
+ else {
+ tokens.Seek(start + streamLength);
+ String line = tokens.ReadString(20);
+ if (!line.StartsWith("\nendstream") &&
+ !line.StartsWith("\r\nendstream") &&
+ !line.StartsWith("\rendstream") &&
+ !line.StartsWith("endstream"))
+ calc = true;
+ }
+ }
+ else
+ calc = true;
+ if (calc) {
+ byte[] tline = new byte[16];
+ tokens.Seek(start);
+ while (true) {
+ int pos = tokens.FilePointer;
+ if (!tokens.ReadLineSegment(tline))
+ break;
+ if (Equalsn(tline, endstream)) {
+ streamLength = pos - start;
+ break;
+ }
+ if (Equalsn(tline, endobj)) {
+ tokens.Seek(pos - 16);
+ String s = tokens.ReadString(16);
+ int index = s.IndexOf("endstream");
+ if (index >= 0)
+ pos = pos - 16 + index;
+ streamLength = pos - start;
+ break;
+ }
+ }
+ }
+ stream.Length = streamLength;
+ }
+
+ protected internal void ReadObjStm(PRStream stream, IntHashtable map) {
+ int first = ((PdfNumber)GetPdfObject(stream.Get(PdfName.FIRST))).IntValue;
+ int n = ((PdfNumber)GetPdfObject(stream.Get(PdfName.N))).IntValue;
+ byte[] b = GetStreamBytes(stream, tokens.File);
+ PRTokeniser saveTokens = tokens;
+ tokens = new PRTokeniser(b);
+ try {
+ int[] address = new int[n];
+ int[] objNumber = new int[n];
+ bool ok = true;
+ for (int k = 0; k < n; ++k) {
+ ok = tokens.NextToken();
+ if (!ok)
+ break;
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER) {
+ ok = false;
+ break;
+ }
+ objNumber[k] = tokens.IntValue;
+ ok = tokens.NextToken();
+ if (!ok)
+ break;
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER) {
+ ok = false;
+ break;
+ }
+ address[k] = tokens.IntValue + first;
+ }
+ if (!ok)
+ throw new IOException("Error reading ObjStm");
+ for (int k = 0; k < n; ++k) {
+ if (map.ContainsKey(k)) {
+ tokens.Seek(address[k]);
+ PdfObject obj = ReadPRObject();
+ xrefObj[objNumber[k]] = obj;
+ }
+ }
+ }
+ finally {
+ tokens = saveTokens;
+ }
+ }
+
+ /**
+ * Eliminates the reference to the object freeing the memory used by it and clearing
+ * the xref entry.
+ * @param obj the object. If it's an indirect reference it will be eliminated
+ * @return the object or the already erased dereferenced object
+ */
+ public static PdfObject KillIndirect(PdfObject obj) {
+ if (obj == null || obj.IsNull())
+ return null;
+ PdfObject ret = GetPdfObjectRelease(obj);
+ if (obj.IsIndirect()) {
+ PRIndirectReference refi = (PRIndirectReference)obj;
+ PdfReader reader = refi.Reader;
+ int n = refi.Number;
+ reader.xrefObj[n] = null;
+ if (reader.partial)
+ reader.xref[n * 2] = -1;
+ }
+ return ret;
+ }
+
+ private void EnsureXrefSize(int size) {
+ if (size == 0)
+ return;
+ if (xref == null)
+ xref = new int[size];
+ else {
+ if (xref.Length < size) {
+ int[] xref2 = new int[size];
+ Array.Copy(xref, 0, xref2, 0, xref.Length);
+ xref = xref2;
+ }
+ }
+ }
+
+ protected internal void ReadXref() {
+ hybridXref = false;
+ newXrefType = false;
+ tokens.Seek(tokens.Startxref);
+ tokens.NextToken();
+ if (!tokens.StringValue.Equals("startxref"))
+ throw new IOException("startxref not found.");
+ tokens.NextToken();
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER)
+ throw new IOException("startxref is not followed by a number.");
+ int startxref = tokens.IntValue;
+ lastXref = startxref;
+ eofPos = tokens.FilePointer;
+ try {
+ if (ReadXRefStream(startxref)) {
+ newXrefType = true;
+ return;
+ }
+ }
+ catch {}
+ xref = null;
+ tokens.Seek(startxref);
+ trailer = ReadXrefSection();
+ PdfDictionary trailer2 = trailer;
+ while (true) {
+ PdfNumber prev = (PdfNumber)trailer2.Get(PdfName.PREV);
+ if (prev == null)
+ break;
+ tokens.Seek(prev.IntValue);
+ trailer2 = ReadXrefSection();
+ }
+ }
+
+ protected internal PdfDictionary ReadXrefSection() {
+ tokens.NextValidToken();
+ if (!tokens.StringValue.Equals("xref"))
+ tokens.ThrowError("xref subsection not found");
+ int start = 0;
+ int end = 0;
+ int pos = 0;
+ int gen = 0;
+ while (true) {
+ tokens.NextValidToken();
+ if (tokens.StringValue.Equals("trailer"))
+ break;
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER)
+ tokens.ThrowError("Object number of the first object in this xref subsection not found");
+ start = tokens.IntValue;
+ tokens.NextValidToken();
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER)
+ tokens.ThrowError("Number of entries in this xref subsection not found");
+ end = tokens.IntValue + start;
+ if (start == 1) { // fix incorrect start number
+ int back = tokens.FilePointer;
+ tokens.NextValidToken();
+ pos = tokens.IntValue;
+ tokens.NextValidToken();
+ gen = tokens.IntValue;
+ if (pos == 0 && gen == 65535) {
+ --start;
+ --end;
+ }
+ tokens.Seek(back);
+ }
+ EnsureXrefSize(end * 2);
+ for (int k = start; k < end; ++k) {
+ tokens.NextValidToken();
+ pos = tokens.IntValue;
+ tokens.NextValidToken();
+ gen = tokens.IntValue;
+ tokens.NextValidToken();
+ int p = k * 2;
+ if (tokens.StringValue.Equals("n")) {
+ if (xref[p] == 0 && xref[p + 1] == 0) {
+ // if (pos == 0)
+ // tokens.ThrowError("File position 0 cross-reference entry in this xref subsection");
+ xref[p] = pos;
+ }
+ }
+ else if (tokens.StringValue.Equals("f")) {
+ if (xref[p] == 0 && xref[p + 1] == 0)
+ xref[p] = -1;
+ }
+ else
+ tokens.ThrowError("Invalid cross-reference entry in this xref subsection");
+ }
+ }
+ PdfDictionary trailer = (PdfDictionary)ReadPRObject();
+ PdfNumber xrefSize = (PdfNumber)trailer.Get(PdfName.SIZE);
+ EnsureXrefSize(xrefSize.IntValue * 2);
+ PdfObject xrs = trailer.Get(PdfName.XREFSTM);
+ if (xrs != null && xrs.IsNumber()) {
+ int loc = ((PdfNumber)xrs).IntValue;
+ try {
+ ReadXRefStream(loc);
+ newXrefType = true;
+ hybridXref = true;
+ }
+ catch (IOException e) {
+ xref = null;
+ throw e;
+ }
+ }
+ return trailer;
+ }
+
+ protected internal bool ReadXRefStream(int ptr) {
+ tokens.Seek(ptr);
+ int thisStream = 0;
+ if (!tokens.NextToken())
+ return false;
+ if (tokens.TokenType != PRTokeniser.TK_NUMBER)
+ return false;
+ thisStream = tokens.IntValue;
+ if (!tokens.NextToken() || tokens.TokenType != PRTokeniser.TK_NUMBER)
+ return false;
+ if (!tokens.NextToken() || !tokens.StringValue.Equals("obj"))
+ return false;
+ PdfObject objecto = ReadPRObject();
+ PRStream stm = null;
+ if (objecto.IsStream()) {
+ stm = (PRStream)objecto;
+ if (!PdfName.XREF.Equals(stm.Get(PdfName.TYPE)))
+ return false;
+ }
+ else
+ return false;
+ if (trailer == null) {
+ trailer = new PdfDictionary();
+ trailer.Merge(stm);
+ }
+ stm.Length = ((PdfNumber)stm.Get(PdfName.LENGTH)).IntValue;
+ int size = ((PdfNumber)stm.Get(PdfName.SIZE)).IntValue;
+ PdfArray index;
+ PdfObject obj = stm.Get(PdfName.INDEX);
+ if (obj == null) {
+ index = new PdfArray();
+ index.Add(new int[]{0, size});
+ }
+ else
+ index = (PdfArray)obj;
+ PdfArray w = (PdfArray)stm.Get(PdfName.W);
+ int prev = -1;
+ obj = stm.Get(PdfName.PREV);
+ if (obj != null)
+ prev = ((PdfNumber)obj).IntValue;
+ // Each xref pair is a position
+ // type 0 -> -1, 0
+ // type 1 -> offset, 0
+ // type 2 -> index, obj num
+ EnsureXrefSize(size * 2);
+ if (objStmMark == null && !partial)
+ objStmMark = new Hashtable();
+ if (objStmToOffset == null && partial)
+ objStmToOffset = new IntHashtable();
+ byte[] b = GetStreamBytes(stm, tokens.File);
+ int bptr = 0;
+ ArrayList wa = w.ArrayList;
+ int[] wc = new int[3];
+ for (int k = 0; k < 3; ++k)
+ wc[k] = ((PdfNumber)wa[k]).IntValue;
+ ArrayList sections = index.ArrayList;
+ for (int idx = 0; idx < sections.Count; idx += 2) {
+ int start = ((PdfNumber)sections[idx]).IntValue;
+ int length = ((PdfNumber)sections[idx + 1]).IntValue;
+ EnsureXrefSize((start + length) * 2);
+ while (length-- > 0) {
+ int type = 1;
+ if (wc[0] > 0) {
+ type = 0;
+ for (int k = 0; k < wc[0]; ++k)
+ type = (type << 8) + (b[bptr++] & 0xff);
+ }
+ int field2 = 0;
+ for (int k = 0; k < wc[1]; ++k)
+ field2 = (field2 << 8) + (b[bptr++] & 0xff);
+ int field3 = 0;
+ for (int k = 0; k < wc[2]; ++k)
+ field3 = (field3 << 8) + (b[bptr++] & 0xff);
+ int baseb = start * 2;
+ if (xref[baseb] == 0 && xref[baseb + 1] == 0) {
+ switch (type) {
+ case 0:
+ xref[baseb] = -1;
+ break;
+ case 1:
+ xref[baseb] = field2;
+ break;
+ case 2:
+ xref[baseb] = field3;
+ xref[baseb + 1] = field2;
+ if (partial) {
+ objStmToOffset[field2] = 0;
+ }
+ else {
+ IntHashtable seq = (IntHashtable)objStmMark[field2];
+ if (seq == null) {
+ seq = new IntHashtable();
+ seq[field3] = 1;
+ objStmMark[field2] = seq;
+ }
+ else
+ seq[field3] = 1;
+ }
+ break;
+ }
+ }
+ ++start;
+ }
+ }
+ thisStream *= 2;
+ if (thisStream < xref.Length)
+ xref[thisStream] = -1;
+
+ if (prev == -1)
+ return true;
+ return ReadXRefStream(prev);
+ }
+
+ protected internal void RebuildXref() {
+ hybridXref = false;
+ newXrefType = false;
+ tokens.Seek(0);
+ int[][] xr = new int[1024][];
+ int top = 0;
+ trailer = null;
+ byte[] line = new byte[64];
+ for (;;) {
+ int pos = tokens.FilePointer;
+ if (!tokens.ReadLineSegment(line))
+ break;
+ if (line[0] == 't') {
+ if (!PdfEncodings.ConvertToString(line, null).StartsWith("trailer"))
+ continue;
+ tokens.Seek(pos);
+ tokens.NextToken();
+ pos = tokens.FilePointer;
+ try {
+ PdfDictionary dic = (PdfDictionary)ReadPRObject();
+ if (dic.Get(PdfName.ROOT) != null)
+ trailer = dic;
+ else
+ tokens.Seek(pos);
+ }
+ catch {
+ tokens.Seek(pos);
+ }
+ }
+ else if (line[0] >= '0' && line[0] <= '9') {
+ int[] obj = PRTokeniser.CheckObjectStart(line);
+ if (obj == null)
+ continue;
+ int num = obj[0];
+ int gen = obj[1];
+ if (num >= xr.Length) {
+ int newLength = num * 2;
+ int[][] xr2 = new int[newLength][];
+ Array.Copy(xr, 0, xr2, 0, top);
+ xr = xr2;
+ }
+ if (num >= top)
+ top = num + 1;
+ if (xr[num] == null || gen >= xr[num][1]) {
+ obj[0] = pos;
+ xr[num] = obj;
+ }
+ }
+ }
+ if (trailer == null)
+ throw new IOException("trailer not found.");
+ xref = new int[top * 2];
+ for (int k = 0; k < top; ++k) {
+ int[] obj = xr[k];
+ if (obj != null)
+ xref[k * 2] = obj[0];
+ }
+ }
+
+ protected internal PdfDictionary ReadDictionary() {
+ PdfDictionary dic = new PdfDictionary();
+ while (true) {
+ tokens.NextValidToken();
+ if (tokens.TokenType == PRTokeniser.TK_END_DIC)
+ break;
+ if (tokens.TokenType != PRTokeniser.TK_NAME)
+ tokens.ThrowError("Dictionary key is not a name.");
+ PdfName name = new PdfName(tokens.StringValue, false);
+ PdfObject obj = ReadPRObject();
+ int type = obj.Type;
+ if (-type == PRTokeniser.TK_END_DIC)
+ tokens.ThrowError("Unexpected '>>'");
+ if (-type == PRTokeniser.TK_END_ARRAY)
+ tokens.ThrowError("Unexpected ']'");
+ dic.Put(name, obj);
+ }
+ return dic;
+ }
+
+ protected internal PdfArray ReadArray() {
+ PdfArray array = new PdfArray();
+ while (true) {
+ PdfObject obj = ReadPRObject();
+ int type = obj.Type;
+ if (-type == PRTokeniser.TK_END_ARRAY)
+ break;
+ if (-type == PRTokeniser.TK_END_DIC)
+ tokens.ThrowError("Unexpected '>>'");
+ array.Add(obj);
+ }
+ return array;
+ }
+
+ protected internal PdfObject ReadPRObject() {
+ tokens.NextValidToken();
+ int type = tokens.TokenType;
+ switch (type) {
+ case PRTokeniser.TK_START_DIC: {
+ PdfDictionary dic = ReadDictionary();
+ int pos = tokens.FilePointer;
+ // be careful in the trailer. May not be a "next" token.
+ if (tokens.NextToken() && tokens.StringValue.Equals("stream")) {
+ int ch = tokens.Read();
+ if (ch != '\n')
+ ch = tokens.Read();
+ if (ch != '\n')
+ tokens.BackOnePosition(ch);
+ PRStream stream = new PRStream(this, tokens.FilePointer);
+ stream.Merge(dic);
+ stream.ObjNum = objNum;
+ stream.ObjGen = objGen;
+ return stream;
+ }
+ else {
+ tokens.Seek(pos);
+ return dic;
+ }
+ }
+ case PRTokeniser.TK_START_ARRAY:
+ return ReadArray();
+ case PRTokeniser.TK_NUMBER:
+ return new PdfNumber(tokens.StringValue);
+ case PRTokeniser.TK_STRING:
+ PdfString str = new PdfString(tokens.StringValue, null).SetHexWriting(tokens.IsHexString());
+ str.SetObjNum(objNum, objGen);
+ if (strings != null)
+ strings.Add(str);
+ return str;
+ case PRTokeniser.TK_NAME:
+ return new PdfName(tokens.StringValue, false);
+ case PRTokeniser.TK_REF:
+ int num = tokens.Reference;
+ PRIndirectReference refi = new PRIndirectReference(this, num, tokens.Generation);
+ return refi;
+ default:
+ String sv = tokens.StringValue;
+ if ("null".Equals(sv))
+ return PdfNull.PDFNULL;
+ else if ("true".Equals(sv))
+ return PdfBoolean.PDFTRUE;
+ else if ("false".Equals(sv))
+ return PdfBoolean.PDFFALSE;
+ return new PdfLiteral(-type, tokens.StringValue);
+ }
+ }
+
+ /** Decodes a stream that has the FlateDecode filter.
+ * @param in the input data
+ * @return the decoded data
+ */
+ public static byte[] FlateDecode(byte[] inp) {
+ byte[] b = FlateDecode(inp, true);
+ if (b == null)
+ return FlateDecode(inp, false);
+ return b;
+ }
+
+ /**
+ * @param in
+ * @param dicPar
+ * @return a byte array
+ */
+ public static byte[] DecodePredictor(byte[] inp, PdfObject dicPar) {
+ if (dicPar == null || !dicPar.IsDictionary())
+ return inp;
+ PdfDictionary dic = (PdfDictionary)dicPar;
+ PdfObject obj = GetPdfObject(dic.Get(PdfName.PREDICTOR));
+ if (obj == null || !obj.IsNumber())
+ return inp;
+ int predictor = ((PdfNumber)obj).IntValue;
+ if (predictor < 10)
+ return inp;
+ int width = 1;
+ obj = GetPdfObject(dic.Get(PdfName.COLUMNS));
+ if (obj != null && obj.IsNumber())
+ width = ((PdfNumber)obj).IntValue;
+ int colors = 1;
+ obj = GetPdfObject(dic.Get(PdfName.COLORS));
+ if (obj != null && obj.IsNumber())
+ colors = ((PdfNumber)obj).IntValue;
+ int bpc = 8;
+ obj = GetPdfObject(dic.Get(PdfName.BITSPERCOMPONENT));
+ if (obj != null && obj.IsNumber())
+ bpc = ((PdfNumber)obj).IntValue;
+ MemoryStream dataStream = new MemoryStream(inp);
+ MemoryStream fout = new MemoryStream(inp.Length);
+ int bytesPerPixel = colors * bpc / 8;
+ int bytesPerRow = (colors*width*bpc + 7)/8;
+ byte[] curr = new byte[bytesPerRow];
+ byte[] prior = new byte[bytesPerRow];
+
+ // Decode the (sub)image row-by-row
+ while (true) {
+ // Read the filter type byte and a row of data
+ int filter = 0;
+ try {
+ filter = dataStream.ReadByte();
+ if (filter < 0) {
+ return fout.ToArray();
+ }
+ int tot = 0;
+ while (tot < bytesPerRow) {
+ int n = dataStream.Read(curr, tot, bytesPerRow - tot);
+ if (n <= 0)
+ return fout.ToArray();
+ tot += n;
+ }
+ } catch {
+ return fout.ToArray();
+ }
+
+ switch (filter) {
+ case 0: //PNG_FILTER_NONE
+ break;
+ case 1: //PNG_FILTER_SUB
+ for (int i = bytesPerPixel; i < bytesPerRow; i++) {
+ curr[i] += curr[i - bytesPerPixel];
+ }
+ break;
+ case 2: //PNG_FILTER_UP
+ for (int i = 0; i < bytesPerRow; i++) {
+ curr[i] += prior[i];
+ }
+ break;
+ case 3: //PNG_FILTER_AVERAGE
+ for (int i = 0; i < bytesPerPixel; i++) {
+ curr[i] += (byte)(prior[i] / 2);
+ }
+ for (int i = bytesPerPixel; i < bytesPerRow; i++) {
+ curr[i] += (byte)(((curr[i - bytesPerPixel] & 0xff) + (prior[i] & 0xff))/2);
+ }
+ break;
+ case 4: //PNG_FILTER_PAETH
+ for (int i = 0; i < bytesPerPixel; i++) {
+ curr[i] += prior[i];
+ }
+
+ for (int i = bytesPerPixel; i < bytesPerRow; i++) {
+ int a = curr[i - bytesPerPixel] & 0xff;
+ int b = prior[i] & 0xff;
+ int c = prior[i - bytesPerPixel] & 0xff;
+
+ int p = a + b - c;
+ int pa = Math.Abs(p - a);
+ int pb = Math.Abs(p - b);
+ int pc = Math.Abs(p - c);
+
+ int ret;
+
+ if ((pa <= pb) && (pa <= pc)) {
+ ret = a;
+ } else if (pb <= pc) {
+ ret = b;
+ } else {
+ ret = c;
+ }
+ curr[i] += (byte)(ret);
+ }
+ break;
+ default:
+ // Error -- uknown filter type
+ throw new Exception("PNG filter unknown.");
+ }
+ fout.Write(curr, 0, curr.Length);
+
+ // Swap curr and prior
+ byte[] tmp = prior;
+ prior = curr;
+ curr = tmp;
+ }
+ }
+
+ /** A helper to FlateDecode.
+ * @param in the input data
+ * @param strict true
to read a correct stream. false
+ * to try to read a corrupted stream
+ * @return the decoded data
+ */
+ public static byte[] FlateDecode(byte[] inp, bool strict) {
+ MemoryStream stream = new MemoryStream(inp);
+ ZInflaterInputStream zip = new ZInflaterInputStream(stream);
+ MemoryStream outp = new MemoryStream();
+ byte[] b = new byte[strict ? 4092 : 1];
+ try {
+ int n;
+ while ((n = zip.Read(b, 0, b.Length)) > 0) {
+ outp.Write(b, 0, n);
+ }
+ zip.Close();
+ outp.Close();
+ return outp.ToArray();
+ }
+ catch {
+ if (strict)
+ return null;
+ return outp.ToArray();
+ }
+ }
+
+ /** Decodes a stream that has the ASCIIHexDecode filter.
+ * @param in the input data
+ * @return the decoded data
+ */
+ public static byte[] ASCIIHexDecode(byte[] inp) {
+ MemoryStream outp = new MemoryStream();
+ bool first = true;
+ int n1 = 0;
+ for (int k = 0; k < inp.Length; ++k) {
+ int ch = inp[k] & 0xff;
+ if (ch == '>')
+ break;
+ if (PRTokeniser.IsWhitespace(ch))
+ continue;
+ int n = PRTokeniser.GetHex(ch);
+ if (n == -1)
+ throw new ArgumentException("Illegal character in ASCIIHexDecode.");
+ if (first)
+ n1 = n;
+ else
+ outp.WriteByte((byte)((n1 << 4) + n));
+ first = !first;
+ }
+ if (!first)
+ outp.WriteByte((byte)(n1 << 4));
+ return outp.ToArray();
+ }
+
+ /** Decodes a stream that has the ASCII85Decode filter.
+ * @param in the input data
+ * @return the decoded data
+ */
+ public static byte[] ASCII85Decode(byte[] inp) {
+ MemoryStream outp = new MemoryStream();
+ int state = 0;
+ int[] chn = new int[5];
+ for (int k = 0; k < inp.Length; ++k) {
+ int ch = inp[k] & 0xff;
+ if (ch == '~')
+ break;
+ if (PRTokeniser.IsWhitespace(ch))
+ continue;
+ if (ch == 'z' && state == 0) {
+ outp.WriteByte(0);
+ outp.WriteByte(0);
+ outp.WriteByte(0);
+ outp.WriteByte(0);
+ continue;
+ }
+ if (ch < '!' || ch > 'u')
+ throw new ArgumentException("Illegal character in ASCII85Decode.");
+ chn[state] = ch - '!';
+ ++state;
+ if (state == 5) {
+ state = 0;
+ int rx = 0;
+ for (int j = 0; j < 5; ++j)
+ rx = rx * 85 + chn[j];
+ outp.WriteByte((byte)(rx >> 24));
+ outp.WriteByte((byte)(rx >> 16));
+ outp.WriteByte((byte)(rx >> 8));
+ outp.WriteByte((byte)rx);
+ }
+ }
+ int r = 0;
+ // We'll ignore the next two lines for the sake of perpetuating broken PDFs
+// if (state == 1)
+// throw new ArgumentException("Illegal length in ASCII85Decode.");
+ if (state == 2) {
+ r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85 + 85 * 85 * 85 + 85 * 85 + 85;
+ outp.WriteByte((byte)(r >> 24));
+ }
+ else if (state == 3) {
+ r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85 + chn[2] * 85 * 85 + 85 * 85 + 85;
+ outp.WriteByte((byte)(r >> 24));
+ outp.WriteByte((byte)(r >> 16));
+ }
+ else if (state == 4) {
+ r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85 + chn[2] * 85 * 85 + chn[3] * 85 + 85;
+ outp.WriteByte((byte)(r >> 24));
+ outp.WriteByte((byte)(r >> 16));
+ outp.WriteByte((byte)(r >> 8));
+ }
+ return outp.ToArray();
+ }
+
+ /** Decodes a stream that has the LZWDecode filter.
+ * @param in the input data
+ * @return the decoded data
+ */
+ public static byte[] LZWDecode(byte[] inp) {
+ MemoryStream outp = new MemoryStream();
+ LZWDecoder lzw = new LZWDecoder();
+ lzw.Decode(inp, outp);
+ return outp.ToArray();
+ }
+
+ /** Checks if the document had errors and was rebuilt.
+ * @return true if rebuilt.
+ *
+ */
+ public bool IsRebuilt() {
+ return this.rebuilt;
+ }
+
+ /** Gets the dictionary that represents a page.
+ * @param pageNum the page number. 1 is the first
+ * @return the page dictionary
+ */
+ public PdfDictionary GetPageN(int pageNum) {
+ PdfDictionary dic = pageRefs.GetPageN(pageNum);
+ if (dic == null)
+ return null;
+ if (appendable)
+ dic.IndRef = pageRefs.GetPageOrigRef(pageNum);
+ return dic;
+ }
+
+ /**
+ * @param pageNum
+ * @return a Dictionary object
+ */
+ public PdfDictionary GetPageNRelease(int pageNum) {
+ PdfDictionary dic = GetPageN(pageNum);
+ pageRefs.ReleasePage(pageNum);
+ return dic;
+ }
+
+ /**
+ * @param pageNum
+ */
+ public void ReleasePage(int pageNum) {
+ pageRefs.ReleasePage(pageNum);
+ }
+
+ /**
+ *
+ */
+ public void ResetReleasePage() {
+ pageRefs.ResetReleasePage();
+ }
+
+ /** Gets the page reference to this page.
+ * @param pageNum the page number. 1 is the first
+ * @return the page reference
+ */
+ public PRIndirectReference GetPageOrigRef(int pageNum) {
+ return pageRefs.GetPageOrigRef(pageNum);
+ }
+
+ /** Gets the contents of the page.
+ * @param pageNum the page number. 1 is the first
+ * @param file the location of the PDF document
+ * @throws IOException on error
+ * @return the content
+ */
+ public byte[] GetPageContent(int pageNum, RandomAccessFileOrArray file) {
+ PdfDictionary page = GetPageNRelease(pageNum);
+ if (page == null)
+ return null;
+ PdfObject contents = GetPdfObjectRelease(page.Get(PdfName.CONTENTS));
+ if (contents == null)
+ return new byte[0];
+ MemoryStream bout = null;
+ if (contents.IsStream()) {
+ return GetStreamBytes((PRStream)contents, file);
+ }
+ else if (contents.IsArray()) {
+ PdfArray array = (PdfArray)contents;
+ ArrayList list = array.ArrayList;
+ bout = new MemoryStream();
+ for (int k = 0; k < list.Count; ++k) {
+ PdfObject item = GetPdfObjectRelease((PdfObject)list[k]);
+ if (item == null || !item.IsStream())
+ continue;
+ byte[] b = GetStreamBytes((PRStream)item, file);
+ bout.Write(b, 0, b.Length);
+ if (k != list.Count - 1)
+ bout.WriteByte((byte)'\n');
+ }
+ return bout.ToArray();
+ }
+ else
+ return new byte[0];
+ }
+
+ /** Gets the contents of the page.
+ * @param pageNum the page number. 1 is the first
+ * @throws IOException on error
+ * @return the content
+ */
+ public byte[] GetPageContent(int pageNum) {
+ RandomAccessFileOrArray rf = SafeFile;
+ try {
+ rf.ReOpen();
+ return GetPageContent(pageNum, rf);
+ }
+ finally {
+ try{rf.Close();}catch{}
+ }
+ }
+
+ protected internal void KillXref(PdfObject obj) {
+ if (obj == null)
+ return;
+ if ((obj is PdfIndirectReference) && !obj.IsIndirect())
+ return;
+ switch (obj.Type) {
+ case PdfObject.INDIRECT: {
+ int xr = ((PRIndirectReference)obj).Number;
+ obj = (PdfObject)xrefObj[xr];
+ xrefObj[xr] = null;
+ freeXref = xr;
+ KillXref(obj);
+ break;
+ }
+ case PdfObject.ARRAY: {
+ ArrayList t = ((PdfArray)obj).ArrayList;
+ for (int i = 0; i < t.Count; ++i)
+ KillXref((PdfObject)t[i]);
+ break;
+ }
+ case PdfObject.STREAM:
+ case PdfObject.DICTIONARY: {
+ PdfDictionary dic = (PdfDictionary)obj;
+ foreach (PdfName key in dic.Keys){
+ KillXref(dic.Get(key));
+ }
+ break;
+ }
+ }
+ }
+
+ /** Sets the contents of the page.
+ * @param content the new page content
+ * @param pageNum the page number. 1 is the first
+ * @throws IOException on error
+ */
+ public void SetPageContent(int pageNum, byte[] content) {
+ PdfDictionary page = GetPageN(pageNum);
+ if (page == null)
+ return;
+ PdfObject contents = page.Get(PdfName.CONTENTS);
+ freeXref = -1;
+ KillXref(contents);
+ if (freeXref == -1) {
+ xrefObj.Add(null);
+ freeXref = xrefObj.Count - 1;
+ }
+ page.Put(PdfName.CONTENTS, new PRIndirectReference(this, freeXref));
+ xrefObj[freeXref] = new PRStream(this, content);
+ }
+
+ /** Get the content from a stream applying the required filters.
+ * @param stream the stream
+ * @param file the location where the stream is
+ * @throws IOException on error
+ * @return the stream content
+ */
+ public static byte[] GetStreamBytes(PRStream stream, RandomAccessFileOrArray file) {
+ PdfObject filter = GetPdfObjectRelease(stream.Get(PdfName.FILTER));
+ byte[] b = GetStreamBytesRaw(stream, file);
+ ArrayList filters = new ArrayList();
+ if (filter != null) {
+ if (filter.IsName())
+ filters.Add(filter);
+ else if (filter.IsArray())
+ filters = ((PdfArray)filter).ArrayList;
+ }
+ ArrayList dp = new ArrayList();
+ PdfObject dpo = GetPdfObjectRelease(stream.Get(PdfName.DECODEPARMS));
+ if (dpo == null || (!dpo.IsDictionary() && !dpo.IsArray()))
+ dpo = GetPdfObjectRelease(stream.Get(PdfName.DP));
+ if (dpo != null) {
+ if (dpo.IsDictionary())
+ dp.Add(dpo);
+ else if (dpo.IsArray())
+ dp = ((PdfArray)dpo).ArrayList;
+ }
+ String name;
+ for (int j = 0; j < filters.Count; ++j) {
+ name = ((PdfName)GetPdfObjectRelease((PdfObject)filters[j])).ToString();
+ if (name.Equals("/FlateDecode") || name.Equals("/Fl")) {
+ b = FlateDecode(b);
+ PdfObject dicParam = null;
+ if (j < dp.Count) {
+ dicParam = (PdfObject)dp[j];
+ b = DecodePredictor(b, dicParam);
+ }
+ }
+ else if (name.Equals("/ASCIIHexDecode") || name.Equals("/AHx"))
+ b = ASCIIHexDecode(b);
+ else if (name.Equals("/ASCII85Decode") || name.Equals("/A85"))
+ b = ASCII85Decode(b);
+ else if (name.Equals("/LZWDecode")) {
+ b = LZWDecode(b);
+ PdfObject dicParam = null;
+ if (j < dp.Count) {
+ dicParam = (PdfObject)dp[j];
+ b = DecodePredictor(b, dicParam);
+ }
+ }
+ else if (name.Equals("/Crypt")) {
+ }
+ else
+ throw new IOException("The filter " + name + " is not supported.");
+ }
+ return b;
+ }
+
+ /** Get the content from a stream applying the required filters.
+ * @param stream the stream
+ * @throws IOException on error
+ * @return the stream content
+ */
+ public static byte[] GetStreamBytes(PRStream stream) {
+ RandomAccessFileOrArray rf = stream.Reader.SafeFile;
+ try {
+ rf.ReOpen();
+ return GetStreamBytes(stream, rf);
+ }
+ finally {
+ try{rf.Close();}catch{}
+ }
+ }
+
+ /** Get the content from a stream as it is without applying any filter.
+ * @param stream the stream
+ * @param file the location where the stream is
+ * @throws IOException on error
+ * @return the stream content
+ */
+ public static byte[] GetStreamBytesRaw(PRStream stream, RandomAccessFileOrArray file) {
+ PdfReader reader = stream.Reader;
+ byte[] b;
+ if (stream.Offset < 0)
+ b = stream.GetBytes();
+ else {
+ b = new byte[stream.Length];
+ file.Seek(stream.Offset);
+ file.ReadFully(b);
+ PdfEncryption decrypt = reader.Decrypt;
+ if (decrypt != null) {
+ PdfObject filter = GetPdfObjectRelease(stream.Get(PdfName.FILTER));
+ ArrayList filters = new ArrayList();
+ if (filter != null) {
+ if (filter.IsName())
+ filters.Add(filter);
+ else if (filter.IsArray())
+ filters = ((PdfArray)filter).ArrayList;
+ }
+ bool skip = false;
+ for (int k = 0; k < filters.Count; ++k) {
+ PdfObject obj = GetPdfObjectRelease((PdfObject)filters[k]);
+ if (obj != null && obj.ToString().Equals("/Crypt")) {
+ skip = true;
+ break;
+ }
+ }
+ if (!skip) {
+ decrypt.SetHashKey(stream.ObjNum, stream.ObjGen);
+ b = decrypt.DecryptByteArray(b);
+ }
+ }
+ }
+ return b;
+ }
+
+ /** Get the content from a stream as it is without applying any filter.
+ * @param stream the stream
+ * @throws IOException on error
+ * @return the stream content
+ */
+ public static byte[] GetStreamBytesRaw(PRStream stream) {
+ RandomAccessFileOrArray rf = stream.Reader.SafeFile;
+ try {
+ rf.ReOpen();
+ return GetStreamBytesRaw(stream, rf);
+ }
+ finally {
+ try{rf.Close();}catch{}
+ }
+ }
+
+ /** Eliminates shared streams if they exist. */
+ public void EliminateSharedStreams() {
+ if (!sharedStreams)
+ return;
+ sharedStreams = false;
+ if (pageRefs.Size == 1)
+ return;
+ ArrayList newRefs = new ArrayList();
+ ArrayList newStreams = new ArrayList();
+ IntHashtable visited = new IntHashtable();
+ for (int k = 1; k <= pageRefs.Size; ++k) {
+ PdfDictionary page = pageRefs.GetPageN(k);
+ if (page == null)
+ continue;
+ PdfObject contents = GetPdfObject(page.Get(PdfName.CONTENTS));
+ if (contents == null)
+ continue;
+ if (contents.IsStream()) {
+ PRIndirectReference refi = (PRIndirectReference)page.Get(PdfName.CONTENTS);
+ if (visited.ContainsKey(refi.Number)) {
+ // need to duplicate
+ newRefs.Add(refi);
+ newStreams.Add(new PRStream((PRStream)contents, null));
+ }
+ else
+ visited[refi.Number] = 1;
+ }
+ else if (contents.IsArray()) {
+ PdfArray array = (PdfArray)contents;
+ ArrayList list = array.ArrayList;
+ for (int j = 0; j < list.Count; ++j) {
+ PRIndirectReference refi = (PRIndirectReference)list[j];
+ if (visited.ContainsKey(refi.Number)) {
+ // need to duplicate
+ newRefs.Add(refi);
+ newStreams.Add(new PRStream((PRStream)GetPdfObject(refi), null));
+ }
+ else
+ visited[refi.Number] = 1;
+ }
+ }
+ }
+ if (newStreams.Count == 0)
+ return;
+ for (int k = 0; k < newStreams.Count; ++k) {
+ xrefObj.Add(newStreams[k]);
+ PRIndirectReference refi = (PRIndirectReference)newRefs[k];
+ refi.SetNumber(xrefObj.Count - 1, 0);
+ }
+ }
+
+ /**
+ * Sets the tampered state. A tampered PdfReader cannot be reused in PdfStamper.
+ * @param tampered the tampered state
+ */
+ public bool Tampered {
+ get {
+ return tampered;
+ }
+ set {
+ tampered = value;
+ pageRefs.KeepPages(); }
+ }
+
+ /** Gets the XML metadata.
+ * @throws IOException on error
+ * @return the XML metadata
+ */
+ public byte[] Metadata {
+ get {
+ PdfObject obj = GetPdfObject(catalog.Get(PdfName.METADATA));
+ if (!(obj is PRStream))
+ return null;
+ RandomAccessFileOrArray rf = SafeFile;
+ byte[] b = null;
+ try {
+ rf.ReOpen();
+ b = GetStreamBytes((PRStream)obj, rf);
+ }
+ finally {
+ try {
+ rf.Close();
+ }
+ catch{
+ // empty on purpose
+ }
+ }
+ return b;
+ }
+ }
+
+ /**
+ * Gets the byte address of the last xref table.
+ * @return the byte address of the last xref table
+ */
+ public int LastXref {
+ get {
+ return lastXref;
+ }
+ }
+
+ /**
+ * Gets the number of xref objects.
+ * @return the number of xref objects
+ */
+ public int XrefSize {
+ get {
+ return xrefObj.Count;
+ }
+ }
+
+ /**
+ * Gets the byte address of the %%EOF marker.
+ * @return the byte address of the %%EOF marker
+ */
+ public int EofPos {
+ get {
+ return eofPos;
+ }
+ }
+
+ /**
+ * Gets the PDF version. Only the last version char is returned. For example
+ * version 1.4 is returned as '4'.
+ * @return the PDF version
+ */
+ public char PdfVersion {
+ get {
+ return pdfVersion;
+ }
+ }
+
+ /**
+ * Returns true
if the PDF is encrypted.
+ * @return true
if the PDF is encrypted
+ */
+ public bool IsEncrypted() {
+ return encrypted;
+ }
+
+ /**
+ * Gets the encryption permissions. It can be used directly in
+ * PdfWriter.SetEncryption()
.
+ * @return the encryption permissions
+ */
+ public int Permissions {
+ get {
+ return pValue;
+ }
+ }
+
+ /**
+ * Returns true
if the PDF has a 128 bit key encryption.
+ * @return true
if the PDF has a 128 bit key encryption
+ */
+ public bool Is128Key() {
+ return rValue == 3;
+ }
+
+ /**
+ * Gets the trailer dictionary
+ * @return the trailer dictionary
+ */
+ public PdfDictionary Trailer {
+ get {
+ return trailer;
+ }
+ }
+
+ internal PdfEncryption Decrypt {
+ get {
+ return decrypt;
+ }
+ }
+
+ internal static bool Equalsn(byte[] a1, byte[] a2) {
+ int length = a2.Length;
+ for (int k = 0; k < length; ++k) {
+ if (a1[k] != a2[k])
+ return false;
+ }
+ return true;
+ }
+
+ internal static bool ExistsName(PdfDictionary dic, PdfName key, PdfName value) {
+ PdfObject type = GetPdfObjectRelease(dic.Get(key));
+ if (type == null || !type.IsName())
+ return false;
+ PdfName name = (PdfName)type;
+ return name.Equals(value);
+ }
+
+ internal static String GetFontName(PdfDictionary dic) {
+ if (dic == null)
+ return null;
+ PdfObject type = GetPdfObjectRelease(dic.Get(PdfName.BASEFONT));
+ if (type == null || !type.IsName())
+ return null;
+ return PdfName.DecodeName(type.ToString());
+ }
+
+ internal static String GetSubsetPrefix(PdfDictionary dic) {
+ if (dic == null)
+ return null;
+ String s = GetFontName(dic);
+ if (s == null)
+ return null;
+ if (s.Length < 8 || s[6] != '+')
+ return null;
+ for (int k = 0; k < 6; ++k) {
+ char c = s[k];
+ if (c < 'A' || c > 'Z')
+ return null;
+ }
+ return s;
+ }
+
+ /** Finds all the font subsets and changes the prefixes to some
+ * random values.
+ * @return the number of font subsets altered
+ */
+ public int ShuffleSubsetNames() {
+ int total = 0;
+ for (int k = 1; k < xrefObj.Count; ++k) {
+ PdfObject obj = GetPdfObjectRelease(k);
+ if (obj == null || !obj.IsDictionary())
+ continue;
+ PdfDictionary dic = (PdfDictionary)obj;
+ if (!ExistsName(dic, PdfName.TYPE, PdfName.FONT))
+ continue;
+ if (ExistsName(dic, PdfName.SUBTYPE, PdfName.TYPE1)
+ || ExistsName(dic, PdfName.SUBTYPE, PdfName.MMTYPE1)
+ || ExistsName(dic, PdfName.SUBTYPE, PdfName.TRUETYPE)) {
+ String s = GetSubsetPrefix(dic);
+ if (s == null)
+ continue;
+ String ns = BaseFont.CreateSubsetPrefix() + s.Substring(7);
+ PdfName newName = new PdfName(ns);
+ dic.Put(PdfName.BASEFONT, newName);
+ SetXrefPartialObject(k, dic);
+ ++total;
+ PdfDictionary fd = (PdfDictionary)GetPdfObject(dic.Get(PdfName.FONTDESCRIPTOR));
+ if (fd == null)
+ continue;
+ fd.Put(PdfName.FONTNAME, newName);
+ }
+ else if (ExistsName(dic, PdfName.SUBTYPE, PdfName.TYPE0)) {
+ String s = GetSubsetPrefix(dic);
+ PdfArray arr = (PdfArray)GetPdfObject(dic.Get(PdfName.DESCENDANTFONTS));
+ if (arr == null)
+ continue;
+ ArrayList list = arr.ArrayList;
+ if (list.Count == 0)
+ continue;
+ PdfDictionary desc = (PdfDictionary)GetPdfObject((PdfObject)list[0]);
+ String sde = GetSubsetPrefix(desc);
+ if (sde == null)
+ continue;
+ String ns = BaseFont.CreateSubsetPrefix();
+ if (s != null)
+ dic.Put(PdfName.BASEFONT, new PdfName(ns + s.Substring(7)));
+ SetXrefPartialObject(k, dic);
+ PdfName newName = new PdfName(ns + sde.Substring(7));
+ desc.Put(PdfName.BASEFONT, newName);
+ ++total;
+ PdfDictionary fd = (PdfDictionary)GetPdfObject(desc.Get(PdfName.FONTDESCRIPTOR));
+ if (fd == null)
+ continue;
+ fd.Put(PdfName.FONTNAME, newName);
+ }
+ }
+ return total;
+ }
+
+ /** Finds all the fonts not subset but embedded and marks them as subset.
+ * @return the number of fonts altered
+ */
+ public int CreateFakeFontSubsets() {
+ int total = 0;
+ for (int k = 1; k < xrefObj.Count; ++k) {
+ PdfObject obj = GetPdfObjectRelease(k);
+ if (obj == null || !obj.IsDictionary())
+ continue;
+ PdfDictionary dic = (PdfDictionary)obj;
+ if (!ExistsName(dic, PdfName.TYPE, PdfName.FONT))
+ continue;
+ if (ExistsName(dic, PdfName.SUBTYPE, PdfName.TYPE1)
+ || ExistsName(dic, PdfName.SUBTYPE, PdfName.MMTYPE1)
+ || ExistsName(dic, PdfName.SUBTYPE, PdfName.TRUETYPE)) {
+ String s = GetSubsetPrefix(dic);
+ if (s != null)
+ continue;
+ s = GetFontName(dic);
+ if (s == null)
+ continue;
+ String ns = BaseFont.CreateSubsetPrefix() + s;
+ PdfDictionary fd = (PdfDictionary)GetPdfObjectRelease(dic.Get(PdfName.FONTDESCRIPTOR));
+ if (fd == null)
+ continue;
+ if (fd.Get(PdfName.FONTFILE) == null && fd.Get(PdfName.FONTFILE2) == null
+ && fd.Get(PdfName.FONTFILE3) == null)
+ continue;
+ fd = (PdfDictionary)GetPdfObject(dic.Get(PdfName.FONTDESCRIPTOR));
+ PdfName newName = new PdfName(ns);
+ dic.Put(PdfName.BASEFONT, newName);
+ fd.Put(PdfName.FONTNAME, newName);
+ SetXrefPartialObject(k, dic);
+ ++total;
+ }
+ }
+ return total;
+ }
+
+ private static PdfArray GetNameArray(PdfObject obj) {
+ if (obj == null)
+ return null;
+ obj = GetPdfObjectRelease(obj);
+ if (obj == null)
+ return null;
+ if (obj.IsArray())
+ return (PdfArray)obj;
+ else if (obj.IsDictionary()) {
+ PdfObject arr2 = GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.D));
+ if (arr2 != null && arr2.IsArray())
+ return (PdfArray)arr2;
+ }
+ return null;
+ }
+
+ /**
+ * Gets all the named destinations as an Hashtable
. The key is the name
+ * and the value is the destinations array.
+ * @return gets all the named destinations
+ */
+ public Hashtable GetNamedDestination() {
+ Hashtable names = GetNamedDestinationFromNames();
+ Hashtable names2 = GetNamedDestinationFromStrings();
+ foreach (DictionaryEntry ie in names2)
+ names[ie.Key] = ie.Value;
+ return names;
+ }
+
+ /**
+ * Gets the named destinations from the /Dests key in the catalog as an Hashtable
. The key is the name
+ * and the value is the destinations array.
+ * @return gets the named destinations
+ */
+ public Hashtable GetNamedDestinationFromNames() {
+ Hashtable names = new Hashtable();
+ if (catalog.Get(PdfName.DESTS) != null) {
+ PdfDictionary dic = (PdfDictionary)GetPdfObjectRelease(catalog.Get(PdfName.DESTS));
+ if (dic == null)
+ return names;
+ foreach (PdfName key in dic.Keys) {
+ String name = PdfName.DecodeName(key.ToString());
+ PdfArray arr = GetNameArray(dic.Get(key));
+ if (arr != null)
+ names[name] = arr;
+ }
+ }
+ return names;
+ }
+
+ /**
+ * Gets the named destinations from the /Names key in the catalog as an Hashtable
. The key is the name
+ * and the value is the destinations array.
+ * @return gets the named destinations
+ */
+ public Hashtable GetNamedDestinationFromStrings() {
+ if (catalog.Get(PdfName.NAMES) != null) {
+ PdfDictionary dic = (PdfDictionary)GetPdfObjectRelease(catalog.Get(PdfName.NAMES));
+ if (dic != null) {
+ dic = (PdfDictionary)GetPdfObjectRelease(dic.Get(PdfName.DESTS));
+ if (dic != null) {
+ Hashtable names = PdfNameTree.ReadTree(dic);
+ object[] keys = new object[names.Count];
+ names.Keys.CopyTo(keys, 0);
+ foreach (object key in keys) {
+ PdfArray arr = GetNameArray((PdfObject)names[key]);
+ if (arr != null)
+ names[key] = arr;
+ else
+ names.Remove(key);
+ }
+ return names;
+ }
+ }
+ }
+ return new Hashtable();
+ }
+
+ private bool ReplaceNamedDestination(PdfObject obj, Hashtable names) {
+ obj = GetPdfObject(obj);
+ int objIdx = lastXrefPartial;
+ ReleaseLastXrefPartial();
+ if (obj != null && obj.IsDictionary()) {
+ PdfObject ob2 = GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.DEST));
+ String name = null;
+ if (ob2 != null) {
+ if (ob2.IsName())
+ name = PdfName.DecodeName(ob2.ToString());
+ else if (ob2.IsString())
+ name = ob2.ToString();
+ if (name != null) {
+ PdfArray dest = (PdfArray)names[name];
+ if (dest != null) {
+ ((PdfDictionary)obj).Put(PdfName.DEST, dest);
+ SetXrefPartialObject(objIdx, obj);
+ return true;
+ }
+ }
+ }
+ else if ((ob2 = GetPdfObject(((PdfDictionary)obj).Get(PdfName.A))) != null) {
+ int obj2Idx = lastXrefPartial;
+ ReleaseLastXrefPartial();
+ PdfDictionary dic = (PdfDictionary)ob2;
+ PdfName type = (PdfName)GetPdfObjectRelease(dic.Get(PdfName.S));
+ if (PdfName.GOTO.Equals(type)) {
+ PdfObject ob3 = GetPdfObjectRelease(dic.Get(PdfName.D));
+ if (ob3 != null) {
+ if (ob3.IsName())
+ name = PdfName.DecodeName(ob3.ToString());
+ else if (ob3.IsString())
+ name = ob3.ToString();
+ }
+ if (name != null) {
+ PdfArray dest = (PdfArray)names[name];
+ if (dest != null) {
+ dic.Put(PdfName.D, dest);
+ SetXrefPartialObject(obj2Idx, ob2);
+ SetXrefPartialObject(objIdx, obj);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Removes all the fields from the document.
+ */
+ public void RemoveFields() {
+ pageRefs.ResetReleasePage();
+ for (int k = 1; k <= pageRefs.Size; ++k) {
+ PdfDictionary page = pageRefs.GetPageN(k);
+ PdfArray annots = (PdfArray)GetPdfObject(page.Get(PdfName.ANNOTS));
+ if (annots == null) {
+ pageRefs.ReleasePage(k);
+ continue;
+ }
+ ArrayList arr = annots.ArrayList;
+ for (int j = 0; j < arr.Count; ++j) {
+ PdfObject obj = GetPdfObjectRelease((PdfObject)arr[j]);
+ if (obj == null || !obj.IsDictionary())
+ continue;
+ PdfDictionary annot = (PdfDictionary)obj;
+ if (PdfName.WIDGET.Equals(annot.Get(PdfName.SUBTYPE)))
+ arr.RemoveAt(j--);
+ }
+ if (arr.Count == 0)
+ page.Remove(PdfName.ANNOTS);
+ else
+ pageRefs.ReleasePage(k);
+ }
+ catalog.Remove(PdfName.ACROFORM);
+ pageRefs.ResetReleasePage();
+ }
+
+ /**
+ * Removes all the annotations and fields from the document.
+ */
+ public void RemoveAnnotations() {
+ pageRefs.ResetReleasePage();
+ for (int k = 1; k <= pageRefs.Size; ++k) {
+ PdfDictionary page = pageRefs.GetPageN(k);
+ if (page.Get(PdfName.ANNOTS) == null)
+ pageRefs.ReleasePage(k);
+ else
+ page.Remove(PdfName.ANNOTS);
+ }
+ catalog.Remove(PdfName.ACROFORM);
+ pageRefs.ResetReleasePage();
+ }
+
+ public ArrayList GetLinks(int page) {
+ pageRefs.ResetReleasePage();
+ ArrayList result = new ArrayList();
+ PdfDictionary pageDic = pageRefs.GetPageN(page);
+ if (pageDic.Get(PdfName.ANNOTS) != null) {
+ PdfArray annots = (PdfArray)GetPdfObject(pageDic.Get(PdfName.ANNOTS));
+ ArrayList arr = annots.ArrayList;
+ for (int j = 0; j < arr.Count; ++j) {
+ PdfDictionary annot = (PdfDictionary)GetPdfObjectRelease((PdfObject)arr[j]);
+
+ if (PdfName.LINK.Equals(annot.Get(PdfName.SUBTYPE))) {
+ result.Add(new PdfAnnotation.PdfImportedLink(annot));
+ }
+ }
+ }
+ pageRefs.ReleasePage(page);
+ pageRefs.ResetReleasePage();
+ return result;
+ }
+
+ private void IterateBookmarks(PdfObject outlineRef, Hashtable names) {
+ while (outlineRef != null) {
+ ReplaceNamedDestination(outlineRef, names);
+ PdfDictionary outline = (PdfDictionary)GetPdfObjectRelease(outlineRef);
+ PdfObject first = outline.Get(PdfName.FIRST);
+ if (first != null) {
+ IterateBookmarks(first, names);
+ }
+ outlineRef = outline.Get(PdfName.NEXT);
+ }
+ }
+
+ /** Replaces all the local named links with the actual destinations. */
+ public void ConsolidateNamedDestinations() {
+ if (consolidateNamedDestinations)
+ return;
+ consolidateNamedDestinations = true;
+ Hashtable names = GetNamedDestination();
+ if (names.Count == 0)
+ return;
+ for (int k = 1; k <= pageRefs.Size; ++k) {
+ PdfDictionary page = pageRefs.GetPageN(k);
+ PdfObject annotsRef;
+ PdfArray annots = (PdfArray)GetPdfObject(annotsRef = page.Get(PdfName.ANNOTS));
+ int annotIdx = lastXrefPartial;
+ ReleaseLastXrefPartial();
+ if (annots == null) {
+ pageRefs.ReleasePage(k);
+ continue;
+ }
+ ArrayList list = annots.ArrayList;
+ bool commitAnnots = false;
+ for (int an = 0; an < list.Count; ++an) {
+ PdfObject objRef = (PdfObject)list[an];
+ if (ReplaceNamedDestination(objRef, names) && !objRef.IsIndirect())
+ commitAnnots = true;
+ }
+ if (commitAnnots)
+ SetXrefPartialObject(annotIdx, annots);
+ if (!commitAnnots || annotsRef.IsIndirect())
+ pageRefs.ReleasePage(k);
+ }
+ PdfDictionary outlines = (PdfDictionary)GetPdfObjectRelease(catalog.Get(PdfName.OUTLINES));
+ if (outlines == null)
+ return;
+ IterateBookmarks(outlines.Get(PdfName.FIRST), names);
+ }
+
+ protected internal static PdfDictionary DuplicatePdfDictionary(PdfDictionary original, PdfDictionary copy, PdfReader newReader) {
+ if (copy == null)
+ copy = new PdfDictionary();
+ foreach (PdfName key in original.Keys) {
+ copy.Put(key, DuplicatePdfObject(original.Get(key), newReader));
+ }
+ return copy;
+ }
+
+ protected internal static PdfObject DuplicatePdfObject(PdfObject original, PdfReader newReader) {
+ if (original == null)
+ return null;
+ switch (original.Type) {
+ case PdfObject.DICTIONARY: {
+ return DuplicatePdfDictionary((PdfDictionary)original, null, newReader);
+ }
+ case PdfObject.STREAM: {
+ PRStream org = (PRStream)original;
+ PRStream stream = new PRStream(org, null, newReader);
+ DuplicatePdfDictionary(org, stream, newReader);
+ return stream;
+ }
+ case PdfObject.ARRAY: {
+ ArrayList list = ((PdfArray)original).ArrayList;
+ PdfArray arr = new PdfArray();
+ foreach (PdfObject ob in list) {
+ arr.Add(DuplicatePdfObject(ob, newReader));
+ }
+ return arr;
+ }
+ case PdfObject.INDIRECT: {
+ PRIndirectReference org = (PRIndirectReference)original;
+ return new PRIndirectReference(newReader, org.Number, org.Generation);
+ }
+ default:
+ return original;
+ }
+ }
+
+ /**
+ * Closes the reader
+ */
+ public void Close() {
+ if (!partial)
+ return;
+ tokens.Close();
+ }
+
+ protected internal void RemoveUnusedNode(PdfObject obj, bool[] hits) {
+ Stack state = new Stack();
+ state.Push(obj);
+ while (state.Count != 0) {
+ Object current = state.Pop();
+ if (current == null)
+ continue;
+ ArrayList ar = null;
+ PdfDictionary dic = null;
+ PdfName[] keys = null;
+ Object[] objs = null;
+ int idx = 0;
+ if (current is PdfObject) {
+ obj = (PdfObject)current;
+ switch (obj.Type) {
+ case PdfObject.DICTIONARY:
+ case PdfObject.STREAM:
+ dic = (PdfDictionary)obj;
+ keys = new PdfName[dic.Size];
+ dic.Keys.CopyTo(keys, 0);
+ break;
+ case PdfObject.ARRAY:
+ ar = ((PdfArray)obj).ArrayList;
+ break;
+ case PdfObject.INDIRECT:
+ PRIndirectReference refi = (PRIndirectReference)obj;
+ int num = refi.Number;
+ if (!hits[num]) {
+ hits[num] = true;
+ state.Push(GetPdfObjectRelease(refi));
+ }
+ continue;
+ default:
+ continue;
+ }
+ }
+ else {
+ objs = (Object[])current;
+ if (objs[0] is ArrayList) {
+ ar = (ArrayList)objs[0];
+ idx = (int)objs[1];
+ }
+ else {
+ keys = (PdfName[])objs[0];
+ dic = (PdfDictionary)objs[1];
+ idx = (int)objs[2];
+ }
+ }
+ if (ar != null) {
+ for (int k = idx; k < ar.Count; ++k) {
+ PdfObject v = (PdfObject)ar[k];
+ if (v.IsIndirect()) {
+ int num = ((PRIndirectReference)v).Number;
+ if (num >= xrefObj.Count || (!partial && xrefObj[num] == null)) {
+ ar[k] = PdfNull.PDFNULL;
+ continue;
+ }
+ }
+ if (objs == null)
+ state.Push(new Object[]{ar, k + 1});
+ else {
+ objs[1] = k + 1;
+ state.Push(objs);
+ }
+ state.Push(v);
+ break;
+ }
+ }
+ else {
+ for (int k = idx; k < keys.Length; ++k) {
+ PdfName key = keys[k];
+ PdfObject v = dic.Get(key);
+ if (v.IsIndirect()) {
+ int num = ((PRIndirectReference)v).Number;
+ if (num >= xrefObj.Count || (!partial && xrefObj[num] == null)) {
+ dic.Put(key, PdfNull.PDFNULL);
+ continue;
+ }
+ }
+ if (objs == null)
+ state.Push(new Object[]{keys, dic, k + 1});
+ else {
+ objs[2] = k + 1;
+ state.Push(objs);
+ }
+ state.Push(v);
+ break;
+ }
+ }
+ }
+ }
+
+ /** Removes all the unreachable objects.
+ * @return the number of indirect objects removed
+ */
+ public int RemoveUnusedObjects() {
+ bool[] hits = new bool[xrefObj.Count];
+ RemoveUnusedNode(trailer, hits);
+ int total = 0;
+ if (partial) {
+ for (int k = 1; k < hits.Length; ++k) {
+ if (!hits[k]) {
+ xref[k * 2] = -1;
+ xref[k * 2 + 1] = 0;
+ xrefObj[k] = null;
+ ++total;
+ }
+ }
+ }
+ else {
+ for (int k = 1; k < hits.Length; ++k) {
+ if (!hits[k]) {
+ xrefObj[k] = null;
+ ++total;
+ }
+ }
+ }
+ return total;
+ }
+
+ /** Gets a read-only version of AcroFields
.
+ * @return a read-only version of AcroFields
+ */
+ public AcroFields AcroFields {
+ get {
+ return new AcroFields(this, null);
+ }
+ }
+
+ /**
+ * Gets the global document JavaScript.
+ * @param file the document file
+ * @throws IOException on error
+ * @return the global document JavaScript
+ */
+ public String GetJavaScript(RandomAccessFileOrArray file) {
+ PdfDictionary names = (PdfDictionary)GetPdfObjectRelease(catalog.Get(PdfName.NAMES));
+ if (names == null)
+ return null;
+ PdfDictionary js = (PdfDictionary)GetPdfObjectRelease(names.Get(PdfName.JAVASCRIPT));
+ if (js == null)
+ return null;
+ Hashtable jscript = PdfNameTree.ReadTree(js);
+ String[] sortedNames = new String[jscript.Count];
+ jscript.Keys.CopyTo(sortedNames, 0);
+ Array.Sort(sortedNames);
+ StringBuilder buf = new StringBuilder();
+ for (int k = 0; k < sortedNames.Length; ++k) {
+ PdfDictionary j = (PdfDictionary)GetPdfObjectRelease((PdfIndirectReference)jscript[sortedNames[k]]);
+ if (j == null)
+ continue;
+ PdfObject obj = GetPdfObjectRelease(j.Get(PdfName.JS));
+ if (obj != null) {
+ if (obj.IsString())
+ buf.Append(((PdfString)obj).ToUnicodeString()).Append('\n');
+ else if (obj.IsStream()) {
+ byte[] bytes = GetStreamBytes((PRStream)obj, file);
+ if (bytes.Length >= 2 && bytes[0] == (byte)254 && bytes[1] == (byte)255)
+ buf.Append(PdfEncodings.ConvertToString(bytes, PdfObject.TEXT_UNICODE));
+ else
+ buf.Append(PdfEncodings.ConvertToString(bytes, PdfObject.TEXT_PDFDOCENCODING));
+ buf.Append('\n');
+ }
+ }
+ }
+ return buf.ToString();
+ }
+
+ /**
+ * Gets the global document JavaScript.
+ * @throws IOException on error
+ * @return the global document JavaScript
+ */
+ public String JavaScript {
+ get {
+ RandomAccessFileOrArray rf = SafeFile;
+ try {
+ rf.ReOpen();
+ return GetJavaScript(rf);
+ }
+ finally {
+ try{rf.Close();}catch{}
+ }
+ }
+ }
+
+ /**
+ * Selects the pages to keep in the document. The pages are described as
+ * ranges. The page ordering can be changed but
+ * no page repetitions are allowed. Note that it may be very slow in partial mode.
+ * @param ranges the comma separated ranges as described in {@link SequenceList}
+ */
+ public void SelectPages(String ranges) {
+ SelectPages(SequenceList.Expand(ranges, NumberOfPages));
+ }
+
+ /**
+ * Selects the pages to keep in the document. The pages are described as a
+ * List
of Integer
. The page ordering can be changed but
+ * no page repetitions are allowed. Note that it may be very slow in partial mode.
+ * @param pagesToKeep the pages to keep in the document
+ */
+ public void SelectPages(ArrayList pagesToKeep) {
+ pageRefs.SelectPages(pagesToKeep);
+ RemoveUnusedObjects();
+ }
+
+ /** Sets the viewer preferences as the sum of several constants.
+ * @param preferences the viewer preferences
+ * @see PdfViewerPreferences#setViewerPreferences
+ */
+ public virtual int ViewerPreferences {
+ set {
+ this.viewerPreferences.ViewerPreferences = value;
+ SetViewerPreferences(this.viewerPreferences);
+ }
+ }
+
+ /** Adds a viewer preference
+ * @param key a key for a viewer preference
+ * @param value a value for the viewer preference
+ * @see PdfViewerPreferences#addViewerPreference
+ */
+ public virtual void AddViewerPreference(PdfName key, PdfObject value) {
+ this.viewerPreferences.AddViewerPreference(key, value);
+ SetViewerPreferences(this.viewerPreferences);
+ }
+
+ internal virtual void SetViewerPreferences(PdfViewerPreferencesImp vp) {
+ vp.AddToCatalog(catalog);
+ }
+
+ /**
+ * @return an int that contains the Viewer Preferences.
+ */
+ public virtual int SimpleViewerPreferences {
+ get {
+ return PdfViewerPreferencesImp.GetViewerPreferences(catalog).PageLayoutAndMode;
+ }
+ }
+
+ public bool Appendable {
+ set {
+ appendable = value;
+ if (appendable)
+ GetPdfObject(trailer.Get(PdfName.ROOT));
+ }
+ get {
+ return appendable;
+ }
+ }
+
+ /**
+ * Getter for property newXrefType.
+ * @return Value of property newXrefType.
+ */
+ public bool IsNewXrefType() {
+ return newXrefType;
+ }
+
+ /**
+ * Getter for property fileLength.
+ * @return Value of property fileLength.
+ */
+ public int FileLength {
+ get {
+ return fileLength;
+ }
+ }
+
+ /**
+ * Getter for property hybridXref.
+ * @return Value of property hybridXref.
+ */
+ public bool IsHybridXref() {
+ return hybridXref;
+ }
+
+ public class PageRefs {
+ private PdfReader reader;
+ private IntHashtable refsp;
+ private ArrayList refsn;
+ private ArrayList pageInh;
+ private int lastPageRead = -1;
+ private int sizep;
+ private bool keepPages;
+
+ internal PageRefs(PdfReader reader) {
+ this.reader = reader;
+ if (reader.partial) {
+ refsp = new IntHashtable();
+ PdfNumber npages = (PdfNumber)PdfReader.GetPdfObjectRelease(reader.rootPages.Get(PdfName.COUNT));
+ sizep = npages.IntValue;
+ }
+ else {
+ ReadPages();
+ }
+ }
+
+ internal PageRefs(PageRefs other, PdfReader reader) {
+ this.reader = reader;
+ this.sizep = other.sizep;
+ if (other.refsn != null) {
+ refsn = new ArrayList(other.refsn);
+ for (int k = 0; k < refsn.Count; ++k) {
+ refsn[k] = DuplicatePdfObject((PdfObject)refsn[k], reader);
+ }
+ }
+ else
+ this.refsp = (IntHashtable)other.refsp.Clone();
+ }
+
+ internal int Size {
+ get {
+ if (refsn != null)
+ return refsn.Count;
+ else
+ return sizep;
+ }
+ }
+
+ internal void ReadPages() {
+ if (refsn != null)
+ return;
+ refsp = null;
+ refsn = new ArrayList();
+ pageInh = new ArrayList();
+ IteratePages((PRIndirectReference)reader.catalog.Get(PdfName.PAGES));
+ pageInh = null;
+ reader.rootPages.Put(PdfName.COUNT, new PdfNumber(refsn.Count));
+ }
+
+ internal void ReReadPages() {
+ refsn = null;
+ ReadPages();
+ }
+
+ /** Gets the dictionary that represents a page.
+ * @param pageNum the page number. 1 is the first
+ * @return the page dictionary
+ */
+ public PdfDictionary GetPageN(int pageNum) {
+ PRIndirectReference refi = GetPageOrigRef(pageNum);
+ return (PdfDictionary)PdfReader.GetPdfObject(refi);
+ }
+
+ /**
+ * @param pageNum
+ * @return a dictionary object
+ */
+ public PdfDictionary GetPageNRelease(int pageNum) {
+ PdfDictionary page = GetPageN(pageNum);
+ ReleasePage(pageNum);
+ return page;
+ }
+
+ /**
+ * @param pageNum
+ * @return an indirect reference
+ */
+ public PRIndirectReference GetPageOrigRefRelease(int pageNum) {
+ PRIndirectReference refi = GetPageOrigRef(pageNum);
+ ReleasePage(pageNum);
+ return refi;
+ }
+
+ /** Gets the page reference to this page.
+ * @param pageNum the page number. 1 is the first
+ * @return the page reference
+ */
+ public PRIndirectReference GetPageOrigRef(int pageNum) {
+ --pageNum;
+ if (pageNum < 0 || pageNum >= Size)
+ return null;
+ if (refsn != null)
+ return (PRIndirectReference)refsn[pageNum];
+ else {
+ int n = refsp[pageNum];
+ if (n == 0) {
+ PRIndirectReference refi = GetSinglePage(pageNum);
+ if (reader.lastXrefPartial == -1)
+ lastPageRead = -1;
+ else
+ lastPageRead = pageNum;
+ reader.lastXrefPartial = -1;
+ refsp[pageNum] = refi.Number;
+ if (keepPages)
+ lastPageRead = -1;
+ return refi;
+ }
+ else {
+ if (lastPageRead != pageNum)
+ lastPageRead = -1;
+ if (keepPages)
+ lastPageRead = -1;
+ return new PRIndirectReference(reader, n);
+ }
+ }
+ }
+
+ internal void KeepPages() {
+ if (refsp == null || keepPages)
+ return;
+ keepPages = true;
+ refsp.Clear();
+ }
+
+ /**
+ * @param pageNum
+ */
+ public void ReleasePage(int pageNum) {
+ if (refsp == null)
+ return;
+ --pageNum;
+ if (pageNum < 0 || pageNum >= Size)
+ return;
+ if (pageNum != lastPageRead)
+ return;
+ lastPageRead = -1;
+ reader.lastXrefPartial = refsp[pageNum];
+ reader.ReleaseLastXrefPartial();
+ refsp.Remove(pageNum);
+ }
+
+ /**
+ *
+ */
+ public void ResetReleasePage() {
+ if (refsp == null)
+ return;
+ lastPageRead = -1;
+ }
+
+ internal void InsertPage(int pageNum, PRIndirectReference refi) {
+ --pageNum;
+ if (refsn != null) {
+ if (pageNum >= refsn.Count)
+ refsn.Add(refi);
+ else
+ refsn.Insert(pageNum, refi);
+ }
+ else {
+ ++sizep;
+ lastPageRead = -1;
+ if (pageNum >= Size) {
+ refsp[Size] = refi.Number;
+ }
+ else {
+ IntHashtable refs2 = new IntHashtable((refsp.Size + 1) * 2);
+ for (IntHashtable.IntHashtableIterator it = refsp.GetEntryIterator(); it.HasNext();) {
+ IntHashtable.IntHashtableEntry entry = (IntHashtable.IntHashtableEntry)it.Next();
+ int p = entry.Key;
+ refs2[p >= pageNum ? p + 1 : p] = entry.Value;
+ }
+ refs2[pageNum] = refi.Number;
+ refsp = refs2;
+ }
+ }
+ }
+
+ private void PushPageAttributes(PdfDictionary nodePages) {
+ PdfDictionary dic = new PdfDictionary();
+ if (pageInh.Count != 0) {
+ dic.Merge((PdfDictionary)pageInh[pageInh.Count - 1]);
+ }
+ for (int k = 0; k < pageInhCandidates.Length; ++k) {
+ PdfObject obj = nodePages.Get(pageInhCandidates[k]);
+ if (obj != null)
+ dic.Put(pageInhCandidates[k], obj);
+ }
+ pageInh.Add(dic);
+ }
+
+ private void PopPageAttributes() {
+ pageInh.RemoveAt(pageInh.Count - 1);
+ }
+
+ private void IteratePages(PRIndirectReference rpage) {
+ PdfDictionary page = (PdfDictionary)GetPdfObject(rpage);
+ PdfArray kidsPR = (PdfArray)GetPdfObject(page.Get(PdfName.KIDS));
+ if (kidsPR == null) {
+ page.Put(PdfName.TYPE, PdfName.PAGE);
+ PdfDictionary dic = (PdfDictionary)pageInh[pageInh.Count - 1];
+ foreach (PdfName key in dic.Keys) {
+ if (page.Get(key) == null)
+ page.Put(key, dic.Get(key));
+ }
+ if (page.Get(PdfName.MEDIABOX) == null) {
+ PdfArray arr = new PdfArray(new float[]{0,0,PageSize.LETTER.Right,PageSize.LETTER.Top});
+ page.Put(PdfName.MEDIABOX, arr);
+ }
+ refsn.Add(rpage);
+ }
+ else {
+ page.Put(PdfName.TYPE, PdfName.PAGES);
+ PushPageAttributes(page);
+ ArrayList kids = kidsPR.ArrayList;
+ for (int k = 0; k < kids.Count; ++k){
+ PdfObject obj = (PdfObject)kids[k];
+ if (!obj.IsIndirect()) {
+ while (k < kids.Count)
+ kids.RemoveAt(k);
+ break;
+ }
+ IteratePages((PRIndirectReference)obj);
+ }
+ PopPageAttributes();
+ }
+ }
+
+ protected internal PRIndirectReference GetSinglePage(int n) {
+ PdfDictionary acc = new PdfDictionary();
+ PdfDictionary top = reader.rootPages;
+ int baseb = 0;
+ while (true) {
+ for (int k = 0; k < pageInhCandidates.Length; ++k) {
+ PdfObject obj = top.Get(pageInhCandidates[k]);
+ if (obj != null)
+ acc.Put(pageInhCandidates[k], obj);
+ }
+ PdfArray kids = (PdfArray)PdfReader.GetPdfObjectRelease(top.Get(PdfName.KIDS));
+ for (ListIterator it = new ListIterator(kids.ArrayList); it.HasNext();) {
+ PRIndirectReference refi = (PRIndirectReference)it.Next();
+ PdfDictionary dic = (PdfDictionary)GetPdfObject(refi);
+ int last = reader.lastXrefPartial;
+ PdfObject count = GetPdfObjectRelease(dic.Get(PdfName.COUNT));
+ reader.lastXrefPartial = last;
+ int acn = 1;
+ if (count != null && count.Type == PdfObject.NUMBER)
+ acn = ((PdfNumber)count).IntValue;
+ if (n < baseb + acn) {
+ if (count == null) {
+ dic.MergeDifferent(acc);
+ return refi;
+ }
+ reader.ReleaseLastXrefPartial();
+ top = dic;
+ break;
+ }
+ reader.ReleaseLastXrefPartial();
+ baseb += acn;
+ }
+ }
+ }
+
+ internal void SelectPages(ArrayList pagesToKeep) {
+ IntHashtable pg = new IntHashtable();
+ ArrayList finalPages = new ArrayList();
+ int psize = Size;
+ foreach (int p in pagesToKeep) {
+ if (p >= 1 && p <= psize && !pg.ContainsKey(p)) {
+ pg[p] = 1;
+ finalPages.Add(p);
+ }
+ }
+ if (reader.partial) {
+ for (int k = 1; k <= psize; ++k) {
+ GetPageOrigRef(k);
+ ResetReleasePage();
+ }
+ }
+ PRIndirectReference parent = (PRIndirectReference)reader.catalog.Get(PdfName.PAGES);
+ PdfDictionary topPages = (PdfDictionary)PdfReader.GetPdfObject(parent);
+ ArrayList newPageRefs = new ArrayList(finalPages.Count);
+ PdfArray kids = new PdfArray();
+ foreach (int p in finalPages) {
+ PRIndirectReference pref = GetPageOrigRef(p);
+ ResetReleasePage();
+ kids.Add(pref);
+ newPageRefs.Add(pref);
+ GetPageN(p).Put(PdfName.PARENT, parent);
+ }
+ AcroFields af = reader.AcroFields;
+ bool removeFields = (af.Fields.Count > 0);
+ for (int k = 1; k <= psize; ++k) {
+ if (!pg.ContainsKey(k)) {
+ if (removeFields)
+ af.RemoveFieldsFromPage(k);
+ PRIndirectReference pref = GetPageOrigRef(k);
+ int nref = pref.Number;
+ reader.xrefObj[nref] = null;
+ if (reader.partial) {
+ reader.xref[nref * 2] = -1;
+ reader.xref[nref * 2 + 1] = 0;
+ }
+ }
+ }
+ topPages.Put(PdfName.COUNT, new PdfNumber(finalPages.Count));
+ topPages.Put(PdfName.KIDS, kids);
+ refsp = null;
+ refsn = newPageRefs;
+ }
+ }
+
+ internal PdfIndirectReference GetCryptoRef() {
+ if (cryptoRef == null)
+ return null;
+ return new PdfIndirectReference(0, cryptoRef.Number, cryptoRef.Generation);
+ }
+
+ /**
+ * Removes any usage rights that this PDF may have. Only Adobe can grant usage rights
+ * and any PDF modification with iText will invalidate them. Invalidated usage rights may
+ * confuse Acrobat and it's advisabe to remove them altogether.
+ */
+ public void RemoveUsageRights() {
+ PdfDictionary perms = (PdfDictionary)GetPdfObject(catalog.Get(PdfName.PERMS));
+ if (perms == null)
+ return;
+ perms.Remove(PdfName.UR);
+ perms.Remove(PdfName.UR3);
+ if (perms.Size == 0)
+ catalog.Remove(PdfName.PERMS);
+ }
+
+ /**
+ * Gets the certification level for this document. The return values can be PdfSignatureAppearance.NOT_CERTIFIED
,
+ * PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED
,
+ * PdfSignatureAppearance.CERTIFIED_FORM_FILLING
and
+ * PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS
.
+ * AcroFields
.
+ * true
.
+ * @return true
if the document was opened with the owner password or if it's not encrypted,
+ * false
if the document was opened with the user password
+ */
+ public bool IsOpenedWithFullPermissions {
+ get {
+ return !encrypted || ownerPasswordUsed;
+ }
+ }
+
+ public int GetCryptoMode() {
+ if (decrypt == null)
+ return -1;
+ else
+ return decrypt.GetCryptoMode();
+ }
+
+ public bool IsMetadataEncrypted() {
+ if (decrypt == null)
+ return false;
+ else
+ return decrypt.IsMetadataEncrypted();
+ }
+
+ public byte[] ComputeUserPassword() {
+ if (!encrypted || !ownerPasswordUsed) return null;
+ return decrypt.ComputeUserPassword(password);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfReaderInstance.cs b/iTechSharp/iTextSharp/text/pdf/PdfReaderInstance.cs
new file mode 100644
index 0000000..e17b847
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfReaderInstance.cs
@@ -0,0 +1,185 @@
+using System;
+using System.IO;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Instance of PdfReader in each output document.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfReaderInstance {
+ internal static PdfLiteral IDENTITYMATRIX = new PdfLiteral("[1 0 0 1 0 0]");
+ internal static PdfNumber ONE = new PdfNumber(1);
+ internal int[] myXref;
+ internal PdfReader reader;
+ internal RandomAccessFileOrArray file;
+ internal Hashtable importedPages = new Hashtable();
+ internal PdfWriter writer;
+ internal Hashtable visited = new Hashtable();
+ internal ArrayList nextRound = new ArrayList();
+
+ internal PdfReaderInstance(PdfReader reader, PdfWriter writer) {
+ this.reader = reader;
+ this.writer = writer;
+ file = reader.SafeFile;
+ myXref = new int[reader.XrefSize];
+ }
+
+ internal PdfReader Reader {
+ get {
+ return reader;
+ }
+ }
+
+ internal PdfImportedPage GetImportedPage(int pageNumber) {
+ if (!reader.IsOpenedWithFullPermissions)
+ throw new ArgumentException("PdfReader not opened with owner password");
+ if (pageNumber < 1 || pageNumber > reader.NumberOfPages)
+ throw new ArgumentException("Invalid page number: " + pageNumber);
+ PdfImportedPage pageT = (PdfImportedPage)importedPages[pageNumber];
+ if (pageT == null) {
+ pageT = new PdfImportedPage(this, writer, pageNumber);
+ importedPages[pageNumber] = pageT;
+ }
+ return pageT;
+ }
+
+ internal int GetNewObjectNumber(int number, int generation) {
+ if (myXref[number] == 0) {
+ myXref[number] = writer.IndirectReferenceNumber;
+ nextRound.Add(number);
+ }
+ return myXref[number];
+ }
+
+ internal RandomAccessFileOrArray ReaderFile {
+ get {
+ return file;
+ }
+ }
+
+ internal PdfObject GetResources(int pageNumber) {
+ PdfObject obj = PdfReader.GetPdfObjectRelease(reader.GetPageNRelease(pageNumber).Get(PdfName.RESOURCES));
+ return obj;
+ }
+
+
+ internal PdfStream GetFormXObject(int pageNumber) {
+ PdfDictionary page = reader.GetPageNRelease(pageNumber);
+ PdfObject contents = PdfReader.GetPdfObjectRelease(page.Get(PdfName.CONTENTS));
+ PdfDictionary dic = new PdfDictionary();
+ byte[] bout = null;
+ if (contents != null) {
+ if (contents.IsStream())
+ dic.Merge((PRStream)contents);
+ else
+ bout = reader.GetPageContent(pageNumber, file);
+ }
+ else
+ bout = new byte[0];
+ dic.Put(PdfName.RESOURCES, PdfReader.GetPdfObjectRelease(page.Get(PdfName.RESOURCES)));
+ dic.Put(PdfName.TYPE, PdfName.XOBJECT);
+ dic.Put(PdfName.SUBTYPE, PdfName.FORM);
+ PdfImportedPage impPage = (PdfImportedPage)importedPages[pageNumber];
+ dic.Put(PdfName.BBOX, new PdfRectangle(impPage.BoundingBox));
+ PdfArray matrix = impPage.Matrix;
+ if (matrix == null)
+ dic.Put(PdfName.MATRIX, IDENTITYMATRIX);
+ else
+ dic.Put(PdfName.MATRIX, matrix);
+ dic.Put(PdfName.FORMTYPE, ONE);
+ PRStream stream;
+ if (bout == null) {
+ stream = new PRStream((PRStream)contents, dic);
+ }
+ else {
+ stream = new PRStream(reader, bout);
+ stream.Merge(dic);
+ }
+ return stream;
+ }
+
+ internal void WriteAllVisited() {
+ while (nextRound.Count > 0) {
+ ArrayList vec = nextRound;
+ nextRound = new ArrayList();
+ for (int k = 0; k < vec.Count; ++k) {
+ int i = (int)vec[k];
+ if (!visited.ContainsKey(i)) {
+ visited[i] = null;
+ writer.AddToBody(reader.GetPdfObjectRelease(i), myXref[i]);
+ }
+ }
+ }
+ }
+
+ internal void WriteAllPages() {
+ try {
+ file.ReOpen();
+ foreach (PdfImportedPage ip in importedPages.Values) {
+ writer.AddToBody(ip.FormXObject, ip.IndirectReference);
+ }
+ WriteAllVisited();
+ }
+ finally {
+ try {
+ reader.Close();
+ file.Close();
+ }
+ catch {
+ //Empty on purpose
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfRectangle.cs b/iTechSharp/iTextSharp/text/pdf/PdfRectangle.cs
new file mode 100644
index 0000000..42b36b5
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfRectangle.cs
@@ -0,0 +1,290 @@
+using System;
+
+using iTextSharp.text;
+
+/*
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfRectangle
is the PDF Rectangle object.
+ * array
of
+ * four numbers, specifying the lower lef x, lower left y, upper right x,
+ * and upper right y coordinates of the rectangle, in that order.
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 7.1 (page 183).
+ *
+ * @see iTextSharp.text.Rectangle
+ * @see PdfArray
+ */
+
+ public class PdfRectangle : PdfArray {
+
+ // membervariables
+
+ /** lower left x */
+ private float llx = 0;
+
+ /** lower left y */
+ private float lly = 0;
+
+ /** upper right x */
+ private float urx = 0;
+
+ /** upper right y */
+ private float ury = 0;
+
+ // constructors
+
+ /**
+ * Constructs a PdfRectangle
-object.
+ *
+ * @param llx lower left x
+ * @param lly lower left y
+ * @param urx upper right x
+ * @param ury upper right y
+ *
+ * @since rugPdf0.10
+ */
+
+ public PdfRectangle(float llx, float lly, float urx, float ury, int rotation) : base() {
+ if (rotation == 90 || rotation == 270) {
+ this.llx = lly;
+ this.lly = llx;
+ this.urx = ury;
+ this.ury = urx;
+ }
+ else {
+ this.llx = llx;
+ this.lly = lly;
+ this.urx = urx;
+ this.ury = ury;
+ }
+ base.Add(new PdfNumber(this.llx));
+ base.Add(new PdfNumber(this.lly));
+ base.Add(new PdfNumber(this.urx));
+ base.Add(new PdfNumber(this.ury));
+ }
+
+ public PdfRectangle(float llx, float lly, float urx, float ury) : this(llx, lly, urx, ury, 0) {}
+
+ /**
+ * Constructs a PdfRectangle
-object starting from the origin (0, 0).
+ *
+ * @param urx upper right x
+ * @param ury upper right y
+ */
+
+ public PdfRectangle(float urx, float ury, int rotation) : this(0, 0, urx, ury, rotation) {}
+
+ public PdfRectangle(float urx, float ury) : this(0, 0, urx, ury, 0) {}
+
+ /**
+ * Constructs a PdfRectangle
-object with a Rectangle
-object.
+ *
+ * @param rectangle a Rectangle
+ */
+
+ public PdfRectangle(Rectangle rectangle, int rotation) : this(rectangle.Left, rectangle.Bottom, rectangle.Right, rectangle.Top, rotation) {}
+
+ public PdfRectangle(Rectangle rectangle) : this(rectangle.Left, rectangle.Bottom, rectangle.Right, rectangle.Top, 0) {}
+
+ // methods
+
+ /**
+ * Returns the high level version of this PdfRectangle
+ * @return this PdfRectangle translated to class Rectangle
+ */
+ public Rectangle Rectangle {
+ get {
+ return new Rectangle(Left, Bottom, Right, Top);
+ }
+ }
+
+ /**
+ * Overrides the add
-method in PdfArray
in order to prevent the adding of extra object to the array.
+ *
+ * @param object PdfObject
to add (will not be added here)
+ * @return false
+ */
+
+ public override bool Add(PdfObject obj) {
+ return false;
+ }
+
+ /**
+ * Returns the lower left x-coordinate.
+ *
+ * @return the lower left x-coordinaat
+ */
+
+ public float Left {
+ get {
+ return llx;
+ }
+ }
+
+ /**
+ * Returns the upper right x-coordinate.
+ *
+ * @return the upper right x-coordinate
+ */
+
+ public float Right {
+ get {
+ return urx;
+ }
+ }
+
+ /**
+ * Returns the upper right y-coordinate.
+ *
+ * @return the upper right y-coordinate
+ */
+
+ public float Top {
+ get {
+ return ury;
+ }
+ }
+
+ /**
+ * Returns the lower left y-coordinate.
+ *
+ * @return the lower left y-coordinate
+ */
+
+ public float Bottom {
+ get {
+ return lly;
+ }
+ }
+
+ /**
+ * Returns the lower left x-coordinate, considering a given margin.
+ *
+ * @param margin a margin
+ * @return the lower left x-coordinate
+ */
+
+ public float GetLeft(int margin) {
+ return llx + margin;
+ }
+
+ /**
+ * Returns the upper right x-coordinate, considering a given margin.
+ *
+ * @param margin a margin
+ * @return the upper right x-coordinate
+ */
+
+ public float GetRight(int margin) {
+ return urx - margin;
+ }
+
+ /**
+ * Returns the upper right y-coordinate, considering a given margin.
+ *
+ * @param margin a margin
+ * @return the upper right y-coordinate
+ */
+
+ public float GetTop(int margin) {
+ return ury - margin;
+ }
+
+ /**
+ * Returns the lower left y-coordinate, considering a given margin.
+ *
+ * @param margin a margin
+ * @return the lower left y-coordinate
+ */
+
+ public float GetBottom(int margin) {
+ return lly + margin;
+ }
+
+ /**
+ * Returns the width of the rectangle.
+ *
+ * @return a width
+ */
+
+ public float Width {
+ get {
+ return urx - llx;
+ }
+ }
+
+ /**
+ * Returns the height of the rectangle.
+ *
+ * @return a height
+ */
+
+ public float Height {
+ get {
+ return ury - lly;
+ }
+ }
+
+ /**
+ * Swaps the values of urx and ury and of lly and llx in order to rotate the rectangle.
+ *
+ * @return a PdfRectangle
+ */
+
+ public PdfRectangle Rotate {
+ get {
+ return new PdfRectangle(lly, llx, ury, urx, 0);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfRendition.cs b/iTechSharp/iTextSharp/text/pdf/PdfRendition.cs
new file mode 100644
index 0000000..f859ef9
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfRendition.cs
@@ -0,0 +1,60 @@
+using System;
+/*
+ * Copyright 2003 Galo Gimenez
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * A Rendition dictionary (pdf spec 1.5)
+ */
+ public class PdfRendition : PdfDictionary {
+ public PdfRendition(String file, PdfFileSpecification fs, String mimeType) {
+ Put(PdfName.S, new PdfName("MR"));
+ Put(PdfName.N, new PdfString("Rendition for "+file));
+ Put(PdfName.C, new PdfMediaClipData(file, fs, mimeType));
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfResources.cs b/iTechSharp/iTextSharp/text/pdf/PdfResources.cs
new file mode 100644
index 0000000..1d44d88
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfResources.cs
@@ -0,0 +1,92 @@
+using System;
+
+/*
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfResources
is the PDF Resources-object.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 7.5 (page 195-197).
+ *
+ * @see PdfResource
+ * @see PdfProcSet
+ * @see PdfFontDictionary
+ * @see PdfPage
+ */
+
+ internal class PdfResources : PdfDictionary {
+
+ // constructor
+
+ /**
+ * Constructs a PDF ResourcesDictionary.
+ */
+
+ internal PdfResources() : base() {}
+
+ // methods
+
+ internal void Add(PdfName key, PdfDictionary resource) {
+ if (resource.Size == 0)
+ return;
+ PdfDictionary dic = (PdfDictionary)PdfReader.GetPdfObject(Get(key));
+ if (dic == null)
+ Put(key, resource);
+ else
+ dic.Merge(resource);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfShading.cs b/iTechSharp/iTextSharp/text/pdf/PdfShading.cs
new file mode 100644
index 0000000..5a8fb1e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfShading.cs
@@ -0,0 +1,277 @@
+using System;
+using iTextSharp.text;
+/*
+ * Copyright 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /** Implements the shading dictionary (or stream).
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfShading {
+
+ protected PdfDictionary shading;
+
+ protected PdfWriter writer;
+
+ protected int shadingType;
+
+ protected ColorDetails colorDetails;
+
+ protected PdfName shadingName;
+
+ protected PdfIndirectReference shadingReference;
+
+ /** Holds value of property bBox. */
+ protected float[] bBox;
+
+ /** Holds value of property antiAlias. */
+ protected bool antiAlias = false;
+
+ private Color cspace;
+
+ /** Creates new PdfShading */
+ protected PdfShading(PdfWriter writer) {
+ this.writer = writer;
+ }
+
+ protected void SetColorSpace(Color color) {
+ cspace = color;
+ int type = ExtendedColor.GetType(color);
+ PdfObject colorSpace = null;
+ switch (type) {
+ case ExtendedColor.TYPE_GRAY: {
+ colorSpace = PdfName.DEVICEGRAY;
+ break;
+ }
+ case ExtendedColor.TYPE_CMYK: {
+ colorSpace = PdfName.DEVICECMYK;
+ break;
+ }
+ case ExtendedColor.TYPE_SEPARATION: {
+ SpotColor spot = (SpotColor)color;
+ colorDetails = writer.AddSimple(spot.PdfSpotColor);
+ colorSpace = colorDetails.IndirectReference;
+ break;
+ }
+ case ExtendedColor.TYPE_PATTERN:
+ case ExtendedColor.TYPE_SHADING: {
+ ThrowColorSpaceError();
+ break;
+ }
+ default:
+ colorSpace = PdfName.DEVICERGB;
+ break;
+ }
+ shading.Put(PdfName.COLORSPACE, colorSpace);
+ }
+
+ public Color ColorSpace {
+ get {
+ return cspace;
+ }
+ }
+
+ public static void ThrowColorSpaceError() {
+ throw new ArgumentException("A tiling or shading pattern cannot be used as a color space in a shading pattern");
+ }
+
+ public static void CheckCompatibleColors(Color c1, Color c2) {
+ int type1 = ExtendedColor.GetType(c1);
+ int type2 = ExtendedColor.GetType(c2);
+ if (type1 != type2)
+ throw new ArgumentException("Both colors must be of the same type.");
+ if (type1 == ExtendedColor.TYPE_SEPARATION && ((SpotColor)c1).PdfSpotColor != ((SpotColor)c2).PdfSpotColor)
+ throw new ArgumentException("The spot color must be the same, only the tint can vary.");
+ if (type1 == ExtendedColor.TYPE_PATTERN || type1 == ExtendedColor.TYPE_SHADING)
+ ThrowColorSpaceError();
+ }
+
+ public static float[] GetColorArray(Color color) {
+ int type = ExtendedColor.GetType(color);
+ switch (type) {
+ case ExtendedColor.TYPE_GRAY: {
+ return new float[]{((GrayColor)color).Gray};
+ }
+ case ExtendedColor.TYPE_CMYK: {
+ CMYKColor cmyk = (CMYKColor)color;
+ return new float[]{cmyk.Cyan, cmyk.Magenta, cmyk.Yellow, cmyk.Black};
+ }
+ case ExtendedColor.TYPE_SEPARATION: {
+ return new float[]{((SpotColor)color).Tint};
+ }
+ case ExtendedColor.TYPE_RGB: {
+ return new float[]{color.R / 255f, color.G / 255f, color.B / 255f};
+ }
+ }
+ ThrowColorSpaceError();
+ return null;
+ }
+
+ public static PdfShading Type1(PdfWriter writer, Color colorSpace, float[] domain, float[] tMatrix, PdfFunction function) {
+ PdfShading sp = new PdfShading(writer);
+ sp.shading = new PdfDictionary();
+ sp.shadingType = 1;
+ sp.shading.Put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType));
+ sp.SetColorSpace(colorSpace);
+ if (domain != null)
+ sp.shading.Put(PdfName.DOMAIN, new PdfArray(domain));
+ if (tMatrix != null)
+ sp.shading.Put(PdfName.MATRIX, new PdfArray(tMatrix));
+ sp.shading.Put(PdfName.FUNCTION, function.Reference);
+ return sp;
+ }
+
+ public static PdfShading Type2(PdfWriter writer, Color colorSpace, float[] coords, float[] domain, PdfFunction function, bool[] extend) {
+ PdfShading sp = new PdfShading(writer);
+ sp.shading = new PdfDictionary();
+ sp.shadingType = 2;
+ sp.shading.Put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType));
+ sp.SetColorSpace(colorSpace);
+ sp.shading.Put(PdfName.COORDS, new PdfArray(coords));
+ if (domain != null)
+ sp.shading.Put(PdfName.DOMAIN, new PdfArray(domain));
+ sp.shading.Put(PdfName.FUNCTION, function.Reference);
+ if (extend != null && (extend[0] || extend[1])) {
+ PdfArray array = new PdfArray(extend[0] ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE);
+ array.Add(extend[1] ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE);
+ sp.shading.Put(PdfName.EXTEND, array);
+ }
+ return sp;
+ }
+
+ public static PdfShading Type3(PdfWriter writer, Color colorSpace, float[] coords, float[] domain, PdfFunction function, bool[] extend) {
+ PdfShading sp = Type2(writer, colorSpace, coords, domain, function, extend);
+ sp.shadingType = 3;
+ sp.shading.Put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType));
+ return sp;
+ }
+
+ public static PdfShading SimpleAxial(PdfWriter writer, float x0, float y0, float x1, float y1, Color startColor, Color endColor, bool extendStart, bool extendEnd) {
+ CheckCompatibleColors(startColor, endColor);
+ PdfFunction function = PdfFunction.Type2(writer, new float[]{0, 1}, null, GetColorArray(startColor),
+ GetColorArray(endColor), 1);
+ return Type2(writer, startColor, new float[]{x0, y0, x1, y1}, null, function, new bool[]{extendStart, extendEnd});
+ }
+
+ public static PdfShading SimpleAxial(PdfWriter writer, float x0, float y0, float x1, float y1, Color startColor, Color endColor) {
+ return SimpleAxial(writer, x0, y0, x1, y1, startColor, endColor, true, true);
+ }
+
+ public static PdfShading SimpleRadial(PdfWriter writer, float x0, float y0, float r0, float x1, float y1, float r1, Color startColor, Color endColor, bool extendStart, bool extendEnd) {
+ CheckCompatibleColors(startColor, endColor);
+ PdfFunction function = PdfFunction.Type2(writer, new float[]{0, 1}, null, GetColorArray(startColor),
+ GetColorArray(endColor), 1);
+ return Type3(writer, startColor, new float[]{x0, y0, r0, x1, y1, r1}, null, function, new bool[]{extendStart, extendEnd});
+ }
+
+ public static PdfShading SimpleRadial(PdfWriter writer, float x0, float y0, float r0, float x1, float y1, float r1, Color startColor, Color endColor) {
+ return SimpleRadial(writer, x0, y0, r0, x1, y1, r1, startColor, endColor, true, true);
+ }
+
+ internal PdfName ShadingName {
+ get {
+ return shadingName;
+ }
+ }
+
+ internal PdfIndirectReference ShadingReference {
+ get {
+ if (shadingReference == null)
+ shadingReference = writer.PdfIndirectReference;
+ return shadingReference;
+ }
+ }
+
+ internal int Name {
+ set {
+ shadingName = new PdfName("Sh" + value);
+ }
+ }
+
+ internal void AddToBody() {
+ if (bBox != null)
+ shading.Put(PdfName.BBOX, new PdfArray(bBox));
+ if (antiAlias)
+ shading.Put(PdfName.ANTIALIAS, PdfBoolean.PDFTRUE);
+ writer.AddToBody(shading, this.ShadingReference);
+ }
+
+ internal PdfWriter Writer {
+ get {
+ return writer;
+ }
+ }
+
+ internal ColorDetails ColorDetails {
+ get {
+ return colorDetails;
+ }
+ }
+
+ public float[] BBox {
+ get {
+ return bBox;
+ }
+ set {
+ if (value.Length != 4)
+ throw new ArgumentException("BBox must be a 4 element array.");
+ this.bBox = value;
+ }
+ }
+
+ public bool AntiAlias {
+ set {
+ this.antiAlias = value;
+ }
+ get {
+ return antiAlias;
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfShadingPattern.cs b/iTechSharp/iTextSharp/text/pdf/PdfShadingPattern.cs
new file mode 100644
index 0000000..b633e95
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfShadingPattern.cs
@@ -0,0 +1,137 @@
+using System;
+
+/*
+ * Copyright 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /** Implements the shading pattern dictionary.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfShadingPattern : PdfDictionary {
+
+ protected PdfShading shading;
+
+ protected PdfWriter writer;
+
+ protected float[] matrix = {1, 0, 0, 1, 0, 0};
+
+ protected PdfName patternName;
+
+ protected PdfIndirectReference patternReference;
+
+ /** Creates new PdfShadingPattern */
+ public PdfShadingPattern(PdfShading shading) {
+ writer = shading.Writer;
+ Put(PdfName.PATTERNTYPE, new PdfNumber(2));
+ this.shading = shading;
+ }
+
+ internal PdfName PatternName {
+ get {
+ return patternName;
+ }
+ }
+
+ internal PdfName ShadingName {
+ get {
+ return shading.ShadingName;
+ }
+ }
+
+ internal PdfIndirectReference PatternReference {
+ get {
+ if (patternReference == null)
+ patternReference = writer.PdfIndirectReference;
+ return patternReference;
+ }
+ }
+
+ internal PdfIndirectReference ShadingReference {
+ get {
+ return shading.ShadingReference;
+ }
+ }
+
+ internal int Name {
+ set {
+ patternName = new PdfName("P" + value);
+ }
+ }
+
+ internal void AddToBody() {
+ Put(PdfName.SHADING, ShadingReference);
+ Put(PdfName.MATRIX, new PdfArray(matrix));
+ writer.AddToBody(this, PatternReference);
+ }
+
+ public float[] Matrix {
+ get {
+ return matrix;
+ }
+
+ set {
+ if (value.Length != 6)
+ throw new Exception("The matrix size must be 6.");
+ this.matrix = value;
+ }
+ }
+
+ public PdfShading Shading {
+ get {
+ return shading;
+ }
+ }
+
+ internal ColorDetails ColorDetails {
+ get {
+ return shading.ColorDetails;
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfSigGenericPKCS.cs b/iTechSharp/iTextSharp/text/pdf/PdfSigGenericPKCS.cs
new file mode 100644
index 0000000..469a8d5
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfSigGenericPKCS.cs
@@ -0,0 +1,196 @@
+using System;
+using System.IO;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.Crypto;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A signature dictionary representation for the standard filters.
+ */
+ public abstract class PdfSigGenericPKCS : PdfSignature {
+ /**
+ * The hash algorith, for example "SHA1"
+ */
+ protected String hashAlgorithm;
+ /**
+ * The class instance that calculates the PKCS#1 and PKCS#7
+ */
+ protected PdfPKCS7 pkcs;
+ /**
+ * The subject name in the signing certificate (the element "CN")
+ */
+ protected String name;
+
+ private byte[] externalDigest;
+ private byte[] externalRSAdata;
+ private String digestEncryptionAlgorithm;
+
+ /**
+ * Creates a generic standard filter.
+ * @param filter the filter name
+ * @param subFilter the sub-filter name
+ */
+ public PdfSigGenericPKCS(PdfName filter, PdfName subFilter) : base(filter, subFilter) {
+ }
+
+ /**
+ * Sets the crypto information to sign.
+ * @param privKey the private key
+ * @param certChain the certificate chain
+ * @param crlList the certificate revocation list. It can be null
+ */
+ public void SetSignInfo(ICipherParameters privKey, X509Certificate[] certChain, object[] crlList) {
+ pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, PdfName.ADBE_PKCS7_SHA1.Equals(Get(PdfName.SUBFILTER)));
+ pkcs.SetExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm);
+ if (PdfName.ADBE_X509_RSA_SHA1.Equals(Get(PdfName.SUBFILTER))) {
+ MemoryStream bout = new MemoryStream();
+ for (int k = 0; k < certChain.Length; ++k) {
+ byte[] tmp = certChain[k].GetEncoded();
+ bout.Write(tmp, 0, tmp.Length);
+ }
+ bout.Close();
+ Cert = bout.ToArray();
+ Contents = pkcs.GetEncodedPKCS1();
+ }
+ else
+ Contents = pkcs.GetEncodedPKCS7();
+ name = PdfPKCS7.GetSubjectFields(pkcs.SigningCertificate).GetField("CN");
+ if (name != null)
+ Put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE));
+ pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, PdfName.ADBE_PKCS7_SHA1.Equals(Get(PdfName.SUBFILTER)));
+ pkcs.SetExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm);
+ }
+
+ /**
+ * Sets the digest/signature to an external calculated value.
+ * @param digest the digest. This is the actual signature
+ * @param RSAdata the extra data that goes into the data tag in PKCS#7
+ * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null
if the digest
+ * is also null
. If the digest
is not null
+ * then it may be "RSA" or "DSA"
+ */
+ public void SetExternalDigest(byte[] digest, byte[] RSAdata, String digestEncryptionAlgorithm) {
+ externalDigest = digest;
+ externalRSAdata = RSAdata;
+ this.digestEncryptionAlgorithm = digestEncryptionAlgorithm;
+ }
+
+ /**
+ * Gets the subject name in the signing certificate (the element "CN")
+ * @return the subject name in the signing certificate (the element "CN")
+ */
+ public new String Name {
+ get {
+ return name;
+ }
+ }
+
+ /**
+ * Gets the class instance that does the actual signing.
+ * @return the class instance that does the actual signing
+ */
+ public PdfPKCS7 Signer {
+ get {
+ return pkcs;
+ }
+ }
+
+ /**
+ * Gets the signature content. This can be a PKCS#1 or a PKCS#7. It corresponds to
+ * the /Contents key.
+ * @return the signature content
+ */
+ public byte[] SignerContents {
+ get {
+ if (PdfName.ADBE_X509_RSA_SHA1.Equals(Get(PdfName.SUBFILTER)))
+ return pkcs.GetEncodedPKCS1();
+ else
+ return pkcs.GetEncodedPKCS7();
+ }
+ }
+
+ /**
+ * Creates a standard filter of the type VeriSign.
+ */
+ public class VeriSign : PdfSigGenericPKCS {
+ /**
+ * The constructor for the default provider.
+ */
+ public VeriSign() : base(PdfName.VERISIGN_PPKVS, PdfName.ADBE_PKCS7_DETACHED) {
+ hashAlgorithm = "MD5";
+ Put(PdfName.R, new PdfNumber(65537));
+ }
+ }
+
+ /**
+ * Creates a standard filter of the type self signed.
+ */
+ public class PPKLite : PdfSigGenericPKCS {
+ /**
+ * The constructor for the default provider.
+ */
+ public PPKLite() : base(PdfName.ADOBE_PPKLITE, PdfName.ADBE_X509_RSA_SHA1) {
+ hashAlgorithm = "SHA1";
+ Put(PdfName.R, new PdfNumber(65541));
+ }
+ }
+
+ /**
+ * Creates a standard filter of the type Windows Certificate.
+ */
+ public class PPKMS : PdfSigGenericPKCS {
+ /**
+ * The constructor for the default provider.
+ */
+ public PPKMS() : base(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1) {
+ hashAlgorithm = "SHA1";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfSignature.cs b/iTechSharp/iTextSharp/text/pdf/PdfSignature.cs
new file mode 100644
index 0000000..570fae7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfSignature.cs
@@ -0,0 +1,115 @@
+using System;
+
+/*
+ * Copyright 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Implements the signature dictionary.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfSignature : PdfDictionary {
+
+ /** Creates new PdfSignature */
+ public PdfSignature(PdfName filter, PdfName subFilter) : base(PdfName.SIG) {
+ Put(PdfName.FILTER, filter);
+ Put(PdfName.SUBFILTER, subFilter);
+ }
+
+ public int[] ByteRange {
+ set {
+ PdfArray array = new PdfArray();
+ for (int k = 0; k < value.Length; ++k)
+ array.Add(new PdfNumber(value[k]));
+ Put(PdfName.BYTERANGE, array);
+ }
+ }
+
+ public byte[] Contents {
+ set {
+ Put(PdfName.CONTENTS, new PdfString(value).SetHexWriting(true));
+ }
+ }
+
+ public byte[] Cert {
+ set {
+ Put(PdfName.CERT, new PdfString(value));
+ }
+ }
+
+ public string Name {
+ set {
+ Put(PdfName.NAME, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public PdfDate Date {
+ set {
+ Put(PdfName.M, value);
+ }
+ }
+
+ public string Location {
+ set {
+ Put(PdfName.LOCATION, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public string Reason {
+ set {
+ Put(PdfName.REASON, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+
+ public string Contact {
+ set {
+ Put(PdfName.CONTACTINFO, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfSignatureAppearance.cs b/iTechSharp/iTextSharp/text/pdf/PdfSignatureAppearance.cs
new file mode 100644
index 0000000..2393763
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfSignatureAppearance.cs
@@ -0,0 +1,1445 @@
+using System;
+using System.Collections;
+using System.Text;
+using System.IO;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.Crypto;
+using iTextSharp.text;
+/*
+ * $Id: PdfSignatureAppearance.cs,v 1.13 2008/04/17 15:32:39 psoares33 Exp $
+ *
+ * Copyright 2004-2006 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /**
+ * This class takes care of the cryptographic options and appearances that form a signature.
+ */
+ public class PdfSignatureAppearance {
+
+ /**
+ * Enumeration representing the different rendering options of a signature
+ */
+ public enum SignatureRender {
+ Description,
+ NameAndDescription,
+ GraphicAndDescription
+ }
+
+ /**
+ * The self signed filter.
+ */
+ public static PdfName SELF_SIGNED = PdfName.ADOBE_PPKLITE;
+ /**
+ * The VeriSign filter.
+ */
+ public static PdfName VERISIGN_SIGNED = PdfName.VERISIGN_PPKVS;
+ /**
+ * The Windows Certificate Security.
+ */
+ public static PdfName WINCER_SIGNED = PdfName.ADOBE_PPKMS;
+
+ public const int NOT_CERTIFIED = 0;
+ public const int CERTIFIED_NO_CHANGES_ALLOWED = 1;
+ public const int CERTIFIED_FORM_FILLING = 2;
+ public const int CERTIFIED_FORM_FILLING_AND_ANNOTATIONS = 3;
+
+ private const float TOP_SECTION = 0.3f;
+ private const float MARGIN = 2;
+ private Rectangle rect;
+ private Rectangle pageRect;
+ private PdfTemplate[] app = new PdfTemplate[5];
+ private PdfTemplate frm;
+ private PdfStamperImp writer;
+ private String layer2Text;
+ private String reason;
+ private String location;
+ private DateTime signDate;
+ private int page = 1;
+ private String fieldName;
+ private ICipherParameters privKey;
+ private X509Certificate[] certChain;
+ private object[] crlList;
+ private PdfName filter;
+ private bool newField;
+ private ByteBuffer sigout;
+ private Stream originalout;
+ private string tempFile;
+ private PdfDictionary cryptoDictionary;
+ private PdfStamper stamper;
+ private bool preClosed = false;
+ private PdfSigGenericPKCS sigStandard;
+ private int[] range;
+ private FileStream raf;
+ private byte[] bout;
+ private int boutLen;
+ private byte[] externalDigest;
+ private byte[] externalRSAdata;
+ private String digestEncryptionAlgorithm;
+ private Hashtable exclusionLocations;
+
+ internal PdfSignatureAppearance(PdfStamperImp writer) {
+ this.writer = writer;
+ signDate = DateTime.Now;
+ fieldName = GetNewSigName();
+ }
+
+ /**
+ * Gets the rendering mode for this signature .
+ * @return the rectangle rendering mode for this signature.
+ */
+ private SignatureRender render = SignatureRender.Description;
+
+ public SignatureRender Render {
+ get {
+ return render;
+ }
+ set {
+ render = value;
+ }
+ }
+
+ /**
+ * Sets the Image object to render when Render is set to SignatureRender.GraphicAndDescription
+ * @param image rendered. If null
the mode is defaulted
+ * to SignatureRender.Description
+ */
+ private Image signatureGraphic = null;
+
+ public Image SignatureGraphic {
+ get {
+ return signatureGraphic;
+ }
+ set {
+ signatureGraphic = value;
+ }
+ }
+
+ /**
+ * Sets the signature text identifying the signer.
+ * @param text the signature text identifying the signer. If null
or not set
+ * a standard description will be used
+ */
+ public string Layer2Text {
+ get {
+ return layer2Text;
+ }
+ set {
+ layer2Text = value;
+ }
+ }
+
+ /**
+ * Sets the text identifying the signature status.
+ * @param text the text identifying the signature status. If null
or not set
+ * the description "Signature Not Verified" will be used
+ */
+ public string Layer4Text {
+ get {
+ return layer4Text;
+ }
+ set {
+ layer4Text = value;
+ }
+ }
+
+ /**
+ * Gets the rectangle representing the signature dimensions.
+ * @return the rectangle representing the signature dimensions. It may be null
+ * or have zero width or height for invisible signatures
+ */
+ public Rectangle Rect {
+ get {
+ return rect;
+ }
+ }
+
+ /**
+ * Gets the visibility status of the signature.
+ * @return the visibility status of the signature
+ */
+ public bool IsInvisible() {
+ return (rect == null || rect.Width == 0 || rect.Height == 0);
+ }
+
+ /**
+ * Sets the cryptographic parameters.
+ * @param privKey the private key
+ * @param certChain the certificate chain
+ * @param crlList the certificate revocation list. It may be null
+ * @param filter the crytographic filter type. It can be SELF_SIGNED, VERISIGN_SIGNED or WINCER_SIGNED
+ */
+ public void SetCrypto(ICipherParameters privKey, X509Certificate[] certChain, object[] crlList, PdfName filter) {
+ this.privKey = privKey;
+ this.certChain = certChain;
+ this.crlList = crlList;
+ this.filter = filter;
+ }
+
+ /**
+ * Sets the signature to be visible. It creates a new visible signature field.
+ * @param pageRect the position and dimension of the field in the page
+ * @param page the page to place the field. The fist page is 1
+ * @param fieldName the field name or null
to generate automatically a new field name
+ */
+ public void SetVisibleSignature(Rectangle pageRect, int page, String fieldName) {
+ if (fieldName != null) {
+ if (fieldName.IndexOf('.') >= 0)
+ throw new ArgumentException("Field names cannot contain a dot.");
+ AcroFields af = writer.AcroFields;
+ AcroFields.Item item = af.GetFieldItem(fieldName);
+ if (item != null)
+ throw new ArgumentException("The field " + fieldName + " already exists.");
+ this.fieldName = fieldName;
+ }
+ if (page < 1 || page > writer.reader.NumberOfPages)
+ throw new ArgumentException("Invalid page number: " + page);
+ this.pageRect = new Rectangle(pageRect);
+ this.pageRect.Normalize();
+ rect = new Rectangle(this.pageRect.Width, this.pageRect.Height);
+ this.page = page;
+ newField = true;
+ }
+
+ /**
+ * Sets the signature to be visible. An empty signature field with the same name must already exist.
+ * @param fieldName the existing empty signature field name
+ */
+ public void SetVisibleSignature(String fieldName) {
+ AcroFields af = writer.AcroFields;
+ AcroFields.Item item = af.GetFieldItem(fieldName);
+ if (item == null)
+ throw new ArgumentException("The field " + fieldName + " does not exist.");
+ PdfDictionary merged = (PdfDictionary)item.merged[0];
+ if (!PdfName.SIG.Equals(PdfReader.GetPdfObject(merged.Get(PdfName.FT))))
+ throw new ArgumentException("The field " + fieldName + " is not a signature field.");
+ this.fieldName = fieldName;
+ PdfArray r = (PdfArray)PdfReader.GetPdfObject(merged.Get(PdfName.RECT));
+ ArrayList ar = r.ArrayList;
+ float llx = ((PdfNumber)PdfReader.GetPdfObject((PdfObject)ar[0])).FloatValue;
+ float lly = ((PdfNumber)PdfReader.GetPdfObject((PdfObject)ar[1])).FloatValue;
+ float urx = ((PdfNumber)PdfReader.GetPdfObject((PdfObject)ar[2])).FloatValue;
+ float ury = ((PdfNumber)PdfReader.GetPdfObject((PdfObject)ar[3])).FloatValue;
+ pageRect = new Rectangle(llx, lly, urx, ury);
+ pageRect.Normalize();
+ page = (int)item.page[0];
+ int rotation = writer.reader.GetPageRotation(page);
+ Rectangle pageSize = writer.reader.GetPageSizeWithRotation(page);
+ switch (rotation) {
+ case 90:
+ pageRect = new Rectangle(
+ pageRect.Bottom,
+ pageSize.Top - pageRect.Left,
+ pageRect.Top,
+ pageSize.Top - pageRect.Right);
+ break;
+ case 180:
+ pageRect = new Rectangle(
+ pageSize.Right - pageRect.Left,
+ pageSize.Top - pageRect.Bottom,
+ pageSize.Right - pageRect.Right,
+ pageSize.Top - pageRect.Top);
+ break;
+ case 270:
+ pageRect = new Rectangle(
+ pageSize.Right - pageRect.Bottom,
+ pageRect.Left,
+ pageSize.Right - pageRect.Top,
+ pageRect.Right);
+ break;
+ }
+ if (rotation != 0)
+ pageRect.Normalize();
+ rect = new Rectangle(this.pageRect.Width, this.pageRect.Height);
+ }
+
+ /**
+ * Gets a template layer to create a signature appearance. The layers can go from 0 to 4.
+ * null
if the digest
+ * is also null
. If the digest
is not null
+ * then it may be "RSA" or "DSA"
+ */
+ public void SetExternalDigest(byte[] digest, byte[] RSAdata, String digestEncryptionAlgorithm) {
+ externalDigest = digest;
+ externalRSAdata = RSAdata;
+ this.digestEncryptionAlgorithm = digestEncryptionAlgorithm;
+ }
+
+ /**
+ * Sets the signing reason.
+ * @param reason the signing reason
+ */
+ public string Reason {
+ get {
+ return reason;
+ }
+ set {
+ reason = value;
+ }
+ }
+
+ /**
+ * Sets the signing location.
+ * @param location the signing location
+ */
+ public string Location {
+ get {
+ return location;
+ }
+ set {
+ location = value;
+ }
+ }
+
+ /**
+ * Gets the private key.
+ * @return the private key
+ */
+ public ICipherParameters PrivKey {
+ get {
+ return privKey;
+ }
+ }
+
+ /**
+ * Gets the certificate chain.
+ * @return the certificate chain
+ */
+ public X509Certificate[] CertChain {
+ get {
+ return this.certChain;
+ }
+ }
+
+ /**
+ * Gets the certificate revocation list.
+ * @return the certificate revocation list
+ */
+ public object[] CrlList {
+ get {
+ return this.crlList;
+ }
+ }
+
+ /**
+ * Gets the filter used to sign the document.
+ * @return the filter used to sign the document
+ */
+ public PdfName Filter {
+ get {
+ return filter;
+ }
+ }
+
+ /**
+ * Checks if a new field was created.
+ * @return true
if a new field was created, false
if signing
+ * an existing field or if the signature is invisible
+ */
+ public bool IsNewField() {
+ return this.newField;
+ }
+
+ /**
+ * Gets the page number of the field.
+ * @return the page number of the field
+ */
+ public int Page {
+ get {
+ return page;
+ }
+ }
+
+ /**
+ * Gets the field name.
+ * @return the field name
+ */
+ public String FieldName {
+ get {
+ return fieldName;
+ }
+ }
+
+ /**
+ * Gets the rectangle that represent the position and dimension of the signature in the page.
+ * @return the rectangle that represent the position and dimension of the signature in the page
+ */
+ public Rectangle PageRect {
+ get {
+ return pageRect;
+ }
+ }
+
+ /**
+ * Gets the signature date.
+ * @return the signature date
+ */
+ public DateTime SignDate {
+ get {
+ return signDate;
+ }
+ set {
+ signDate = value;
+ }
+ }
+
+ internal ByteBuffer Sigout {
+ get {
+ return sigout;
+ }
+ set {
+ sigout = value;
+ }
+ }
+
+ internal Stream Originalout {
+ get {
+ return originalout;
+ }
+ set {
+ originalout = value;
+ }
+ }
+
+ /**
+ * Gets the temporary file.
+ * @return the temporary file or null
is the document is created in memory
+ */
+ public string TempFile {
+ get {
+ return tempFile;
+ }
+ }
+
+ internal void SetTempFile(string tempFile) {
+ this.tempFile = tempFile;
+ }
+
+ /**
+ * Gets a new signature fied name that doesn't clash with any existing name.
+ * @return a new signature fied name
+ */
+ public String GetNewSigName() {
+ AcroFields af = writer.AcroFields;
+ String name = "Signature";
+ int step = 0;
+ bool found = false;
+ while (!found) {
+ ++step;
+ String n1 = name + step;
+ if (af.GetFieldItem(n1) != null)
+ continue;
+ n1 += ".";
+ found = true;
+ foreach (String fn in af.Fields.Keys) {
+ if (fn.StartsWith(n1)) {
+ found = false;
+ break;
+ }
+ }
+ }
+ name += step;
+ return name;
+ }
+
+ /**
+ * This is the first method to be called when using external signatures. The general sequence is:
+ * PreClose(), GetDocumentBytes() and Close().
+ * exclusionSizes
must contain at least
+ * the PdfName.CONTENTS
key with the size that it will take in the
+ * document. Note that due to the hex string coding this size should be
+ * byte_size*2+2.
+ * @param exclusionSizes a Hashtable
with names and sizes to be excluded in the signature
+ * calculation. The key is a PdfName
and the value an
+ * Integer
. At least the PdfName.CONTENTS
must be present
+ * @throws IOException on error
+ * @throws DocumentException on error
+ */
+ public void PreClose(Hashtable exclusionSizes) {
+ if (preClosed)
+ throw new DocumentException("Document already pre closed.");
+ preClosed = true;
+ AcroFields af = writer.AcroFields;
+ String name = FieldName;
+ bool fieldExists = !(IsInvisible() || IsNewField());
+ PdfIndirectReference refSig = writer.PdfIndirectReference;
+ writer.SigFlags = 3;
+ if (fieldExists) {
+ ArrayList widgets = af.GetFieldItem(name).widgets;
+ PdfDictionary widget = (PdfDictionary)widgets[0];
+ writer.MarkUsed(widget);
+ widget.Put(PdfName.P, writer.GetPageReference(Page));
+ widget.Put(PdfName.V, refSig);
+ PdfObject obj = PdfReader.GetPdfObjectRelease(widget.Get(PdfName.F));
+ int flags = 0;
+ if (obj != null && obj.IsNumber())
+ flags = ((PdfNumber)obj).IntValue;
+ flags |= PdfAnnotation.FLAGS_LOCKED;
+ widget.Put(PdfName.F, new PdfNumber(flags));
+ PdfDictionary ap = new PdfDictionary();
+ ap.Put(PdfName.N, GetAppearance().IndirectReference);
+ widget.Put(PdfName.AP, ap);
+ }
+ else {
+ PdfFormField sigField = PdfFormField.CreateSignature(writer);
+ sigField.FieldName = name;
+ sigField.Put(PdfName.V, refSig);
+ sigField.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_LOCKED;
+
+ int pagen = Page;
+ if (!IsInvisible())
+ sigField.SetWidget(PageRect, null);
+ else
+ sigField.SetWidget(new Rectangle(0, 0), null);
+ sigField.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, GetAppearance());
+ sigField.Page = pagen;
+ writer.AddAnnotation(sigField, pagen);
+ }
+
+ exclusionLocations = new Hashtable();
+ if (cryptoDictionary == null) {
+ if (PdfName.ADOBE_PPKLITE.Equals(Filter))
+ sigStandard = new PdfSigGenericPKCS.PPKLite();
+ else if (PdfName.ADOBE_PPKMS.Equals(Filter))
+ sigStandard = new PdfSigGenericPKCS.PPKMS();
+ else if (PdfName.VERISIGN_PPKVS.Equals(Filter))
+ sigStandard = new PdfSigGenericPKCS.VeriSign();
+ else
+ throw new ArgumentException("Unknown filter: " + Filter);
+ sigStandard.SetExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm);
+ if (Reason != null)
+ sigStandard.Reason = Reason;
+ if (Location != null)
+ sigStandard.Location = Location;
+ if (Contact != null)
+ sigStandard.Contact = Contact;
+ sigStandard.Put(PdfName.M, new PdfDate(SignDate));
+ sigStandard.SetSignInfo(PrivKey, CertChain, CrlList);
+ PdfString contents = (PdfString)sigStandard.Get(PdfName.CONTENTS);
+ PdfLiteral lit = new PdfLiteral((contents.ToString().Length + (PdfName.ADOBE_PPKLITE.Equals(Filter)?0:64)) * 2 + 2);
+ exclusionLocations[PdfName.CONTENTS] = lit;
+ sigStandard.Put(PdfName.CONTENTS, lit);
+ lit = new PdfLiteral(80);
+ exclusionLocations[PdfName.BYTERANGE] = lit;
+ sigStandard.Put(PdfName.BYTERANGE, lit);
+ if (certificationLevel > 0)
+ AddDocMDP(sigStandard);
+ if (signatureEvent != null)
+ signatureEvent.GetSignatureDictionary(sigStandard);
+ writer.AddToBody(sigStandard, refSig, false);
+ }
+ else {
+ PdfLiteral lit = new PdfLiteral(80);
+ exclusionLocations[PdfName.BYTERANGE] = lit;
+ cryptoDictionary.Put(PdfName.BYTERANGE, lit);
+ foreach (DictionaryEntry entry in exclusionSizes) {
+ PdfName key = (PdfName)entry.Key;
+ int v = (int)entry.Value;
+ lit = new PdfLiteral(v);
+ exclusionLocations[key] = lit;
+ cryptoDictionary.Put(key, lit);
+ }
+ if (certificationLevel > 0)
+ AddDocMDP(cryptoDictionary);
+ if (signatureEvent != null)
+ signatureEvent.GetSignatureDictionary(cryptoDictionary);
+ writer.AddToBody(cryptoDictionary, refSig, false);
+ }
+ if (certificationLevel > 0) {
+ // add DocMDP entry to root
+ PdfDictionary docmdp = new PdfDictionary();
+ docmdp.Put(new PdfName("DocMDP"), refSig);
+ writer.reader.Catalog.Put(new PdfName("Perms"), docmdp);
+ }
+ writer.Close(stamper.MoreInfo);
+
+ range = new int[exclusionLocations.Count * 2];
+ int byteRangePosition = ((PdfLiteral)exclusionLocations[PdfName.BYTERANGE]).Position;
+ exclusionLocations.Remove(PdfName.BYTERANGE);
+ int idx = 1;
+ foreach (PdfLiteral lit in exclusionLocations.Values) {
+ int n = lit.Position;
+ range[idx++] = n;
+ range[idx++] = lit.PosLength + n;
+ }
+ Array.Sort(range, 1, range.Length - 2);
+ for (int k = 3; k < range.Length - 2; k += 2)
+ range[k] -= range[k - 1];
+
+ if (tempFile == null) {
+ bout = sigout.Buffer;
+ boutLen = sigout.Size;
+ range[range.Length - 1] = boutLen - range[range.Length - 2];
+ ByteBuffer bf = new ByteBuffer();
+ bf.Append('[');
+ for (int k = 0; k < range.Length; ++k)
+ bf.Append(range[k]).Append(' ');
+ bf.Append(']');
+ Array.Copy(bf.Buffer, 0, bout, byteRangePosition, bf.Size);
+ }
+ else {
+ try {
+ raf = new FileStream(tempFile, FileMode.Open, FileAccess.ReadWrite);
+ int boutLen = (int)raf.Length;
+ range[range.Length - 1] = boutLen - range[range.Length - 2];
+ ByteBuffer bf = new ByteBuffer();
+ bf.Append('[');
+ for (int k = 0; k < range.Length; ++k)
+ bf.Append(range[k]).Append(' ');
+ bf.Append(']');
+ raf.Seek(byteRangePosition, SeekOrigin.Begin);
+ raf.Write(bf.Buffer, 0, bf.Size);
+ }
+ catch (IOException e) {
+ try{raf.Close();}catch{}
+ try{File.Delete(tempFile);}catch{}
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * This is the last method to be called when using external signatures. The general sequence is:
+ * PreClose(), GetDocumentBytes() and Close().
+ * update
is a PdfDictionary
that must have exactly the
+ * same keys as the ones provided in {@link #preClose(Hashtable)}.
+ * @param update a PdfDictionary
with the key/value that will fill the holes defined
+ * in {@link #preClose(Hashtable)}
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public void Close(PdfDictionary update) {
+ try {
+ if (!preClosed)
+ throw new DocumentException("preClose() must be called first.");
+ ByteBuffer bf = new ByteBuffer();
+ foreach (PdfName key in update.Keys) {
+ PdfObject obj = update.Get(key);
+ PdfLiteral lit = (PdfLiteral)exclusionLocations[key];
+ if (lit == null)
+ throw new ArgumentException("The key " + key.ToString() + " didn't reserve space in PreClose().");
+ bf.Reset();
+ obj.ToPdf(null, bf);
+ if (bf.Size > lit.PosLength)
+ throw new ArgumentException("The key " + key.ToString() + " is too big. Is " + bf.Size + ", reserved " + lit.PosLength);
+ if (tempFile == null)
+ Array.Copy(bf.Buffer, 0, bout, lit.Position, bf.Size);
+ else {
+ raf.Seek(lit.Position, SeekOrigin.Begin);
+ raf.Write(bf.Buffer, 0, bf.Size);
+ }
+ }
+ if (update.Size != exclusionLocations.Count)
+ throw new ArgumentException("The update dictionary has less keys than required.");
+ if (tempFile == null) {
+ originalout.Write(bout, 0, boutLen);
+ }
+ else {
+ if (originalout != null) {
+ raf.Seek(0, SeekOrigin.Begin);
+ int length = (int)raf.Length;
+ byte[] buf = new byte[8192];
+ while (length > 0) {
+ int r = raf.Read(buf, 0, Math.Min(buf.Length, length));
+ if (r < 0)
+ throw new EndOfStreamException("Unexpected EOF");
+ originalout.Write(buf, 0, r);
+ length -= r;
+ }
+ }
+ }
+ }
+ finally {
+ if (tempFile != null) {
+ try{raf.Close();}catch{}
+ if (originalout != null)
+ try{File.Delete(tempFile);}catch{}
+ }
+ if (originalout != null)
+ try{originalout.Close();}catch{}
+ }
+ }
+
+ private void AddDocMDP(PdfDictionary crypto) {
+ PdfDictionary reference = new PdfDictionary();
+ PdfDictionary transformParams = new PdfDictionary();
+ transformParams.Put(PdfName.P, new PdfNumber(certificationLevel));
+ transformParams.Put(PdfName.V, new PdfName("1.2"));
+ transformParams.Put(PdfName.TYPE, PdfName.TRANSFORMPARAMS);
+ reference.Put(PdfName.TRANSFORMMETHOD, PdfName.DOCMDP);
+ reference.Put(PdfName.TYPE, PdfName.SIGREF);
+ reference.Put(PdfName.TRANSFORMPARAMS, transformParams);
+ reference.Put(new PdfName("DigestValue"), new PdfString("aa"));
+ PdfArray loc = new PdfArray();
+ loc.Add(new PdfNumber(0));
+ loc.Add(new PdfNumber(0));
+ reference.Put(new PdfName("DigestLocation"), loc);
+ reference.Put(new PdfName("DigestMethod"), new PdfName("MD5"));
+ reference.Put(PdfName.DATA, writer.reader.Trailer.Get(PdfName.ROOT));
+ PdfArray types = new PdfArray();
+ types.Add(reference);
+ crypto.Put(PdfName.REFERENCE, types);
+ }
+
+ /**
+ * Gets the document bytes that are hashable when using external signatures. The general sequence is:
+ * PreClose(), GetRangeStream() and Close().
+ * PdfStamper
associated with this instance.
+ * @return the PdfStamper
associated with this instance
+ */
+ public PdfStamper Stamper {
+ get {
+ return stamper;
+ }
+ }
+
+ internal void SetStamper(PdfStamper stamper) {
+ this.stamper = stamper;
+ }
+
+ /**
+ * Checks if the document is in the process of closing.
+ * @return true
if the document is in the process of closing,
+ * false
otherwise
+ */
+ public bool IsPreClosed() {
+ return preClosed;
+ }
+
+ /**
+ * Gets the instance of the standard signature dictionary. This instance
+ * is only available after pre close.
+ * true
only the layers n2 and n4 will be present
+ */
+ public bool Acro6Layers {
+ get {
+ return acro6Layers;
+ }
+ set {
+ acro6Layers = value;
+ }
+ }
+
+ /** Sets the run direction in the n2 and n4 layer.
+ * @param runDirection the run direction
+ */
+ public int RunDirection {
+ set {
+ if (value < PdfWriter.RUN_DIRECTION_DEFAULT || value > PdfWriter.RUN_DIRECTION_RTL)
+ throw new ArgumentException("Invalid run direction: " + runDirection);
+ this.runDirection = value;
+ }
+ get {
+ return runDirection;
+ }
+ }
+
+ /**
+ * Sets the signature event to allow modification of the signature dictionary.
+ * @param signatureEvent the signature event
+ */
+ public ISignatureEvent SignatureEvent {
+ get {
+ return signatureEvent;
+ }
+ set {
+ signatureEvent = value;
+ }
+ }
+ /**
+ * Gets the background image for the layer 2.
+ * @return the background image for the layer 2
+ */
+ public Image GetImage() {
+ return this.image;
+ }
+
+ /**
+ * Sets the background image for the layer 2.
+ * @param image the background image for the layer 2
+ */
+ public Image Image {
+ get {
+ return image;
+ }
+ set {
+ image = value;
+ }
+ }
+
+ /**
+ * Sets the scaling to be applied to the background image. If it's zero the image
+ * will fully fill the rectangle. If it's less than zero the image will fill the rectangle but
+ * will keep the proportions. If it's greater than zero that scaling will be applied.
+ * In any of the cases the image will always be centered. It's zero by default.
+ * @param imageScale the scaling to be applied to the background image
+ */
+ public float ImageScale {
+ get {
+ return imageScale;
+ }
+ set {
+ imageScale = value;
+ }
+ }
+
+ /**
+ * Commands to draw a yellow question mark in a stream content
+ */
+ public const String questionMark =
+ "% DSUnknown\n" +
+ "q\n" +
+ "1 G\n" +
+ "1 g\n" +
+ "0.1 0 0 0.1 9 0 cm\n" +
+ "0 J 0 j 4 M []0 d\n" +
+ "1 i \n" +
+ "0 g\n" +
+ "313 292 m\n" +
+ "313 404 325 453 432 529 c\n" +
+ "478 561 504 597 504 645 c\n" +
+ "504 736 440 760 391 760 c\n" +
+ "286 760 271 681 265 626 c\n" +
+ "265 625 l\n" +
+ "100 625 l\n" +
+ "100 828 253 898 381 898 c\n" +
+ "451 898 679 878 679 650 c\n" +
+ "679 555 628 499 538 435 c\n" +
+ "488 399 467 376 467 292 c\n" +
+ "313 292 l\n" +
+ "h\n" +
+ "308 214 170 -164 re\n" +
+ "f\n" +
+ "0.44 G\n" +
+ "1.2 w\n" +
+ "1 1 0.4 rg\n" +
+ "287 318 m\n" +
+ "287 430 299 479 406 555 c\n" +
+ "451 587 478 623 478 671 c\n" +
+ "478 762 414 786 365 786 c\n" +
+ "260 786 245 707 239 652 c\n" +
+ "239 651 l\n" +
+ "74 651 l\n" +
+ "74 854 227 924 355 924 c\n" +
+ "425 924 653 904 653 676 c\n" +
+ "653 581 602 525 512 461 c\n" +
+ "462 425 441 402 441 318 c\n" +
+ "287 318 l\n" +
+ "h\n" +
+ "282 240 170 -164 re\n" +
+ "B\n" +
+ "Q\n";
+
+ /**
+ * Holds value of property contact.
+ */
+ private String contact;
+
+ /**
+ * Holds value of property layer2Font.
+ */
+ private Font layer2Font;
+
+ /**
+ * Holds value of property layer4Text.
+ */
+ private String layer4Text;
+
+ /**
+ * Holds value of property acro6Layers.
+ */
+ private bool acro6Layers;
+
+ /**
+ * Holds value of property runDirection.
+ */
+ private int runDirection = PdfWriter.RUN_DIRECTION_NO_BIDI;
+
+ /**
+ * Holds value of property signatureEvent.
+ */
+ private ISignatureEvent signatureEvent;
+
+ /**
+ * Holds value of property image.
+ */
+ private Image image;
+
+ /**
+ * Holds value of property imageScale.
+ */
+ private float imageScale;
+
+ /**
+ *
+ */
+ public class FRangeStream : Stream {
+ private byte[] b = new byte[1];
+ private FileStream raf;
+ private byte[] bout;
+ private int[] range;
+ private int rangePosition = 0;
+
+ internal FRangeStream(FileStream raf, byte[] bout, int[] range) {
+ this.raf = raf;
+ this.bout = bout;
+ this.range = range;
+ }
+
+ /**
+ * @see java.io.Stream#read()
+ */
+ public override int ReadByte() {
+ int n = Read(b, 0, 1);
+ if (n != 1)
+ return -1;
+ return b[0] & 0xff;
+ }
+
+ /**
+ * @see java.io.Stream#read(byte[], int, int)
+ */
+ public override int Read(byte[] b, int off, int len) {
+ if (b == null) {
+ throw new ArgumentNullException();
+ } else if ((off < 0) || (off > b.Length) || (len < 0) ||
+ ((off + len) > b.Length) || ((off + len) < 0)) {
+ throw new ArgumentOutOfRangeException();
+ } else if (len == 0) {
+ return 0;
+ }
+ if (rangePosition >= range[range.Length - 2] + range[range.Length - 1]) {
+ return -1;
+ }
+ for (int k = 0; k < range.Length; k += 2) {
+ int start = range[k];
+ int end = start + range[k + 1];
+ if (rangePosition < start)
+ rangePosition = start;
+ if (rangePosition >= start && rangePosition < end) {
+ int lenf = Math.Min(len, end - rangePosition);
+ if (raf == null)
+ Array.Copy(bout, rangePosition, b, off, lenf);
+ else {
+ raf.Seek(rangePosition, SeekOrigin.Begin);
+ ReadFully(b, off, lenf);
+ }
+ rangePosition += lenf;
+ return lenf;
+ }
+ }
+ return -1;
+ }
+
+ private void ReadFully(byte[] b, int offset, int count) {
+ while (count > 0) {
+ int n = raf.Read(b, offset, count);
+ if (n <= 0)
+ throw new IOException("Insufficient data.");
+ count -= n;
+ offset += n;
+ }
+ }
+
+ public override bool CanRead {
+ get {
+ return true;
+ }
+ }
+
+ public override bool CanSeek {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanWrite {
+ get {
+ return false;
+ }
+ }
+
+ public override long Length {
+ get {
+ return 0;
+ }
+ }
+
+ public override long Position {
+ get {
+ return 0;
+ }
+ set {
+ }
+ }
+
+ public override void Flush() {
+ }
+
+ public override long Seek(long offset, SeekOrigin origin) {
+ return 0;
+ }
+
+ public override void SetLength(long value) {
+ }
+
+ public override void Write(byte[] buffer, int offset, int count) {
+ }
+
+ public override void WriteByte(byte value) {
+ }
+ }
+
+ /**
+ * An interface to retrieve the signature dictionary for modification.
+ */
+ public interface ISignatureEvent {
+ /**
+ * Allows modification of the signature dictionary.
+ * @param sig the signature dictionary
+ */
+ void GetSignatureDictionary(PdfDictionary sig);
+ }
+
+ private int certificationLevel = NOT_CERTIFIED;
+
+ /**
+ * Sets the document type to certified instead of simply signed.
+ * @param certificationLevel the values can be: NOT_CERTIFIED
, CERTIFIED_NO_CHANGES_ALLOWED
,
+ * CERTIFIED_FORM_FILLING
and CERTIFIED_FORM_FILLING_AND_ANNOTATIONS
+ */
+ public int CertificationLevel {
+ get {
+ return certificationLevel;
+ }
+ set {
+ certificationLevel = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfSmartCopy.cs b/iTechSharp/iTextSharp/text/pdf/PdfSmartCopy.cs
new file mode 100644
index 0000000..1311cfa
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfSmartCopy.cs
@@ -0,0 +1,228 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Security.Cryptography;
+using iTextSharp.text;
+/*
+ * $Id: PdfSmartCopy.cs,v 1.7 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 Michael Neuweiler and Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * This class was written by Michael Neuweiler based on hints given by Bruno Lowagie
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfSmartCopy has the same functionality as PdfCopy,
+ * but when resources (such as fonts, images,...) are
+ * encountered, a reference to these resources is saved
+ * in a cache, so that they can be reused.
+ * This requires more memory, but reduces the file size
+ * of the resulting PDF document.
+ */
+
+ public class PdfSmartCopy : PdfCopy {
+
+ /** the cache with the streams and references. */
+ private Hashtable streamMap = null;
+
+ /** Creates a PdfSmartCopy instance. */
+ public PdfSmartCopy(Document document, Stream os) : base(document, os) {
+ this.streamMap = new Hashtable();
+ }
+ /**
+ * Translate a PRIndirectReference to a PdfIndirectReference
+ * In addition, translates the object numbers, and copies the
+ * referenced object to the output file if it wasn't available
+ * in the cache yet. If it's in the cache, the reference to
+ * the already used stream is returned.
+ *
+ * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what
+ * file they came from, because each file has its own namespace. The translation
+ * we do from their namespace to ours is *at best* heuristic, and guaranteed to
+ * fail under some circumstances.
+ */
+ protected override PdfIndirectReference CopyIndirect(PRIndirectReference inp) {
+ PdfObject srcObj = PdfReader.GetPdfObjectRelease(inp);
+ ByteStore streamKey = null;
+ bool validStream = false;
+ if (srcObj.IsStream()) {
+ streamKey = new ByteStore((PRStream)srcObj);
+ validStream = true;
+ PdfIndirectReference streamRef = (PdfIndirectReference) streamMap[streamKey];
+ if (streamRef != null) {
+ return streamRef;
+ }
+ }
+
+ PdfIndirectReference theRef;
+ RefKey key = new RefKey(inp);
+ IndirectReferences iRef = (IndirectReferences) indirects[key];
+ if (iRef != null) {
+ theRef = iRef.Ref;
+ if (iRef.Copied) {
+ return theRef;
+ }
+ } else {
+ theRef = body.PdfIndirectReference;
+ iRef = new IndirectReferences(theRef);
+ indirects[key] = iRef;
+ }
+ if (srcObj != null && srcObj.IsDictionary()) {
+ PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE));
+ if (type != null && PdfName.PAGE.Equals(type)) {
+ return theRef;
+ }
+ }
+ iRef.SetCopied();
+
+ if (validStream) {
+ streamMap[streamKey] = theRef;
+ }
+
+ PdfObject obj = CopyObject(srcObj);
+ AddToBody(obj, theRef);
+ return theRef;
+ }
+
+ internal class ByteStore {
+ private byte[] b;
+ private int hash;
+ private MD5 md5;
+
+ private void SerObject(PdfObject obj, int level, ByteBuffer bb) {
+ if (level <= 0)
+ return;
+ if (obj == null) {
+ bb.Append("$Lnull");
+ return;
+ }
+ obj = PdfReader.GetPdfObject(obj);
+ if (obj.IsStream()) {
+ bb.Append("$B");
+ SerDic((PdfDictionary)obj, level - 1, bb);
+ if (level > 0) {
+ md5.Initialize();
+ bb.Append(md5.ComputeHash(PdfReader.GetStreamBytesRaw((PRStream)obj)));
+ }
+ }
+ else if (obj.IsDictionary()) {
+ SerDic((PdfDictionary)obj, level - 1, bb);
+ }
+ else if (obj.IsArray()) {
+ SerArray((PdfArray)obj, level - 1, bb);
+ }
+ else if (obj.IsString()) {
+ bb.Append("$S").Append(obj.ToString());
+ }
+ else if (obj.IsName()) {
+ bb.Append("$N").Append(obj.ToString());
+ }
+ else
+ bb.Append("$L").Append(obj.ToString());
+ }
+
+ private void SerDic(PdfDictionary dic, int level, ByteBuffer bb) {
+ bb.Append("$D");
+ if (level <= 0)
+ return;
+ Object[] keys = new Object[dic.Size];
+ dic.Keys.CopyTo(keys, 0);
+ Array.Sort(keys);
+ for (int k = 0; k < keys.Length; ++k) {
+ SerObject((PdfObject)keys[k], level, bb);
+ SerObject(dic.Get((PdfName)keys[k]), level, bb);
+ }
+ }
+
+ private void SerArray(PdfArray array, int level, ByteBuffer bb) {
+ bb.Append("$A");
+ if (level <= 0)
+ return;
+ ArrayList ar = array.ArrayList;
+ for (int k = 0; k < ar.Count; ++k) {
+ SerObject((PdfObject)ar[k], level, bb);
+ }
+ }
+
+ internal ByteStore(PRStream str) {
+ md5 = new MD5CryptoServiceProvider();
+ ByteBuffer bb = new ByteBuffer();
+ int level = 10;
+ SerObject(str, level, bb);
+ this.b = bb.ToByteArray();
+ md5 = null;
+ }
+
+ public override bool Equals(Object obj) {
+ if (obj == null || !(obj is ByteStore))
+ return false;
+ if (GetHashCode() != obj.GetHashCode())
+ return false;
+ byte[] b2 = ((ByteStore)obj).b;
+ if (b2.Length != b.Length)
+ return false;
+ int len = b.Length;
+ for (int k = 0; k < len; ++k) {
+ if (b[k] != b2[k])
+ return false;
+ }
+ return true;
+ }
+
+ public override int GetHashCode() {
+ if (hash == 0) {
+ int len = b.Length;
+ for (int k = 0; k < len; ++k) {
+ hash = hash * 31 + b[k];
+ }
+ }
+ return hash;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfSpotColor.cs b/iTechSharp/iTextSharp/text/pdf/PdfSpotColor.cs
new file mode 100644
index 0000000..0cfe5de
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfSpotColor.cs
@@ -0,0 +1,126 @@
+using System;
+
+/*
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfSpotColor
defines a ColorSpace
+ *
+ * @see PdfDictionary
+ */
+
+ public class PdfSpotColor{
+
+ /* The tint value */
+ protected float tint;
+
+ /* The color name */
+ public PdfName name;
+
+ /* The alternative color space */
+ public Color altcs;
+ // constructors
+
+ /**
+ * Constructs a new PdfSpotColor
.
+ *
+ * @param name a string value
+ * @param tint a tint value between 0 and 1
+ * @param altcs a altnative colorspace value
+ */
+
+ public PdfSpotColor(string name, float tint, Color altcs) {
+ this.name = new PdfName(name);
+ this.tint = tint;
+ this.altcs = altcs;
+ }
+
+ public float Tint {
+ get {
+ return tint;
+ }
+ }
+
+ public Color AlternativeCS {
+ get {
+ return altcs;
+ }
+ }
+
+ protected internal PdfObject GetSpotObject(PdfWriter writer) {
+ PdfArray array = new PdfArray(PdfName.SEPARATION);
+ array.Add(name);
+ PdfFunction func = null;
+ if (altcs is ExtendedColor) {
+ int type = ((ExtendedColor)altcs).Type;
+ switch (type) {
+ case ExtendedColor.TYPE_GRAY:
+ array.Add(PdfName.DEVICEGRAY);
+ func = PdfFunction.Type2(writer, new float[]{0, 1}, null, new float[]{0}, new float[]{((GrayColor)altcs).Gray}, 1);
+ break;
+ case ExtendedColor.TYPE_CMYK:
+ array.Add(PdfName.DEVICECMYK);
+ CMYKColor cmyk = (CMYKColor)altcs;
+ func = PdfFunction.Type2(writer, new float[]{0, 1}, null, new float[]{0, 0, 0, 0},
+ new float[]{cmyk.Cyan, cmyk.Magenta, cmyk.Yellow, cmyk.Black}, 1);
+ break;
+ default:
+ throw new Exception("Only RGB, Gray and CMYK are supported as alternative color spaces.");
+ }
+ }
+ else {
+ array.Add(PdfName.DEVICERGB);
+ func = PdfFunction.Type2(writer, new float[]{0, 1}, null, new float[]{1, 1, 1},
+ new float[]{(float)altcs.R / 255, (float)altcs.G / 255, (float)altcs.B / 255}, 1);
+ }
+ array.Add(func.Reference);
+ return array;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfStamper.cs b/iTechSharp/iTextSharp/text/pdf/PdfStamper.cs
new file mode 100644
index 0000000..4ec5833
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfStamper.cs
@@ -0,0 +1,742 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text.pdf.interfaces;
+using iTextSharp.text.pdf.collection;
+using Org.BouncyCastle.X509;
+/*
+ * Copyright 2003, 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** Applies extra content to the pages of a PDF document.
+ * This extra content can be all the objects allowed in PdfContentByte
+ * including pages from other Pdfs. The original PDF will keep
+ * all the interactive elements including bookmarks, links and form fields.
+ * true
appends the document changes as a new revision. This is
+ * only useful for multiple signatures as nothing is gained in speed or memory
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public PdfStamper(PdfReader reader, Stream os, char pdfVersion, bool append) {
+ stamper = new PdfStamperImp(reader, os, pdfVersion, append);
+ }
+
+ /** Gets the optional String
map to add or change values in
+ * the info dictionary.
+ * @return the map or null
+ *
+ */
+ /** An optional String
map to add or change values in
+ * the info dictionary. Entries with null
+ * values delete the key in the original info dictionary
+ * @param moreInfo additional entries to the info dictionary
+ *
+ */
+ public Hashtable MoreInfo {
+ set {
+ moreInfo = value;
+ }
+ get {
+ return moreInfo;
+ }
+ }
+
+ /**
+ * Replaces a page from this document with a page from other document. Only the content
+ * is replaced not the fields and annotations. This method must be called before
+ * getOverContent() or getUndercontent() are called for the same page.
+ * @param r the PdfReader
from where the new page will be imported
+ * @param pageImported the page number of the imported page
+ * @param pageReplaced the page to replace in this document
+ */
+ public void ReplacePage(PdfReader r, int pageImported, int pageReplaced) {
+ stamper.ReplacePage(r, pageImported, pageReplaced);
+ }
+
+ /**
+ * Inserts a blank page. All the pages above and including pageNumber
will
+ * be shifted up. If pageNumber
is bigger than the total number of pages
+ * the new page will be the last one.
+ * @param pageNumber the page number position where the new page will be inserted
+ * @param mediabox the size of the new page
+ */
+ public void InsertPage(int pageNumber, Rectangle mediabox) {
+ stamper.InsertPage(pageNumber, mediabox);
+ }
+
+ /**
+ * Gets the signing instance. The appearances and other parameters can the be set.
+ * @return the signing instance
+ */
+ public PdfSignatureAppearance SignatureAppearance {
+ get {
+ return sigApp;
+ }
+ }
+
+ /**
+ * Closes the document. No more content can be written after the
+ * document is closed.
+ * PdfSignatureAppearance
instance.
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public void Close() {
+ if (!hasSignature) {
+ stamper.Close(moreInfo);
+ return;
+ }
+ sigApp.PreClose();
+ PdfSigGenericPKCS sig = sigApp.SigStandard;
+ PdfLiteral lit = (PdfLiteral)sig.Get(PdfName.CONTENTS);
+ int totalBuf = (lit.PosLength - 2) / 2;
+ byte[] buf = new byte[8192];
+ int n;
+ Stream inp = sigApp.RangeStream;
+ while ((n = inp.Read(buf, 0, buf.Length)) > 0) {
+ sig.Signer.Update(buf, 0, n);
+ }
+ buf = new byte[totalBuf];
+ byte[] bsig = sig.SignerContents;
+ Array.Copy(bsig, 0, buf, 0, bsig.Length);
+ PdfString str = new PdfString(buf);
+ str.SetHexWriting(true);
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.CONTENTS, str);
+ sigApp.Close(dic);
+ stamper.reader.Close();
+ }
+
+ /** Gets a PdfContentByte
to write under the page of
+ * the original document.
+ * @param pageNum the page number where the extra content is written
+ * @return a PdfContentByte
to write under the page of
+ * the original document
+ */
+ public PdfContentByte GetUnderContent(int pageNum) {
+ return stamper.GetUnderContent(pageNum);
+ }
+
+ /** Gets a PdfContentByte
to write over the page of
+ * the original document.
+ * @param pageNum the page number where the extra content is written
+ * @return a PdfContentByte
to write over the page of
+ * the original document
+ */
+ public PdfContentByte GetOverContent(int pageNum) {
+ return stamper.GetOverContent(pageNum);
+ }
+
+ /** Checks if the content is automatically adjusted to compensate
+ * the original page rotation.
+ * @return the auto-rotation status
+ */
+ /** Flags the content to be automatically adjusted to compensate
+ * the original page rotation. The default is true
.
+ * @param rotateContents true
to set auto-rotation, false
+ * otherwise
+ */
+ public bool RotateContents {
+ set {
+ stamper.RotateContents = value;
+ }
+ get {
+ return stamper.RotateContents;
+ }
+ }
+
+ /** Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param strength128Bits true
for 128 bit key length, false
for 40 bit key length
+ * @throws DocumentException if anything was already written to the output
+ */
+ public void SetEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, bool strength128Bits) {
+ if (stamper.append)
+ throw new DocumentException("Append mode does not support changing the encryption status.");
+ if (stamper.ContentWritten)
+ throw new DocumentException("Content was already written to the output.");
+ stamper.SetEncryption(userPassword, ownerPassword, permissions, strength128Bits ? PdfWriter.STANDARD_ENCRYPTION_128 : PdfWriter.STANDARD_ENCRYPTION_40);
+ }
+
+ /** Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType) {
+ if (stamper.IsAppend())
+ throw new DocumentException("Append mode does not support changing the encryption status.");
+ if (stamper.ContentWritten)
+ throw new DocumentException("Content was already written to the output.");
+ stamper.SetEncryption(userPassword, ownerPassword, permissions, encryptionType);
+ }
+
+ /**
+ * Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param strength true
for 128 bit key length, false
for 40 bit key length
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @throws DocumentException if anything was already written to the output
+ */
+ public void SetEncryption(bool strength, String userPassword, String ownerPassword, int permissions) {
+ SetEncryption(DocWriter.GetISOBytes(userPassword), DocWriter.GetISOBytes(ownerPassword), permissions, strength);
+ }
+
+ /**
+ * Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(int encryptionType, String userPassword, String ownerPassword, int permissions) {
+ SetEncryption(DocWriter.GetISOBytes(userPassword), DocWriter.GetISOBytes(ownerPassword), permissions, encryptionType);
+ }
+
+ /**
+ * Sets the certificate encryption options for this document. An array of one or more public certificates
+ * must be provided together with an array of the same size for the permissions for each certificate.
+ * The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @param certs the public certificates to be used for the encryption
+ * @param permissions the user permissions for each of the certicates
+ * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * @throws DocumentException if the encryption was set too late
+ */
+ public void SetEncryption(X509Certificate[] certs, int[] permissions, int encryptionType) {
+ if (stamper.IsAppend())
+ throw new DocumentException("Append mode does not support changing the encryption status.");
+ if (stamper.ContentWritten)
+ throw new DocumentException("Content was already written to the output.");
+ stamper.SetEncryption(certs, permissions, encryptionType);
+ }
+
+ /** Gets a page from other PDF document. Note that calling this method more than
+ * once with the same parameters will retrieve the same object.
+ * @param reader the PDF document where the page is
+ * @param pageNumber the page number. The first page is 1
+ * @return the template representing the imported page
+ */
+ public PdfImportedPage GetImportedPage(PdfReader reader, int pageNumber) {
+ return stamper.GetImportedPage(reader, pageNumber);
+ }
+
+ /** Gets the underlying PdfWriter.
+ * @return the underlying PdfWriter
+ */
+ public PdfWriter Writer {
+ get {
+ return stamper;
+ }
+ }
+
+ /** Gets the underlying PdfReader.
+ * @return the underlying PdfReader
+ */
+ public PdfReader Reader {
+ get {
+ return stamper.reader;
+ }
+ }
+
+ /** Gets the AcroFields
object that allows to get and set field values
+ * and to merge FDF forms.
+ * @return the AcroFields
object
+ */
+ public AcroFields AcroFields {
+ get {
+ return stamper.AcroFields;
+ }
+ }
+
+ /** Determines if the fields are flattened on close. The fields added with
+ * {@link #addAnnotation(PdfAnnotation,int)} will never be flattened.
+ * @param flat true
to flatten the fields, false
+ * to keep the fields
+ */
+ public bool FormFlattening {
+ set {
+ stamper.FormFlattening = value;
+ }
+ }
+
+ /** Determines if the FreeText annotations are flattened on close.
+ * @param flat true
to flatten the FreeText annotations, false
+ * (the default) to keep the FreeText annotations as active content.
+ */
+ public bool FreeTextFlattening {
+ set {
+ stamper.FreeTextFlattening = value;
+ }
+ }
+ /**
+ * Adds an annotation of form field in a specific page. This page number
+ * can be overridden with {@link PdfAnnotation#setPlaceInPage(int)}.
+ * @param annot the annotation
+ * @param page the page
+ */
+ public void AddAnnotation(PdfAnnotation annot, int page) {
+ stamper.AddAnnotation(annot, page);
+ }
+
+ /**
+ * Adds the comments present in an FDF file.
+ * @param fdf the FDF file
+ * @throws IOException on error
+ */
+ public void AddComments(FdfReader fdf) {
+ stamper.AddComments(fdf);
+ }
+
+ /**
+ * Sets the bookmarks. The list structure is defined in
+ * {@link SimpleBookmark}.
+ * @param outlines the bookmarks or null
to remove any
+ */
+ public ArrayList Outlines {
+ set {
+ stamper.Outlines = value;
+ }
+ }
+
+ /**
+ * Sets the thumbnail image for a page.
+ * @param image the image
+ * @param page the page
+ * @throws PdfException on error
+ * @throws DocumentException on error
+ */
+ public void SetThumbnail(Image image, int page) {
+ stamper.SetThumbnail(image, page);
+ }
+
+ /**
+ * Adds name
to the list of fields that will be flattened on close,
+ * all the other fields will remain. If this method is never called or is called
+ * with invalid field names, all the fields will be flattened.
+ * setFormFlattening(true)
is needed to have any kind of
+ * flattening.
+ * @param name the field name
+ * @return true
if the field exists, false
otherwise
+ */
+ public bool PartialFormFlattening(String name) {
+ return stamper.PartialFormFlattening(name);
+ }
+
+ /** Adds a JavaScript action at the document level. When the document
+ * opens all this JavaScript runs. The existing JavaScript will be replaced.
+ * @param js the JavaScript code
+ */
+ public string JavaScript {
+ set {
+ stamper.AddJavaScript(value, !PdfEncodings.IsPdfDocEncoding(value));
+ }
+ }
+
+ /** Adds a file attachment at the document level. Existing attachments will be kept.
+ * @param description the file description
+ * @param fileStore an array with the file. If it's null
+ * the file will be read from the disk
+ * @param file the path to the file. It will only be used if
+ * fileStore
is not null
+ * @param fileDisplay the actual file name stored in the pdf
+ * @throws IOException on error
+ */
+ public void AddFileAttachment(String description, byte[] fileStore, String file, String fileDisplay) {
+ AddFileAttachment(description, PdfFileSpecification.FileEmbedded(stamper, file, fileDisplay, fileStore));
+ }
+
+ /** Adds a file attachment at the document level. Existing attachments will be kept.
+ * @param description the file description
+ * @param fs the file specification
+ */
+ public void AddFileAttachment(String description, PdfFileSpecification fs) {
+ stamper.AddFileAttachment(description, fs);
+ }
+
+ /**
+ * This is the most simple way to change a PDF into a
+ * portable collection. Choose one of the following names:
+ *
+ *
+ * Pass this name as a parameter and your PDF will be
+ * a portable collection with all the embedded and
+ * attached files as entries.
+ * @param initialView can be PdfName.D, PdfName.T or PdfName.H
+ */
+ public void MakePackage( PdfName initialView ) {
+ PdfCollection collection = new PdfCollection(0);
+ collection.Put(PdfName.VIEW, initialView);
+ stamper.MakePackage( collection );
+ }
+
+ /**
+ * Adds or replaces the Collection Dictionary in the Catalog.
+ * @param collection the new collection dictionary.
+ */
+ public void MakePackage(PdfCollection collection) {
+ stamper.MakePackage(collection);
+ }
+
+ /**
+ * Sets the viewer preferences.
+ * @param preferences the viewer preferences
+ * @see PdfViewerPreferences#setViewerPreferences(int)
+ */
+ public virtual int ViewerPreferences {
+ set {
+ stamper.ViewerPreferences = value;
+ }
+ }
+
+ /** Adds a viewer preference
+ * @param preferences the viewer preferences
+ * @see PdfViewerPreferences#addViewerPreference
+ */
+
+ public virtual void AddViewerPreference(PdfName key, PdfObject value) {
+ stamper.AddViewerPreference(key, value);
+ }
+
+ /**
+ * Sets the XMP metadata.
+ * @param xmp
+ * @see PdfWriter#setXmpMetadata(byte[])
+ */
+ public byte[] XmpMetadata {
+ set {
+ stamper.XmpMetadata = value;
+ }
+ }
+
+ /**
+ * Gets the 1.5 compression status.
+ * @return true
if the 1.5 compression is on
+ */
+ public bool FullCompression {
+ get {
+ return stamper.FullCompression;
+ }
+ }
+
+ /**
+ * Sets the document's compression to the new 1.5 mode with object streams and xref
+ * streams. It can be set at any time but once set it can't be unset.
+ */
+ public void SetFullCompression() {
+ if (stamper.append)
+ return;
+ stamper.SetFullCompression();
+ }
+
+ /**
+ * Sets the open and close page additional action.
+ * @param actionType the action type. It can be PdfWriter.PAGE_OPEN
+ * or PdfWriter.PAGE_CLOSE
+ * @param action the action to perform
+ * @param page the page where the action will be applied. The first page is 1
+ * @throws PdfException if the action type is invalid
+ */
+ public void SetPageAction(PdfName actionType, PdfAction action, int page) {
+ stamper.SetPageAction(actionType, action, page);
+ }
+
+ /**
+ * Sets the display duration for the page (for presentations)
+ * @param seconds the number of seconds to display the page. A negative value removes the entry
+ * @param page the page where the duration will be applied. The first page is 1
+ */
+ public void SetDuration(int seconds, int page) {
+ stamper.SetDuration(seconds, page);
+ }
+
+ /**
+ * Sets the transition for the page
+ * @param transition the transition object. A null
removes the transition
+ * @param page the page where the transition will be applied. The first page is 1
+ */
+ public void SetTransition(PdfTransition transition, int page) {
+ stamper.SetTransition(transition, page);
+ }
+
+ /**
+ * Applies a digital signature to a document, possibly as a new revision, making
+ * possible multiple signatures. The returned PdfStamper
+ * can be used normally as the signature is only applied when closing.
+ *
+ * KeyStore ks = KeyStore.getInstance("pkcs12");
+ * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
+ * String alias = (String)ks.aliases().nextElement();
+ * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
+ * Certificate[] chain = ks.getCertificateChain(alias);
+ * PdfReader reader = new PdfReader("original.pdf");
+ * FileOutputStream fout = new FileOutputStream("signed.pdf");
+ * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', new
+ * File("/temp"), true);
+ * PdfSignatureAppearance sap = stp.getSignatureAppearance();
+ * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
+ * sap.setReason("I'm the author");
+ * sap.setLocation("Lisbon");
+ * // comment next line to have an invisible signature
+ * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
+ * stp.close();
+ *
+ * @param reader the original document
+ * @param os the output stream or null
to keep the document in the temporary file
+ * @param pdfVersion the new pdf version or '\0' to keep the same version as the original
+ * document
+ * @param tempFile location of the temporary file. If it's a directory a temporary file will be created there.
+ * If it's a file it will be used directly. The file will be deleted on exit unless os
is null.
+ * In that case the document can be retrieved directly from the temporary file. If it's null
+ * no temporary file will be created and memory will be used
+ * @param append if true
the signature and all the other content will be added as a
+ * new revision thus not invalidating existing signatures
+ * @return a PdfStamper
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public static PdfStamper CreateSignature(PdfReader reader, Stream os, char pdfVersion, string tempFile, bool append) {
+ PdfStamper stp;
+ if (tempFile == null) {
+ ByteBuffer bout = new ByteBuffer();
+ stp = new PdfStamper(reader, bout, pdfVersion, append);
+ stp.sigApp = new PdfSignatureAppearance(stp.stamper);
+ stp.sigApp.Sigout = bout;
+ }
+ else {
+ if (Directory.Exists(tempFile))
+ tempFile = Path.GetTempFileName();
+ FileStream fout = new FileStream(tempFile, FileMode.Create, FileAccess.Write);
+ stp = new PdfStamper(reader, fout, pdfVersion, append);
+ stp.sigApp = new PdfSignatureAppearance(stp.stamper);
+ stp.sigApp.SetTempFile(tempFile);
+ }
+ stp.sigApp.Originalout = os;
+ stp.sigApp.SetStamper(stp);
+ stp.hasSignature = true;
+ PdfDictionary catalog = reader.Catalog;
+ PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.ACROFORM), catalog);
+ if (acroForm != null) {
+ acroForm.Remove(PdfName.NEEDAPPEARANCES);
+ stp.stamper.MarkUsed(acroForm);
+ }
+ return stp;
+ }
+
+ /**
+ * Applies a digital signature to a document. The returned PdfStamper
+ * can be used normally as the signature is only applied when closing.
+ *
+ * KeyStore ks = KeyStore.getInstance("pkcs12");
+ * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
+ * String alias = (String)ks.aliases().nextElement();
+ * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
+ * Certificate[] chain = ks.getCertificateChain(alias);
+ * PdfReader reader = new PdfReader("original.pdf");
+ * FileOutputStream fout = new FileOutputStream("signed.pdf");
+ * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
+ * PdfSignatureAppearance sap = stp.getSignatureAppearance();
+ * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
+ * sap.setReason("I'm the author");
+ * sap.setLocation("Lisbon");
+ * // comment next line to have an invisible signature
+ * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
+ * stp.close();
+ *
+ * @param reader the original document
+ * @param os the output stream
+ * @param pdfVersion the new pdf version or '\0' to keep the same version as the original
+ * document
+ * @throws DocumentException on error
+ * @throws IOException on error
+ * @return a PdfStamper
+ */
+ public static PdfStamper CreateSignature(PdfReader reader, Stream os, char pdfVersion) {
+ return CreateSignature(reader, os, pdfVersion, null, false);
+ }
+
+ /**
+ * Applies a digital signature to a document. The returned PdfStamper
+ * can be used normally as the signature is only applied when closing.
+ *
+ * KeyStore ks = KeyStore.getInstance("pkcs12");
+ * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
+ * String alias = (String)ks.aliases().nextElement();
+ * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
+ * Certificate[] chain = ks.getCertificateChain(alias);
+ * PdfReader reader = new PdfReader("original.pdf");
+ * FileOutputStream fout = new FileOutputStream("signed.pdf");
+ * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', new File("/temp"));
+ * PdfSignatureAppearance sap = stp.getSignatureAppearance();
+ * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
+ * sap.setReason("I'm the author");
+ * sap.setLocation("Lisbon");
+ * // comment next line to have an invisible signature
+ * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
+ * stp.close();
+ *
+ * @param reader the original document
+ * @param os the output stream or null
to keep the document in the temporary file
+ * @param pdfVersion the new pdf version or '\0' to keep the same version as the original
+ * document
+ * @param tempFile location of the temporary file. If it's a directory a temporary file will be created there.
+ * If it's a file it will be used directly. The file will be deleted on exit unless os
is null.
+ * In that case the document can be retrieved directly from the temporary file. If it's null
+ * no temporary file will be created and memory will be used
+ * @return a PdfStamper
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ public static PdfStamper CreateSignature(PdfReader reader, Stream os, char pdfVersion, string tempFile) {
+ return CreateSignature(reader, os, pdfVersion, tempFile, false);
+ }
+
+ /**
+ * Gets the PdfLayer objects in an existing document as a Map
+ * with the names/titles of the layers as keys.
+ * @return a Map with all the PdfLayers in the document (and the name/title of the layer as key)
+ * @since 2.1.2
+ */
+ public Hashtable GetPdfLayers() {
+ return stamper.GetPdfLayers();
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfStamperImp.cs b/iTechSharp/iTextSharp/text/pdf/PdfStamperImp.cs
new file mode 100644
index 0000000..a99a24f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfStamperImp.cs
@@ -0,0 +1,1625 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.util;
+using iTextSharp.text.pdf.interfaces;
+using iTextSharp.text.pdf.intern;
+using iTextSharp.text.pdf.collection;
+/*
+ * Copyright 2003 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ public class PdfStamperImp : PdfWriter {
+ internal Hashtable readers2intrefs = new Hashtable();
+ internal Hashtable readers2file = new Hashtable();
+ internal RandomAccessFileOrArray file;
+ internal PdfReader reader;
+ internal IntHashtable myXref = new IntHashtable();
+ /** Integer(page number) -> PageStamp */
+ internal Hashtable pagesToContent = new Hashtable();
+ internal bool closed = false;
+ /** Holds value of property rotateContents. */
+ private bool rotateContents = true;
+ protected AcroFields acroFields;
+ protected bool flat = false;
+ protected bool flatFreeText = false;
+ protected int[] namePtr = {0};
+ protected Hashtable partialFlattening = new Hashtable();
+ protected bool useVp = false;
+ protected PdfViewerPreferencesImp viewerPreferences = new PdfViewerPreferencesImp();
+ protected Hashtable fieldTemplates = new Hashtable();
+ protected bool fieldsAdded = false;
+ protected int sigFlags = 0;
+ protected internal bool append;
+ protected IntHashtable marked;
+ protected int initialXrefSize;
+ protected PdfAction openAction;
+
+ /** Creates new PdfStamperImp.
+ * @param reader the read PDF
+ * @param os the output destination
+ * @param pdfVersion the new pdf version or '\0' to keep the same version as the original
+ * document
+ * @param append
+ * @throws DocumentException on error
+ * @throws IOException
+ */
+ internal PdfStamperImp(PdfReader reader, Stream os, char pdfVersion, bool append) : base(new PdfDocument(), os) {
+ if (!reader.IsOpenedWithFullPermissions)
+ throw new ArgumentException("PdfReader not opened with owner password");
+ if (reader.Tampered)
+ throw new DocumentException("The original document was reused. Read it again from file.");
+ reader.Tampered = true;
+ this.reader = reader;
+ file = reader.SafeFile;
+ this.append = append;
+ if (append) {
+ if (reader.IsRebuilt())
+ throw new DocumentException("Append mode requires a document without errors even if recovery was possible.");
+ if (reader.IsEncrypted())
+ crypto = new PdfEncryption(reader.Decrypt);
+ pdf_version.SetAppendmode(true);
+ file.ReOpen();
+ byte[] buf = new byte[8192];
+ int n;
+ while ((n = file.Read(buf)) > 0)
+ this.os.Write(buf, 0, n);
+ file.Close();
+ prevxref = reader.LastXref;
+ reader.Appendable = true;
+ }
+ else {
+ if (pdfVersion == 0)
+ base.PdfVersion = reader.PdfVersion;
+ else
+ base.PdfVersion = pdfVersion;
+ }
+ base.Open();
+ pdf.AddWriter(this);
+ if (append) {
+ body.Refnum = reader.XrefSize;
+ marked = new IntHashtable();
+ if (reader.IsNewXrefType())
+ fullCompression = true;
+ if (reader.IsHybridXref())
+ fullCompression = false;
+ }
+ initialXrefSize = reader.XrefSize;
+ }
+
+ internal void Close(Hashtable moreInfo) {
+ if (closed)
+ return;
+ if (useVp) {
+ reader.SetViewerPreferences(viewerPreferences);
+ MarkUsed(reader.Trailer.Get(PdfName.ROOT));
+ }
+ if (flat)
+ FlatFields();
+ if (flatFreeText)
+ FlatFreeTextFields();
+ AddFieldResources();
+ PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(reader.Catalog.Get(PdfName.ACROFORM), reader.Catalog);
+ if (acroFields != null && acroFields.Xfa.Changed) {
+ MarkUsed(acroForm);
+ if (!flat)
+ acroFields.Xfa.SetXfa(this);
+ }
+ if (sigFlags != 0) {
+ if (acroForm != null) {
+ acroForm.Put(PdfName.SIGFLAGS, new PdfNumber(sigFlags));
+ MarkUsed(acroForm);
+ }
+ }
+ closed = true;
+ AddSharedObjectsToBody();
+ SetOutlines();
+ SetJavaScript();
+ AddFileAttachments();
+ PdfDictionary catalog = reader.Catalog;
+ if (openAction != null) {
+ catalog.Put(PdfName.OPENACTION, openAction);
+ }
+ if (pdf.pageLabels != null)
+ catalog.Put(PdfName.PAGELABELS, pdf.pageLabels.GetDictionary(this));
+ byte[] altMetadata = null;
+ PdfObject xmpo = PdfReader.GetPdfObject(catalog.Get(PdfName.METADATA));
+ if (xmpo != null && xmpo.IsStream()) {
+ altMetadata = PdfReader.GetStreamBytesRaw((PRStream)xmpo);
+ PdfReader.KillIndirect(catalog.Get(PdfName.METADATA));
+ }
+ if (xmpMetadata != null) {
+ altMetadata = xmpMetadata;
+ }
+ // if there is XMP data to add: add it
+ if (altMetadata != null) {
+ PdfStream xmp = new PdfStream(altMetadata);
+ xmp.Put(PdfName.TYPE, PdfName.METADATA);
+ xmp.Put(PdfName.SUBTYPE, PdfName.XML);
+ if (crypto != null && !crypto.IsMetadataEncrypted()) {
+ PdfArray ar = new PdfArray();
+ ar.Add(PdfName.CRYPT);
+ xmp.Put(PdfName.FILTER, ar);
+ }
+ catalog.Put(PdfName.METADATA, body.Add(xmp).IndirectReference);
+ MarkUsed(catalog);
+ }
+ if (documentOCG.Count != 0) {
+ FillOCProperties(false);
+ PdfDictionary ocdict = catalog.GetAsDict(PdfName.OCPROPERTIES);
+ if (ocdict == null) {
+ reader.Catalog.Put(PdfName.OCPROPERTIES, OCProperties);
+ }
+ else {
+ ocdict.Put(PdfName.OCGS, OCProperties.Get(PdfName.OCGS));
+ PdfDictionary ddict = ocdict.GetAsDict(PdfName.D);
+ ddict.Put(PdfName.ORDER, OCProperties.GetAsDict(PdfName.D).Get(PdfName.ORDER));
+ ddict.Put(PdfName.RBGROUPS, OCProperties.GetAsDict(PdfName.D).Get(PdfName.RBGROUPS));
+ ddict.Put(PdfName.OFF, OCProperties.GetAsDict(PdfName.D).Get(PdfName.OFF));
+ ddict.Put(PdfName.AS, OCProperties.GetAsDict(PdfName.D).Get(PdfName.AS));
+ }
+ }
+ PRIndirectReference iInfo = null;
+ try {
+ file.ReOpen();
+ AlterContents();
+ iInfo = (PRIndirectReference)reader.trailer.Get(PdfName.INFO);
+ int skip = -1;
+ if (iInfo != null)
+ skip = iInfo.Number;
+ int rootN = ((PRIndirectReference)reader.trailer.Get(PdfName.ROOT)).Number;
+ if (append) {
+ int[] keys = marked.GetKeys();
+ for (int k = 0; k < keys.Length; ++k) {
+ int j = keys[k];
+ PdfObject obj = reader.GetPdfObjectRelease(j);
+ if (obj != null && skip != j && j < initialXrefSize) {
+ AddToBody(obj, j, j != rootN);
+ }
+ }
+ for (int k = initialXrefSize; k < reader.XrefSize; ++k) {
+ PdfObject obj = reader.GetPdfObject(k);
+ if (obj != null) {
+ AddToBody(obj, GetNewObjectNumber(reader, k, 0));
+ }
+ }
+ }
+ else {
+ for (int k = 1; k < reader.XrefSize; ++k) {
+ PdfObject obj = reader.GetPdfObjectRelease(k);
+ if (obj != null && skip != k) {
+ AddToBody(obj, GetNewObjectNumber(reader, k, 0), k != rootN);
+ }
+ }
+ }
+ }
+ finally {
+ try {
+ file.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ PdfIndirectReference encryption = null;
+ PdfObject fileID = null;
+ if (crypto != null) {
+ if (append) {
+ encryption = reader.GetCryptoRef();
+ }
+ else {
+ PdfIndirectObject encryptionObject = AddToBody(crypto.GetEncryptionDictionary(), false);
+ encryption = encryptionObject.IndirectReference;
+ }
+ fileID = crypto.FileID;
+ }
+ else
+ fileID = PdfEncryption.CreateInfoId(PdfEncryption.CreateDocumentId());
+ PRIndirectReference iRoot = (PRIndirectReference)reader.trailer.Get(PdfName.ROOT);
+ PdfIndirectReference root = new PdfIndirectReference(0, GetNewObjectNumber(reader, iRoot.Number, 0));
+ PdfIndirectReference info = null;
+ PdfDictionary oldInfo = (PdfDictionary)PdfReader.GetPdfObject(iInfo);
+ PdfDictionary newInfo = new PdfDictionary();
+ if (oldInfo != null) {
+ foreach (PdfName key in oldInfo.Keys) {
+ PdfObject value = PdfReader.GetPdfObject(oldInfo.Get(key));
+ newInfo.Put(key, value);
+ }
+ }
+ if (moreInfo != null) {
+ foreach (DictionaryEntry entry in moreInfo) {
+ PdfName keyName = new PdfName((String)entry.Key);
+ String value = (String)entry.Value;
+ if (value == null)
+ newInfo.Remove(keyName);
+ else
+ newInfo.Put(keyName, new PdfString(value, PdfObject.TEXT_UNICODE));
+ }
+ }
+ if (altMetadata == null) // hack because changing the modification data makes the XMP data inconsistent
+ newInfo.Put(PdfName.MODDATE, new PdfDate());
+ if (append) {
+ if (iInfo == null)
+ info = AddToBody(newInfo, false).IndirectReference;
+ else
+ info = AddToBody(newInfo, iInfo.Number, false).IndirectReference;
+ }
+ else {
+ info = AddToBody(newInfo, false).IndirectReference;
+ }
+ // write the cross-reference table of the body
+ body.WriteCrossReferenceTable(os, root, info, encryption, fileID, prevxref);
+ if (fullCompression) {
+ byte[] tmp = GetISOBytes("startxref\n");
+ os.Write(tmp, 0, tmp.Length);
+ tmp = GetISOBytes(body.Offset.ToString());
+ os.Write(tmp, 0, tmp.Length);
+ tmp = GetISOBytes("\n%%EOF\n");
+ os.Write(tmp, 0, tmp.Length);
+ }
+ else {
+ PdfTrailer trailer = new PdfTrailer(body.Size,
+ body.Offset,
+ root,
+ info,
+ encryption,
+ fileID, prevxref);
+ trailer.ToPdf(this, os);
+ }
+ os.Flush();
+ if (CloseStream)
+ os.Close();
+ reader.Close();
+ }
+
+ internal void ApplyRotation(PdfDictionary pageN, ByteBuffer out_p) {
+ if (!rotateContents)
+ return;
+ Rectangle page = reader.GetPageSizeWithRotation(pageN);
+ int rotation = page.Rotation;
+ switch (rotation) {
+ case 90:
+ out_p.Append(PdfContents.ROTATE90);
+ out_p.Append(page.Top);
+ out_p.Append(' ').Append('0').Append(PdfContents.ROTATEFINAL);
+ break;
+ case 180:
+ out_p.Append(PdfContents.ROTATE180);
+ out_p.Append(page.Right);
+ out_p.Append(' ');
+ out_p.Append(page.Top);
+ out_p.Append(PdfContents.ROTATEFINAL);
+ break;
+ case 270:
+ out_p.Append(PdfContents.ROTATE270);
+ out_p.Append('0').Append(' ');
+ out_p.Append(page.Right);
+ out_p.Append(PdfContents.ROTATEFINAL);
+ break;
+ }
+ }
+
+ internal void AlterContents() {
+ foreach (PageStamp ps in pagesToContent.Values) {
+ PdfDictionary pageN = ps.pageN;
+ MarkUsed(pageN);
+ PdfArray ar = null;
+ PdfObject content = PdfReader.GetPdfObject(pageN.Get(PdfName.CONTENTS), pageN);
+ if (content == null) {
+ ar = new PdfArray();
+ pageN.Put(PdfName.CONTENTS, ar);
+ }
+ else if (content.IsArray()) {
+ ar = (PdfArray)content;
+ MarkUsed(ar);
+ }
+ else if (content.IsStream()) {
+ ar = new PdfArray();
+ ar.Add(pageN.Get(PdfName.CONTENTS));
+ pageN.Put(PdfName.CONTENTS, ar);
+ }
+ else {
+ ar = new PdfArray();
+ pageN.Put(PdfName.CONTENTS, ar);
+ }
+ ByteBuffer out_p = new ByteBuffer();
+ if (ps.under != null) {
+ out_p.Append(PdfContents.SAVESTATE);
+ ApplyRotation(pageN, out_p);
+ out_p.Append(ps.under.InternalBuffer);
+ out_p.Append(PdfContents.RESTORESTATE);
+ }
+ if (ps.over != null)
+ out_p.Append(PdfContents.SAVESTATE);
+ PdfStream stream = new PdfStream(out_p.ToByteArray());
+ stream.FlateCompress();
+ ar.AddFirst(AddToBody(stream).IndirectReference);
+ out_p.Reset();
+ if (ps.over != null) {
+ out_p.Append(' ');
+ out_p.Append(PdfContents.RESTORESTATE);
+ ByteBuffer buf = ps.over.InternalBuffer;
+ out_p.Append(buf.Buffer, 0, ps.replacePoint);
+ out_p.Append(PdfContents.SAVESTATE);
+ ApplyRotation(pageN, out_p);
+ out_p.Append(buf.Buffer, ps.replacePoint, buf.Size - ps.replacePoint);
+ out_p.Append(PdfContents.RESTORESTATE);
+ stream = new PdfStream(out_p.ToByteArray());
+ stream.FlateCompress();
+ ar.Add(AddToBody(stream).IndirectReference);
+ }
+ AlterResources(ps);
+ }
+ }
+
+ internal void AlterResources(PageStamp ps) {
+ ps.pageN.Put(PdfName.RESOURCES, ps.pageResources.Resources);
+ }
+
+ protected internal override int GetNewObjectNumber(PdfReader reader, int number, int generation) {
+ IntHashtable ref_p = (IntHashtable)readers2intrefs[reader];
+ if (ref_p != null) {
+ int n = ref_p[number];
+ if (n == 0) {
+ n = IndirectReferenceNumber;
+ ref_p[number] = n;
+ }
+ return n;
+ }
+ if (currentPdfReaderInstance == null) {
+ if (append && number < initialXrefSize)
+ return number;
+ int n = myXref[number];
+ if (n == 0) {
+ n = IndirectReferenceNumber;
+ myXref[number] = n;
+ }
+ return n;
+ }
+ else
+ return currentPdfReaderInstance.GetNewObjectNumber(number, generation);
+ }
+
+ internal override RandomAccessFileOrArray GetReaderFile(PdfReader reader) {
+ if (readers2intrefs.ContainsKey(reader)) {
+ RandomAccessFileOrArray raf = (RandomAccessFileOrArray)readers2file[reader];
+ if (raf != null)
+ return raf;
+ return reader.SafeFile;
+ }
+ if (currentPdfReaderInstance == null)
+ return file;
+ else
+ return currentPdfReaderInstance.ReaderFile;
+ }
+
+ /**
+ * @param reader
+ * @param openFile
+ * @throws IOException
+ */
+ public void RegisterReader(PdfReader reader, bool openFile) {
+ if (readers2intrefs.ContainsKey(reader))
+ return;
+ readers2intrefs[reader] = new IntHashtable();
+ if (openFile) {
+ RandomAccessFileOrArray raf = reader.SafeFile;
+ readers2file[reader] = raf;
+ raf.ReOpen();
+ }
+ }
+
+ /**
+ * @param reader
+ */
+ public void UnRegisterReader(PdfReader reader) {
+ if (!readers2intrefs.ContainsKey(reader))
+ return;
+ readers2intrefs.Remove(reader);
+ RandomAccessFileOrArray raf = (RandomAccessFileOrArray)readers2file[reader];
+ if (raf == null)
+ return;
+ readers2file.Remove(reader);
+ try{raf.Close();}catch{}
+ }
+
+ internal static void FindAllObjects(PdfReader reader, PdfObject obj, IntHashtable hits) {
+ if (obj == null)
+ return;
+ switch (obj.Type) {
+ case PdfObject.INDIRECT:
+ PRIndirectReference iref = (PRIndirectReference)obj;
+ if (reader != iref.Reader)
+ return;
+ if (hits.ContainsKey(iref.Number))
+ return;
+ hits[iref.Number] = 1;
+ FindAllObjects(reader, PdfReader.GetPdfObject(obj), hits);
+ return;
+ case PdfObject.ARRAY:
+ ArrayList lst = ((PdfArray)obj).ArrayList;
+ for (int k = 0; k < lst.Count; ++k) {
+ FindAllObjects(reader, (PdfObject)lst[k], hits);
+ }
+ return;
+ case PdfObject.DICTIONARY:
+ case PdfObject.STREAM:
+ PdfDictionary dic = (PdfDictionary)obj;
+ foreach (PdfName name in dic.Keys) {
+ FindAllObjects(reader, dic.Get(name), hits);
+ }
+ return;
+ }
+ }
+
+ /**
+ * @param fdf
+ * @throws IOException
+ */
+ public void AddComments(FdfReader fdf) {
+ if (readers2intrefs.ContainsKey(fdf))
+ return;
+ PdfDictionary catalog = fdf.Catalog;
+ catalog = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.FDF));
+ if (catalog == null)
+ return;
+ PdfArray annots = (PdfArray)PdfReader.GetPdfObject(catalog.Get(PdfName.ANNOTS));
+ if (annots == null || annots.Size == 0)
+ return;
+ RegisterReader(fdf, false);
+ IntHashtable hits = new IntHashtable();
+ Hashtable irt = new Hashtable();
+ ArrayList an = new ArrayList();
+ ArrayList ar = annots.ArrayList;
+ for (int k = 0; k < ar.Count; ++k) {
+ PdfObject obj = (PdfObject)ar[k];
+ PdfDictionary annot = (PdfDictionary)PdfReader.GetPdfObject(obj);
+ PdfNumber page = (PdfNumber)PdfReader.GetPdfObject(annot.Get(PdfName.PAGE));
+ if (page == null || page.IntValue >= reader.NumberOfPages)
+ continue;
+ FindAllObjects(fdf, obj, hits);
+ an.Add(obj);
+ if (obj.Type == PdfObject.INDIRECT) {
+ PdfObject nm = PdfReader.GetPdfObject(annot.Get(PdfName.NM));
+ if (nm != null && nm.Type == PdfObject.STRING)
+ irt[nm.ToString()] = obj;
+ }
+ }
+ int[] arhits = hits.GetKeys();
+ for (int k = 0; k < arhits.Length; ++k) {
+ int n = arhits[k];
+ PdfObject obj = fdf.GetPdfObject(n);
+ if (obj.Type == PdfObject.DICTIONARY) {
+ PdfObject str = PdfReader.GetPdfObject(((PdfDictionary)obj).Get(PdfName.IRT));
+ if (str != null && str.Type == PdfObject.STRING) {
+ PdfObject i = (PdfObject)irt[str.ToString()];
+ if (i != null) {
+ PdfDictionary dic2 = new PdfDictionary();
+ dic2.Merge((PdfDictionary)obj);
+ dic2.Put(PdfName.IRT, i);
+ obj = dic2;
+ }
+ }
+ }
+ AddToBody(obj, GetNewObjectNumber(fdf, n, 0));
+ }
+ for (int k = 0; k < an.Count; ++k) {
+ PdfObject obj = (PdfObject)an[k];
+ PdfDictionary annot = (PdfDictionary)PdfReader.GetPdfObject(obj);
+ PdfNumber page = (PdfNumber)PdfReader.GetPdfObject(annot.Get(PdfName.PAGE));
+ PdfDictionary dic = reader.GetPageN(page.IntValue + 1);
+ PdfArray annotsp = (PdfArray)PdfReader.GetPdfObject(dic.Get(PdfName.ANNOTS), dic);
+ if (annotsp == null) {
+ annotsp = new PdfArray();
+ dic.Put(PdfName.ANNOTS, annotsp);
+ MarkUsed(dic);
+ }
+ MarkUsed(annotsp);
+ annotsp.Add(obj);
+ }
+ }
+
+ internal PageStamp GetPageStamp(int pageNum) {
+ PdfDictionary pageN = reader.GetPageN(pageNum);
+ PageStamp ps = (PageStamp)pagesToContent[pageN];
+ if (ps == null) {
+ ps = new PageStamp(this, reader, pageN);
+ pagesToContent[pageN] = ps;
+ }
+ return ps;
+ }
+
+ internal PdfContentByte GetUnderContent(int pageNum) {
+ if (pageNum < 1 || pageNum > reader.NumberOfPages)
+ return null;
+ PageStamp ps = GetPageStamp(pageNum);
+ if (ps.under == null)
+ ps.under = new StampContent(this, ps);
+ return ps.under;
+ }
+
+ internal PdfContentByte GetOverContent(int pageNum) {
+ if (pageNum < 1 || pageNum > reader.NumberOfPages)
+ return null;
+ PageStamp ps = GetPageStamp(pageNum);
+ if (ps.over == null)
+ ps.over = new StampContent(this, ps);
+ return ps.over;
+ }
+
+ internal void CorrectAcroFieldPages(int page) {
+ if (acroFields == null)
+ return;
+ if (page > reader.NumberOfPages)
+ return;
+ Hashtable fields = acroFields.Fields;
+ foreach (AcroFields.Item item in fields.Values) {
+ ArrayList pages = item.page;
+ for (int k = 0; k < pages.Count; ++k) {
+ int p = (int)pages[k];
+ if (p >= page)
+ pages[k] = p + 1;
+ }
+ }
+ }
+
+ private static void MoveRectangle(PdfDictionary dic2, PdfReader r, int pageImported, PdfName key, String name) {
+ Rectangle m = r.GetBoxSize(pageImported, name);
+ if (m == null)
+ dic2.Remove(key);
+ else
+ dic2.Put(key, new PdfRectangle(m));
+ }
+
+ internal void ReplacePage(PdfReader r, int pageImported, int pageReplaced) {
+ PdfDictionary pageN = reader.GetPageN(pageReplaced);
+ if (pagesToContent.ContainsKey(pageN))
+ throw new InvalidOperationException("This page cannot be replaced: new content was already added");
+ PdfImportedPage p = GetImportedPage(r, pageImported);
+ PdfDictionary dic2 = reader.GetPageNRelease(pageReplaced);
+ dic2.Remove(PdfName.RESOURCES);
+ dic2.Remove(PdfName.CONTENTS);
+ MoveRectangle(dic2, r, pageImported, PdfName.MEDIABOX, "media");
+ MoveRectangle(dic2, r, pageImported, PdfName.CROPBOX, "crop");
+ MoveRectangle(dic2, r, pageImported, PdfName.TRIMBOX, "trim");
+ MoveRectangle(dic2, r, pageImported, PdfName.ARTBOX, "art");
+ MoveRectangle(dic2, r, pageImported, PdfName.BLEEDBOX, "bleed");
+ dic2.Put(PdfName.ROTATE, new PdfNumber(r.GetPageRotation(pageImported)));
+ PdfContentByte cb = GetOverContent(pageReplaced);
+ cb.AddTemplate(p, 0, 0);
+ PageStamp ps = (PageStamp)pagesToContent[pageN];
+ ps.replacePoint = ps.over.InternalBuffer.Size;
+ }
+
+ internal void InsertPage(int pageNumber, Rectangle mediabox) {
+ Rectangle media = new Rectangle(mediabox);
+ int rotation = media.Rotation % 360;
+ PdfDictionary page = new PdfDictionary(PdfName.PAGE);
+ PdfDictionary resources = new PdfDictionary();
+ PdfArray procset = new PdfArray();
+ procset.Add(PdfName.PDF);
+ procset.Add(PdfName.TEXT);
+ procset.Add(PdfName.IMAGEB);
+ procset.Add(PdfName.IMAGEC);
+ procset.Add(PdfName.IMAGEI);
+ resources.Put(PdfName.PROCSET, procset);
+ page.Put(PdfName.RESOURCES, resources);
+ page.Put(PdfName.ROTATE, new PdfNumber(rotation));
+ page.Put(PdfName.MEDIABOX, new PdfRectangle(media, rotation));
+ PRIndirectReference pref = reader.AddPdfObject(page);
+ PdfDictionary parent;
+ PRIndirectReference parentRef;
+ if (pageNumber > reader.NumberOfPages) {
+ PdfDictionary lastPage = reader.GetPageNRelease(reader.NumberOfPages);
+ parentRef = (PRIndirectReference)lastPage.Get(PdfName.PARENT);
+ parentRef = new PRIndirectReference(reader, parentRef.Number);
+ parent = (PdfDictionary)PdfReader.GetPdfObject(parentRef);
+ PdfArray kids = (PdfArray)PdfReader.GetPdfObject(parent.Get(PdfName.KIDS), parent);
+ kids.Add(pref);
+ MarkUsed(kids);
+ reader.pageRefs.InsertPage(pageNumber, pref);
+ }
+ else {
+ if (pageNumber < 1)
+ pageNumber = 1;
+ PdfDictionary firstPage = reader.GetPageN(pageNumber);
+ PRIndirectReference firstPageRef = reader.GetPageOrigRef(pageNumber);
+ reader.ReleasePage(pageNumber);
+ parentRef = (PRIndirectReference)firstPage.Get(PdfName.PARENT);
+ parentRef = new PRIndirectReference(reader, parentRef.Number);
+ parent = (PdfDictionary)PdfReader.GetPdfObject(parentRef);
+ PdfArray kids = (PdfArray)PdfReader.GetPdfObject(parent.Get(PdfName.KIDS), parent);
+ ArrayList ar = kids.ArrayList;
+ int len = ar.Count;
+ int num = firstPageRef.Number;
+ for (int k = 0; k < len; ++k) {
+ PRIndirectReference cur = (PRIndirectReference)ar[k];
+ if (num == cur.Number) {
+ ar.Insert(k, pref);
+ break;
+ }
+ }
+ if (len == ar.Count)
+ throw new Exception("Internal inconsistence.");
+ MarkUsed(kids);
+ reader.pageRefs.InsertPage(pageNumber, pref);
+ CorrectAcroFieldPages(pageNumber);
+ }
+ page.Put(PdfName.PARENT, parentRef);
+ while (parent != null) {
+ MarkUsed(parent);
+ PdfNumber count = (PdfNumber)PdfReader.GetPdfObjectRelease(parent.Get(PdfName.COUNT));
+ parent.Put(PdfName.COUNT, new PdfNumber(count.IntValue + 1));
+ parent = (PdfDictionary)PdfReader.GetPdfObject(parent.Get(PdfName.PARENT));
+ }
+ }
+
+ internal bool RotateContents {
+ set {
+ this.rotateContents = value;
+ }
+ get {
+ return rotateContents;
+ }
+ }
+
+ internal bool ContentWritten {
+ get {
+ return body.Size > 1;
+ }
+ }
+
+ internal AcroFields AcroFields {
+ get {
+ if (acroFields == null) {
+ acroFields = new AcroFields(reader, this);
+ }
+ return acroFields;
+ }
+ }
+
+ internal bool FormFlattening {
+ set {
+ flat = value;
+ }
+ }
+
+ internal bool FreeTextFlattening {
+ set {
+ flatFreeText = value;
+ }
+ }
+
+ internal bool PartialFormFlattening(String name) {
+ AcroFields af = AcroFields;
+ if (acroFields.Xfa.XfaPresent)
+ throw new InvalidOperationException("Partial form flattening is not supported with XFA forms.");
+ if (!acroFields.Fields.ContainsKey(name))
+ return false;
+ partialFlattening[name] = null;
+ return true;
+ }
+
+ internal void FlatFields() {
+ if (append)
+ throw new ArgumentException("Field flattening is not supported in append mode.");
+ AcroFields af = AcroFields;
+ Hashtable fields = acroFields.Fields;
+ if (fieldsAdded && partialFlattening.Count == 0) {
+ foreach (object obf in fields.Keys) {
+ partialFlattening[obf] = null;
+ }
+ }
+ PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(reader.Catalog.Get(PdfName.ACROFORM));
+ ArrayList acroFds = null;
+ if (acroForm != null) {
+ PdfArray array = (PdfArray)PdfReader.GetPdfObject(acroForm.Get(PdfName.FIELDS), acroForm);
+ if (array != null)
+ acroFds = array.ArrayList;
+ }
+ foreach (DictionaryEntry entry in fields) {
+ String name = (String)entry.Key;
+ if (partialFlattening.Count != 0 && !partialFlattening.ContainsKey(name))
+ continue;
+ AcroFields.Item item = (AcroFields.Item)entry.Value;
+ for (int k = 0; k < item.merged.Count; ++k) {
+ PdfDictionary merged = (PdfDictionary)item.merged[k];
+ PdfNumber ff = (PdfNumber)PdfReader.GetPdfObject(merged.Get(PdfName.F));
+ int flags = 0;
+ if (ff != null)
+ flags = ff.IntValue;
+ int page = (int)item.page[k];
+ PdfDictionary appDic = (PdfDictionary)PdfReader.GetPdfObject(merged.Get(PdfName.AP));
+ if (appDic != null && (flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_HIDDEN) == 0) {
+ PdfObject obj = appDic.Get(PdfName.N);
+ PdfAppearance app = null;
+ if (obj != null) {
+ PdfObject objReal = PdfReader.GetPdfObject(obj);
+ if (obj is PdfIndirectReference && !obj.IsIndirect())
+ app = new PdfAppearance((PdfIndirectReference)obj);
+ else if (objReal is PdfStream) {
+ ((PdfDictionary)objReal).Put(PdfName.SUBTYPE, PdfName.FORM);
+ app = new PdfAppearance((PdfIndirectReference)obj);
+ }
+ else {
+ if (objReal != null && objReal.IsDictionary()) {
+ PdfName as_p = (PdfName)PdfReader.GetPdfObject(merged.Get(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 (app != null) {
+ Rectangle box = PdfReader.GetNormalizedRectangle((PdfArray)PdfReader.GetPdfObject(merged.Get(PdfName.RECT)));
+ PdfContentByte cb = GetOverContent(page);
+ cb.SetLiteral("Q ");
+ cb.AddTemplate(app, box.Left, box.Bottom);
+ cb.SetLiteral("q ");
+ }
+ }
+ if (partialFlattening.Count == 0)
+ continue;
+ PdfDictionary pageDic = reader.GetPageN(page);
+ PdfArray annots = (PdfArray)PdfReader.GetPdfObject(pageDic.Get(PdfName.ANNOTS));
+ if (annots == null)
+ continue;
+ ArrayList ar = annots.ArrayList;
+ for (int idx = 0; idx < ar.Count; ++idx) {
+ PdfObject ran = (PdfObject)ar[idx];
+ if (!ran.IsIndirect())
+ continue;
+ PdfObject ran2 = (PdfObject)item.widget_refs[k];
+ if (!ran2.IsIndirect())
+ continue;
+ if (((PRIndirectReference)ran).Number == ((PRIndirectReference)ran2).Number) {
+ ar.RemoveAt(idx--);
+ PRIndirectReference wdref = (PRIndirectReference)ran2;
+ while (true) {
+ PdfDictionary wd = (PdfDictionary)PdfReader.GetPdfObject(wdref);
+ PRIndirectReference parentRef = (PRIndirectReference)wd.Get(PdfName.PARENT);
+ PdfReader.KillIndirect(wdref);
+ if (parentRef == null) { // reached AcroForm
+ for (int fr = 0; fr < acroFds.Count; ++fr) {
+ PdfObject h = (PdfObject)acroFds[fr];
+ if (h.IsIndirect() && ((PRIndirectReference)h).Number == wdref.Number) {
+ acroFds.RemoveAt(fr);
+ --fr;
+ }
+ }
+ break;
+ }
+ PdfDictionary parent = (PdfDictionary)PdfReader.GetPdfObject(parentRef);
+ PdfArray kids = (PdfArray)PdfReader.GetPdfObject(parent.Get(PdfName.KIDS));
+ ArrayList kar = kids.ArrayList;
+ for (int fr = 0; fr < kar.Count; ++fr) {
+ PdfObject h = (PdfObject)kar[fr];
+ if (h.IsIndirect() && ((PRIndirectReference)h).Number == wdref.Number) {
+ kar.RemoveAt(fr);
+ --fr;
+ }
+ }
+ if (kar.Count != 0)
+ break;
+ wdref = parentRef;
+ }
+ }
+ }
+ if (ar.Count == 0) {
+ PdfReader.KillIndirect(pageDic.Get(PdfName.ANNOTS));
+ pageDic.Remove(PdfName.ANNOTS);
+ }
+ }
+ }
+ if (!fieldsAdded && partialFlattening.Count == 0) {
+ for (int page = 1; page <= reader.NumberOfPages; ++page) {
+ PdfDictionary pageDic = reader.GetPageN(page);
+ PdfArray annots = (PdfArray)PdfReader.GetPdfObject(pageDic.Get(PdfName.ANNOTS));
+ if (annots == null)
+ continue;
+ ArrayList ar = annots.ArrayList;
+ for (int idx = 0; idx < ar.Count; ++idx) {
+ PdfObject annoto = PdfReader.GetPdfObject((PdfObject)ar[idx]);
+ if ((annoto is PdfIndirectReference) && !annoto.IsIndirect())
+ continue;
+ if (!annoto.IsDictionary() || PdfName.WIDGET.Equals(((PdfDictionary)annoto).Get(PdfName.SUBTYPE))) {
+ ar.RemoveAt(idx);
+ --idx;
+ }
+ }
+ if (ar.Count == 0) {
+ PdfReader.KillIndirect(pageDic.Get(PdfName.ANNOTS));
+ pageDic.Remove(PdfName.ANNOTS);
+ }
+ }
+ EliminateAcroformObjects();
+ }
+ }
+
+ internal void EliminateAcroformObjects() {
+ PdfObject acro = reader.Catalog.Get(PdfName.ACROFORM);
+ if (acro == null)
+ return;
+ PdfDictionary acrodic = (PdfDictionary)PdfReader.GetPdfObject(acro);
+ reader.KillXref(acrodic.Get(PdfName.XFA));
+ acrodic.Remove(PdfName.XFA);
+ PdfObject iFields = acrodic.Get(PdfName.FIELDS);
+ if (iFields != null) {
+ PdfDictionary kids = new PdfDictionary();
+ kids.Put(PdfName.KIDS, iFields);
+ SweepKids(kids);
+ PdfReader.KillIndirect(iFields);
+ acrodic.Put(PdfName.FIELDS, new PdfArray());
+ }
+ // PdfReader.KillIndirect(acro);
+ // reader.GetCatalog().Remove(PdfName.ACROFORM);
+ }
+
+ internal void SweepKids(PdfObject obj) {
+ PdfObject oo = PdfReader.KillIndirect(obj);
+ if (oo == null || !oo.IsDictionary())
+ return;
+ PdfDictionary dic = (PdfDictionary)oo;
+ PdfArray kids = (PdfArray)PdfReader.KillIndirect(dic.Get(PdfName.KIDS));
+ if (kids == null)
+ return;
+ ArrayList ar = kids.ArrayList;
+ for (int k = 0; k < ar.Count; ++k) {
+ SweepKids((PdfObject)ar[k]);
+ }
+ }
+
+ private void FlatFreeTextFields() {
+ if (append)
+ throw new ArgumentException("FreeText flattening is not supported in append mode.");
+
+ for (int page = 1; page <= reader.NumberOfPages; ++page) {
+ PdfDictionary pageDic = reader.GetPageN(page);
+ PdfArray annots = (PdfArray)PdfReader.GetPdfObject(pageDic.Get(PdfName.ANNOTS));
+ if (annots == null)
+ continue;
+ ArrayList ar = annots.ArrayList;
+ for (int idx = 0; idx < ar.Count; ++idx) {
+ PdfObject annoto = PdfReader.GetPdfObject((PdfObject)ar[idx]);
+ if ((annoto is PdfIndirectReference) && !annoto.IsIndirect())
+ continue;
+
+ PdfDictionary annDic = (PdfDictionary)annoto;
+ if (!((PdfName)annDic.Get(PdfName.SUBTYPE)).Equals(PdfName.FREETEXT))
+ continue;
+ PdfNumber ff = (PdfNumber)PdfReader.GetPdfObject(annDic.Get(PdfName.F));
+ int flags = (ff != null) ? ff.IntValue : 0;
+
+ if ( (flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_HIDDEN) == 0) {
+ PdfObject obj1 = annDic.Get(PdfName.AP);
+ if (obj1 == null)
+ continue;
+ PdfDictionary appDic = (obj1 is PdfIndirectReference) ?
+ (PdfDictionary) PdfReader.GetPdfObject(obj1) : (PdfDictionary) obj1;
+ PdfObject obj = appDic.Get(PdfName.N);
+ PdfAppearance app = null;
+ if (obj != null) {
+ PdfObject objReal = PdfReader.GetPdfObject(obj);
+
+ if (obj is PdfIndirectReference && !obj.IsIndirect())
+ app = new PdfAppearance((PdfIndirectReference)obj);
+ else if (objReal is PdfStream) {
+ ((PdfDictionary)objReal).Put(PdfName.SUBTYPE, PdfName.FORM);
+ app = new PdfAppearance((PdfIndirectReference)obj);
+ }
+ else {
+ if (objReal.IsDictionary()) {
+ PdfName as_p = (PdfName)PdfReader.GetPdfObject(appDic.Get(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 (app != null) {
+ Rectangle box = PdfReader.GetNormalizedRectangle((PdfArray)PdfReader.GetPdfObject(annDic.Get(PdfName.RECT)));
+ PdfContentByte cb = this.GetOverContent(page);
+ cb.SetLiteral("Q ");
+ cb.AddTemplate(app, box.Left, box.Bottom);
+ cb.SetLiteral("q ");
+ }
+ }
+ }
+ for (int idx = 0; idx < ar.Count; ++idx) {
+ PdfObject annoto = PdfReader.GetPdfObject((PdfObject)ar[idx]);
+ if (annoto != null && annoto.IsDictionary()) {
+ PdfDictionary annot = (PdfDictionary)annoto;
+ if (PdfName.FREETEXT.Equals(annot.Get(PdfName.SUBTYPE))) {
+ ar.RemoveAt(idx);
+ --idx;
+ }
+ }
+ }
+ if (ar.Count == 0) {
+ PdfReader.KillIndirect(pageDic.Get(PdfName.ANNOTS));
+ pageDic.Remove(PdfName.ANNOTS);
+ }
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfWriter#getPageReference(int)
+ */
+ public override PdfIndirectReference GetPageReference(int page) {
+ PdfIndirectReference ref_p = reader.GetPageOrigRef(page);
+ if (ref_p == null)
+ throw new ArgumentException("Invalid page number " + page);
+ return ref_p;
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfWriter#addAnnotation(com.lowagie.text.pdf.PdfAnnotation)
+ */
+ public override void AddAnnotation(PdfAnnotation annot) {
+ throw new Exception("Unsupported in this context. Use PdfStamper.AddAnnotation()");
+ }
+
+ internal void AddDocumentField(PdfIndirectReference ref_p) {
+ PdfDictionary catalog = reader.Catalog;
+ PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.ACROFORM), catalog);
+ if (acroForm == null) {
+ acroForm = new PdfDictionary();
+ catalog.Put(PdfName.ACROFORM, acroForm);
+ MarkUsed(catalog);
+ }
+ PdfArray fields = (PdfArray)PdfReader.GetPdfObject(acroForm.Get(PdfName.FIELDS), acroForm);
+ if (fields == null) {
+ fields = new PdfArray();
+ acroForm.Put(PdfName.FIELDS, fields);
+ MarkUsed(acroForm);
+ }
+ if (!acroForm.Contains(PdfName.DA)) {
+ acroForm.Put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
+ MarkUsed(acroForm);
+ }
+ fields.Add(ref_p);
+ MarkUsed(fields);
+ }
+
+ internal void AddFieldResources() {
+ if (fieldTemplates.Count == 0)
+ return;
+ PdfDictionary catalog = reader.Catalog;
+ PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.ACROFORM), catalog);
+ if (acroForm == null) {
+ acroForm = new PdfDictionary();
+ catalog.Put(PdfName.ACROFORM, acroForm);
+ MarkUsed(catalog);
+ }
+ PdfDictionary dr = (PdfDictionary)PdfReader.GetPdfObject(acroForm.Get(PdfName.DR), acroForm);
+ if (dr == null) {
+ dr = new PdfDictionary();
+ acroForm.Put(PdfName.DR, dr);
+ MarkUsed(acroForm);
+ }
+ MarkUsed(dr);
+ foreach (PdfTemplate template in fieldTemplates.Keys) {
+ PdfFormField.MergeResources(dr, (PdfDictionary)template.Resources, this);
+ }
+ if (dr.Get(PdfName.ENCODING) == null)
+ dr.Put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING);
+ PdfDictionary fonts = (PdfDictionary)PdfReader.GetPdfObject(dr.Get(PdfName.FONT));
+ if (fonts == null) {
+ fonts = new PdfDictionary();
+ dr.Put(PdfName.FONT, fonts);
+ }
+ if (!fonts.Contains(PdfName.HELV)) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONT);
+ dic.Put(PdfName.BASEFONT, PdfName.HELVETICA);
+ dic.Put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING);
+ dic.Put(PdfName.NAME, PdfName.HELV);
+ dic.Put(PdfName.SUBTYPE, PdfName.TYPE1);
+ fonts.Put(PdfName.HELV, AddToBody(dic).IndirectReference);
+ }
+ if (!fonts.Contains(PdfName.ZADB)) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONT);
+ dic.Put(PdfName.BASEFONT, PdfName.ZAPFDINGBATS);
+ dic.Put(PdfName.NAME, PdfName.ZADB);
+ dic.Put(PdfName.SUBTYPE, PdfName.TYPE1);
+ fonts.Put(PdfName.ZADB, AddToBody(dic).IndirectReference);
+ }
+ if (acroForm.Get(PdfName.DA) == null) {
+ acroForm.Put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
+ MarkUsed(acroForm);
+ }
+ }
+
+ internal void ExpandFields(PdfFormField field, ArrayList allAnnots) {
+ allAnnots.Add(field);
+ ArrayList kids = field.Kids;
+ if (kids != null) {
+ for (int k = 0; k < kids.Count; ++k) {
+ ExpandFields((PdfFormField)kids[k], allAnnots);
+ }
+ }
+ }
+
+ internal void AddAnnotation(PdfAnnotation annot, PdfDictionary pageN) {
+ ArrayList allAnnots = new ArrayList();
+ if (annot.IsForm()) {
+ fieldsAdded = true;
+ AcroFields afdummy = AcroFields;
+ PdfFormField field = (PdfFormField)annot;
+ if (field.Parent != null)
+ return;
+ ExpandFields(field, allAnnots);
+ }
+ else
+ allAnnots.Add(annot);
+ for (int k = 0; k < allAnnots.Count; ++k) {
+ annot = (PdfAnnotation)allAnnots[k];
+ if (annot.PlaceInPage > 0)
+ pageN = reader.GetPageN(annot.PlaceInPage);
+ if (annot.IsForm()) {
+ if (!annot.IsUsed()) {
+ Hashtable templates = annot.Templates;
+ if (templates != null) {
+ foreach (object tpl in templates.Keys) {
+ fieldTemplates[tpl] = null;
+ }
+ }
+ }
+ PdfFormField field = (PdfFormField)annot;
+ if (field.Parent == null)
+ AddDocumentField(field.IndirectReference);
+ }
+ if (annot.IsAnnotation()) {
+ PdfObject pdfobj = PdfReader.GetPdfObject(pageN.Get(PdfName.ANNOTS), pageN);
+ PdfArray annots = null;
+ if (pdfobj == null || !pdfobj.IsArray()) {
+ annots = new PdfArray();
+ pageN.Put(PdfName.ANNOTS, annots);
+ MarkUsed(pageN);
+ }
+ else
+ annots = (PdfArray)pdfobj;
+ annots.Add(annot.IndirectReference);
+ MarkUsed(annots);
+ if (!annot.IsUsed()) {
+ PdfRectangle rect = (PdfRectangle)annot.Get(PdfName.RECT);
+ if (rect != null && (rect.Left != 0 || rect.Right != 0 || rect.Top != 0 || rect.Bottom != 0)) {
+ int rotation = reader.GetPageRotation(pageN);
+ Rectangle pageSize = reader.GetPageSizeWithRotation(pageN);
+ switch (rotation) {
+ case 90:
+ annot.Put(PdfName.RECT, new PdfRectangle(
+ pageSize.Top - rect.Bottom,
+ rect.Left,
+ pageSize.Top - rect.Top,
+ rect.Right));
+ break;
+ case 180:
+ annot.Put(PdfName.RECT, new PdfRectangle(
+ pageSize.Right - rect.Left,
+ pageSize.Top - rect.Bottom,
+ pageSize.Right - rect.Right,
+ pageSize.Top - rect.Top));
+ break;
+ case 270:
+ annot.Put(PdfName.RECT, new PdfRectangle(
+ rect.Bottom,
+ pageSize.Right - rect.Left,
+ rect.Top,
+ pageSize.Right - rect.Right));
+ break;
+ }
+ }
+ }
+ }
+ if (!annot.IsUsed()) {
+ annot.SetUsed();
+ AddToBody(annot, annot.IndirectReference);
+ }
+ }
+ }
+
+ internal override void AddAnnotation(PdfAnnotation annot, int page) {
+ AddAnnotation(annot, reader.GetPageN(page));
+ }
+
+ private void OutlineTravel(PRIndirectReference outline) {
+ while (outline != null) {
+ PdfDictionary outlineR = (PdfDictionary)PdfReader.GetPdfObjectRelease(outline);
+ PRIndirectReference first = (PRIndirectReference)outlineR.Get(PdfName.FIRST);
+ if (first != null) {
+ OutlineTravel(first);
+ }
+ PdfReader.KillIndirect(outlineR.Get(PdfName.DEST));
+ PdfReader.KillIndirect(outlineR.Get(PdfName.A));
+ PdfReader.KillIndirect(outline);
+ outline = (PRIndirectReference)outlineR.Get(PdfName.NEXT);
+ }
+ }
+
+ internal void DeleteOutlines() {
+ PdfDictionary catalog = reader.Catalog;
+ PRIndirectReference outlines = (PRIndirectReference)catalog.Get(PdfName.OUTLINES);
+ if (outlines == null)
+ return;
+ OutlineTravel(outlines);
+ PdfReader.KillIndirect(outlines);
+ catalog.Remove(PdfName.OUTLINES);
+ MarkUsed(catalog);
+ }
+
+ internal void SetJavaScript() {
+ Hashtable djs = pdf.GetDocumentLevelJS();
+ if (djs.Count == 0)
+ return;
+ PdfDictionary catalog = reader.Catalog;
+ PdfDictionary names = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.NAMES), catalog);
+ if (names == null) {
+ names = new PdfDictionary();
+ catalog.Put(PdfName.NAMES, names);
+ MarkUsed(catalog);
+ }
+ MarkUsed(names);
+ PdfDictionary tree = PdfNameTree.WriteTree(djs, this);
+ names.Put(PdfName.JAVASCRIPT, AddToBody(tree).IndirectReference);
+ }
+
+ void AddFileAttachments() {
+ Hashtable fs = pdf.GetDocumentFileAttachment();
+ if (fs.Count == 0)
+ return;
+ PdfDictionary catalog = reader.Catalog;
+ PdfDictionary names = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.NAMES), catalog);
+ if (names == null) {
+ names = new PdfDictionary();
+ catalog.Put(PdfName.NAMES, names);
+ MarkUsed(catalog);
+ }
+ MarkUsed(names);
+ Hashtable old = PdfNameTree.ReadTree((PdfDictionary)PdfReader.GetPdfObjectRelease(names.Get(PdfName.EMBEDDEDFILES)));
+ foreach (DictionaryEntry entry in fs) {
+ String name = (String)entry.Key;
+ int k = 0;
+ String nn = name;
+ while (old.ContainsKey(nn)) {
+ ++k;
+ nn += " " + k;
+ }
+ old[nn] = entry.Value;
+ }
+ PdfDictionary tree = PdfNameTree.WriteTree(old, this);
+ names.Put(PdfName.EMBEDDEDFILES, AddToBody(tree).IndirectReference);
+ }
+
+ /**
+ * Adds or replaces the Collection Dictionary in the Catalog.
+ * @param collection the new collection dictionary.
+ */
+ internal void MakePackage(PdfCollection collection) {
+ PdfDictionary catalog = reader.Catalog;
+ catalog.Put( PdfName.COLLECTION, collection );
+ }
+
+ internal void SetOutlines() {
+ if (newBookmarks == null)
+ return;
+ DeleteOutlines();
+ if (newBookmarks.Count == 0)
+ return;
+ PdfDictionary catalog = reader.Catalog;
+ bool namedAsNames = (catalog.Get(PdfName.DESTS) != null);
+ WriteOutlines(catalog, namedAsNames);
+ MarkUsed(catalog);
+ }
+
+ /**
+ * Sets the viewer preferences.
+ * @param preferences the viewer preferences
+ * @see PdfWriter#setViewerPreferences(int)
+ */
+ public override int ViewerPreferences {
+ set {
+ useVp = true;
+ this.viewerPreferences.ViewerPreferences = value;
+ }
+ }
+
+ /** Adds a viewer preference
+ * @param preferences the viewer preferences
+ * @see PdfViewerPreferences#addViewerPreference
+ */
+ public override void AddViewerPreference(PdfName key, PdfObject value) {
+ useVp = true;
+ this.viewerPreferences.AddViewerPreference(key, value);
+ }
+
+ /**
+ * Set the signature flags.
+ * @param f the flags. This flags are ORed with current ones
+ */
+ public override int SigFlags {
+ set {
+ sigFlags |= value;
+ }
+ }
+
+ /** Always throws an UnsupportedOperationException
.
+ * @param actionType ignore
+ * @param action ignore
+ * @throws PdfException ignore
+ * @see PdfStamper#setPageAction(PdfName, PdfAction, int)
+ */
+ public override void SetPageAction(PdfName actionType, PdfAction action) {
+ throw new InvalidOperationException("Use SetPageAction(PdfName actionType, PdfAction action, int page)");
+ }
+
+ /**
+ * Sets the open and close page additional action.
+ * @param actionType the action type. It can be PdfWriter.PAGE_OPEN
+ * or PdfWriter.PAGE_CLOSE
+ * @param action the action to perform
+ * @param page the page where the action will be applied. The first page is 1
+ * @throws PdfException if the action type is invalid
+ */
+ internal void SetPageAction(PdfName actionType, PdfAction action, int page) {
+ if (!actionType.Equals(PAGE_OPEN) && !actionType.Equals(PAGE_CLOSE))
+ throw new PdfException("Invalid page additional action type: " + actionType.ToString());
+ PdfDictionary pg = reader.GetPageN(page);
+ PdfDictionary aa = (PdfDictionary)PdfReader.GetPdfObject(pg.Get(PdfName.AA), pg);
+ if (aa == null) {
+ aa = new PdfDictionary();
+ pg.Put(PdfName.AA, aa);
+ MarkUsed(pg);
+ }
+ aa.Put(actionType, action);
+ MarkUsed(aa);
+ }
+
+ /**
+ * Always throws an UnsupportedOperationException
.
+ * @param seconds ignore
+ */
+ public override int Duration {
+ set {
+ throw new InvalidOperationException("Use the methods at Pdfstamper.");
+ }
+ }
+
+ /**
+ * Always throws an UnsupportedOperationException
.
+ * @param transition ignore
+ */
+ public override PdfTransition Transition {
+ set {
+ throw new InvalidOperationException("Use the methods at Pdfstamper.");
+ }
+ }
+
+ /**
+ * Sets the display duration for the page (for presentations)
+ * @param seconds the number of seconds to display the page. A negative value removes the entry
+ * @param page the page where the duration will be applied. The first page is 1
+ */
+ internal void SetDuration(int seconds, int page) {
+ PdfDictionary pg = reader.GetPageN(page);
+ if (seconds < 0)
+ pg.Remove(PdfName.DUR);
+ else
+ pg.Put(PdfName.DUR, new PdfNumber(seconds));
+ MarkUsed(pg);
+ }
+
+ /**
+ * Sets the transition for the page
+ * @param transition the transition object. A null
removes the transition
+ * @param page the page where the transition will be applied. The first page is 1
+ */
+ internal void SetTransition(PdfTransition transition, int page) {
+ PdfDictionary pg = reader.GetPageN(page);
+ if (transition == null)
+ pg.Remove(PdfName.TRANS);
+ else
+ pg.Put(PdfName.TRANS, transition.TransitionDictionary);
+ MarkUsed(pg);
+ }
+
+ protected internal void MarkUsed(PdfObject obj) {
+ if (append && obj != null) {
+ PRIndirectReference ref_p = null;
+ if (obj.Type == PdfObject.INDIRECT)
+ ref_p = (PRIndirectReference)obj;
+ else
+ ref_p = obj.IndRef;
+ if (ref_p != null)
+ marked[ref_p.Number] = 1;
+ }
+ }
+
+ protected internal void MarkUsed(int num) {
+ if (append)
+ marked[num] = 1;
+ }
+
+ /**
+ * Getter for property append.
+ * @return Value of property append.
+ */
+ internal bool IsAppend() {
+ return append;
+ }
+
+ /** Additional-actions defining the actions to be taken in
+ * response to various trigger events affecting the document
+ * as a whole. The actions types allowed are: DOCUMENT_CLOSE
,
+ * WILL_SAVE
, DID_SAVE
, WILL_PRINT
+ * and DID_PRINT
.
+ *
+ * @param actionType the action type
+ * @param action the action to execute in response to the trigger
+ * @throws PdfException on invalid action type
+ */
+ public override void SetAdditionalAction(PdfName actionType, PdfAction action) {
+ if (!(actionType.Equals(DOCUMENT_CLOSE) ||
+ actionType.Equals(WILL_SAVE) ||
+ actionType.Equals(DID_SAVE) ||
+ actionType.Equals(WILL_PRINT) ||
+ actionType.Equals(DID_PRINT))) {
+ throw new PdfException("Invalid additional action type: " + actionType.ToString());
+ }
+ PdfDictionary aa = (PdfDictionary)PdfReader.GetPdfObject(reader.Catalog.Get(PdfName.AA));
+ if (aa == null) {
+ if (action == null)
+ return;
+ aa = new PdfDictionary();
+ reader.Catalog.Put(PdfName.AA, aa);
+ }
+ MarkUsed(aa);
+ if (action == null)
+ aa.Remove(actionType);
+ else
+ aa.Put(actionType, action);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfWriter#setOpenAction(com.lowagie.text.pdf.PdfAction)
+ */
+ public override void SetOpenAction(PdfAction action) {
+ openAction = action;
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfWriter#setOpenAction(java.lang.String)
+ */
+ public override void SetOpenAction(String name) {
+ throw new InvalidOperationException("Open actions by name are not supported.");
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfWriter#setThumbnail(com.lowagie.text.Image)
+ */
+ public override Image Thumbnail {
+ set {
+ throw new InvalidOperationException("Use PdfStamper.Thumbnail");
+ }
+ }
+
+ internal void SetThumbnail(Image image, int page) {
+ PdfIndirectReference thumb = GetImageReference(AddDirectImageSimple(image));
+ reader.ResetReleasePage();
+ PdfDictionary dic = reader.GetPageN(page);
+ dic.Put(PdfName.THUMB, thumb);
+ reader.ResetReleasePage();
+ }
+
+ /**
+ * Reads the OCProperties dictionary from the catalog of the existing document
+ * and fills the documentOCG, documentOCGorder and OCGRadioGroup variables in PdfWriter.
+ * Note that the original OCProperties of the existing document can contain more information.
+ * @since 2.1.2
+ */
+ protected void ReadOCProperties() {
+ if (documentOCG.Count != 0) {
+ return;
+ }
+ PdfDictionary dict = reader.Catalog.GetAsDict(PdfName.OCPROPERTIES);
+ if (dict == null) {
+ return;
+ }
+ PdfArray ocgs = dict.GetAsArray(PdfName.OCGS);
+ PdfIndirectReference refi;
+ PdfLayer layer;
+ Hashtable ocgmap = new Hashtable();
+ for (ListIterator i = ocgs.GetListIterator(); i.HasNext();) {
+ refi = (PdfIndirectReference)i.Next();
+ layer = new PdfLayer(null);
+ layer.Ref = refi;
+ layer.OnPanel = false;
+ layer.Merge((PdfDictionary)PdfReader.GetPdfObject(refi));
+ ocgmap[refi.ToString()] = layer;
+ }
+ PdfDictionary d = dict.GetAsDict(PdfName.D);
+ PdfArray off = d.GetAsArray(PdfName.OFF);
+ if (off != null) {
+ for (ListIterator i = off.GetListIterator(); i.HasNext(); ) {
+ refi = (PdfIndirectReference)i.Next();
+ layer = (PdfLayer)ocgmap[refi.ToString()];
+ layer.On = false;
+ }
+ }
+ PdfArray order = d.GetAsArray(PdfName.ORDER);
+ if (order != null) {
+ AddOrder(null, order, ocgmap);
+ }
+ foreach (object o in ocgmap.Values)
+ documentOCG[o] = null;
+ OCGRadioGroup = d.GetAsArray(PdfName.RBGROUPS);
+ OCGLocked = d.GetAsArray(PdfName.LOCKED);
+ }
+
+ /**
+ * Recursive method to reconstruct the documentOCGorder variable in the writer.
+ * @param parent a parent PdfLayer (can be null)
+ * @param arr an array possibly containing children for the parent PdfLayer
+ * @param ocgmap a Hashtable with indirect reference Strings as keys and PdfLayer objects as values.
+ * @since 2.1.2
+ */
+ private void AddOrder(PdfLayer parent, PdfArray arr, Hashtable ocgmap) {
+ PdfObject obj;
+ PdfLayer layer;
+ for (int i = 0; i < arr.Size; i++) {
+ obj = arr.GetPdfObject(i);
+ if (obj.IsIndirect()) {
+ layer = (PdfLayer)ocgmap[obj.ToString()];
+ layer.OnPanel = true;
+ RegisterLayer(layer);
+ if (parent != null) {
+ parent.AddChild(layer);
+ }
+ if (arr.Size > i + 1 && arr.GetPdfObject(i + 1).IsArray()) {
+ i++;
+ AddOrder(layer, (PdfArray)arr.GetPdfObject(i), ocgmap);
+ }
+ }
+ else if (obj.IsArray()) {
+ ArrayList sub = ((PdfArray)obj).ArrayList;
+ if (sub.Count == 0) return;
+ obj = (PdfObject)sub[0];
+ if (obj.IsString()) {
+ layer = new PdfLayer(sub[0].ToString());
+ layer.OnPanel = true;
+ RegisterLayer(layer);
+ if (parent != null) {
+ parent.AddChild(layer);
+ }
+ PdfArray array = new PdfArray();
+ foreach (PdfObject o2 in sub) {
+ array.Add(o2);
+ }
+ AddOrder(layer, array, ocgmap);
+ }
+ else {
+ AddOrder(parent, (PdfArray)obj, ocgmap);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the PdfLayer objects in an existing document as a Map
+ * with the names/titles of the layers as keys.
+ * @return a Map with all the PdfLayers in the document (and the name/title of the layer as key)
+ * @since 2.1.2
+ */
+ public Hashtable GetPdfLayers() {
+ if (documentOCG.Count == 0) {
+ ReadOCProperties();
+ }
+ Hashtable map = new Hashtable();
+ String key;
+ foreach (PdfLayer layer in documentOCG) {
+ if (layer.Title == null) {
+ key = layer.GetAsString(PdfName.NAME).ToString();
+ }
+ else {
+ key = layer.Title;
+ }
+ if (map.ContainsKey(key)) {
+ int seq = 2;
+ String tmp = key + "(" + seq + ")";
+ while (map.ContainsKey(tmp)) {
+ seq++;
+ tmp = key + "(" + seq + ")";
+ }
+ key = tmp;
+ }
+ map[key] = layer;
+ }
+ return map;
+ }
+
+ internal class PageStamp {
+
+ internal PdfDictionary pageN;
+ internal StampContent under;
+ internal StampContent over;
+ internal PageResources pageResources;
+ internal int replacePoint = 0;
+
+ internal PageStamp(PdfStamperImp stamper, PdfReader reader, PdfDictionary pageN) {
+ this.pageN = pageN;
+ pageResources = new PageResources();
+ PdfDictionary resources = (PdfDictionary)PdfReader.GetPdfObject(pageN.Get(PdfName.RESOURCES));
+ pageResources.SetOriginalResources(resources, stamper.namePtr);
+ }
+ }
+
+ public override PdfContentByte DirectContent {
+ get {
+ throw new InvalidOperationException("Use PdfStamper.GetUnderContent() or PdfStamper.GetOverContent()");
+ }
+ }
+
+ public override PdfContentByte DirectContentUnder {
+ get {
+ throw new InvalidOperationException("Use PdfStamper.GetUnderContent() or PdfStamper.GetOverContent()");
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfStream.cs b/iTechSharp/iTextSharp/text/pdf/PdfStream.cs
new file mode 100644
index 0000000..4abfed8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfStream.cs
@@ -0,0 +1,324 @@
+using System;
+using System.IO;
+using System.Collections;
+
+using System.util.zlib;
+
+/*
+ * $Id: PdfStream.cs,v 1.12 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * PdfStream
is the Pdf stream object.
+ *
+ * A stream consists of a dictionary that describes a sequence of characters, followed by
+ * the keyword stream, followed by zero or more lines of characters, followed by
+ * the keyword endstream.
+ * All streams must be PdfIndirectObject
s. The stream dictionary must be a direct
+ * object. The keyword stream that follows the stream dictionary should be followed by
+ * a carriage return and linefeed or just a linefeed.
+ * Remark: In this version only the FLATEDECODE-filter is supported.
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.8 (page 41-53).
+ *
+ * @see PdfObject
+ * @see PdfDictionary
+ */
+
+ public class PdfStream : PdfDictionary {
+
+ // membervariables
+
+ /** is the stream compressed? */
+ protected bool compressed = false;
+
+ protected MemoryStream streamBytes = null;
+
+ protected Stream inputStream;
+ protected PdfIndirectReference iref;
+ protected int inputStreamLength = -1;
+ protected PdfWriter writer;
+ protected int rawLength;
+
+ internal static byte[] STARTSTREAM = DocWriter.GetISOBytes("stream\n");
+ internal static byte[] ENDSTREAM = DocWriter.GetISOBytes("\nendstream");
+ internal static int SIZESTREAM = STARTSTREAM.Length + ENDSTREAM.Length;
+
+ // constructors
+
+ /**
+ * Constructs a PdfStream
-object.
+ *
+ * @param bytes content of the new PdfObject
as an array of byte
.
+ */
+
+ public PdfStream(byte[] bytes) : base() {
+ type = STREAM;
+ this.bytes = bytes;
+ rawLength = bytes.Length;
+ Put(PdfName.LENGTH, new PdfNumber(bytes.Length));
+ }
+
+ /**
+ * Creates an efficient stream. No temporary array is ever created. The InputStream
+ * is totally consumed but is not closed. The general usage is:
+ *
+ * InputStream in = ...;
+ * PdfStream stream = new PdfStream(in, writer);
+ * stream.FlateCompress();
+ * writer.AddToBody(stream);
+ * stream.WriteLength();
+ * in.Close();
+ *
+ * @param inputStream the data to write to this stream
+ * @param writer the PdfWriter
for this stream
+ */
+ public PdfStream(Stream inputStream, PdfWriter writer) {
+ type = STREAM;
+ this.inputStream = inputStream;
+ this.writer = writer;
+ iref = writer.PdfIndirectReference;
+ Put(PdfName.LENGTH, iref);
+ }
+
+ /**
+ * Constructs a PdfStream
-object.
+ */
+
+ protected PdfStream() : base() {
+ type = STREAM;
+ }
+
+ // methods overriding some methods of PdfObject
+
+ /**
+ * Writes the stream length to the PdfWriter
.
+ * Stream
.
+ * @param os the destination to write to
+ * @throws IOException on error
+ */
+ public void WriteContent(Stream os) {
+ if (streamBytes != null)
+ streamBytes.WriteTo(os);
+ else if (bytes != null)
+ os.Write(bytes, 0, bytes.Length);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.PdfObject#toString()
+ */
+ public override String ToString() {
+ if (Get(PdfName.TYPE) == null) return "Stream";
+ return "Stream of type: " + Get(PdfName.TYPE);
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfString.cs b/iTechSharp/iTextSharp/text/pdf/PdfString.cs
new file mode 100644
index 0000000..01eedef
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfString.cs
@@ -0,0 +1,232 @@
+using System;
+using System.IO;
+
+/*
+ * $Id: PdfString.cs,v 1.6 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A PdfString
-class is the PDF-equivalent of a JAVA-string
-object.
+ *
+ * This object is described in the 'Portable Document Format Reference Manual version 1.3'
+ * section 4.4 (page 37-39).
+ *
+ * @see PdfObject
+ * @see BadPdfFormatException
+ */
+
+ public class PdfString : PdfObject {
+
+ // membervariables
+
+ /** The value of this object. */
+ protected string value = NOTHING;
+ protected string originalValue = null;
+
+ /** The encoding. */
+ protected string encoding = TEXT_PDFDOCENCODING;
+ protected int objNum = 0;
+ protected int objGen = 0;
+ protected bool hexWriting = false;
+ // constructors
+
+ /**
+ * Constructs an empty PdfString
-object.
+ */
+
+ public PdfString() : base(STRING) {}
+
+ /**
+ * Constructs a PdfString
-object.
+ *
+ * @param value the content of the string
+ */
+
+ public PdfString(string value) : base(STRING) {
+ this.value = value;
+ }
+
+ /**
+ * Constructs a PdfString
-object.
+ *
+ * @param value the content of the string
+ * @param encoding an encoding
+ */
+
+ public PdfString(string value, string encoding) : base(STRING) {
+ this.value = value;
+ this.encoding = encoding;
+ }
+
+ /**
+ * Constructs a PdfString
-object.
+ *
+ * @param bytes an array of byte
+ */
+
+ public PdfString(byte[] bytes) : base(STRING) {
+ value = PdfEncodings.ConvertToString(bytes, null);
+ encoding = NOTHING;
+ }
+
+ // methods overriding some methods in PdfObject
+
+ /**
+ * Returns the PDF representation of this PdfString
.
+ *
+ * @return an array of byte
s
+ */
+
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ byte[] b = GetBytes();
+ PdfEncryption crypto = null;
+ if (writer != null)
+ crypto = writer.Encryption;
+ if (crypto != null) {
+ b = crypto.EncryptByteArray(b);
+ }
+ if (hexWriting) {
+ ByteBuffer buf = new ByteBuffer();
+ buf.Append('<');
+ int len = b.Length;
+ for (int k = 0; k < len; ++k)
+ buf.AppendHex(b[k]);
+ buf.Append('>');
+ os.Write(buf.ToByteArray(), 0, buf.Size);
+ }
+ else {
+ b = PdfContentByte.EscapeString(b);
+ os.Write(b, 0, b.Length);
+ }
+ }
+
+ /**
+ * Returns the string
value of the PdfString
-object.
+ *
+ * @return a string
+ */
+
+ public override string ToString() {
+ return value;
+ }
+
+ // other methods
+
+ /**
+ * Gets the encoding of this string.
+ *
+ * @return a string
+ */
+
+ public string Encoding {
+ get {
+ return encoding;
+ }
+ }
+ public String ToUnicodeString() {
+ if (encoding != null && encoding.Length != 0)
+ return value;
+ GetBytes();
+ if (bytes.Length >= 2 && bytes[0] == (byte)254 && bytes[1] == (byte)255)
+ return PdfEncodings.ConvertToString(bytes, PdfObject.TEXT_UNICODE);
+ else
+ return PdfEncodings.ConvertToString(bytes, PdfObject.TEXT_PDFDOCENCODING);
+ }
+
+ internal void SetObjNum(int objNum, int objGen) {
+ this.objNum = objNum;
+ this.objGen = objGen;
+ }
+
+ internal void Decrypt(PdfReader reader) {
+ PdfEncryption decrypt = reader.Decrypt;
+ if (decrypt != null) {
+ originalValue = value;
+ decrypt.SetHashKey(objNum, objGen);
+ bytes = PdfEncodings.ConvertToBytes(value, null);
+ bytes = decrypt.DecryptByteArray(bytes);
+ value = PdfEncodings.ConvertToString(bytes, null);
+ }
+ }
+
+ public override byte[] GetBytes() {
+ if (bytes == null) {
+ if (encoding != null && encoding.Equals(TEXT_UNICODE) && PdfEncodings.IsPdfDocEncoding(value))
+ bytes = PdfEncodings.ConvertToBytes(value, TEXT_PDFDOCENCODING);
+ else
+ bytes = PdfEncodings.ConvertToBytes(value, encoding);
+ }
+ return bytes;
+ }
+
+ public byte[] GetOriginalBytes() {
+ if (originalValue == null)
+ return GetBytes();
+ return PdfEncodings.ConvertToBytes(originalValue, null);
+ }
+
+ public PdfString SetHexWriting(bool hexWriting) {
+ this.hexWriting = hexWriting;
+ return this;
+ }
+
+ public bool IsHexWriting() {
+ return hexWriting;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfStructureElement.cs b/iTechSharp/iTextSharp/text/pdf/PdfStructureElement.cs
new file mode 100644
index 0000000..08c8608
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfStructureElement.cs
@@ -0,0 +1,136 @@
+using System;
+
+/*
+ * $Id: PdfStructureElement.cs,v 1.3 2005/11/02 12:24:06 psoares33 Exp $
+ *
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * This is a node in a document logical structure. It may contain a mark point or it may contain
+ * other nodes.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfStructureElement : PdfDictionary {
+
+ /**
+ * Holds value of property kids.
+ */
+ private PdfStructureElement parent;
+ private PdfStructureTreeRoot top;
+
+ /**
+ * Holds value of property reference.
+ */
+ private PdfIndirectReference reference;
+
+ /**
+ * Creates a new instance of PdfStructureElement.
+ * @param parent the parent of this node
+ * @param structureType the type of structure. It may be a standard type or a user type mapped by the role map
+ */
+ public PdfStructureElement(PdfStructureElement parent, PdfName structureType) {
+ top = parent.top;
+ Init(parent, structureType);
+ this.parent = parent;
+ Put(PdfName.P, parent.reference);
+ }
+
+ /**
+ * Creates a new instance of PdfStructureElement.
+ * @param parent the parent of this node
+ * @param structureType the type of structure. It may be a standard type or a user type mapped by the role map
+ */
+ public PdfStructureElement(PdfStructureTreeRoot parent, PdfName structureType) {
+ top = parent;
+ Init(parent, structureType);
+ Put(PdfName.P, parent.Reference);
+ }
+
+ private void Init(PdfDictionary parent, PdfName structureType) {
+ PdfObject kido = parent.Get(PdfName.K);
+ PdfArray kids = null;
+ if (kido != null && !kido.IsArray())
+ throw new ArgumentException("The parent has already another function.");
+ if (kido == null) {
+ kids = new PdfArray();
+ parent.Put(PdfName.K, kids);
+ }
+ else
+ kids = (PdfArray)kido;
+ kids.Add(this);
+ Put(PdfName.S, structureType);
+ reference = top.Writer.PdfIndirectReference;
+ }
+
+ /**
+ * Gets the parent of this node.
+ * @return the parent of this node
+ */
+ public PdfDictionary Parent {
+ get {
+ return parent;
+ }
+ }
+
+ internal void SetPageMark(int page, int mark) {
+ if (mark >= 0)
+ Put(PdfName.K, new PdfNumber(mark));
+ top.SetPageMark(page, reference);
+ }
+
+ /**
+ * Gets the reference this object will be written to.
+ * @return the reference this object will be written to
+ */
+ public PdfIndirectReference Reference {
+ get {
+ return this.reference;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfStructureTreeRoot.cs b/iTechSharp/iTextSharp/text/pdf/PdfStructureTreeRoot.cs
new file mode 100644
index 0000000..f5c47ba
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfStructureTreeRoot.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections;
+
+/*
+ * $Id: PdfStructureTreeRoot.cs,v 1.2 2005/10/18 15:29:53 psoares33 Exp $
+ *
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /**
+ * The structure tree root corresponds to the highest hierarchy level in a tagged PDF.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfStructureTreeRoot : PdfDictionary {
+
+ private Hashtable parentTree = new Hashtable();
+ private PdfIndirectReference reference;
+
+ /**
+ * Holds value of property writer.
+ */
+ private PdfWriter writer;
+
+ /** Creates a new instance of PdfStructureTreeRoot */
+ internal PdfStructureTreeRoot(PdfWriter writer) : base(PdfName.STRUCTTREEROOT) {
+ this.writer = writer;
+ reference = writer.PdfIndirectReference;
+ }
+
+ /**
+ * Maps the user tags to the standard tags. The mapping will allow a standard application to make some sense of the tagged
+ * document whatever the user tags may be.
+ * @param used the user tag
+ * @param standard the standard tag
+ */
+ public void MapRole(PdfName used, PdfName standard) {
+ PdfDictionary rm = (PdfDictionary)Get(PdfName.ROLEMAP);
+ if (rm == null) {
+ rm = new PdfDictionary();
+ Put(PdfName.ROLEMAP, rm);
+ }
+ rm.Put(used, standard);
+ }
+
+ /**
+ * Gets the writer.
+ * @return the writer
+ */
+ public PdfWriter Writer {
+ get {
+ return this.writer;
+ }
+ }
+
+ /**
+ * Gets the reference this object will be written to.
+ * @return the reference this object will be written to
+ */
+ public PdfIndirectReference Reference {
+ get {
+ return this.reference;
+ }
+ }
+
+ internal void SetPageMark(int page, PdfIndirectReference struc) {
+ PdfArray ar = (PdfArray)parentTree[page];
+ if (ar == null) {
+ ar = new PdfArray();
+ parentTree[page] = ar;
+ }
+ ar.Add(struc);
+ }
+
+ private void NodeProcess(PdfDictionary struc, PdfIndirectReference reference) {
+ PdfObject obj = struc.Get(PdfName.K);
+ if (obj != null && obj.IsArray() && !((PdfObject)((PdfArray)obj).ArrayList[0]).IsNumber()) {
+ PdfArray ar = (PdfArray)obj;
+ ArrayList a = ar.ArrayList;
+ for (int k = 0; k < a.Count; ++k) {
+ PdfStructureElement e = (PdfStructureElement)a[k];
+ a[k] = e.Reference;
+ NodeProcess(e, e.Reference);
+ }
+ }
+ if (reference != null)
+ writer.AddToBody(struc, reference);
+ }
+
+ internal void BuildTree() {
+ Hashtable numTree = new Hashtable();
+ foreach (int i in parentTree.Keys) {
+ PdfArray ar = (PdfArray)parentTree[i];
+ numTree[i] = writer.AddToBody(ar).IndirectReference;
+ }
+ PdfDictionary dicTree = PdfNumberTree.WriteTree(numTree, writer);
+ if (dicTree != null)
+ Put(PdfName.PARENTTREE, writer.AddToBody(dicTree).IndirectReference);
+
+ NodeProcess(this, reference);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfTable.cs b/iTechSharp/iTextSharp/text/pdf/PdfTable.cs
new file mode 100644
index 0000000..f8d567e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfTable.cs
@@ -0,0 +1,319 @@
+using System;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfTable
is an object that contains the graphics and text of a table.
+ *
+ * @see iTextSharp.text.Table
+ * @see iTextSharp.text.Row
+ * @see iTextSharp.text.Cell
+ * @see PdfCell
+ */
+
+ public class PdfTable : Rectangle {
+
+ // membervariables
+
+ /** this is the number of columns in the table. */
+ private int columns;
+
+ /** this is the ArrayList with all the cell of the table header. */
+ private ArrayList headercells;
+
+ /** this is the ArrayList with all the cells in the table. */
+ private ArrayList cells;
+
+ /** Original table used to build this object*/
+ protected Table table;
+
+ /** Cached column widths. */
+ protected float[] positions;
+
+ // constructors
+
+ /**
+ * Constructs a PdfTable
-object.
+ *
+ * @param table a Table
+ * @param left the left border on the page
+ * @param right the right border on the page
+ * @param top the start position of the top of the table
+ */
+
+ internal PdfTable(Table table, float left, float right, float top) : base(left, top, right, top) {
+ // constructs a Rectangle (the bottomvalue will be changed afterwards)
+ this.table = table;
+ table.Complete();
+
+ // copying the attributes from class Table
+ CloneNonPositionParameters(table);
+
+ this.columns = table.Columns;
+ positions = table.GetWidths(left, right - left);
+
+ // initialisation of some parameters
+ Left = positions[0];
+ Right = positions[positions.Length - 1];
+
+ headercells = new ArrayList();
+ cells = new ArrayList();
+
+ UpdateRowAdditionsInternal();
+ }
+
+ // methods
+
+ /**
+ * Updates the table row additions in the underlying table object and deletes all table rows,
+ * in order to preserve memory and detect future row additions.
+ * supportUpdateRowAdditions
equals to true.
+ */
+
+ internal void UpdateRowAdditions() {
+ table.Complete();
+ UpdateRowAdditionsInternal();
+ table.DeleteAllRows();
+ }
+
+ /**
+ * Updates the table row additions in the underlying table object
+ */
+
+ private void UpdateRowAdditionsInternal() {
+ // correct table : fill empty cells/ parse table in table
+ int prevRows = Rows;
+ int rowNumber = 0;
+ int groupNumber = 0;
+ bool groupChange;
+ int firstDataRow = table.LastHeaderRow + 1;
+ Cell cell;
+ PdfCell currentCell;
+ ArrayList newCells = new ArrayList();
+ int rows = table.Size + 1;
+ float[] offsets = new float[rows];
+ for (int i = 0; i < rows; i++) {
+ offsets[i] = Bottom;
+ }
+
+ // loop over all the rows
+ foreach (Row row in table) {
+ groupChange = false;
+ if (row.IsEmpty()) {
+ if (rowNumber < rows - 1 && offsets[rowNumber + 1] > offsets[rowNumber]) offsets[rowNumber + 1] = offsets[rowNumber];
+ }
+ else {
+ for (int i = 0; i < row.Columns; i++) {
+ cell = (Cell) row.GetCell(i);
+ if (cell != null) {
+ currentCell = new PdfCell(cell, rowNumber+prevRows, positions[i], positions[i + cell.Colspan], offsets[rowNumber], Cellspacing, Cellpadding);
+ if (rowNumber < firstDataRow) {
+ currentCell.SetHeader();
+ headercells.Add(currentCell);
+ if (!table.NotAddedYet)
+ continue;
+ }
+ try {
+ if (offsets[rowNumber] - currentCell.Height - Cellpadding < offsets[rowNumber + currentCell.Rowspan]) {
+ offsets[rowNumber + currentCell.Rowspan] = offsets[rowNumber] - currentCell.Height - Cellpadding;
+ }
+ }
+ catch (ArgumentOutOfRangeException) {
+ if (offsets[rowNumber] - currentCell.Height < offsets[rows - 1]) {
+ offsets[rows - 1] = offsets[rowNumber] - currentCell.Height;
+ }
+ }
+ currentCell.GroupNumber = groupNumber;
+ groupChange |= cell.GroupChange;
+ newCells.Add(currentCell);
+ }
+ }
+ }
+ rowNumber++;
+ if ( groupChange ) groupNumber++;
+ }
+
+ // loop over all the cells
+ int n = newCells.Count;
+ for (int i = 0; i < n; i++) {
+ currentCell = (PdfCell) newCells[i];
+ try {
+ currentCell.Bottom = offsets[currentCell.Rownumber-prevRows + currentCell.Rowspan];
+ }
+ catch (ArgumentOutOfRangeException) {
+ currentCell.Bottom = offsets[rows - 1];
+ }
+ }
+ cells.AddRange(newCells);
+ Bottom = offsets[rows - 1];
+ }
+
+ /**
+ * Get the number of rows
+ */
+
+ internal int Rows {
+ get {
+ return cells.Count == 0 ? 0 : ((PdfCell)cells[cells.Count-1]).Rownumber+1;
+ }
+ }
+
+ /** @see com.lowagie.text.Element#type() */
+ public override int Type {
+ get {
+ return Element.TABLE;
+ }
+ }
+
+ /**
+ * Returns the arraylist with the cells of the table header.
+ *
+ * @return an ArrayList
+ */
+
+ internal ArrayList HeaderCells {
+ get {
+ return headercells;
+ }
+ }
+
+ /**
+ * Checks if there is a table header.
+ *
+ * @return an ArrayList
+ */
+
+ internal bool HasHeader() {
+ return headercells.Count > 0;
+ }
+
+ /**
+ * Returns the arraylist with the cells of the table.
+ *
+ * @return an ArrayList
+ */
+
+ internal ArrayList Cells {
+ get {
+ return cells;
+ }
+ }
+
+ /**
+ * Returns the number of columns of the table.
+ *
+ * @return the number of columns
+ */
+
+ internal int Columns {
+ get {
+ return columns;
+ }
+ }
+
+ /**
+ * Returns the cellpadding of the table.
+ *
+ * @return the cellpadding
+ */
+
+ internal float Cellpadding {
+ get {
+ return table.Cellpadding;
+ }
+ }
+
+ /**
+ * Returns the cellspacing of the table.
+ *
+ * @return the cellspacing
+ */
+
+ internal float Cellspacing {
+ get {
+ return table.Cellspacing;
+ }
+ }
+
+ /**
+ * Checks if this Table
has to fit a page.
+ *
+ * @return true if the table may not be split
+ */
+
+ public bool HasToFitPageTable() {
+ return table.TableFitsPage;
+ }
+
+ /**
+ * Checks if the cells of this Table
have to fit a page.
+ *
+ * @return true if the cells may not be split
+ */
+
+ public bool HasToFitPageCells() {
+ return table.CellsFitPage;
+ }
+
+ /**
+ * Gets the offset of this table.
+ *
+ * @return the space between this table and the previous element.
+ */
+ public float Offset {
+ get {
+ return table.Offset;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfTemplate.cs b/iTechSharp/iTextSharp/text/pdf/PdfTemplate.cs
new file mode 100644
index 0000000..f1af760
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfTemplate.cs
@@ -0,0 +1,281 @@
+using System;
+using iTextSharp.text;
+/*
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * Implements the form XObject.
+ */
+
+ public class PdfTemplate : PdfContentByte {
+ public const int TYPE_TEMPLATE = 1;
+ public const int TYPE_IMPORTED = 2;
+ public const int TYPE_PATTERN = 3;
+ protected int type;
+ /** The indirect reference to this template */
+ protected PdfIndirectReference thisReference;
+
+ /** The resources used by this template */
+ protected PageResources pageResources;
+
+ /** The bounding box of this template */
+ protected Rectangle bBox = new Rectangle(0, 0);
+
+ protected PdfArray matrix;
+
+ protected PdfTransparencyGroup group;
+
+ protected IPdfOCG layer;
+
+ /**
+ *Creates a PdfTemplate
.
+ */
+
+ protected PdfTemplate() : base(null) {
+ type = TYPE_TEMPLATE;
+ }
+
+ /**
+ * Creates new PdfTemplate
+ *
+ * @param wr the PdfWriter
+ */
+
+ internal PdfTemplate(PdfWriter wr) : base(wr) {
+ type = TYPE_TEMPLATE;
+ pageResources = new PageResources();
+ pageResources.AddDefaultColor(wr.DefaultColorspace);
+ thisReference = writer.PdfIndirectReference;
+ }
+
+ /**
+ * Creates a new template.
+ * PdfContentByte
or in another template. Templates are only written
+ * to the output when the document is closed permitting things like showing text in the first page
+ * that is only defined in the last page.
+ *
+ * @param width the bounding box width
+ * @param height the bounding box height
+ * @return the templated created
+ */
+ public static PdfTemplate CreateTemplate(PdfWriter writer, float width, float height) {
+ return CreateTemplate(writer, width, height, null);
+ }
+
+ internal static PdfTemplate CreateTemplate(PdfWriter writer, float width, float height, PdfName forcedName) {
+ PdfTemplate template = new PdfTemplate(writer);
+ template.Width = width;
+ template.Height = height;
+ writer.AddDirectTemplateSimple(template, forcedName);
+ return template;
+ }
+
+ /**
+ * Gets the bounding width of this template.
+ *
+ * @return width the bounding width
+ */
+ public float Width {
+ get {
+ return bBox.Width;
+ }
+
+ set {
+ bBox.Left = 0;
+ bBox.Right = value;
+ }
+ }
+
+ /**
+ * Gets the bounding heigth of this template.
+ *
+ * @return heigth the bounding height
+ */
+
+ public float Height {
+ get {
+ return bBox.Height;
+ }
+
+ set {
+ bBox.Bottom = 0;
+ bBox.Top = value;
+ }
+ }
+
+ public Rectangle BoundingBox {
+ get {
+ return bBox;
+ }
+ set {
+ this.bBox = value;
+ }
+ }
+
+ /**
+ * Gets the layer this template belongs to.
+ * @return the layer this template belongs to or null
for no layer defined
+ */
+ public IPdfOCG Layer {
+ get {
+ return layer;
+ }
+ set {
+ layer = value;
+ }
+ }
+
+ public void SetMatrix(float a, float b, float c, float d, float e, float f) {
+ matrix = new PdfArray();
+ matrix.Add(new PdfNumber(a));
+ matrix.Add(new PdfNumber(b));
+ matrix.Add(new PdfNumber(c));
+ matrix.Add(new PdfNumber(d));
+ matrix.Add(new PdfNumber(e));
+ matrix.Add(new PdfNumber(f));
+ }
+
+ internal PdfArray Matrix {
+ get {
+ return matrix;
+ }
+ }
+
+ /**
+ * Gets the indirect reference to this template.
+ *
+ * @return the indirect reference to this template
+ */
+
+ public PdfIndirectReference IndirectReference {
+ get {
+ return thisReference;
+ }
+ }
+
+ public void BeginVariableText() {
+ content.Append("/Tx BMC ");
+ }
+
+ public void EndVariableText() {
+ content.Append("EMC ");
+ }
+
+ /**
+ * Constructs the resources used by this template.
+ *
+ * @return the resources used by this template
+ */
+
+ internal virtual PdfObject Resources {
+ get {
+ return PageResources.Resources;
+ }
+ }
+
+ /**
+ * Gets the stream representing this template.
+ *
+ * @return the stream representing this template
+ */
+
+ internal virtual PdfStream FormXObject {
+ get {
+ return new PdfFormXObject(this);
+ }
+ }
+
+ /**
+ * Gets a duplicate of this PdfTemplate
. All
+ * the members are copied by reference but the buffer stays different.
+ * @return a copy of this PdfTemplate
+ */
+
+ public override PdfContentByte Duplicate {
+ get {
+ PdfTemplate tpl = new PdfTemplate();
+ tpl.writer = writer;
+ tpl.pdf = pdf;
+ tpl.thisReference = thisReference;
+ tpl.pageResources = pageResources;
+ tpl.bBox = new Rectangle(bBox);
+ tpl.group = group;
+ tpl.layer = layer;
+ if (matrix != null) {
+ tpl.matrix = new PdfArray(matrix);
+ }
+ tpl.separator = separator;
+ return tpl;
+ }
+ }
+
+ public int Type {
+ get {
+ return type;
+ }
+ }
+
+ internal override PageResources PageResources {
+ get {
+ return pageResources;
+ }
+ }
+
+ public PdfTransparencyGroup Group {
+ get {
+ return this.group;
+ }
+ set {
+ group = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfTextArray.cs b/iTechSharp/iTextSharp/text/pdf/PdfTextArray.cs
new file mode 100644
index 0000000..f86d366
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfTextArray.cs
@@ -0,0 +1,134 @@
+using System;
+using System.Collections;
+
+/*
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * PdfTextArray
defines an array with displacements and PdfString
-objects.
+ * TextArray
is used with the operator TJ in PdfText
.
+ * The first object in this array has to be a PdfString
;
+ * see reference manual version 1.3 section 8.7.5, pages 346-347.
+ * OR
+ * see reference manual version 1.6 section 5.3.2, pages 378-379.
+ */
+
+ public class PdfTextArray{
+ ArrayList arrayList = new ArrayList();
+
+ // To emit a more efficient array, we consolidate
+ // repeated numbers or strings into single array entries.
+ // "add( 50 ); Add( -50 );" will REMOVE the combined zero from the array.
+ // the alternative (leaving a zero in there) was Just Weird.
+ // --Mark Storer, May 12, 2008
+ private String lastStr;
+ private float lastNum = float.NaN;
+
+ // constructors
+ public PdfTextArray(String str) {
+ Add(str);
+ }
+
+ public PdfTextArray() {
+ }
+
+ /**
+ * Adds a PdfNumber
to the PdfArray
.
+ *
+ * @param number displacement of the string
+ */
+ public void Add(PdfNumber number) {
+ Add((float)number.DoubleValue);
+ }
+
+ public void Add(float number) {
+ if (number != 0) {
+ if (!float.IsNaN(lastNum)) {
+ lastNum += number;
+ if (lastNum != 0) {
+ ReplaceLast(lastNum);
+ } else {
+ arrayList.RemoveAt(arrayList.Count - 1);
+ }
+ } else {
+ lastNum = number;
+ arrayList.Add(lastNum);
+ }
+ lastStr = null;
+ }
+ // adding zero doesn't modify the TextArray at all
+ }
+
+ public void Add(String str) {
+ if (str.Length > 0) {
+ if (lastStr != null) {
+ lastStr = lastStr + str;
+ ReplaceLast(lastStr);
+ } else {
+ lastStr = str;
+ arrayList.Add(lastStr);
+ }
+ lastNum = float.NaN;
+ }
+ // adding an empty string doesn't modify the TextArray at all
+ }
+
+ internal ArrayList ArrayList {
+ get {
+ return arrayList;
+ }
+ }
+
+ private void ReplaceLast(Object obj) {
+ // deliberately throw the IndexOutOfBoundsException if we screw up.
+ arrayList[arrayList.Count - 1] = obj;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfTransition.cs b/iTechSharp/iTextSharp/text/pdf/PdfTransition.cs
new file mode 100644
index 0000000..993d0dd
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfTransition.cs
@@ -0,0 +1,257 @@
+using System;
+
+/*
+ * Copyright 2002 by Josselin PUJO.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ public class PdfTransition {
+ /**
+ * Out Vertical Split
+ */
+ public const int SPLITVOUT = 1;
+ /**
+ * Out Horizontal Split
+ */
+ public const int SPLITHOUT = 2;
+ /**
+ * In Vertical Split
+ */
+ public const int SPLITVIN = 3;
+ /**
+ * IN Horizontal Split
+ */
+ public const int SPLITHIN = 4;
+ /**
+ * Vertical Blinds
+ */
+ public const int BLINDV = 5;
+ /**
+ * Vertical Blinds
+ */
+ public const int BLINDH = 6;
+ /**
+ * Inward Box
+ */
+ public const int INBOX = 7;
+ /**
+ * Outward Box
+ */
+ public const int OUTBOX = 8;
+ /**
+ * Left-Right Wipe
+ */
+ public const int LRWIPE = 9;
+ /**
+ * Right-Left Wipe
+ */
+ public const int RLWIPE = 10;
+ /**
+ * Bottom-Top Wipe
+ */
+ public const int BTWIPE = 11;
+ /**
+ * Top-Bottom Wipe
+ */
+ public const int TBWIPE = 12;
+ /**
+ * Dissolve
+ */
+ public const int DISSOLVE = 13;
+ /**
+ * Left-Right Glitter
+ */
+ public const int LRGLITTER = 14;
+ /**
+ * Top-Bottom Glitter
+ */
+ public const int TBGLITTER = 15;
+ /**
+ * Diagonal Glitter
+ */
+ public const int DGLITTER = 16;
+
+ /**
+ * duration of the transition effect
+ */
+ protected int duration;
+ /**
+ * type of the transition effect
+ */
+ protected int type;
+
+ /**
+ * Constructs a Transition
.
+ *
+ */
+ public PdfTransition() : this(BLINDH) {}
+
+ /**
+ * Constructs a Transition
.
+ *
+ *@param type type of the transition effect
+ */
+ public PdfTransition(int type) : this(type,1) {}
+
+ /**
+ * Constructs a Transition
.
+ *
+ *@param type type of the transition effect
+ *@param duration duration of the transition effect
+ */
+ public PdfTransition(int type, int duration) {
+ this.duration = duration;
+ this.type = type;
+ }
+
+
+ public int Duration {
+ get {
+ return duration;
+ }
+ }
+
+
+ public int Type {
+ get {
+ return type;
+ }
+ }
+
+ public PdfDictionary TransitionDictionary {
+ get {
+ PdfDictionary trans = new PdfDictionary(PdfName.TRANS);
+ switch (type) {
+ case SPLITVOUT:
+ trans.Put(PdfName.S,PdfName.SPLIT);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DM,PdfName.V);
+ trans.Put(PdfName.M,PdfName.O);
+ break;
+ case SPLITHOUT:
+ trans.Put(PdfName.S,PdfName.SPLIT);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DM,PdfName.H);
+ trans.Put(PdfName.M,PdfName.O);
+ break;
+ case SPLITVIN:
+ trans.Put(PdfName.S,PdfName.SPLIT);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DM,PdfName.V);
+ trans.Put(PdfName.M,PdfName.I);
+ break;
+ case SPLITHIN:
+ trans.Put(PdfName.S,PdfName.SPLIT);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DM,PdfName.H);
+ trans.Put(PdfName.M,PdfName.I);
+ break;
+ case BLINDV:
+ trans.Put(PdfName.S,PdfName.BLINDS);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DM,PdfName.V);
+ break;
+ case BLINDH:
+ trans.Put(PdfName.S,PdfName.BLINDS);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DM,PdfName.H);
+ break;
+ case INBOX:
+ trans.Put(PdfName.S,PdfName.BOX);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.M,PdfName.I);
+ break;
+ case OUTBOX:
+ trans.Put(PdfName.S,PdfName.BOX);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.M,PdfName.O);
+ break;
+ case LRWIPE:
+ trans.Put(PdfName.S,PdfName.WIPE);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DI,new PdfNumber(0));
+ break;
+ case RLWIPE:
+ trans.Put(PdfName.S,PdfName.WIPE);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DI,new PdfNumber(180));
+ break;
+ case BTWIPE:
+ trans.Put(PdfName.S,PdfName.WIPE);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DI,new PdfNumber(90));
+ break;
+ case TBWIPE:
+ trans.Put(PdfName.S,PdfName.WIPE);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DI,new PdfNumber(270));
+ break;
+ case DISSOLVE:
+ trans.Put(PdfName.S,PdfName.DISSOLVE);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ break;
+ case LRGLITTER:
+ trans.Put(PdfName.S,PdfName.GLITTER);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DI,new PdfNumber(0));
+ break;
+ case TBGLITTER:
+ trans.Put(PdfName.S,PdfName.GLITTER);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DI,new PdfNumber(270));
+ break;
+ case DGLITTER:
+ trans.Put(PdfName.S,PdfName.GLITTER);
+ trans.Put(PdfName.D,new PdfNumber(duration));
+ trans.Put(PdfName.DI,new PdfNumber(315));
+ break;
+ }
+ return trans;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfTransparencyGroup.cs b/iTechSharp/iTextSharp/text/pdf/PdfTransparencyGroup.cs
new file mode 100644
index 0000000..214bd95
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfTransparencyGroup.cs
@@ -0,0 +1,90 @@
+using System;
+/*
+ * Copyright 2003 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** The transparency group dictionary.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PdfTransparencyGroup : PdfDictionary {
+
+ /**
+ * Constructs a transparencyGroup.
+ */
+ public PdfTransparencyGroup() {
+ Put(PdfName.S, PdfName.TRANSPARENCY);
+ }
+
+ /**
+ * Determining the initial backdrop against which its stack is composited.
+ * @param isolated
+ */
+ public bool Isolated {
+ set {
+ if (value)
+ Put(PdfName.I, PdfBoolean.PDFTRUE);
+ else
+ Remove(PdfName.I);
+ }
+ }
+
+ /**
+ * Determining whether the objects within the stack are composited with one another or only with the group's backdrop.
+ * @param knockout
+ */
+ public bool Knockout {
+ set {
+ if (value)
+ Put(PdfName.K, PdfBoolean.PDFTRUE);
+ else
+ Remove(PdfName.K);
+ }
+ }
+
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfWriter.cs b/iTechSharp/iTextSharp/text/pdf/PdfWriter.cs
new file mode 100644
index 0000000..dafd59d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfWriter.cs
@@ -0,0 +1,2973 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.util.collections;
+using System.util;
+using iTextSharp.text;
+using iTextSharp.text.pdf.events;
+using iTextSharp.text.pdf.interfaces;
+using iTextSharp.text.pdf.intern;
+using iTextSharp.text.pdf.collection;
+using iTextSharp.text.xml.xmp;
+using Org.BouncyCastle.X509;
+/*
+ * $Id: PdfWriter.cs,v 1.48 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * A DocWriter
class for PDF.
+ * PdfWriter
is added
+ * to a certain PdfDocument
, the PDF representation of every Element
+ * added to this Document will be written to the outputstream.PdfCrossReference
is an entry in the PDF Cross-Reference table.
+ */
+
+ internal class PdfCrossReference : IComparable {
+
+ // membervariables
+ private int type;
+
+ /** Byte offset in the PDF file. */
+ private int offset;
+
+ private int refnum;
+ /** generation of the object. */
+ private int generation;
+
+ // constructors
+ /**
+ * Constructs a cross-reference element for a PdfIndirectObject.
+ * @param refnum
+ * @param offset byte offset of the object
+ * @param generation generationnumber of the object
+ */
+
+ internal PdfCrossReference(int refnum, int offset, int generation) {
+ type = 0;
+ this.offset = offset;
+ this.refnum = refnum;
+ this.generation = generation;
+ }
+
+ /**
+ * Constructs a cross-reference element for a PdfIndirectObject.
+ * @param refnum
+ * @param offset byte offset of the object
+ */
+
+ internal PdfCrossReference(int refnum, int offset) {
+ type = 1;
+ this.offset = offset;
+ this.refnum = refnum;
+ this.generation = 0;
+ }
+
+ internal PdfCrossReference(int type, int refnum, int offset, int generation) {
+ this.type = type;
+ this.offset = offset;
+ this.refnum = refnum;
+ this.generation = generation;
+ }
+
+ internal int Refnum {
+ get {
+ return refnum;
+ }
+ }
+
+ /**
+ * Returns the PDF representation of this PdfObject
.
+ * @param os
+ * @throws IOException
+ */
+
+ public void ToPdf(Stream os) {
+ String s1 = offset.ToString().PadLeft(10, '0');
+ String s2 = generation.ToString().PadLeft(5, '0');
+ ByteBuffer buf = new ByteBuffer(40);
+ if (generation == 65535) {
+ buf.Append(s1).Append(' ').Append(s2).Append(" f \n");
+ }
+ else {
+ buf.Append(s1).Append(' ').Append(s2).Append(" n \n");
+ }
+ os.Write(buf.Buffer, 0, buf.Size);
+ }
+
+ /**
+ * Writes PDF syntax to the Stream
+ * @param midSize
+ * @param os
+ * @throws IOException
+ */
+ public void ToPdf(int midSize, Stream os) {
+ os.WriteByte((byte)type);
+ while (--midSize >= 0)
+ os.WriteByte((byte)((offset >> (8 * midSize)) & 0xff));
+ os.WriteByte((byte)((generation >> 8) & 0xff));
+ os.WriteByte((byte)(generation & 0xff));
+ }
+
+ /**
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int CompareTo(Object o) {
+ PdfCrossReference other = (PdfCrossReference)o;
+ return (refnum < other.refnum ? -1 : (refnum==other.refnum ? 0 : 1));
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public override bool Equals(Object obj) {
+ if (obj is PdfCrossReference) {
+ PdfCrossReference other = (PdfCrossReference)obj;
+ return (refnum == other.refnum);
+ }
+ else
+ return false;
+ }
+
+
+ public override int GetHashCode() {
+ return refnum;
+ }
+ }
+
+ // membervariables
+
+ private const int OBJSINSTREAM = 200;
+
+ /** array containing the cross-reference table of the normal objects. */
+ private k_Tree xrefs;
+ private int refnum;
+ /** the current byteposition in the body. */
+ private int position;
+ private PdfWriter writer;
+ private ByteBuffer index;
+ private ByteBuffer streamObjects;
+ private int currentObjNum;
+ private int numObj = 0;
+
+ // constructors
+
+ /**
+ * Constructs a new PdfBody
.
+ * @param writer
+ */
+ internal PdfBody(PdfWriter writer) {
+ xrefs = new k_Tree();
+ xrefs[new PdfCrossReference(0, 0, 65535)] = null;
+ position = writer.Os.Counter;
+ refnum = 1;
+ this.writer = writer;
+ }
+
+ // methods
+
+ internal int Refnum {
+ set {
+ this.refnum = value;
+ }
+ }
+
+ private PdfWriter.PdfBody.PdfCrossReference AddToObjStm(PdfObject obj, int nObj) {
+ if (numObj >= OBJSINSTREAM)
+ FlushObjStm();
+ if (index == null) {
+ index = new ByteBuffer();
+ streamObjects = new ByteBuffer();
+ currentObjNum = IndirectReferenceNumber;
+ numObj = 0;
+ }
+ int p = streamObjects.Size;
+ int idx = numObj++;
+ PdfEncryption enc = writer.crypto;
+ writer.crypto = null;
+ obj.ToPdf(writer, streamObjects);
+ writer.crypto = enc;
+ streamObjects.Append(' ');
+ index.Append(nObj).Append(' ').Append(p).Append(' ');
+ return new PdfWriter.PdfBody.PdfCrossReference(2, nObj, currentObjNum, idx);
+ }
+
+ internal void FlushObjStm() {
+ if (numObj == 0)
+ return;
+ int first = index.Size;
+ index.Append(streamObjects);
+ PdfStream stream = new PdfStream(index.ToByteArray());
+ stream.FlateCompress();
+ stream.Put(PdfName.TYPE, PdfName.OBJSTM);
+ stream.Put(PdfName.N, new PdfNumber(numObj));
+ stream.Put(PdfName.FIRST, new PdfNumber(first));
+ Add(stream, currentObjNum);
+ index = null;
+ streamObjects = null;
+ numObj = 0;
+ }
+
+ /**
+ * Adds a PdfObject
to the body.
+ * PdfIndirectObject
with a
+ * certain number, containing the given PdfObject
.
+ * It also adds a PdfCrossReference
for this object
+ * to an ArrayList
that will be used to build the
+ * Cross-reference Table.
+ *
+ * @param object a PdfObject
+ * @return a PdfIndirectObject
+ * @throws IOException
+ */
+
+ internal PdfIndirectObject Add(PdfObject objecta) {
+ return Add(objecta, IndirectReferenceNumber);
+ }
+
+ internal PdfIndirectObject Add(PdfObject objecta, bool inObjStm) {
+ return Add(objecta, IndirectReferenceNumber, inObjStm);
+ }
+
+ /**
+ * Gets a PdfIndirectReference for an object that will be created in the future.
+ * @return a PdfIndirectReference
+ */
+
+ internal PdfIndirectReference PdfIndirectReference {
+ get {
+ return new PdfIndirectReference(0, IndirectReferenceNumber);
+ }
+ }
+
+ internal int IndirectReferenceNumber {
+ get {
+ int n = refnum++;
+ xrefs[new PdfCrossReference(n, 0, 65536)] = null;
+ return n;
+ }
+ }
+
+ /**
+ * Adds a PdfObject
to the body given an already existing
+ * PdfIndirectReference.
+ * PdfIndirectObject
with the number given by
+ * ref
, containing the given PdfObject
.
+ * It also adds a PdfCrossReference
for this object
+ * to an ArrayList
that will be used to build the
+ * Cross-reference Table.
+ *
+ * @param object a PdfObject
+ * @param ref a PdfIndirectReference
+ * @return a PdfIndirectObject
+ * @throws IOException
+ */
+
+ internal PdfIndirectObject Add(PdfObject objecta, PdfIndirectReference refa) {
+ return Add(objecta, refa.Number);
+ }
+
+ internal PdfIndirectObject Add(PdfObject objecta, PdfIndirectReference refa, bool inObjStm) {
+ return Add(objecta, refa.Number, inObjStm);
+ }
+
+ internal PdfIndirectObject Add(PdfObject objecta, int refNumber) {
+ return Add(objecta, refNumber, true); // to false
+ }
+
+ internal PdfIndirectObject Add(PdfObject objecta, int refNumber, bool inObjStm) {
+ if (inObjStm && objecta.CanBeInObjStm() && writer.FullCompression) {
+ PdfCrossReference pxref = AddToObjStm(objecta, refNumber);
+ PdfIndirectObject indirect = new PdfIndirectObject(refNumber, objecta, writer);
+ xrefs.Remove(pxref);
+ xrefs[pxref] = null;
+ return indirect;
+ }
+ else {
+ PdfIndirectObject indirect = new PdfIndirectObject(refNumber, objecta, writer);
+ PdfCrossReference pxref = new PdfCrossReference(refNumber, position);
+ xrefs.Remove(pxref);
+ xrefs[pxref] = null;
+ indirect.WriteTo(writer.Os);
+ position = writer.Os.Counter;
+ return indirect;
+ }
+ }
+
+ /**
+ * Returns the offset of the Cross-Reference table.
+ *
+ * @return an offset
+ */
+
+ internal int Offset {
+ get {
+ return position;
+ }
+ }
+
+ /**
+ * Returns the total number of objects contained in the CrossReferenceTable of this Body
.
+ *
+ * @return a number of objects
+ */
+
+ internal int Size {
+ get {
+ k_Iterator it = xrefs.End.Clone();
+ it.Prev();
+ return Math.Max(((PdfCrossReference)((DictionaryEntry)it.Current).Key).Refnum + 1, refnum);
+ }
+ }
+
+ /**
+ * Returns the CrossReferenceTable of the Body
.
+ * @param os
+ * @param root
+ * @param info
+ * @param encryption
+ * @param fileID
+ * @param prevxref
+ * @throws IOException
+ */
+
+ internal void WriteCrossReferenceTable(Stream os, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) {
+ int refNumber = 0;
+ if (writer.FullCompression) {
+ FlushObjStm();
+ refNumber = IndirectReferenceNumber;
+ xrefs[new PdfCrossReference(refNumber, position)] = null;
+ }
+ PdfCrossReference entry = (PdfCrossReference)((DictionaryEntry)xrefs.Begin.Current).Key;
+ int first = entry.Refnum;
+ int len = 0;
+ ArrayList sections = new ArrayList();
+ for (k_Iterator i = xrefs.Begin.Clone(); i != xrefs.End; i.Next()) {
+ entry = (PdfCrossReference)((DictionaryEntry)i.Current).Key;
+ if (first + len == entry.Refnum)
+ ++len;
+ else {
+ sections.Add(first);
+ sections.Add(len);
+ first = entry.Refnum;
+ len = 1;
+ }
+ }
+ sections.Add(first);
+ sections.Add(len);
+ if (writer.FullCompression) {
+ int mid = 4;
+ uint mask = 0xff000000;
+ for (; mid > 1; --mid) {
+ if ((mask & position) != 0)
+ break;
+ mask >>= 8;
+ }
+ ByteBuffer buf = new ByteBuffer();
+
+ for (k_Iterator i = xrefs.Begin.Clone(); i != xrefs.End; i.Next()) {
+ entry = (PdfCrossReference)((DictionaryEntry)i.Current).Key;
+ entry.ToPdf(mid, buf);
+ }
+ PdfStream xr = new PdfStream(buf.ToByteArray());
+ buf = null;
+ xr.FlateCompress();
+ xr.Put(PdfName.SIZE, new PdfNumber(Size));
+ xr.Put(PdfName.ROOT, root);
+ if (info != null) {
+ xr.Put(PdfName.INFO, info);
+ }
+ if (encryption != null)
+ xr.Put(PdfName.ENCRYPT, encryption);
+ if (fileID != null)
+ xr.Put(PdfName.ID, fileID);
+ xr.Put(PdfName.W, new PdfArray(new int[]{1, mid, 2}));
+ xr.Put(PdfName.TYPE, PdfName.XREF);
+ PdfArray idx = new PdfArray();
+ for (int k = 0; k < sections.Count; ++k)
+ idx.Add(new PdfNumber((int)sections[k]));
+ xr.Put(PdfName.INDEX, idx);
+ if (prevxref > 0)
+ xr.Put(PdfName.PREV, new PdfNumber(prevxref));
+ PdfEncryption enc = writer.crypto;
+ writer.crypto = null;
+ PdfIndirectObject indirect = new PdfIndirectObject(refNumber, xr, writer);
+ indirect.WriteTo(writer.Os);
+ writer.crypto = enc;
+ }
+ else {
+ byte[] tmp = GetISOBytes("xref\n");
+ os.Write(tmp, 0, tmp.Length);
+ k_Iterator i = xrefs.Begin.Clone();
+ for (int k = 0; k < sections.Count; k += 2) {
+ first = (int)sections[k];
+ len = (int)sections[k + 1];
+ tmp = GetISOBytes(first.ToString());
+ os.Write(tmp, 0, tmp.Length);
+ os.WriteByte((byte)' ');
+ tmp = GetISOBytes(len.ToString());
+ os.Write(tmp, 0, tmp.Length);
+ os.WriteByte((byte)'\n');
+ while (len-- > 0) {
+ entry = (PdfCrossReference)((DictionaryEntry)i.Current).Key;
+ entry.ToPdf(os);
+ i.Next();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * PdfTrailer
is the PDF Trailer object.
+ * PdfCrossReferenceTable
+ * @param offset offset of the PdfCrossReferenceTable
+ * @param root an indirect reference to the root of the PDF document
+ * @param info an indirect reference to the info object of the PDF document
+ * @param encryption
+ * @param fileID
+ * @param prevxref
+ */
+
+ internal PdfTrailer(int size, int offset, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) {
+ this.offset = offset;
+ Put(PdfName.SIZE, new PdfNumber(size));
+ Put(PdfName.ROOT, root);
+ if (info != null) {
+ Put(PdfName.INFO, info);
+ }
+ if (encryption != null)
+ Put(PdfName.ENCRYPT, encryption);
+ if (fileID != null)
+ Put(PdfName.ID, fileID);
+ if (prevxref > 0)
+ Put(PdfName.PREV, new PdfNumber(prevxref));
+ }
+
+ /**
+ * Returns the PDF representation of this PdfObject
.
+ * @param writer
+ * @param os
+ * @throws IOException
+ */
+ public override void ToPdf(PdfWriter writer, Stream os) {
+ byte[] tmp = GetISOBytes("trailer\n");
+ os.Write(tmp, 0, tmp.Length);
+ base.ToPdf(null, os);
+ tmp = GetISOBytes("\nstartxref\n");
+ os.Write(tmp, 0, tmp.Length);
+ tmp = GetISOBytes(offset.ToString());
+ os.Write(tmp, 0, tmp.Length);
+ tmp = GetISOBytes("\n%%EOF\n");
+ os.Write(tmp, 0, tmp.Length);
+ }
+ }
+
+ // ESSENTIALS
+
+ // Construct a PdfWriter instance
+
+ /**
+ * Constructs a PdfWriter
.
+ */
+ protected PdfWriter() {
+ root = new PdfPages(this);
+ }
+
+ /**
+ * Constructs a PdfWriter
.
+ * getInstance(Document document, Stream os)
.
+ *
+ * @param document The PdfDocument
that has to be written
+ * @param os The Stream
the writer has to write to.
+ */
+
+ protected PdfWriter(PdfDocument document, Stream os) : base(document, os) {
+ root = new PdfPages(this);
+ pdf = document;
+ directContent = new PdfContentByte(this);
+ directContentUnder = new PdfContentByte(this);
+ }
+
+ // get an instance of the PdfWriter
+
+ /**
+ * Use this method to get an instance of the PdfWriter
.
+ *
+ * @param document The Document
that has to be written
+ * @param os The Stream
the writer has to write to.
+ * @return a new PdfWriter
+ *
+ * @throws DocumentException on error
+ */
+
+ public static PdfWriter GetInstance(Document document, Stream os)
+ {
+ PdfDocument pdf = new PdfDocument();
+ document.AddDocListener(pdf);
+ PdfWriter writer = new PdfWriter(pdf, os);
+ pdf.AddWriter(writer);
+ return writer;
+ }
+
+ /**
+ * Use this method to get an instance of the PdfWriter
.
+ *
+ * @return a new PdfWriter
+ * @param document The Document
that has to be written
+ * @param os The Stream
the writer has to write to.
+ * @param listener A DocListener
to pass to the PdfDocument.
+ * @throws DocumentException on error
+ */
+
+ public static PdfWriter GetInstance(Document document, Stream os, IDocListener listener)
+ {
+ PdfDocument pdf = new PdfDocument();
+ pdf.AddDocListener(listener);
+ document.AddDocListener(pdf);
+ PdfWriter writer = new PdfWriter(pdf, os);
+ pdf.AddWriter(writer);
+ return writer;
+ }
+
+ // the PdfDocument instance
+ /** the pdfdocument object. */
+ protected internal PdfDocument pdf;
+
+ /**
+ * Gets the PdfDocument
associated with this writer.
+ * @return the PdfDocument
+ */
+ internal PdfDocument PdfDocument {
+ get {
+ return pdf;
+ }
+ }
+
+ /**
+ * Use this method to get the info dictionary if you want to
+ * change it directly (add keys and values to the info dictionary).
+ * @return the info dictionary
+ */
+ public PdfDictionary Info {
+ get {
+ return ((PdfDocument)document).Info;
+ }
+ }
+
+ /**
+ * Use this method to get the current vertical page position.
+ * @param ensureNewLine Tells whether a new line shall be enforced. This may cause side effects
+ * for elements that do not terminate the lines they've started because those lines will get
+ * terminated.
+ * @return The current vertical page position.
+ */
+ public float GetVerticalPosition(bool ensureNewLine) {
+ return pdf.GetVerticalPosition(ensureNewLine);
+ }
+
+ // the PdfDirectContentByte instances
+
+ /*
+ * You should see Direct Content as a canvas on which you can draw
+ * graphics and text. One canvas goes on top of the page (getDirectContent),
+ * the other goes underneath (getDirectContentUnder).
+ * You can always the same object throughout your document,
+ * even if you have moved to a new page. Whatever you add on
+ * the canvas will be displayed on top or under the current page.
+ */
+
+ /** The direct content in this document. */
+ protected PdfContentByte directContent;
+
+ /** The direct content under in this document. */
+ protected PdfContentByte directContentUnder;
+
+ /**
+ * Use this method to get the direct content for this document.
+ * There is only one direct content, multiple calls to this method
+ * will allways retrieve the same object.
+ * @return the direct content
+ */
+ public virtual PdfContentByte DirectContent {
+ get {
+ if (!open)
+ throw new Exception("The document is not open.");
+ return directContent;
+ }
+ }
+
+ /**
+ * Use this method to get the direct content under for this document.
+ * There is only one direct content, multiple calls to this method
+ * will allways retrieve the same object.
+ * @return the direct content
+ */
+ public virtual PdfContentByte DirectContentUnder {
+ get {
+ if (!open)
+ throw new Exception("The document is not open.");
+ return directContentUnder;
+ }
+ }
+
+ /**
+ * Resets all the direct contents to empty.
+ * This happens when a new page is started.
+ */
+ internal void ResetContent() {
+ directContent.Reset();
+ directContentUnder.Reset();
+ }
+
+ // PDF body
+
+ /*
+ * A PDF file has 4 parts: a header, a body, a cross-reference table, and a trailer.
+ * The body contains all the PDF objects that make up the PDF document.
+ * Each element gets a reference (a set of numbers) and the byte position of
+ * every object is stored in the cross-reference table.
+ * Use these methods only if you know what you're doing.
+ */
+
+ /** body of the PDF document */
+ protected internal PdfBody body;
+
+ /**
+ * Adds the local destinations to the body of the document.
+ * @param dest the Hashtable
containing the destinations
+ * @throws IOException on error
+ */
+ internal void AddLocalDestinations(k_Tree dest) {
+ foreach (String name in dest.Keys) {
+ Object[] obj = (Object[])dest[name];
+ PdfDestination destination = (PdfDestination)obj[2];
+ if (destination == null)
+ throw new Exception("The name '" + name + "' has no local destination.");
+ if (obj[1] == null)
+ obj[1] = PdfIndirectReference;
+ AddToBody(destination, (PdfIndirectReference)obj[1]);
+ }
+ }
+
+ /**
+ * Adds an object to the PDF body.
+ * @param object
+ * @return a PdfIndirectObject
+ * @throws IOException
+ */
+ public PdfIndirectObject AddToBody(PdfObject objecta) {
+ PdfIndirectObject iobj = body.Add(objecta);
+ return iobj;
+ }
+
+ /**
+ * Adds an object to the PDF body.
+ * @param object
+ * @param inObjStm
+ * @return a PdfIndirectObject
+ * @throws IOException
+ */
+ public PdfIndirectObject AddToBody(PdfObject objecta, bool inObjStm) {
+ PdfIndirectObject iobj = body.Add(objecta, inObjStm);
+ return iobj;
+ }
+
+ /**
+ * Adds an object to the PDF body.
+ * @param object
+ * @param ref
+ * @return a PdfIndirectObject
+ * @throws IOException
+ */
+ public PdfIndirectObject AddToBody(PdfObject objecta, PdfIndirectReference refa) {
+ PdfIndirectObject iobj = body.Add(objecta, refa);
+ return iobj;
+ }
+
+ /**
+ * Adds an object to the PDF body.
+ * @param object
+ * @param ref
+ * @param inObjStm
+ * @return a PdfIndirectObject
+ * @throws IOException
+ */
+ public PdfIndirectObject AddToBody(PdfObject objecta, PdfIndirectReference refa, bool inObjStm) {
+ PdfIndirectObject iobj = body.Add(objecta, refa, inObjStm);
+ return iobj;
+ }
+
+ /**
+ * Adds an object to the PDF body.
+ * @param object
+ * @param refNumber
+ * @return a PdfIndirectObject
+ * @throws IOException
+ */
+ public PdfIndirectObject AddToBody(PdfObject objecta, int refNumber) {
+ PdfIndirectObject iobj = body.Add(objecta, refNumber);
+ return iobj;
+ }
+
+ /**
+ * Adds an object to the PDF body.
+ * @param object
+ * @param refNumber
+ * @param inObjStm
+ * @return a PdfIndirectObject
+ * @throws IOException
+ */
+ public PdfIndirectObject AddToBody(PdfObject objecta, int refNumber, bool inObjStm) {
+ PdfIndirectObject iobj = body.Add(objecta, refNumber, inObjStm);
+ return iobj;
+ }
+
+ /**
+ * Gets a PdfIndirectReference
for an object that
+ * will be created in the future.
+ * @return the PdfIndirectReference
+ */
+ public PdfIndirectReference PdfIndirectReference {
+ get {
+ return body.PdfIndirectReference;
+ }
+ }
+
+ internal int IndirectReferenceNumber {
+ get {
+ return body.IndirectReferenceNumber;
+ }
+ }
+
+ /**
+ * Returns the outputStreamCounter.
+ * @return the outputStreamCounter
+ */
+ internal OutputStreamCounter Os {
+ get {
+ return os;
+ }
+ }
+
+ // PDF Catalog
+
+ /*
+ * The Catalog is also called the root object of the document.
+ * Whereas the Cross-Reference maps the objects number with the
+ * byte offset so that the viewer can find the objects, the
+ * Catalog tells the viewer the numbers of the objects needed
+ * to render the document.
+ */
+
+ protected virtual PdfDictionary GetCatalog(PdfIndirectReference rootObj) {
+ PdfDictionary catalog = pdf.GetCatalog(rootObj);
+ // [F12] tagged PDF
+ if (tagged) {
+ this.StructureTreeRoot.BuildTree();
+ catalog.Put(PdfName.STRUCTTREEROOT, structureTreeRoot.Reference);
+ PdfDictionary mi = new PdfDictionary();
+ mi.Put(PdfName.MARKED, PdfBoolean.PDFTRUE);
+ if (userProperties)
+ mi.Put(PdfName.USERPROPERTIES, PdfBoolean.PDFTRUE);
+ catalog.Put(PdfName.MARKINFO, mi);
+ }
+ // [F13] OCG
+ if (documentOCG.Count != 0) {
+ FillOCProperties(false);
+ catalog.Put(PdfName.OCPROPERTIES, vOCProperties);
+ }
+ return catalog;
+ }
+
+ /** Holds value of property extraCatalog. */
+ protected internal PdfDictionary extraCatalog;
+
+ /**
+ * Sets extra keys to the catalog.
+ * @return the catalog to change
+ */
+ public PdfDictionary ExtraCatalog {
+ get {
+ if (extraCatalog == null)
+ extraCatalog = new PdfDictionary();
+ return this.extraCatalog;
+ }
+ }
+
+ // PdfPages
+
+ /*
+ * The page root keeps the complete page tree of the document.
+ * There's an entry in the Catalog that refers to the root
+ * of the page tree, the page tree contains the references
+ * to pages and other page trees.
+ */
+
+ /** The root of the page tree. */
+ protected PdfPages root;
+ /** The PdfIndirectReference to the pages. */
+ protected ArrayList pageReferences = new ArrayList();
+ /** The current page number. */
+ protected int currentPageNumber = 1;
+
+ /**
+ * Use this method to make sure the page tree has a lineair structure
+ * (every leave is attached directly to the root).
+ * Use this method to allow page reordering with method reorderPages.
+ */
+ public void SetLinearPageMode() {
+ root.SetLinearMode(null);
+ }
+
+ /**
+ * Use this method to reorder the pages in the document.
+ * A null
argument value only returns the number of pages to process.
+ * It is advisable to issue a Document.newPage()
before using this method.
+ * @return the total number of pages
+ * @param order an array with the new page sequence. It must have the
+ * same size as the number of pages.
+ * @throws DocumentException if all the pages are not present in the array
+ */
+ public int ReorderPages(int[] order) {
+ return root.ReorderPages(order);
+ }
+
+ /**
+ * Use this method to get a reference to a page existing or not.
+ * If the page does not exist yet the reference will be created
+ * in advance. If on closing the document, a page number greater
+ * than the total number of pages was requested, an exception
+ * is thrown.
+ * @param page the page number. The first page is 1
+ * @return the reference to the page
+ */
+ public virtual PdfIndirectReference GetPageReference(int page) {
+ --page;
+ if (page < 0)
+ throw new ArgumentOutOfRangeException("The page numbers start at 1.");
+ PdfIndirectReference refa;
+ if (page < pageReferences.Count) {
+ refa = (PdfIndirectReference)pageReferences[page];
+ if (refa == null) {
+ refa = body.PdfIndirectReference;
+ pageReferences[page] = refa;
+ }
+ }
+ else {
+ int empty = page - pageReferences.Count;
+ for (int k = 0; k < empty; ++k)
+ pageReferences.Add(null);
+ refa = body.PdfIndirectReference;
+ pageReferences.Add(refa);
+ }
+ return refa;
+ }
+
+ /**
+ * Gets the pagenumber of this document.
+ * This number can be different from the real pagenumber,
+ * if you have (re)set the page number previously.
+ * @return a page number
+ */
+ public int PageNumber {
+ get {
+ return pdf.PageNumber;
+ }
+ }
+
+ internal virtual PdfIndirectReference CurrentPage {
+ get {
+ return GetPageReference(currentPageNumber);
+ }
+ }
+
+ public virtual int CurrentPageNumber {
+ get {
+ return currentPageNumber;
+ }
+ }
+
+ /**
+ * Adds some PdfContents
to this Writer.
+ * PdfIndirectReference
+ * @param page the PdfPage
to add
+ * @param contents the PdfContents
of the page
+ * @throws PdfException on error
+ */
+ internal virtual PdfIndirectReference Add(PdfPage page, PdfContents contents) {
+ if (!open) {
+ throw new PdfException("The document isn't open.");
+ }
+ PdfIndirectObject objecta;
+ objecta = AddToBody(contents);
+ page.Add(objecta.IndirectReference);
+ if (group != null) {
+ page.Put(PdfName.GROUP, group);
+ group = null;
+ }
+ else if (rgbTransparencyBlending) {
+ PdfDictionary pp = new PdfDictionary();
+ pp.Put(PdfName.TYPE, PdfName.GROUP);
+ pp.Put(PdfName.S, PdfName.TRANSPARENCY);
+ pp.Put(PdfName.CS, PdfName.DEVICERGB);
+ page.Put(PdfName.GROUP, pp);
+ }
+ root.AddPage(page);
+ currentPageNumber++;
+ return null;
+ }
+
+ // page events
+
+ /*
+ * Page events are specific for iText, not for PDF.
+ * Upon specific events (for instance when a page starts
+ * or ends), the corresponing method in the page event
+ * implementation that is added to the writer is invoked.
+ */
+
+ /** The PdfPageEvent
for this document. */
+ private IPdfPageEvent pageEvent;
+
+ /**
+ * Gets the PdfPageEvent
for this document or null
+ * if none is set.
+ * @return the PdfPageEvent
for this document or null
+ * if none is set
+ */
+ public IPdfPageEvent PageEvent {
+ get {
+ return pageEvent;
+ }
+ set {
+ if (value == null) this.pageEvent = null;
+ else if (this.pageEvent == null) this.pageEvent = value;
+ else if (this.pageEvent is PdfPageEventForwarder) ((PdfPageEventForwarder)this.pageEvent).AddPageEvent(value);
+ else {
+ PdfPageEventForwarder forward = new PdfPageEventForwarder();
+ forward.AddPageEvent(this.pageEvent);
+ forward.AddPageEvent(value);
+ this.pageEvent = forward;
+ }
+ }
+ }
+
+ // Open en Close method + method that create the PDF
+
+ /** A number refering to the previous Cross-Reference Table. */
+ protected int prevxref = 0;
+
+ /**
+ * Signals that the Document
has been opened and that
+ * Elements
can be added.
+ * Document
was closed and that no other
+ * Elements
will be added.
+ * null
to remove any
+ */
+ public ArrayList Outlines {
+ set {
+ newBookmarks = value;
+ }
+ }
+
+ protected internal void WriteOutlines(PdfDictionary catalog, bool namedAsNames) {
+ if (newBookmarks == null || newBookmarks.Count == 0)
+ return;
+ PdfDictionary top = new PdfDictionary();
+ PdfIndirectReference topRef = this.PdfIndirectReference;
+ Object[] kids = SimpleBookmark.IterateOutlines(this, topRef, newBookmarks, namedAsNames);
+ top.Put(PdfName.FIRST, (PdfIndirectReference)kids[0]);
+ top.Put(PdfName.LAST, (PdfIndirectReference)kids[1]);
+ top.Put(PdfName.COUNT, new PdfNumber((int)kids[2]));
+ AddToBody(top, topRef);
+ catalog.Put(PdfName.OUTLINES, topRef);
+ }
+
+ // [C2] PdfVersion interface
+ /** possible PDF version (header) */
+ public const char VERSION_1_2 = '2';
+ /** possible PDF version (header) */
+ public const char VERSION_1_3 = '3';
+ /** possible PDF version (header) */
+ public const char VERSION_1_4 = '4';
+ /** possible PDF version (header) */
+ public const char VERSION_1_5 = '5';
+ /** possible PDF version (header) */
+ public const char VERSION_1_6 = '6';
+ /** possible PDF version (header) */
+ public const char VERSION_1_7 = '7';
+
+ /** possible PDF version (catalog) */
+ public static readonly PdfName PDF_VERSION_1_2 = new PdfName("1.2");
+ /** possible PDF version (catalog) */
+ public static readonly PdfName PDF_VERSION_1_3 = new PdfName("1.3");
+ /** possible PDF version (catalog) */
+ public static readonly PdfName PDF_VERSION_1_4 = new PdfName("1.4");
+ /** possible PDF version (catalog) */
+ public static readonly PdfName PDF_VERSION_1_5 = new PdfName("1.5");
+ /** possible PDF version (catalog) */
+ public static readonly PdfName PDF_VERSION_1_6 = new PdfName("1.6");
+ /** possible PDF version (catalog) */
+ public static readonly PdfName PDF_VERSION_1_7 = new PdfName("1.7");
+
+ /** Stores the version information for the header and the catalog. */
+ protected PdfVersionImp pdf_version = new PdfVersionImp();
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(char)
+ */
+ public virtual char PdfVersion {
+ set {
+ pdf_version.PdfVersion = value;
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfVersion#setAtLeastPdfVersion(char)
+ */
+ public void SetAtLeastPdfVersion(char version) {
+ pdf_version.SetAtLeastPdfVersion(version);
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(com.lowagie.text.pdf.PdfName)
+ */
+ public void SetPdfVersion(PdfName version) {
+ pdf_version.SetPdfVersion(version);
+ }
+
+ /**
+ * Returns the version information.
+ */
+ internal PdfVersionImp GetPdfVersion() {
+ return pdf_version;
+ }
+
+ // [C3] PdfViewerPreferences interface
+
+ // page layout (section 13.1.1 of "iText in Action")
+
+ /** A viewer preference */
+ public const int PageLayoutSinglePage = 1;
+ /** A viewer preference */
+ public const int PageLayoutOneColumn = 2;
+ /** A viewer preference */
+ public const int PageLayoutTwoColumnLeft = 4;
+ /** A viewer preference */
+ public const int PageLayoutTwoColumnRight = 8;
+ /** A viewer preference */
+ public const int PageLayoutTwoPageLeft = 16;
+ /** A viewer preference */
+ public const int PageLayoutTwoPageRight = 32;
+
+ // page mode (section 13.1.2 of "iText in Action")
+
+ /** A viewer preference */
+ public const int PageModeUseNone = 64;
+ /** A viewer preference */
+ public const int PageModeUseOutlines = 128;
+ /** A viewer preference */
+ public const int PageModeUseThumbs = 256;
+ /** A viewer preference */
+ public const int PageModeFullScreen = 512;
+ /** A viewer preference */
+ public const int PageModeUseOC = 1024;
+ /** A viewer preference */
+ public const int PageModeUseAttachments = 2048;
+
+ // values for setting viewer preferences in iText versions older than 2.x
+
+ /** A viewer preference */
+ public const int HideToolbar = 1 << 12;
+ /** A viewer preference */
+ public const int HideMenubar = 1 << 13;
+ /** A viewer preference */
+ public const int HideWindowUI = 1 << 14;
+ /** A viewer preference */
+ public const int FitWindow = 1 << 15;
+ /** A viewer preference */
+ public const int CenterWindow = 1 << 16;
+ /** A viewer preference */
+ public const int DisplayDocTitle = 1 << 17;
+
+ /** A viewer preference */
+ public const int NonFullScreenPageModeUseNone = 1 << 18;
+ /** A viewer preference */
+ public const int NonFullScreenPageModeUseOutlines = 1 << 19;
+ /** A viewer preference */
+ public const int NonFullScreenPageModeUseThumbs = 1 << 20;
+ /** A viewer preference */
+ public const int NonFullScreenPageModeUseOC = 1 << 21;
+
+ /** A viewer preference */
+ public const int DirectionL2R = 1 << 22;
+ /** A viewer preference */
+ public const int DirectionR2L = 1 << 23;
+
+ /** A viewer preference */
+ public const int PrintScalingNone = 1 << 24;
+
+ /**
+ * Sets the viewer preferences as the sum of several constants.
+ * @param preferences the viewer preferences
+ * @see PdfViewerPreferences#setViewerPreferences
+ */
+ public virtual int ViewerPreferences {
+ set {
+ pdf.ViewerPreferences = value;
+ }
+ }
+
+ /** Adds a viewer preference
+ * @param preferences the viewer preferences
+ * @see PdfViewerPreferences#addViewerPreference
+ */
+ public virtual void AddViewerPreference(PdfName key, PdfObject value) {
+ pdf.AddViewerPreference(key, value);
+ }
+
+ // [C4] Page labels
+
+ /**
+ * Use this method to add page labels
+ * @param pageLabels the page labels
+ */
+ public virtual PdfPageLabels PageLabels {
+ set {
+ pdf.PageLabels = value;
+ }
+ }
+
+ // [C5] named objects: named destinations, javascript, embedded files
+
+ /**
+ * Use this method to add a JavaScript action at the document level.
+ * When the document opens, all this JavaScript runs.
+ * @param js The JavaScript action
+ */
+ public virtual void AddJavaScript(PdfAction js) {
+ pdf.AddJavaScript(js);
+ }
+
+ /** Adds a JavaScript action at the document level. When the document
+ * opens all this JavaScript runs.
+ * @param code the JavaScript code
+ * @param unicode select JavaScript unicode. Note that the internal
+ * Acrobat JavaScript engine does not support unicode,
+ * so this may or may not work for you
+ */
+ public virtual void AddJavaScript(String code, bool unicode) {
+ AddJavaScript(PdfAction.JavaScript(code, this, unicode));
+ }
+
+ /** Adds a JavaScript action at the document level. When the document
+ * opens all this JavaScript runs.
+ * @param code the JavaScript code
+ */
+ public virtual void AddJavaScript(String code) {
+ AddJavaScript(code, false);
+ }
+
+ /**
+ * Use this method to add a JavaScript action at the document level.
+ * When the document opens, all this JavaScript runs.
+ * @param name The name of the JS Action in the name tree
+ * @param js The JavaScript action
+ */
+ public void AddJavaScript(String name, PdfAction js) {
+ pdf.AddJavaScript(name, js);
+ }
+
+ /**
+ * Use this method to add a JavaScript action at the document level.
+ * When the document opens, all this JavaScript runs.
+ * @param name The name of the JS Action in the name tree
+ * @param code the JavaScript code
+ * @param unicode select JavaScript unicode. Note that the internal
+ * Acrobat JavaScript engine does not support unicode,
+ * so this may or may not work for you
+ */
+ public void AddJavaScript(String name, String code, bool unicode) {
+ AddJavaScript(name, PdfAction.JavaScript(code, this, unicode));
+ }
+
+ /**
+ * Use this method to adds a JavaScript action at the document level.
+ * When the document opens, all this JavaScript runs.
+ * @param name The name of the JS Action in the name tree
+ * @param code the JavaScript code
+ */
+ public void AddJavaScript(String name, String code) {
+ AddJavaScript(name, code, false);
+ }
+
+ /** Adds a file attachment at the document level.
+ * @param description the file description
+ * @param fileStore an array with the file. If it's null
+ * the file will be read from the disk
+ * @param file the path to the file. It will only be used if
+ * fileStore
is not null
+ * @param fileDisplay the actual file name stored in the pdf
+ * @throws IOException on error
+ */
+ public virtual void AddFileAttachment(String description, byte[] fileStore, String file, String fileDisplay) {
+ AddFileAttachment(description, PdfFileSpecification.FileEmbedded(this, file, fileDisplay, fileStore));
+ }
+
+ /** Adds a file attachment at the document level.
+ * @param description the file description
+ * @param fs the file specification
+ */
+ public virtual void AddFileAttachment(String description, PdfFileSpecification fs) {
+ pdf.AddFileAttachment(description, fs);
+ }
+
+ /** Adds a file attachment at the document level.
+ * @param fs the file specification
+ */
+ public void AddFileAttachment(PdfFileSpecification fs) {
+ pdf.AddFileAttachment(null, fs);
+ }
+
+ // [C6] Actions (open and additional)
+
+ /** action value */
+ public static PdfName DOCUMENT_CLOSE = PdfName.WC;
+ /** action value */
+ public static PdfName WILL_SAVE = PdfName.WS;
+ /** action value */
+ public static PdfName DID_SAVE = PdfName.DS;
+ /** action value */
+ public static PdfName WILL_PRINT = PdfName.WP;
+ /** action value */
+ public static PdfName DID_PRINT = PdfName.DP;
+
+ /** When the document opens it will jump to the destination with
+ * this name.
+ * @param name the name of the destination to jump to
+ */
+ public virtual void SetOpenAction(String name) {
+ pdf.SetOpenAction(name);
+ }
+
+ /** When the document opens this action
will be
+ * invoked.
+ * @param action the action to be invoked
+ */
+ public virtual void SetOpenAction(PdfAction action) {
+ pdf.SetOpenAction(action);
+ }
+
+ /** Additional-actions defining the actions to be taken in
+ * response to various trigger events affecting the document
+ * as a whole. The actions types allowed are: DOCUMENT_CLOSE
,
+ * WILL_SAVE
, DID_SAVE
, WILL_PRINT
+ * and DID_PRINT
.
+ *
+ * @param actionType the action type
+ * @param action the action to execute in response to the trigger
+ * @throws PdfException on invalid action type
+ */
+ public virtual void SetAdditionalAction(PdfName actionType, PdfAction action) {
+ if (!(actionType.Equals(DOCUMENT_CLOSE) ||
+ actionType.Equals(WILL_SAVE) ||
+ actionType.Equals(DID_SAVE) ||
+ actionType.Equals(WILL_PRINT) ||
+ actionType.Equals(DID_PRINT))) {
+ throw new PdfException("Invalid additional action type: " + actionType.ToString());
+ }
+ pdf.AddAdditionalAction(actionType, action);
+ }
+
+ // [C7] portable collections
+ /**
+ * Sets the Collection dictionary.
+ * @param collection a dictionary of type PdfCollection
+ */
+ public PdfCollection Collection {
+ set {
+ SetAtLeastPdfVersion(VERSION_1_7);
+ pdf.Collection = value;
+ }
+ }
+
+ // [C8] AcroForm
+
+ /** signature value */
+ public const int SIGNATURE_EXISTS = 1;
+ /** signature value */
+ public const int SIGNATURE_APPEND_ONLY = 2;
+
+ /** Gets the AcroForm object.
+ * @return the PdfAcroForm
+ */
+
+ public PdfAcroForm AcroForm {
+ get {
+ return pdf.AcroForm;
+ }
+ }
+
+ /** Adds a PdfAnnotation
or a PdfFormField
+ * to the document. Only the top parent of a PdfFormField
+ * needs to be added.
+ * @param annot the PdfAnnotation
or the PdfFormField
to add
+ */
+ public virtual void AddAnnotation(PdfAnnotation annot) {
+ pdf.AddAnnotation(annot);
+ }
+
+ internal virtual void AddAnnotation(PdfAnnotation annot, int page) {
+ AddAnnotation(annot);
+ }
+
+ /** Adds the PdfAnnotation
to the calculation order
+ * array.
+ * @param annot the PdfAnnotation
to be added
+ */
+ public virtual void AddCalculationOrder(PdfFormField annot) {
+ pdf.AddCalculationOrder(annot);
+ }
+
+ /** Set the signature flags.
+ * @param f the flags. This flags are ORed with current ones
+ */
+ public virtual int SigFlags {
+ set {
+ pdf.SigFlags = value;
+ }
+ }
+
+ // [C9] Metadata
+
+ /** XMP Metadata for the document. */
+ protected byte[] xmpMetadata = null;
+
+ /**
+ * Sets XMP Metadata.
+ * @param xmpMetadata The xmpMetadata to set.
+ */
+ public byte[] XmpMetadata {
+ set {
+ this.xmpMetadata = value;
+ }
+ get {
+ return this.xmpMetadata;
+ }
+ }
+
+ /**
+ * Use this method to set the XMP Metadata for each page.
+ * @param xmpMetadata The xmpMetadata to set.
+ */
+ public byte[] PageXmpMetadata {
+ set {
+ pdf.XmpMetadata = value;
+ }
+ }
+
+ /**
+ * Creates XMP Metadata based on the metadata in the PdfDocument.
+ */
+ public void CreateXmpMetadata() {
+ XmpMetadata = CreateXmpMetadataBytes();
+ }
+
+ /**
+ * @return an XmpMetadata byte array
+ */
+ private byte[] CreateXmpMetadataBytes() {
+ MemoryStream baos = new MemoryStream();
+ try {
+ XmpWriter xmp = new XmpWriter(baos, pdf.Info, pdfxConformance.PDFXConformance);
+ xmp.Close();
+ }
+ catch(IOException) {
+ }
+ return baos.ToArray();
+ }
+
+ // [C10] PDFX Conformance
+
+ /** PDF/X level */
+ public const int PDFXNONE = 0;
+ /** PDF/X level */
+ public const int PDFX1A2001 = 1;
+ /** PDF/X level */
+ public const int PDFX32002 = 2;
+ /** PDFA-1A level. */
+ public const int PDFA1A = 3;
+ /** PDFA-1B level. */
+ public const int PDFA1B = 4;
+
+ /** Stores the PDF/X level. */
+ private PdfXConformanceImp pdfxConformance = new PdfXConformanceImp();
+
+ /**
+ * Sets the PDFX conformance level. Allowed values are PDFX1A2001 and PDFX32002. It
+ * must be called before opening the document.
+ * @param pdfxConformance the conformance level
+ */
+ public int PDFXConformance {
+ set {
+ if (pdfxConformance.PDFXConformance == value)
+ return;
+ if (pdf.IsOpen())
+ throw new PdfXConformanceException("PDFX conformance can only be set before opening the document.");
+ if (crypto != null)
+ throw new PdfXConformanceException("A PDFX conforming document cannot be encrypted.");
+ if (value == PDFA1A || value == PDFA1B)
+ PdfVersion = VERSION_1_4;
+ else if (value != PDFXNONE)
+ PdfVersion = VERSION_1_3;
+ pdfxConformance.PDFXConformance = value;
+ }
+ get {
+ return pdfxConformance.PDFXConformance;
+ }
+ }
+
+ /** @see com.lowagie.text.pdf.interfaces.PdfXConformance#isPdfX() */
+ public bool IsPdfX() {
+ return pdfxConformance.IsPdfX();
+ }
+
+ // [C11] Output intents
+
+ /**
+ * Sets the values of the output intent dictionary. Null values are allowed to
+ * suppress any key.
+ * @param outputConditionIdentifier a value
+ * @param outputCondition a value
+ * @param registryName a value
+ * @param info a value
+ * @param destOutputProfile a value
+ * @throws IOException on error
+ */
+ public void SetOutputIntents(String outputConditionIdentifier, String outputCondition, String registryName, String info, byte[] destOutputProfile) {
+ PdfDictionary outa = ExtraCatalog; //force the creation
+ outa = new PdfDictionary(PdfName.OUTPUTINTENT);
+ if (outputCondition != null)
+ outa.Put(PdfName.OUTPUTCONDITION, new PdfString(outputCondition, PdfObject.TEXT_UNICODE));
+ if (outputConditionIdentifier != null)
+ outa.Put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString(outputConditionIdentifier, PdfObject.TEXT_UNICODE));
+ if (registryName != null)
+ outa.Put(PdfName.REGISTRYNAME, new PdfString(registryName, PdfObject.TEXT_UNICODE));
+ if (info != null)
+ outa.Put(PdfName.INFO, new PdfString(info, PdfObject.TEXT_UNICODE));
+ if (destOutputProfile != null) {
+ PdfStream stream = new PdfStream(destOutputProfile);
+ stream.FlateCompress();
+ outa.Put(PdfName.DESTOUTPUTPROFILE, AddToBody(stream).IndirectReference);
+ }
+ outa.Put(PdfName.S, PdfName.GTS_PDFX);
+ extraCatalog.Put(PdfName.OUTPUTINTENTS, new PdfArray(outa));
+ }
+
+ /**
+ * Copies the output intent dictionary from other document to this one.
+ * @param reader the other document
+ * @param checkExistence true
to just check for the existence of a valid output intent
+ * dictionary, false
to insert the dictionary if it exists
+ * @throws IOException on error
+ * @return true
if the output intent dictionary exists, false
+ * otherwise
+ */
+ public bool SetOutputIntents(PdfReader reader, bool checkExistence) {
+ PdfDictionary catalog = reader.Catalog;
+ PdfArray outs = (PdfArray)PdfReader.GetPdfObject(catalog.Get(PdfName.OUTPUTINTENTS));
+ if (outs == null)
+ return false;
+ ArrayList arr = outs.ArrayList;
+ if (arr.Count == 0)
+ return false;
+ PdfDictionary outa = (PdfDictionary)PdfReader.GetPdfObject((PdfObject)arr[0]);
+ PdfObject obj = PdfReader.GetPdfObject(outa.Get(PdfName.S));
+ if (obj == null || !PdfName.GTS_PDFX.Equals(obj))
+ return false;
+ if (checkExistence)
+ return true;
+ PRStream stream = (PRStream)PdfReader.GetPdfObject(outa.Get(PdfName.DESTOUTPUTPROFILE));
+ byte[] destProfile = null;
+ if (stream != null) {
+ destProfile = PdfReader.GetStreamBytes(stream);
+ }
+ SetOutputIntents(GetNameString(outa, PdfName.OUTPUTCONDITIONIDENTIFIER), GetNameString(outa, PdfName.OUTPUTCONDITION),
+ GetNameString(outa, PdfName.REGISTRYNAME), GetNameString(outa, PdfName.INFO), destProfile);
+ return true;
+ }
+
+ private static String GetNameString(PdfDictionary dic, PdfName key) {
+ PdfObject obj = PdfReader.GetPdfObject(dic.Get(key));
+ if (obj == null || !obj.IsString())
+ return null;
+ return ((PdfString)obj).ToUnicodeString();
+ }
+
+ // PDF Objects that have an impact on the PDF body
+
+ // [F1] PdfEncryptionSettings interface
+
+ // types of encryption
+
+ /** Type of encryption */
+ public const int STANDARD_ENCRYPTION_40 = 0;
+ /** Type of encryption */
+ public const int STANDARD_ENCRYPTION_128 = 1;
+ /** Type of encryption */
+ public const int ENCRYPTION_AES_128 = 2;
+ /** Mask to separate the encryption type from the encryption mode. */
+ internal const int ENCRYPTION_MASK = 7;
+ /** Add this to the mode to keep the metadata in clear text */
+ public const int DO_NOT_ENCRYPT_METADATA = 8;
+
+ // permissions
+
+ /** The operation permitted when the document is opened with the user password
+ *
+ * @since 2.0.7
+ */
+ public const int ALLOW_PRINTING = 4 + 2048;
+
+ /** The operation permitted when the document is opened with the user password
+ *
+ * @since 2.0.7
+ */
+ public const int ALLOW_MODIFY_CONTENTS = 8;
+
+ /** The operation permitted when the document is opened with the user password
+ *
+ * @since 2.0.7
+ */
+ public const int ALLOW_COPY = 16;
+
+ /** The operation permitted when the document is opened with the user password
+ *
+ * @since 2.0.7
+ */
+ public const int ALLOW_MODIFY_ANNOTATIONS = 32;
+
+ /** The operation permitted when the document is opened with the user password
+ *
+ * @since 2.0.7
+ */
+ public const int ALLOW_FILL_IN = 256;
+
+ /** The operation permitted when the document is opened with the user password
+ *
+ * @since 2.0.7
+ */
+ public const int ALLOW_SCREENREADERS = 512;
+
+ /** The operation permitted when the document is opened with the user password
+ *
+ * @since 2.0.7
+ */
+ public const int ALLOW_ASSEMBLY = 1024;
+
+ /** The operation permitted when the document is opened with the user password
+ *
+ * @since 2.0.7
+ */
+ public const int ALLOW_DEGRADED_PRINTING = 4;
+
+ /** @deprecated As of iText 2.0.7, use {@link #ALLOW_PRINTING} instead. Scheduled for removal at or after 2.2.0 */
+ public const int AllowPrinting = ALLOW_PRINTING;
+ /** @deprecated As of iText 2.0.7, use {@link #ALLOW_MODIFY_CONTENTS} instead. Scheduled for removal at or after 2.2.0 */
+ public const int AllowModifyContents = ALLOW_MODIFY_CONTENTS;
+ /** @deprecated As of iText 2.0.7, use {@link #ALLOW_COPY} instead. Scheduled for removal at or after 2.2.0 */
+ public const int AllowCopy = ALLOW_COPY;
+ /** @deprecated As of iText 2.0.7, use {@link #ALLOW_MODIFY_ANNOTATIONS} instead. Scheduled for removal at or after 2.2.0 */
+ public const int AllowModifyAnnotations = ALLOW_MODIFY_ANNOTATIONS;
+ /** @deprecated As of iText 2.0.7, use {@link #ALLOW_FILL_IN} instead. Scheduled for removal at or after 2.2.0 */
+ public const int AllowFillIn = ALLOW_FILL_IN;
+ /** @deprecated As of iText 2.0.7, use {@link #ALLOW_SCREENREADERS} instead. Scheduled for removal at or after 2.2.0 */
+ public const int AllowScreenReaders = ALLOW_SCREENREADERS;
+ /** @deprecated As of iText 2.0.7, use {@link #ALLOW_ASSEMBLY} instead. Scheduled for removal at or after 2.2.0 */
+ public const int AllowAssembly = ALLOW_ASSEMBLY;
+ /** @deprecated As of iText 2.0.7, use {@link #ALLOW_DEGRADED_PRINTING} instead. Scheduled for removal at or after 2.2.0 */
+ public const int AllowDegradedPrinting = ALLOW_DEGRADED_PRINTING;
+
+ // Strength of the encryption (kept for historical reasons)
+ /** @deprecated As of iText 2.0.7, use {@link #STANDARD_ENCRYPTION_40} instead. Scheduled for removal at or after 2.2.0 */
+ public const bool STRENGTH40BITS = false;
+ /** @deprecated As of iText 2.0.7, use {@link #STANDARD_ENCRYPTION_128} instead. Scheduled for removal at or after 2.2.0 */
+ public const bool STRENGTH128BITS = true;
+
+ /** Contains the business logic for cryptography. */
+ protected PdfEncryption crypto;
+
+ internal PdfEncryption Encryption {
+ get {
+ return crypto;
+ }
+ }
+
+ /** Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType) {
+ if (pdf.IsOpen())
+ throw new DocumentException("Encryption can only be added before opening the document.");
+ crypto = new PdfEncryption();
+ crypto.SetCryptoMode(encryptionType, 0);
+ crypto.SetupAllKeys(userPassword, ownerPassword, permissions);
+ }
+
+ /**
+ * Sets the certificate encryption options for this document. An array of one or more public certificates
+ * must be provided together with an array of the same size for the permissions for each certificate.
+ * The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @param certs the public certificates to be used for the encryption
+ * @param permissions the user permissions for each of the certicates
+ * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(X509Certificate[] certs, int[] permissions, int encryptionType) {
+ if (pdf.IsOpen())
+ throw new DocumentException("Encryption can only be added before opening the document.");
+ crypto = new PdfEncryption();
+ if (certs != null) {
+ for (int i=0; i < certs.Length; i++) {
+ crypto.AddRecipient(certs[i], permissions[i]);
+ }
+ }
+ crypto.SetCryptoMode(encryptionType, 0);
+ crypto.GetEncryptionDictionary();
+ }
+
+ /** Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param strength128Bits true
for 128 bit key length, false
for 40 bit key length
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, bool strength128Bits) {
+ SetEncryption(userPassword, ownerPassword, permissions, strength128Bits ? STANDARD_ENCRYPTION_128 : STANDARD_ENCRYPTION_40);
+ }
+
+ /**
+ * Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param strength true
for 128 bit key length, false
for 40 bit key length
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(bool strength, String userPassword, String ownerPassword, int permissions) {
+ SetEncryption(GetISOBytes(userPassword), GetISOBytes(ownerPassword), permissions, strength);
+ }
+
+ /**
+ * Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @throws DocumentException if the document is already open
+ */
+ public void SetEncryption(int encryptionType, String userPassword, String ownerPassword, int permissions) {
+ SetEncryption(GetISOBytes(userPassword), GetISOBytes(ownerPassword), permissions, encryptionType);
+ }
+
+ // [F2] compression
+
+ /**
+ * Holds value of property fullCompression.
+ */
+ protected bool fullCompression = false;
+
+ /**
+ * Gets the 1.5 compression status.
+ * @return true
if the 1.5 compression is on
+ */
+ public bool FullCompression {
+ get {
+ return this.fullCompression;
+ }
+ }
+
+ /**
+ * Sets the document's compression to the new 1.5 mode with object streams and xref
+ * streams. It can be set at any time but once set it can't be unset.
+ * BaseFont
to the document but not to the page resources.
+ * It is used for templates.
+ * @param bf the BaseFont
to add
+ * @return an Object[]
where position 0 is a PdfName
+ * and position 1 is an PdfIndirectReference
+ */
+ internal FontDetails AddSimple(BaseFont bf) {
+ if (bf.FontType == BaseFont.FONT_TYPE_DOCUMENT) {
+ return new FontDetails(new PdfName("F" + (fontNumber++)), ((DocumentFont)bf).IndirectReference, bf);
+ }
+ FontDetails ret = (FontDetails)documentFonts[bf];
+ if (ret == null) {
+ PdfXConformanceImp.CheckPDFXConformance(this, PdfXConformanceImp.PDFXKEY_FONT, bf);
+ ret = new FontDetails(new PdfName("F" + (fontNumber++)), body.PdfIndirectReference, bf);
+ documentFonts[bf] = ret;
+ }
+ return ret;
+ }
+
+ internal void EliminateFontSubset(PdfDictionary fonts) {
+ foreach (FontDetails ft in documentFonts.Values) {
+ if (fonts.Get(ft.FontName) != null)
+ ft.Subset = false;
+ }
+ }
+
+ // [F4] adding (and releasing) form XObjects
+
+ /** The form XObjects in this document. The key is the xref and the value
+ is Object[]{PdfName, template}.*/
+ protected Hashtable formXObjects = new Hashtable();
+
+ /** The name counter for the form XObjects name. */
+ protected int formXObjectsCounter = 1;
+
+ /**
+ * Adds a template to the document but not to the page resources.
+ * @param template the template to add
+ * @param forcedName the template name, rather than a generated one. Can be null
+ * @return the PdfName
for this template
+ */
+ internal PdfName AddDirectTemplateSimple(PdfTemplate template, PdfName forcedName) {
+ PdfIndirectReference refa = template.IndirectReference;
+ Object[] obj = (Object[])formXObjects[refa];
+ PdfName name = null;
+ if (obj == null) {
+ if (forcedName == null) {
+ name = new PdfName("Xf" + formXObjectsCounter);
+ ++formXObjectsCounter;
+ }
+ else
+ name = forcedName;
+ if (template.Type == PdfTemplate.TYPE_IMPORTED) {
+ // If we got here from PdfCopy we'll have to fill importedPages
+ PdfImportedPage ip = (PdfImportedPage)template;
+ PdfReader r = ip.PdfReaderInstance.Reader;
+ if (!importedPages.ContainsKey(r)) {
+ importedPages[r] = ip.PdfReaderInstance;
+ }
+ template = null;
+ }
+ formXObjects[refa] = new Object[]{name, template};
+ }
+ else
+ name = (PdfName)obj[0];
+ return name;
+ }
+
+ /**
+ * Releases the memory used by a template by writing it to the output. The template
+ * can still be added to any content but changes to the template itself won't have
+ * any effect.
+ * @param tp the template to release
+ * @throws IOException on error
+ */
+ public void ReleaseTemplate(PdfTemplate tp) {
+ PdfIndirectReference refi = tp.IndirectReference;
+ Object[] objs = (Object[])formXObjects[refi];
+ if (objs == null || objs[1] == null)
+ return;
+ PdfTemplate template = (PdfTemplate)objs[1];
+ if (template.IndirectReference is PRIndirectReference)
+ return;
+ if (template.Type == PdfTemplate.TYPE_TEMPLATE) {
+ AddToBody(template.FormXObject, template.IndirectReference);
+ objs[1] = null;
+ }
+ }
+
+ // [F5] adding pages imported form other PDF documents
+
+ protected Hashtable importedPages = new Hashtable();
+
+ /** Gets a page from other PDF document. The page can be used as
+ * any other PdfTemplate. Note that calling this method more than
+ * once with the same parameters will retrieve the same object.
+ * @param reader the PDF document where the page is
+ * @param pageNumber the page number. The first page is 1
+ * @return the template representing the imported page
+ */
+ public virtual PdfImportedPage GetImportedPage(PdfReader reader, int pageNumber) {
+ PdfReaderInstance inst = (PdfReaderInstance)importedPages[reader];
+ if (inst == null) {
+ inst = reader.GetPdfReaderInstance(this);
+ importedPages[reader] = inst;
+ }
+ return inst.GetImportedPage(pageNumber);
+ }
+
+ /** Writes the reader to the document and frees the memory used by it.
+ * The main use is when concatenating multiple documents to keep the
+ * memory usage restricted to the current appending document.
+ * @param reader the PdfReader
to free
+ * @throws IOException on error
+ */
+ public virtual void FreeReader(PdfReader reader) {
+ currentPdfReaderInstance = (PdfReaderInstance)importedPages[reader];
+ if (currentPdfReaderInstance == null)
+ return;
+ currentPdfReaderInstance.WriteAllPages();
+ currentPdfReaderInstance = null;
+ importedPages.Remove(reader);
+ }
+
+ /** Gets the current document size. This size only includes
+ * the data already writen to the output stream, it does not
+ * include templates or fonts. It is usefull if used with
+ * freeReader()
when concatenating many documents
+ * and an idea of the current size is needed.
+ * @return the approximate size without fonts or templates
+ */
+ public int CurrentDocumentSize {
+ get {
+ return body.Offset + body.Size * 20 + 0x48;
+ }
+ }
+
+ protected PdfReaderInstance currentPdfReaderInstance;
+
+ protected internal virtual int GetNewObjectNumber(PdfReader reader, int number, int generation) {
+ return currentPdfReaderInstance.GetNewObjectNumber(number, generation);
+ }
+
+ internal virtual RandomAccessFileOrArray GetReaderFile(PdfReader reader) {
+ return currentPdfReaderInstance.ReaderFile;
+ }
+
+ // [F6] spot colors
+
+ /** The colors of this document */
+ protected Hashtable documentColors = new Hashtable();
+
+ /** The color number counter for the colors in the document. */
+ protected int colorNumber = 1;
+
+ internal PdfName GetColorspaceName() {
+ return new PdfName("CS" + (colorNumber++));
+ }
+
+ /**
+ * Adds a SpotColor
to the document but not to the page resources.
+ * @param spc the SpotColor
to add
+ * @return an Object[]
where position 0 is a PdfName
+ * and position 1 is an PdfIndirectReference
+ */
+ internal ColorDetails AddSimple(PdfSpotColor spc) {
+ ColorDetails ret = (ColorDetails)documentColors[spc];
+ if (ret == null) {
+ ret = new ColorDetails(GetColorspaceName(), body.PdfIndirectReference, spc);
+ documentColors[spc] = ret;
+ }
+ return ret;
+ }
+
+ // [F7] document patterns
+
+ /** The patterns of this document */
+ protected Hashtable documentPatterns = new Hashtable();
+
+ /** The patten number counter for the colors in the document. */
+ protected int patternNumber = 1;
+
+ internal PdfName AddSimplePattern(PdfPatternPainter painter) {
+ PdfName name = (PdfName)documentPatterns[painter];
+ if ( name == null ) {
+ name = new PdfName("P" + patternNumber);
+ ++patternNumber;
+ documentPatterns[painter] = name;
+ }
+ return name;
+ }
+
+ // [F8] shading patterns
+
+ protected Hashtable documentShadingPatterns = new Hashtable();
+
+ internal void AddSimpleShadingPattern(PdfShadingPattern shading) {
+ if (!documentShadingPatterns.ContainsKey(shading)) {
+ shading.Name = patternNumber;
+ ++patternNumber;
+ documentShadingPatterns[shading] = null;
+ AddSimpleShading(shading.Shading);
+ }
+ }
+
+ // [F9] document shadings
+
+ protected Hashtable documentShadings = new Hashtable();
+
+ internal void AddSimpleShading(PdfShading shading) {
+ if (!documentShadings.ContainsKey(shading)) {
+ documentShadings[shading] = null;
+ shading.Name = documentShadings.Count;
+ }
+ }
+
+ // [F10] extended graphics state (for instance for transparency)
+
+ protected Hashtable documentExtGState = new Hashtable();
+
+ internal PdfObject[] AddSimpleExtGState(PdfDictionary gstate) {
+ if (!documentExtGState.ContainsKey(gstate)) {
+ PdfXConformanceImp.CheckPDFXConformance(this, PdfXConformanceImp.PDFXKEY_GSTATE, gstate);
+ documentExtGState[gstate] = new PdfObject[]{new PdfName("GS" + (documentExtGState.Count + 1)), PdfIndirectReference};
+ }
+ return (PdfObject[])documentExtGState[gstate];
+ }
+
+ // [F11] adding properties (OCG, marked content)
+
+ protected Hashtable documentProperties = new Hashtable();
+
+ internal PdfObject[] AddSimpleProperty(Object prop, PdfIndirectReference refi) {
+ if (!documentProperties.ContainsKey(prop)) {
+ if (prop is IPdfOCG)
+ PdfXConformanceImp.CheckPDFXConformance(this, PdfXConformanceImp.PDFXKEY_LAYER, null);
+ documentProperties[prop] = new PdfObject[]{new PdfName("Pr" + (documentProperties.Count + 1)), refi};
+ }
+ return (PdfObject[])documentProperties[prop];
+ }
+
+ internal bool PropertyExists(Object prop) {
+ return documentProperties.ContainsKey(prop);
+ }
+
+ // [F12] tagged PDF
+
+ protected bool tagged = false;
+ protected PdfStructureTreeRoot structureTreeRoot;
+
+ /**
+ * Mark this document for tagging. It must be called before open.
+ */
+ public void SetTagged() {
+ if (open)
+ throw new ArgumentException("Tagging must be set before opening the document.");
+ tagged = true;
+ }
+
+ /**
+ * Check if the document is marked for tagging.
+ * @return true
if the document is marked for tagging
+ */
+ public bool IsTagged() {
+ return tagged;
+ }
+
+ /**
+ * Gets the structure tree root. If the document is not marked for tagging it will return null
.
+ * @return the structure tree root
+ */
+ public PdfStructureTreeRoot StructureTreeRoot {
+ get {
+ if (tagged && structureTreeRoot == null)
+ structureTreeRoot = new PdfStructureTreeRoot(this);
+ return structureTreeRoot;
+ }
+ }
+
+ // [F13] Optional Content Groups
+
+ protected Hashtable documentOCG = new Hashtable();
+ protected ArrayList documentOCGorder = new ArrayList();
+ protected PdfOCProperties vOCProperties;
+ protected PdfArray OCGRadioGroup = new PdfArray();
+ protected PdfArray OCGLocked = new PdfArray();
+
+ /**
+ * Gets the Optional Content Properties Dictionary. Each call fills the dictionary with the current layer
+ * state. It's advisable to only call this method right before close and do any modifications
+ * at that time.
+ * @return the Optional Content Properties Dictionary
+ */
+ public PdfOCProperties OCProperties {
+ get {
+ FillOCProperties(true);
+ return vOCProperties;
+ }
+ }
+
+ /**
+ * Sets a collection of optional content groups whose states are intended to follow
+ * a "radio button" paradigm. That is, the state of at most one optional
+ * content group in the array should be ON at a time: if one group is turned
+ * ON, all others must be turned OFF.
+ * @param group the radio group
+ */
+ public void AddOCGRadioGroup(ArrayList group) {
+ PdfArray ar = new PdfArray();
+ for (int k = 0; k < group.Count; ++k) {
+ PdfLayer layer = (PdfLayer)group[k];
+ if (layer.Title == null)
+ ar.Add(layer.Ref);
+ }
+ if (ar.Size == 0)
+ return;
+ OCGRadioGroup.Add(ar);
+ }
+
+ /**
+ * Use this method to lock an optional content group.
+ * The state of a locked group cannot be changed through the user interface
+ * of a viewer application. Producers can use this entry to prevent the visibility
+ * of content that depends on these groups from being changed by users.
+ * @param layer the layer that needs to be added to the array of locked OCGs
+ * @since 2.1.2
+ */
+ public void LockLayer(PdfLayer layer) {
+ OCGLocked.Add(layer.Ref);
+ }
+
+ private static void GetOCGOrder(PdfArray order, PdfLayer layer) {
+ if (!layer.OnPanel)
+ return;
+ if (layer.Title == null)
+ order.Add(layer.Ref);
+ ArrayList children = layer.Children;
+ if (children == null)
+ return;
+ PdfArray kids = new PdfArray();
+ if (layer.Title != null)
+ kids.Add(new PdfString(layer.Title, PdfObject.TEXT_UNICODE));
+ for (int k = 0; k < children.Count; ++k) {
+ GetOCGOrder(kids, (PdfLayer)children[k]);
+ }
+ if (kids.Size > 0)
+ order.Add(kids);
+ }
+
+ private void AddASEvent(PdfName eventa, PdfName category) {
+ PdfArray arr = new PdfArray();
+ foreach (PdfLayer layer in documentOCG.Keys) {
+ PdfDictionary usage = (PdfDictionary)layer.Get(PdfName.USAGE);
+ if (usage != null && usage.Get(category) != null)
+ arr.Add(layer.Ref);
+ }
+ if (arr.Size == 0)
+ return;
+ PdfDictionary d = (PdfDictionary)vOCProperties.Get(PdfName.D);
+ PdfArray arras = (PdfArray)d.Get(PdfName.AS);
+ if (arras == null) {
+ arras = new PdfArray();
+ d.Put(PdfName.AS, arras);
+ }
+ PdfDictionary asa = new PdfDictionary();
+ asa.Put(PdfName.EVENT, eventa);
+ asa.Put(PdfName.CATEGORY, new PdfArray(category));
+ asa.Put(PdfName.OCGS, arr);
+ arras.Add(asa);
+ }
+
+ protected void FillOCProperties(bool erase) {
+ if (vOCProperties == null)
+ vOCProperties = new PdfOCProperties();
+ if (erase) {
+ vOCProperties.Remove(PdfName.OCGS);
+ vOCProperties.Remove(PdfName.D);
+ }
+ if (vOCProperties.Get(PdfName.OCGS) == null) {
+ PdfArray gr = new PdfArray();
+ foreach (PdfLayer layer in documentOCG.Keys) {
+ gr.Add(layer.Ref);
+ }
+ vOCProperties.Put(PdfName.OCGS, gr);
+ }
+ if (vOCProperties.Get(PdfName.D) != null)
+ return;
+ ArrayList docOrder = new ArrayList(documentOCGorder);
+ for (ListIterator it = new ListIterator(docOrder); it.HasNext();) {
+ PdfLayer layer = (PdfLayer)it.Next();
+ if (layer.Parent != null)
+ it.Remove();
+ }
+ PdfArray order = new PdfArray();
+ foreach (PdfLayer layer in docOrder) {
+ GetOCGOrder(order, layer);
+ }
+ PdfDictionary d = new PdfDictionary();
+ vOCProperties.Put(PdfName.D, d);
+ d.Put(PdfName.ORDER, order);
+ PdfArray grx = new PdfArray();
+ foreach (PdfLayer layer in documentOCG.Keys) {
+ if (!layer.On)
+ grx.Add(layer.Ref);
+ }
+ if (grx.Size > 0)
+ d.Put(PdfName.OFF, grx);
+ if (OCGRadioGroup.Size > 0)
+ d.Put(PdfName.RBGROUPS, OCGRadioGroup);
+ if (OCGLocked.Size > 0)
+ d.Put(PdfName.LOCKED, OCGLocked);
+ AddASEvent(PdfName.VIEW, PdfName.ZOOM);
+ AddASEvent(PdfName.VIEW, PdfName.VIEW);
+ AddASEvent(PdfName.PRINT, PdfName.PRINT);
+ AddASEvent(PdfName.EXPORT, PdfName.EXPORT);
+ d.Put(PdfName.LISTMODE, PdfName.VISIBLEPAGES);
+ }
+
+ internal void RegisterLayer(IPdfOCG layer) {
+ PdfXConformanceImp.CheckPDFXConformance(this, PdfXConformanceImp.PDFXKEY_LAYER, null);
+ if (layer is PdfLayer) {
+ PdfLayer la = (PdfLayer)layer;
+ if (la.Title == null) {
+ if (!documentOCG.ContainsKey(layer)) {
+ documentOCG[layer] = null;
+ documentOCGorder.Add(layer);
+ }
+ }
+ else {
+ documentOCGorder.Add(layer);
+ }
+ }
+ else
+ throw new ArgumentException("Only PdfLayer is accepted.");
+ }
+
+ // User methods to change aspects of the page
+
+ // [U1] page size
+
+ /**
+ * Gives the size of the media box.
+ * @return a Rectangle
+ */
+ public Rectangle PageSize {
+ get {
+ return pdf.PageSize;
+ }
+ }
+
+ /** Sets the crop box. The crop box should not be rotated even if the
+ * page is rotated. This change only takes effect in the next
+ * page.
+ * @param crop the crop box
+ */
+ public virtual Rectangle CropBoxSize {
+ set {
+ pdf.CropBoxSize = value;
+ }
+ }
+
+ /**
+ * Sets the page box sizes. Allowed names are: "crop", "trim", "art" and "bleed".
+ * @param boxName the box size
+ * @param size the size
+ */
+ public void SetBoxSize(String boxName, Rectangle size) {
+ pdf.SetBoxSize(boxName, size);
+ }
+
+ /**
+ * Gives the size of a trim, art, crop or bleed box, or null if not defined.
+ * @param boxName crop, trim, art or bleed
+ */
+ public Rectangle GetBoxSize(String boxName) {
+ return pdf.GetBoxSize(boxName);
+ }
+
+ // [U2] take care of empty pages
+
+ /**
+ * If you use SetPageEmpty(false), invoking NewPage() after a blank page will add a newPage.
+ * @param pageEmpty the state
+ */
+ public bool PageEmpty {
+ set {
+ pdf.PageEmpty = value;
+ }
+ }
+
+ // [U3] page actions (open and close)
+
+ /** action value */
+ public static readonly PdfName PAGE_OPEN = PdfName.O;
+ /** action value */
+ public static readonly PdfName PAGE_CLOSE = PdfName.C;
+
+ /** Sets the open and close page additional action.
+ * @param actionType the action type. It can be PdfWriter.PAGE_OPEN
+ * or PdfWriter.PAGE_CLOSE
+ * @param action the action to perform
+ * @throws PdfException if the action type is invalid
+ */
+ public virtual void SetPageAction(PdfName actionType, PdfAction action) {
+ if (!actionType.Equals(PAGE_OPEN) && !actionType.Equals(PAGE_CLOSE))
+ throw new PdfException("Invalid page additional action type: " + actionType.ToString());
+ pdf.SetPageAction(actionType, action);
+ }
+
+ /**
+ * Sets the display duration for the page (for presentations)
+ * @param seconds the number of seconds to display the page
+ */
+ public virtual int Duration {
+ set {
+ pdf.Duration = value;
+ }
+ }
+
+ /**
+ * Sets the transition for the page
+ * @param transition the Transition object
+ */
+ public virtual PdfTransition Transition {
+ set {
+ pdf.Transition = value;
+ }
+ }
+
+ // [U4] Thumbnail image
+
+ /**
+ * Sets the the thumbnail image for the current page.
+ * @param image the image
+ * @throws PdfException on error
+ * @throws DocumentException or error
+ */
+ public virtual Image Thumbnail {
+ set {
+ pdf.Thumbnail = value;
+ }
+ }
+
+ // [U5] Transparency groups
+
+ /**
+ * A group attributes dictionary specifying the attributes
+ * of the page’s page group for use in the transparent
+ * imaging model
+ */
+ protected PdfDictionary group;
+
+ public PdfDictionary Group {
+ get {
+ return this.group;
+ }
+ set {
+ group = value;
+ }
+ }
+
+ // [U6] space char ratio
+
+ /** The default space-char ratio. */
+ public const float SPACE_CHAR_RATIO_DEFAULT = 2.5f;
+ /** Disable the inter-character spacing. */
+ public const float NO_SPACE_CHAR_RATIO = 10000000f;
+
+ /**
+ * The ratio between the extra word spacing and the extra character spacing.
+ * Extra word spacing will grow ratio
times more than extra character spacing.
+ */
+ private float spaceCharRatio = SPACE_CHAR_RATIO_DEFAULT;
+
+ /** Sets the ratio between the extra word spacing and the extra character spacing
+ * when the text is fully justified.
+ * Extra word spacing will grow spaceCharRatio
times more than extra character spacing.
+ * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO
then the extra character spacing
+ * will be zero.
+ * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing
+ */
+ public virtual float SpaceCharRatio {
+ set {
+ if (value < 0.001f)
+ this.spaceCharRatio = 0.001f;
+ else
+ this.spaceCharRatio = value;
+ }
+ get {
+ return spaceCharRatio;
+ }
+ }
+
+ // [U7] run direction (doesn't actually do anything)
+
+ /** Use the default run direction. */
+ public const int RUN_DIRECTION_DEFAULT = 0;
+ /** Do not use bidirectional reordering. */
+ public const int RUN_DIRECTION_NO_BIDI = 1;
+ /** Use bidirectional reordering with left-to-right
+ * preferential run direction.
+ */
+ public const int RUN_DIRECTION_LTR = 2;
+ /** Use bidirectional reordering with right-to-left
+ * preferential run direction.
+ */
+ public const int RUN_DIRECTION_RTL = 3;
+ protected int runDirection = RUN_DIRECTION_NO_BIDI;
+
+ /** Sets the run direction. This is only used as a placeholder
+ * as it does not affect anything.
+ * @param runDirection the run direction
+ */
+ public virtual int RunDirection {
+ set {
+ if (value < RUN_DIRECTION_NO_BIDI || value > RUN_DIRECTION_RTL)
+ throw new Exception("Invalid run direction: " + value);
+ this.runDirection = value;
+ }
+ get {
+ return runDirection;
+ }
+ }
+
+ // [U8] user units
+
+ protected float userunit = 0f;
+
+ /**
+ * A UserUnit is a value that defines the default user space unit.
+ * The minimum UserUnit is 1 (1 unit = 1/72 inch).
+ * The maximum UserUnit is 75,000.
+ * Remark that this userunit only works starting with PDF1.6!
+ */
+ public float Userunit {
+ get {
+ return userunit;
+ }
+ set {
+ if (value < 1f || value > 75000f) throw new DocumentException("UserUnit should be a value between 1 and 75000.");
+ this.userunit = value;
+ SetAtLeastPdfVersion(VERSION_1_6);
+ }
+ }
+
+ // Miscellaneous topics
+
+ // [M1] Color settings
+
+ protected PdfDictionary defaultColorspace = new PdfDictionary();
+
+ /**
+ * Gets the default colorspaces.
+ * @return the default colorspaces
+ */
+ public PdfDictionary DefaultColorspace {
+ get {
+ return defaultColorspace;
+ }
+ }
+
+ /**
+ * Sets the default colorspace that will be applied to all the document.
+ * The colorspace is only applied if another colorspace with the same name
+ * is not present in the content.
+ * PdfName.DEFAULTGRAY
, PdfName.DEFAULTRGB
+ * or PdfName.DEFAULTCMYK
+ * @param cs the colorspace. A null
or PdfNull
removes any colorspace with the same name
+ */
+ public void SetDefaultColorspace(PdfName key, PdfObject cs) {
+ if (cs == null || cs.IsNull())
+ defaultColorspace.Remove(key);
+ defaultColorspace.Put(key, cs);
+ }
+
+ // [M2] spot patterns
+
+ protected Hashtable documentSpotPatterns = new Hashtable();
+ protected ColorDetails patternColorspaceRGB;
+ protected ColorDetails patternColorspaceGRAY;
+ protected ColorDetails patternColorspaceCMYK;
+
+ internal ColorDetails AddSimplePatternColorspace(Color color) {
+ int type = ExtendedColor.GetType(color);
+ if (type == ExtendedColor.TYPE_PATTERN || type == ExtendedColor.TYPE_SHADING)
+ throw new Exception("An uncolored tile pattern can not have another pattern or shading as color.");
+ switch (type) {
+ case ExtendedColor.TYPE_RGB:
+ if (patternColorspaceRGB == null) {
+ patternColorspaceRGB = new ColorDetails(GetColorspaceName(), body.PdfIndirectReference, null);
+ PdfArray array = new PdfArray(PdfName.PATTERN);
+ array.Add(PdfName.DEVICERGB);
+ AddToBody(array, patternColorspaceRGB.IndirectReference);
+ }
+ return patternColorspaceRGB;
+ case ExtendedColor.TYPE_CMYK:
+ if (patternColorspaceCMYK == null) {
+ patternColorspaceCMYK = new ColorDetails(GetColorspaceName(), body.PdfIndirectReference, null);
+ PdfArray array = new PdfArray(PdfName.PATTERN);
+ array.Add(PdfName.DEVICECMYK);
+ AddToBody(array, patternColorspaceCMYK.IndirectReference);
+ }
+ return patternColorspaceCMYK;
+ case ExtendedColor.TYPE_GRAY:
+ if (patternColorspaceGRAY == null) {
+ patternColorspaceGRAY = new ColorDetails(GetColorspaceName(), body.PdfIndirectReference, null);
+ PdfArray array = new PdfArray(PdfName.PATTERN);
+ array.Add(PdfName.DEVICEGRAY);
+ AddToBody(array, patternColorspaceGRAY.IndirectReference);
+ }
+ return patternColorspaceGRAY;
+ case ExtendedColor.TYPE_SEPARATION: {
+ ColorDetails details = AddSimple(((SpotColor)color).PdfSpotColor);
+ ColorDetails patternDetails = (ColorDetails)documentSpotPatterns[details];
+ if (patternDetails == null) {
+ patternDetails = new ColorDetails(GetColorspaceName(), body.PdfIndirectReference, null);
+ PdfArray array = new PdfArray(PdfName.PATTERN);
+ array.Add(details.IndirectReference);
+ AddToBody(array, patternDetails.IndirectReference);
+ documentSpotPatterns[details] = patternDetails;
+ }
+ return patternDetails;
+ }
+ default:
+ throw new Exception("Invalid color type in PdfWriter.AddSimplePatternColorspace().");
+ }
+ }
+
+ // [M3] Images
+
+ /** Sets the image sequence to follow the text in strict order.
+ * @param strictImageSequence new value of property strictImageSequence
+ *
+ */
+ public bool StrictImageSequence {
+ set {
+ pdf.StrictImageSequence = value;
+ }
+ get {
+ return pdf.StrictImageSequence;
+ }
+ }
+
+ /**
+ * Clears text wrapping around images (if applicable).
+ * Method suggested by Pelikan Stephan
+ * @throws DocumentException
+ */
+ public void ClearTextWrap() {
+ pdf.ClearTextWrap();
+ }
+
+ /** Dictionary, containing all the images of the PDF document */
+ protected PdfDictionary imageDictionary = new PdfDictionary();
+
+ /** This is the list with all the images in the document. */
+ private Hashtable images = new Hashtable();
+
+ /**
+ * Adds an image to the document but not to the page resources. It is used with
+ * templates and Document.Add(Image)
.
+ * @param image the Image
to add
+ * @return the name of the image added
+ * @throws PdfException on error
+ * @throws DocumentException on error
+ */
+ public PdfName AddDirectImageSimple(Image image) {
+ return AddDirectImageSimple(image, null);
+ }
+
+ /**
+ * Adds an image to the document but not to the page resources. It is used with
+ * templates and Document.Add(Image)
.
+ * @param image the Image
to add
+ * @param fixedRef the reference to used. It may be null
,
+ * a PdfIndirectReference
or a PRIndirectReference
.
+ * @return the name of the image added
+ * @throws PdfException on error
+ * @throws DocumentException on error
+ */
+ public PdfName AddDirectImageSimple(Image image, PdfIndirectReference fixedRef) {
+ PdfName name;
+ // if the images is already added, just retrieve the name
+ if (images.ContainsKey(image.MySerialId)) {
+ name = (PdfName) images[image.MySerialId];
+ }
+ // if it's a new image, add it to the document
+ else {
+ if (image.IsImgTemplate()) {
+ name = new PdfName("img" + images.Count);
+ if (image is ImgWMF){
+ ImgWMF wmf = (ImgWMF)image;
+ wmf.ReadWMF(PdfTemplate.CreateTemplate(this, 0, 0));
+ }
+ }
+ else {
+ PdfIndirectReference dref = image.DirectReference;
+ if (dref != null) {
+ PdfName rname = new PdfName("img" + images.Count);
+ images[image.MySerialId] = rname;
+ imageDictionary.Put(rname, dref);
+ return rname;
+ }
+ Image maskImage = image.ImageMask;
+ PdfIndirectReference maskRef = null;
+ if (maskImage != null) {
+ PdfName mname = (PdfName)images[maskImage.MySerialId];
+ maskRef = GetImageReference(mname);
+ }
+ PdfImage i = new PdfImage(image, "img" + images.Count, maskRef);
+ if (image.HasICCProfile()) {
+ PdfICCBased icc = new PdfICCBased(image.TagICC);
+ PdfIndirectReference iccRef = Add(icc);
+ PdfArray iccArray = new PdfArray();
+ iccArray.Add(PdfName.ICCBASED);
+ iccArray.Add(iccRef);
+ PdfObject colorspace = i.Get(PdfName.COLORSPACE);
+ if (colorspace != null && colorspace.IsArray()) {
+ ArrayList ar = ((PdfArray)colorspace).ArrayList;
+ if (ar.Count > 1 && PdfName.INDEXED.Equals(ar[0]))
+ ar[1] = iccArray;
+ else
+ i.Put(PdfName.COLORSPACE, iccArray);
+ }
+ else
+ i.Put(PdfName.COLORSPACE, iccArray);
+ }
+ Add(i, fixedRef);
+ name = i.Name;
+ }
+ images[image.MySerialId] = name;
+ }
+ return name;
+ }
+
+ /**
+ * Writes a PdfImage
to the outputstream.
+ *
+ * @param pdfImage the image to be added
+ * @return a PdfIndirectReference
to the encapsulated image
+ * @throws PdfException when a document isn't open yet, or has been closed
+ */
+ internal virtual PdfIndirectReference Add(PdfImage pdfImage, PdfIndirectReference fixedRef) {
+ if (! imageDictionary.Contains(pdfImage.Name)) {
+ PdfXConformanceImp.CheckPDFXConformance(this, PdfXConformanceImp.PDFXKEY_IMAGE, pdfImage);
+ if (fixedRef is PRIndirectReference) {
+ PRIndirectReference r2 = (PRIndirectReference)fixedRef;
+ fixedRef = new PdfIndirectReference(0, GetNewObjectNumber(r2.Reader, r2.Number, r2.Generation));
+ }
+ if (fixedRef == null)
+ fixedRef = AddToBody(pdfImage).IndirectReference;
+ else
+ AddToBody(pdfImage, fixedRef);
+ imageDictionary.Put(pdfImage.Name, fixedRef);
+ return fixedRef;
+ }
+ return (PdfIndirectReference)imageDictionary.Get(pdfImage.Name);
+ }
+
+ /**
+ * return the PdfIndirectReference
to the image with a given name.
+ *
+ * @param name the name of the image
+ * @return a PdfIndirectReference
+ */
+ internal virtual PdfIndirectReference GetImageReference(PdfName name) {
+ return (PdfIndirectReference) imageDictionary.Get(name);
+ }
+
+ protected virtual PdfIndirectReference Add(PdfICCBased icc) {
+ PdfIndirectObject objecta;
+ objecta = AddToBody(icc);
+ return objecta.IndirectReference;
+ }
+
+ // [M4] Old table functionality; do we still need it?
+
+ /**
+ * Checks if a Table
fits the current page of the PdfDocument
.
+ *
+ * @param table the table that has to be checked
+ * @param margin a certain margin
+ * @return true
if the Table
fits the page, false
otherwise.
+ */
+ public bool FitsPage(Table table, float margin) {
+ return pdf.GetBottom(table) > pdf.IndentBottom + margin;
+ }
+
+ /**
+ * Checks if a Table
fits the current page of the PdfDocument
.
+ *
+ * @param table the table that has to be checked
+ * @return true
if the Table
fits the page, false
otherwise.
+ */
+ public bool FitsPage(Table table) {
+ return FitsPage(table, 0);
+ }
+
+ // [F12] tagged PDF
+ /**
+ * A flag indicating the presence of structure elements that contain user properties attributes.
+ */
+ private bool userProperties;
+
+ /**
+ * Sets the flag indicating the presence of structure elements that contain user properties attributes.
+ * @param userProperties the user properties flag
+ */
+ public bool UserProperties {
+ set {
+ userProperties = value;
+ }
+ get {
+ return userProperties;
+ }
+ }
+
+ /**
+ * Holds value of property RGBTranparency.
+ */
+ private bool rgbTransparencyBlending;
+
+ /**
+ * Sets the transparency blending colorspace to RGB. The default blending colorspace is
+ * CMYK and will result in faded colors in the screen and in printing. Calling this method
+ * will return the RGB colors to what is expected. The RGB blending will be applied to all subsequent pages
+ * until other value is set.
+ * Note that this is a generic solution that may not work in all cases.
+ * @param rgbTransparencyBlending true
to set the transparency blending colorspace to RGB, false
+ * to use the default blending colorspace
+ */
+ public bool RgbTransparencyBlending {
+ get {
+ return this.rgbTransparencyBlending;
+ }
+ set {
+ this.rgbTransparencyBlending = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/PdfXConformanceException.cs b/iTechSharp/iTextSharp/text/pdf/PdfXConformanceException.cs
new file mode 100644
index 0000000..78b7490
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PdfXConformanceException.cs
@@ -0,0 +1,67 @@
+using System;
+/*
+ * Copyright 2004 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ *
+ * @author psoares
+ */
+ public class PdfXConformanceException : Exception {
+
+ /** Creates a new instance of PdfXConformanceException. */
+ public PdfXConformanceException() {
+ }
+
+ /**
+ * Creates a new instance of PdfXConformanceException.
+ * @param s
+ */
+ public PdfXConformanceException(String s) : base(s) {
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/Pfm2afm.cs b/iTechSharp/iTextSharp/text/pdf/Pfm2afm.cs
new file mode 100644
index 0000000..3f96e12
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/Pfm2afm.cs
@@ -0,0 +1,805 @@
+using System;
+using System.IO;
+using System.Text;
+/*
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except inp compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added inp the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), inp which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed inp 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+/********************************************************************
+ * *
+ * Title: pfm2afm - Convert Windows .pfm files to .afm files *
+ * *
+ * Author: Ken Borgendale 10/9/91 Version 1.0 *
+ * *
+ * Function: *
+ * Convert a Windows .pfm (Printer Font Metrics) file to a *
+ * .afm (Adobe Font Metrics) file. The purpose of this is *
+ * to allow fonts put outp for Windows to be used with OS/2. *
+ * *
+ * Syntax: *
+ * pfm2afm infile [outfile] -a *
+ * *
+ * Copyright: *
+ * pfm2afm - Copyright (C) IBM Corp., 1991 *
+ * *
+ * This code is released for public use as long as the *
+ * copyright remains intact. This code is provided asis *
+ * without any warrenties, express or implied. *
+ * *
+ * Notes: *
+ * 1. Much of the information inp the original .afm file is *
+ * lost when the .pfm file is created, and thus cannot be *
+ * reconstructed by this utility. This is especially true *
+ * of data for characters not inp the Windows character set. *
+ * *
+ * 2. This module is coded to be compiled by the MSC 6.0. *
+ * For other compilers, be careful of the packing of the *
+ * PFM structure. *
+ * *
+ ********************************************************************/
+
+/********************************************************************
+ * *
+ * Modifications by Rod Smith, 5/22/96 *
+ * *
+ * These changes look for the strings "italic", "bold", "black", *
+ * and "light" inp the font's name and set the weight accordingly *
+ * and adds an ItalicAngle line with a value of "0" or "-12.00". *
+ * This allows OS/2 programs such as DeScribe to handle the bold *
+ * and italic attributes appropriately, which was not the case *
+ * when I used the original version on fonts from the KeyFonts *
+ * Pro 2002 font CD. *
+ * *
+ * I've also increased the size of the buffer used to load the *
+ * .PFM file; the old size was inadequate for most of the fonts *
+ * from the SoftKey collection. *
+ * *
+ * Compiled with Watcom C 10.6 *
+ * *
+ ********************************************************************/
+
+/********************************************************************
+ * *
+ * Further modifications, 4/21/98, by Rod Smith *
+ * *
+ * Minor changes to get the program to compile with gcc under *
+ * Linux (Red Hat 5.0, to be precise). I had to add an itoa *
+ * function from the net (the function was buggy, so I had to fix *
+ * it, too!). I also made the program more friendly towards *
+ * files with mixed-case filenames. *
+ * *
+ ********************************************************************/
+
+/********************************************************************
+ * *
+ * 1/31/2005, by Paulo Soares *
+ * *
+ * This code was integrated into iText. *
+ * Note that the itoa function mentioned in the comment by Rod *
+ * Smith is no longer in the code because Java has native support *
+ * in PrintWriter to convert integers to strings *
+ * *
+ ********************************************************************/
+
+/********************************************************************
+ * *
+ * 7/16/2005, by Bruno Lowagie *
+ * *
+ * I solved an Eclipse Warning. *
+ * *
+ ********************************************************************/
+
+/********************************************************************
+ * *
+ * 9/14/2006, by Xavier Le Vourch *
+ * *
+ * expand import clauses (import java.io.*) *
+ * the removal of an exception in readString was restored on 9/16 *
+ * *
+ ********************************************************************/
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Converts a PFM file into an AFM file.
+ */
+ public sealed class Pfm2afm {
+ private RandomAccessFileOrArray inp;
+ private StreamWriter outp;
+ private Encoding encoding;
+
+ /** Creates a new instance of Pfm2afm */
+ private Pfm2afm(RandomAccessFileOrArray inp, Stream outp) {
+ this.inp = inp;
+ encoding = Encoding.GetEncoding(1252);
+ this.outp = new StreamWriter(outp, encoding);
+ }
+
+ /**
+ * Converts a PFM file into an AFM file.
+ * @param inp the PFM file
+ * @param outp the AFM file
+ * @throws IOException on error
+ */
+ public static void Convert(RandomAccessFileOrArray inp, Stream outp) {
+ Pfm2afm p = new Pfm2afm(inp, outp);
+ p.Openpfm();
+ p.Putheader();
+ p.Putchartab();
+ p.Putkerntab();
+ p.Puttrailer();
+ p.outp.Flush();
+ }
+
+/* public static void Main(String[] args) {
+ try {
+ RandomAccessFileOrArray inp = new RandomAccessFileOrArray(args[0]);
+ Stream outp = new FileOutputStream(args[1]);
+ Convert(inp, outp);
+ inp.Close();
+ outp.Close();
+ }
+ catch (Exception e) {
+ e.PrintStackTrace();
+ }
+ }*/
+
+ private String ReadString(int n) {
+ byte[] b = new byte[n];
+ inp.ReadFully(b);
+ int k;
+ for (k = 0; k < b.Length; ++k) {
+ if (b[k] == 0)
+ break;
+ }
+ return encoding.GetString(b, 0, k);
+ }
+
+ private String ReadString() {
+ StringBuilder buf = new StringBuilder();
+ while (true) {
+ int c = inp.Read();
+ if (c <= 0)
+ break;
+ buf.Append((char)c);
+ }
+ return buf.ToString();
+ }
+
+ private void Outval(int n) {
+ outp.Write(' ');
+ outp.Write(n);
+ }
+
+ /*
+ * Output a character entry
+ */
+ private void Outchar(int code, int width, String name) {
+ outp.Write("C ");
+ Outval(code);
+ outp.Write(" ; WX ");
+ Outval(width);
+ if (name != null) {
+ outp.Write(" ; N ");
+ outp.Write(name);
+ }
+ outp.Write(" ;\n");
+ }
+
+ private void Openpfm() {
+ inp.Seek(0);
+ vers = inp.ReadShortLE();
+ h_len = inp.ReadIntLE();
+ copyright = ReadString(60);
+ type = inp.ReadShortLE();
+ points = inp.ReadShortLE();
+ verres = inp.ReadShortLE();
+ horres = inp.ReadShortLE();
+ ascent = inp.ReadShortLE();
+ intleading = inp.ReadShortLE();
+ extleading = inp.ReadShortLE();
+ italic = (byte)inp.Read();
+ uline = (byte)inp.Read();
+ overs = (byte)inp.Read();
+ weight = inp.ReadShortLE();
+ charset = (byte)inp.Read();
+ pixwidth = inp.ReadShortLE();
+ pixheight = inp.ReadShortLE();
+ kind = (byte)inp.Read();
+ avgwidth = inp.ReadShortLE();
+ maxwidth = inp.ReadShortLE();
+ firstchar = inp.Read();
+ lastchar = inp.Read();
+ defchar = (byte)inp.Read();
+ brkchar = (byte)inp.Read();
+ widthby = inp.ReadShortLE();
+ device = inp.ReadIntLE();
+ face = inp.ReadIntLE();
+ bits = inp.ReadIntLE();
+ bitoff = inp.ReadIntLE();
+ extlen = inp.ReadShortLE();
+ psext = inp.ReadIntLE();
+ chartab = inp.ReadIntLE();
+ res1 = inp.ReadIntLE();
+ kernpairs = inp.ReadIntLE();
+ res2 = inp.ReadIntLE();
+ fontname = inp.ReadIntLE();
+ if (h_len != inp.Length || extlen != 30 || fontname < 75 || fontname > 512)
+ throw new IOException("Not a valid PFM file.");
+ inp.Seek(psext + 14);
+ capheight = inp.ReadShortLE();
+ xheight = inp.ReadShortLE();
+ ascender = inp.ReadShortLE();
+ descender = inp.ReadShortLE();
+ }
+
+ private void Putheader() {
+ outp.Write("StartFontMetrics 2.0\n");
+ if (copyright.Length > 0)
+ outp.Write("Comment " + copyright + '\n');
+ outp.Write("FontName ");
+ inp.Seek(fontname);
+ String fname = ReadString();
+ outp.Write(fname);
+ outp.Write("\nEncodingScheme ");
+ if (charset != 0)
+ outp.Write("FontSpecific\n");
+ else
+ outp.Write("AdobeStandardEncoding\n");
+ /*
+ * The .pfm is missing full name, so construct from font name by
+ * changing the hyphen to a space. This actually works inp a lot
+ * of cases.
+ */
+ outp.Write("FullName " + fname.Replace('-', ' '));
+ if (face != 0) {
+ inp.Seek(face);
+ outp.Write("\nFamilyName " + ReadString());
+ }
+
+ outp.Write("\nWeight ");
+ if (weight > 475 || fname.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf("bold") >= 0)
+ outp.Write("Bold");
+ else if ((weight < 325 && weight != 0) || fname.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf("light") >= 0)
+ outp.Write("Light");
+ else if (fname.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf("black") >= 0)
+ outp.Write("Black");
+ else
+ outp.Write("Medium");
+
+ outp.Write("\nItalicAngle ");
+ if (italic != 0 || fname.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf("italic") >= 0)
+ outp.Write("-12.00");
+ /* this is a typical value; something else may work better for a
+ specific font */
+ else
+ outp.Write("0");
+
+ /*
+ * The mono flag inp the pfm actually indicates whether there is a
+ * table of font widths, not if they are all the same.
+ */
+ outp.Write("\nIsFixedPitch ");
+ if ((kind & 1) == 0 || /* Flag for mono */
+ avgwidth == maxwidth ) { /* Avg width = max width */
+ outp.Write("true");
+ isMono = true;
+ }
+ else {
+ outp.Write("false");
+ isMono = false;
+ }
+
+ /*
+ * The font bounding box is lost, but try to reconstruct it.
+ * Much of this is just guess work. The bounding box is required inp
+ * the .afm, but is not used by the PM font installer.
+ */
+ outp.Write("\nFontBBox");
+ if (isMono)
+ Outval(-20); /* Just guess at left bounds */
+ else
+ Outval(-100);
+ Outval(-(descender+5)); /* Descender is given as positive value */
+ Outval(maxwidth+10);
+ Outval(ascent+5);
+
+ /*
+ * Give other metrics that were kept
+ */
+ outp.Write("\nCapHeight");
+ Outval(capheight);
+ outp.Write("\nXHeight");
+ Outval(xheight);
+ outp.Write("\nDescender");
+ Outval(descender);
+ outp.Write("\nAscender");
+ Outval(ascender);
+ outp.Write('\n');
+ }
+
+ private void Putchartab() {
+ int count = lastchar - firstchar + 1;
+ int[] ctabs = new int[count];
+ inp.Seek(chartab);
+ for (int k = 0; k < count; ++k)
+ ctabs[k] = inp.ReadUnsignedShortLE();
+ int[] back = new int[256];
+ if (charset == 0) {
+ for (int i = firstchar; i <= lastchar; ++i) {
+ if (Win2PSStd[i] != 0)
+ back[Win2PSStd[i]] = i;
+ }
+ }
+ /* Put outp the header */
+ outp.Write("StartCharMetrics");
+ Outval(count);
+ outp.Write('\n');
+
+ /* Put outp all encoded chars */
+ if (charset != 0) {
+ /*
+ * If the charset is not the Windows standard, just put outp
+ * unnamed entries.
+ */
+ for (int i = firstchar; i <= lastchar; i++) {
+ if (ctabs[i - firstchar] != 0) {
+ Outchar(i, ctabs[i - firstchar], null);
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < 256; i++) {
+ int j = back[i];
+ if (j != 0) {
+ Outchar(i, ctabs[j - firstchar], WinChars[j]);
+ ctabs[j - firstchar] = 0;
+ }
+ }
+ /* Put outp all non-encoded chars */
+ for (int i = firstchar; i <= lastchar; i++) {
+ if (ctabs[i - firstchar] != 0) {
+ Outchar(-1, ctabs[i - firstchar], WinChars[i]);
+ }
+ }
+ }
+ /* Put outp the trailer */
+ outp.Write("EndCharMetrics\n");
+
+ }
+
+ private void Putkerntab() {
+ if (kernpairs == 0)
+ return;
+ inp.Seek(kernpairs);
+ int count = inp.ReadUnsignedShortLE();
+ int nzero = 0;
+ int[] kerns = new int[count * 3];
+ for (int k = 0; k < kerns.Length;) {
+ kerns[k++] = inp.Read();
+ kerns[k++] = inp.Read();
+ if ((kerns[k++] = inp.ReadShortLE()) != 0)
+ ++nzero;
+ }
+ if (nzero == 0)
+ return;
+ outp.Write("StartKernData\nStartKernPairs");
+ Outval(nzero);
+ outp.Write('\n');
+ for (int k = 0; k < kerns.Length; k += 3) {
+ if (kerns[k + 2] != 0) {
+ outp.Write("KPX ");
+ outp.Write(WinChars[kerns[k]]);
+ outp.Write(' ');
+ outp.Write(WinChars[kerns[k + 1]]);
+ Outval(kerns[k + 2]);
+ outp.Write('\n');
+ }
+ }
+ /* Put outp trailer */
+ outp.Write("EndKernPairs\nEndKernData\n");
+ }
+
+
+ private void Puttrailer() {
+ outp.Write("EndFontMetrics\n");
+ }
+
+ private short vers;
+ private int h_len; /* Total length of .pfm file */
+ private String copyright; /* Copyright string [60]*/
+ private short type;
+ private short points;
+ private short verres;
+ private short horres;
+ private short ascent;
+ private short intleading;
+ private short extleading;
+ private byte italic;
+ private byte uline;
+ private byte overs;
+ private short weight;
+ private byte charset; /* 0=windows, otherwise nomap */
+ private short pixwidth; /* Width for mono fonts */
+ private short pixheight;
+ private byte kind; /* Lower bit off inp mono */
+ private short avgwidth; /* Mono if avg=max width */
+ private short maxwidth; /* Use to compute bounding box */
+ private int firstchar; /* First char inp table */
+ private int lastchar; /* Last char inp table */
+ private byte defchar;
+ private byte brkchar;
+ private short widthby;
+ private int device;
+ private int face; /* Face name */
+ private int bits;
+ private int bitoff;
+ private short extlen;
+ private int psext; /* PostScript extension */
+ private int chartab; /* Character width tables */
+ private int res1;
+ private int kernpairs; /* Kerning pairs */
+ private int res2;
+ private int fontname; /* Font name */
+
+ /*
+ * Some metrics from the PostScript extension
+ */
+ private short capheight; /* Cap height */
+ private short xheight; /* X height */
+ private short ascender; /* Ascender */
+ private short descender; /* Descender (positive) */
+
+
+ private bool isMono;
+ /*
+ * Translate table from 1004 to psstd. 1004 is an extension of the
+ * Windows translate table used inp PM.
+ */
+ private int[] Win2PSStd = {
+ 0, 0, 0, 0, 197, 198, 199, 0, 202, 0, 205, 206, 207, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 32, 33, 34, 35, 36, 37, 38, 169, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 193, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 0, 0, 184, 0, 185, 188, 178, 179, 94, 189, 0, 172, 234, 0, 0, 0,
+ 0, 96, 0, 170, 186, 0, 177, 208, 126, 0, 0, 173, 250, 0, 0, 0,
+ 0, 161, 162, 163, 168, 165, 0, 167, 200, 0, 227, 171, 0, 0, 0, 0,
+ 0, 0, 0, 0, 194, 0, 182, 180, 203, 0, 235, 187, 0, 0, 0, 191,
+ 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 251,
+ 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ /*
+ * Character class. This is a minor attempt to overcome the problem that
+ * inp the pfm file, all unused characters are given the width of space.
+ */
+ private int[] WinClass = {
+ 0, 0, 0, 0, 2, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 0, /* 00 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, /* 70 */
+ 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, /* 80 */
+ 0, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, /* 90 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a0 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b0 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c0 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d0 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e0 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f0 */
+ };
+
+ /*
+ * Windows chararacter names. Give a name to the usused locations
+ * for when the all flag is specified.
+ */
+ private String[] WinChars = {
+ "W00", /* 00 */
+ "W01", /* 01 */
+ "W02", /* 02 */
+ "W03", /* 03 */
+ "macron", /* 04 */
+ "breve", /* 05 */
+ "dotaccent", /* 06 */
+ "W07", /* 07 */
+ "ring", /* 08 */
+ "W09", /* 09 */
+ "W0a", /* 0a */
+ "W0b", /* 0b */
+ "W0c", /* 0c */
+ "W0d", /* 0d */
+ "W0e", /* 0e */
+ "W0f", /* 0f */
+ "hungarumlaut", /* 10 */
+ "ogonek", /* 11 */
+ "caron", /* 12 */
+ "W13", /* 13 */
+ "W14", /* 14 */
+ "W15", /* 15 */
+ "W16", /* 16 */
+ "W17", /* 17 */
+ "W18", /* 18 */
+ "W19", /* 19 */
+ "W1a", /* 1a */
+ "W1b", /* 1b */
+ "W1c", /* 1c */
+ "W1d", /* 1d */
+ "W1e", /* 1e */
+ "W1f", /* 1f */
+ "space", /* 20 */
+ "exclam", /* 21 */
+ "quotedbl", /* 22 */
+ "numbersign", /* 23 */
+ "dollar", /* 24 */
+ "percent", /* 25 */
+ "ampersand", /* 26 */
+ "quotesingle", /* 27 */
+ "parenleft", /* 28 */
+ "parenright", /* 29 */
+ "asterisk", /* 2A */
+ "plus", /* 2B */
+ "comma", /* 2C */
+ "hyphen", /* 2D */
+ "period", /* 2E */
+ "slash", /* 2F */
+ "zero", /* 30 */
+ "one", /* 31 */
+ "two", /* 32 */
+ "three", /* 33 */
+ "four", /* 34 */
+ "five", /* 35 */
+ "six", /* 36 */
+ "seven", /* 37 */
+ "eight", /* 38 */
+ "nine", /* 39 */
+ "colon", /* 3A */
+ "semicolon", /* 3B */
+ "less", /* 3C */
+ "equal", /* 3D */
+ "greater", /* 3E */
+ "question", /* 3F */
+ "at", /* 40 */
+ "A", /* 41 */
+ "B", /* 42 */
+ "C", /* 43 */
+ "D", /* 44 */
+ "E", /* 45 */
+ "F", /* 46 */
+ "G", /* 47 */
+ "H", /* 48 */
+ "I", /* 49 */
+ "J", /* 4A */
+ "K", /* 4B */
+ "L", /* 4C */
+ "M", /* 4D */
+ "N", /* 4E */
+ "O", /* 4F */
+ "P", /* 50 */
+ "Q", /* 51 */
+ "R", /* 52 */
+ "S", /* 53 */
+ "T", /* 54 */
+ "U", /* 55 */
+ "V", /* 56 */
+ "W", /* 57 */
+ "X", /* 58 */
+ "Y", /* 59 */
+ "Z", /* 5A */
+ "bracketleft", /* 5B */
+ "backslash", /* 5C */
+ "bracketright", /* 5D */
+ "asciicircum", /* 5E */
+ "underscore", /* 5F */
+ "grave", /* 60 */
+ "a", /* 61 */
+ "b", /* 62 */
+ "c", /* 63 */
+ "d", /* 64 */
+ "e", /* 65 */
+ "f", /* 66 */
+ "g", /* 67 */
+ "h", /* 68 */
+ "i", /* 69 */
+ "j", /* 6A */
+ "k", /* 6B */
+ "l", /* 6C */
+ "m", /* 6D */
+ "n", /* 6E */
+ "o", /* 6F */
+ "p", /* 70 */
+ "q", /* 71 */
+ "r", /* 72 */
+ "s", /* 73 */
+ "t", /* 74 */
+ "u", /* 75 */
+ "v", /* 76 */
+ "w", /* 77 */
+ "x", /* 78 */
+ "y", /* 79 */
+ "z", /* 7A */
+ "braceleft", /* 7B */
+ "bar", /* 7C */
+ "braceright", /* 7D */
+ "asciitilde", /* 7E */
+ "W7f", /* 7F */
+ "W80", /* 80 */
+ "W81", /* 81 */
+ "quotesinglbase", /* 82 */
+ "W83", /* 83 */
+ "quotedblbase", /* 84 */
+ "ellipsis", /* 85 */
+ "dagger", /* 86 */
+ "daggerdbl", /* 87 */
+ "asciicircum", /* 88 */
+ "perthousand", /* 89 */
+ "Scaron", /* 8A */
+ "guilsinglleft", /* 8B */
+ "OE", /* 8C */
+ "W8d", /* 8D */
+ "W8e", /* 8E */
+ "W8f", /* 8F */
+ "W90", /* 90 */
+ "quoteleft", /* 91 */
+ "quoteright", /* 92 */
+ "quotedblleft", /* 93 */
+ "quotedblright", /* 94 */
+ "bullet1", /* 95 */
+ "endash", /* 96 */
+ "emdash", /* 97 */
+ "asciitilde", /* 98 */
+ "trademark", /* 99 */
+ "scaron", /* 9A */
+ "guilsinglright", /* 9B */
+ "oe", /* 9C */
+ "W9d", /* 9D */
+ "W9e", /* 9E */
+ "Ydieresis", /* 9F */
+ "reqspace", /* A0 */
+ "exclamdown", /* A1 */
+ "cent", /* A2 */
+ "sterling", /* A3 */
+ "currency", /* A4 */
+ "yen", /* A5 */
+ "brokenbar", /* A6 */
+ "section", /* A7 */
+ "dieresis", /* A8 */
+ "copyright", /* A9 */
+ "ordfeminine", /* AA */
+ "guillemotleft", /* AB */
+ "logicalnot", /* AC */
+ "syllable", /* AD */
+ "registered", /* AE */
+ "overbar", /* AF */
+ "degree", /* B0 */
+ "plusminus", /* B1 */
+ "twosuperior", /* B2 */
+ "threesuperior", /* B3 */
+ "acute", /* B4 */
+ "mu", /* B5 */
+ "paragraph", /* B6 */
+ "periodcentered", /* B7 */
+ "cedilla", /* B8 */
+ "onesuperior", /* B9 */
+ "ordmasculine", /* BA */
+ "guillemotright", /* BB */
+ "onequarter", /* BC */
+ "onehalf", /* BD */
+ "threequarters", /* BE */
+ "questiondown", /* BF */
+ "Agrave", /* C0 */
+ "Aacute", /* C1 */
+ "Acircumflex", /* C2 */
+ "Atilde", /* C3 */
+ "Adieresis", /* C4 */
+ "Aring", /* C5 */
+ "AE", /* C6 */
+ "Ccedilla", /* C7 */
+ "Egrave", /* C8 */
+ "Eacute", /* C9 */
+ "Ecircumflex", /* CA */
+ "Edieresis", /* CB */
+ "Igrave", /* CC */
+ "Iacute", /* CD */
+ "Icircumflex", /* CE */
+ "Idieresis", /* CF */
+ "Eth", /* D0 */
+ "Ntilde", /* D1 */
+ "Ograve", /* D2 */
+ "Oacute", /* D3 */
+ "Ocircumflex", /* D4 */
+ "Otilde", /* D5 */
+ "Odieresis", /* D6 */
+ "multiply", /* D7 */
+ "Oslash", /* D8 */
+ "Ugrave", /* D9 */
+ "Uacute", /* DA */
+ "Ucircumflex", /* DB */
+ "Udieresis", /* DC */
+ "Yacute", /* DD */
+ "Thorn", /* DE */
+ "germandbls", /* DF */
+ "agrave", /* E0 */
+ "aacute", /* E1 */
+ "acircumflex", /* E2 */
+ "atilde", /* E3 */
+ "adieresis", /* E4 */
+ "aring", /* E5 */
+ "ae", /* E6 */
+ "ccedilla", /* E7 */
+ "egrave", /* E8 */
+ "eacute", /* E9 */
+ "ecircumflex", /* EA */
+ "edieresis", /* EB */
+ "igrave", /* EC */
+ "iacute", /* ED */
+ "icircumflex", /* EE */
+ "idieresis", /* EF */
+ "eth", /* F0 */
+ "ntilde", /* F1 */
+ "ograve", /* F2 */
+ "oacute", /* F3 */
+ "ocircumflex", /* F4 */
+ "otilde", /* F5 */
+ "odieresis", /* F6 */
+ "divide", /* F7 */
+ "oslash", /* F8 */
+ "ugrave", /* F9 */
+ "uacute", /* FA */
+ "ucircumflex", /* FB */
+ "udieresis", /* FC */
+ "yacute", /* FD */
+ "thorn", /* FE */
+ "ydieresis" /* FF */
+ };
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/PushbuttonField.cs b/iTechSharp/iTextSharp/text/pdf/PushbuttonField.cs
new file mode 100644
index 0000000..df38a5a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/PushbuttonField.cs
@@ -0,0 +1,628 @@
+using System;
+using iTextSharp.text;
+/*
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Creates a pushbutton field. It supports all the text and icon alignments.
+ * The icon may be an image or a template.
+ *
+ * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
+ * PdfWriter writer = PdfWriter.GetInstance(document, new FileOutputStream("output.pdf"));
+ * document.Open();
+ * PdfContentByte cb = writer.GetDirectContent();
+ * Image img = Image.GetInstance("image.png");
+ * PushbuttonField bt = new PushbuttonField(writer, new Rectangle(100, 100, 200, 200), "Button1");
+ * bt.SetText("My Caption");
+ * bt.SetFontSize(0);
+ * bt.SetImage(img);
+ * bt.SetLayout(PushbuttonField.LAYOUT_ICON_TOP_LABEL_BOTTOM);
+ * bt.SetBackgroundColor(Color.cyan);
+ * bt.SetBorderStyle(PdfBorderDictionary.STYLE_SOLID);
+ * bt.SetBorderColor(Color.red);
+ * bt.SetBorderWidth(3);
+ * PdfFormField ff = bt.GetField();
+ * PdfAction ac = PdfAction.CreateSubmitForm("http://www.submit-site.com", null, 0);
+ * ff.SetAction(ac);
+ * writer.AddAnnotation(ff);
+ * document.Close();
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class PushbuttonField : BaseField {
+
+ /** A layout option */
+ public const int LAYOUT_LABEL_ONLY = 1;
+ /** A layout option */
+ public const int LAYOUT_ICON_ONLY = 2;
+ /** A layout option */
+ public const int LAYOUT_ICON_TOP_LABEL_BOTTOM = 3;
+ /** A layout option */
+ public const int LAYOUT_LABEL_TOP_ICON_BOTTOM = 4;
+ /** A layout option */
+ public const int LAYOUT_ICON_LEFT_LABEL_RIGHT = 5;
+ /** A layout option */
+ public const int LAYOUT_LABEL_LEFT_ICON_RIGHT = 6;
+ /** A layout option */
+ public const int LAYOUT_LABEL_OVER_ICON = 7;
+ /** An icon scaling option */
+ public const int SCALE_ICON_ALWAYS = 1;
+ /** An icon scaling option */
+ public const int SCALE_ICON_NEVER = 2;
+ /** An icon scaling option */
+ public const int SCALE_ICON_IS_TOO_BIG = 3;
+ /** An icon scaling option */
+ public const int SCALE_ICON_IS_TOO_SMALL = 4;
+
+ /**
+ * Holds value of property layout.
+ */
+ private int layout = LAYOUT_LABEL_ONLY;
+
+ /**
+ * Holds value of property image.
+ */
+ private Image image;
+
+ /**
+ * Holds value of property template.
+ */
+ private PdfTemplate template;
+
+ /**
+ * Holds value of property scaleIcon.
+ */
+ private int scaleIcon = SCALE_ICON_ALWAYS;
+
+ /**
+ * Holds value of property proportionalIcon.
+ */
+ private bool proportionalIcon = true;
+
+ /**
+ * Holds value of property iconVerticalAdjustment.
+ */
+ private float iconVerticalAdjustment = 0.5f;
+
+ /**
+ * Holds value of property iconHorizontalAdjustment.
+ */
+ private float iconHorizontalAdjustment = 0.5f;
+
+ /**
+ * Holds value of property iconFitToBounds.
+ */
+ private bool iconFitToBounds;
+
+ private PdfTemplate tp;
+
+ /**
+ * Creates a new instance of PushbuttonField
+ * @param writer the document PdfWriter
+ * @param box the field location and dimensions
+ * @param fieldName the field name. If null
only the widget keys
+ * will be included in the field allowing it to be used as a kid field.
+ */
+ public PushbuttonField(PdfWriter writer, Rectangle box, String fieldName) : base(writer, box, fieldName) {
+ }
+
+ /**
+ * Sets the icon and label layout. Possible values are LAYOUT_LABEL_ONLY
,
+ * LAYOUT_ICON_ONLY
, LAYOUT_ICON_TOP_LABEL_BOTTOM
,
+ * LAYOUT_LABEL_TOP_ICON_BOTTOM
, LAYOUT_ICON_LEFT_LABEL_RIGHT
,
+ * LAYOUT_LABEL_LEFT_ICON_RIGHT
and LAYOUT_LABEL_OVER_ICON
.
+ * The default is LAYOUT_LABEL_ONLY
.
+ * @param layout New value of property layout.
+ */
+ public int Layout {
+ set {
+ if (value < LAYOUT_LABEL_ONLY || value > LAYOUT_LABEL_OVER_ICON)
+ throw new ArgumentException("Layout out of bounds.");
+ this.layout = value;
+ }
+ get {
+ return layout;
+ }
+ }
+
+ /**
+ * Sets the icon as an image.
+ * @param image the image
+ */
+ public Image Image {
+ get {
+ return this.image;
+ }
+ set {
+ image = value;
+ template = null;
+ }
+ }
+
+ /**
+ * Sets the icon as a template.
+ * @param template the template
+ */
+ public PdfTemplate Template {
+ set {
+ this.template = value;
+ image = null;
+ }
+ get {
+ return template;
+ }
+ }
+
+ /**
+ * Sets the way the icon will be scaled. Possible values are
+ * SCALE_ICON_ALWAYS
, SCALE_ICON_NEVER
,
+ * SCALE_ICON_IS_TOO_BIG
and SCALE_ICON_IS_TOO_SMALL
.
+ * The default is SCALE_ICON_ALWAYS
.
+ * @param scaleIcon the way the icon will be scaled
+ */
+ public int ScaleIcon {
+ set {
+ if (value < SCALE_ICON_ALWAYS || value > SCALE_ICON_IS_TOO_SMALL)
+ scaleIcon = SCALE_ICON_ALWAYS;
+ else
+ scaleIcon = value;
+ }
+ get {
+ return scaleIcon;
+ }
+ }
+
+ /**
+ * Sets the way the icon is scaled. If true
the icon is scaled proportionally,
+ * if false
the scaling is done anamorphicaly.
+ * @param proportionalIcon the way the icon is scaled
+ */
+ public bool ProportionalIcon {
+ get {
+ return proportionalIcon;
+ }
+ set {
+ proportionalIcon = value;
+ }
+ }
+
+ /**
+ * A number between 0 and 1 indicating the fraction of leftover space to allocate at the bottom of the icon.
+ * A value of 0 positions the icon at the bottom of the annotation rectangle.
+ * A value of 0.5 centers it within the rectangle. The default is 0.5.
+ * @param iconVerticalAdjustment a number between 0 and 1 indicating the fraction of leftover space to allocate at the bottom of the icon
+ */
+ public float IconVerticalAdjustment {
+ get {
+ return iconVerticalAdjustment;
+ }
+ set {
+ iconVerticalAdjustment = value;
+ if (iconVerticalAdjustment < 0)
+ iconVerticalAdjustment = 0;
+ else if (iconVerticalAdjustment > 1)
+ iconVerticalAdjustment = 1;
+ }
+ }
+
+ /**
+ * A number between 0 and 1 indicating the fraction of leftover space to allocate at the left of the icon.
+ * A value of 0 positions the icon at the left of the annotation rectangle.
+ * A value of 0.5 centers it within the rectangle. The default is 0.5.
+ * @param iconHorizontalAdjustment a number between 0 and 1 indicating the fraction of leftover space to allocate at the left of the icon
+ */
+ public float IconHorizontalAdjustment {
+ get {
+ return iconHorizontalAdjustment;
+ }
+ set {
+ iconHorizontalAdjustment = value;
+ if (iconHorizontalAdjustment < 0)
+ iconHorizontalAdjustment = 0;
+ else if (iconHorizontalAdjustment > 1)
+ iconHorizontalAdjustment = 1;
+ }
+ }
+ private float CalculateFontSize(float w, float h) {
+ BaseFont ufont = RealFont;
+ float fsize = fontSize;
+ if (fsize == 0) {
+ float bw = ufont.GetWidthPoint(text, 1);
+ if (bw == 0)
+ fsize = 12;
+ else
+ fsize = w / bw;
+ float nfsize = h / (1 - ufont.GetFontDescriptor(BaseFont.DESCENT, 1));
+ fsize = Math.Min(fsize, nfsize);
+ if (fsize < 4)
+ fsize = 4;
+ }
+ return fsize;
+ }
+
+ /**
+ * Gets the button appearance.
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return the button appearance
+ */
+ public PdfAppearance GetAppearance() {
+ PdfAppearance app = GetBorderAppearance();
+ Rectangle box = new Rectangle(app.BoundingBox);
+ if ((text == null || text.Length == 0) && (layout == LAYOUT_LABEL_ONLY || (image == null && template == null && iconReference == null))) {
+ return app;
+ }
+ if (layout == LAYOUT_ICON_ONLY && image == null && template == null && iconReference == null)
+ return app;
+ BaseFont ufont = RealFont;
+ bool borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET;
+ float h = box.Height - borderWidth * 2;
+ float bw2 = borderWidth;
+ if (borderExtra) {
+ h -= borderWidth * 2;
+ bw2 *= 2;
+ }
+ float offsetX = (borderExtra ? 2 * borderWidth : borderWidth);
+ offsetX = Math.Max(offsetX, 1);
+ float offX = Math.Min(bw2, offsetX);
+ tp = null;
+ float textX = float.NaN;
+ float textY = 0;
+ float fsize = fontSize;
+ float wt = box.Width - 2 * offX - 2;
+ float ht = box.Height - 2 * offX;
+ float adj = (iconFitToBounds ? 0 : offX + 1);
+ int nlayout = layout;
+ if (image == null && template == null && iconReference == null)
+ nlayout = LAYOUT_LABEL_ONLY;
+ Rectangle iconBox = null;
+ while (true) {
+ switch (nlayout) {
+ case LAYOUT_LABEL_ONLY:
+ case LAYOUT_LABEL_OVER_ICON:
+ if (text != null && text.Length > 0 && wt > 0 && ht > 0) {
+ fsize = CalculateFontSize(wt, ht);
+ textX = (box.Width - ufont.GetWidthPoint(text, fsize)) / 2;
+ textY = (box.Height - ufont.GetFontDescriptor(BaseFont.ASCENT, fsize)) / 2;
+ }
+ goto case LAYOUT_ICON_ONLY;
+ case LAYOUT_ICON_ONLY:
+ if (nlayout == LAYOUT_LABEL_OVER_ICON || nlayout == LAYOUT_ICON_ONLY)
+ iconBox = new Rectangle(box.Left + adj, box.Bottom + adj, box.Right - adj, box.Top - adj);
+ break;
+ case LAYOUT_ICON_TOP_LABEL_BOTTOM:
+ if (text == null || text.Length == 0 || wt <= 0 || ht <= 0) {
+ nlayout = LAYOUT_ICON_ONLY;
+ continue;
+ }
+ float nht = box.Height * 0.35f - offX;
+ if (nht > 0)
+ fsize = CalculateFontSize(wt, nht);
+ else
+ fsize = 4;
+ textX = (box.Width - ufont.GetWidthPoint(text, fsize)) / 2;
+ textY = offX - ufont.GetFontDescriptor(BaseFont.DESCENT, fsize);
+ iconBox = new Rectangle(box.Left + adj, textY + fsize, box.Right - adj, box.Top - adj);
+ break;
+ case LAYOUT_LABEL_TOP_ICON_BOTTOM:
+ if (text == null || text.Length == 0 || wt <= 0 || ht <= 0) {
+ nlayout = LAYOUT_ICON_ONLY;
+ continue;
+ }
+ nht = box.Height * 0.35f - offX;
+ if (nht > 0)
+ fsize = CalculateFontSize(wt, nht);
+ else
+ fsize = 4;
+ textX = (box.Width - ufont.GetWidthPoint(text, fsize)) / 2;
+ textY = box.Height - offX - fsize;
+ if (textY < offX)
+ textY = offX;
+ iconBox = new Rectangle(box.Left + adj, box.Bottom + adj, box.Right - adj, textY + ufont.GetFontDescriptor(BaseFont.DESCENT, fsize));
+ break;
+ case LAYOUT_LABEL_LEFT_ICON_RIGHT:
+ if (text == null || text.Length == 0 || wt <= 0 || ht <= 0) {
+ nlayout = LAYOUT_ICON_ONLY;
+ continue;
+ }
+ float nw = box.Width * 0.35f - offX;
+ if (nw > 0)
+ fsize = CalculateFontSize(wt, nw);
+ else
+ fsize = 4;
+ if (ufont.GetWidthPoint(text, fsize) >= wt) {
+ nlayout = LAYOUT_LABEL_ONLY;
+ fsize = fontSize;
+ continue;
+ }
+ textX = offX + 1;
+ textY = (box.Height - ufont.GetFontDescriptor(BaseFont.ASCENT, fsize)) / 2;
+ iconBox = new Rectangle(textX + ufont.GetWidthPoint(text, fsize), box.Bottom + adj, box.Right - adj, box.Top - adj);
+ break;
+ case LAYOUT_ICON_LEFT_LABEL_RIGHT:
+ if (text == null || text.Length == 0 || wt <= 0 || ht <= 0) {
+ nlayout = LAYOUT_ICON_ONLY;
+ continue;
+ }
+ nw = box.Width * 0.35f - offX;
+ if (nw > 0)
+ fsize = CalculateFontSize(wt, nw);
+ else
+ fsize = 4;
+ if (ufont.GetWidthPoint(text, fsize) >= wt) {
+ nlayout = LAYOUT_LABEL_ONLY;
+ fsize = fontSize;
+ continue;
+ }
+ textX = box.Width - ufont.GetWidthPoint(text, fsize) - offX - 1;
+ textY = (box.Height - ufont.GetFontDescriptor(BaseFont.ASCENT, fsize)) / 2;
+ iconBox = new Rectangle(box.Left + adj, box.Bottom + adj, textX - 1, box.Top - adj);
+ break;
+ }
+ break;
+ }
+ if (textY < box.Bottom + offX)
+ textY = box.Bottom + offX;
+ if (iconBox != null && (iconBox.Width <= 0 || iconBox.Height <= 0))
+ iconBox = null;
+ bool haveIcon = false;
+ float boundingBoxWidth = 0;
+ float boundingBoxHeight = 0;
+ PdfArray matrix = null;
+ if (iconBox != null) {
+ if (image != null) {
+ tp = new PdfTemplate(writer);
+ tp.BoundingBox = new Rectangle(image);
+ writer.AddDirectTemplateSimple(tp, PdfName.FRM);
+ tp.AddImage(image, image.Width, 0, 0, image.Height, 0, 0);
+ haveIcon = true;
+ boundingBoxWidth = tp.BoundingBox.Width;
+ boundingBoxHeight = tp.BoundingBox.Height;
+ }
+ else if (template != null) {
+ tp = new PdfTemplate(writer);
+ tp.BoundingBox = new Rectangle(template.Width, template.Height);
+ writer.AddDirectTemplateSimple(tp, PdfName.FRM);
+ tp.AddTemplate(template, template.BoundingBox.Left, template.BoundingBox.Bottom);
+ haveIcon = true;
+ boundingBoxWidth = tp.BoundingBox.Width;
+ boundingBoxHeight = tp.BoundingBox.Height;
+ }
+ else if (iconReference != null) {
+ PdfDictionary dic = (PdfDictionary)PdfReader.GetPdfObject(iconReference);
+ if (dic != null) {
+ Rectangle r2 = PdfReader.GetNormalizedRectangle((PdfArray)PdfReader.GetPdfObject(dic.Get(PdfName.BBOX)));
+ matrix = (PdfArray)PdfReader.GetPdfObject(dic.Get(PdfName.MATRIX));
+ haveIcon = true;
+ boundingBoxWidth = r2.Width;
+ boundingBoxHeight = r2.Height;
+ }
+ }
+ }
+ if (haveIcon) {
+ float icx = iconBox.Width / boundingBoxWidth;
+ float icy = iconBox.Height / boundingBoxHeight;
+ if (proportionalIcon) {
+ switch (scaleIcon) {
+ case SCALE_ICON_IS_TOO_BIG:
+ icx = Math.Min(icx, icy);
+ icx = Math.Min(icx, 1);
+ break;
+ case SCALE_ICON_IS_TOO_SMALL:
+ icx = Math.Min(icx, icy);
+ icx = Math.Max(icx, 1);
+ break;
+ case SCALE_ICON_NEVER:
+ icx = 1;
+ break;
+ default:
+ icx = Math.Min(icx, icy);
+ break;
+ }
+ icy = icx;
+ }
+ else {
+ switch (scaleIcon) {
+ case SCALE_ICON_IS_TOO_BIG:
+ icx = Math.Min(icx, 1);
+ icy = Math.Min(icy, 1);
+ break;
+ case SCALE_ICON_IS_TOO_SMALL:
+ icx = Math.Max(icx, 1);
+ icy = Math.Max(icy, 1);
+ break;
+ case SCALE_ICON_NEVER:
+ icx = icy = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ float xpos = iconBox.Left + (iconBox.Width - (boundingBoxWidth * icx)) * iconHorizontalAdjustment;
+ float ypos = iconBox.Bottom + (iconBox.Height - (boundingBoxHeight * icy)) * iconVerticalAdjustment;
+ app.SaveState();
+ app.Rectangle(iconBox.Left, iconBox.Bottom, iconBox.Width, iconBox.Height);
+ app.Clip();
+ app.NewPath();
+ if (tp != null)
+ app.AddTemplate(tp, icx, 0, 0, icy, xpos, ypos);
+ else {
+ float cox = 0;
+ float coy = 0;
+ if (matrix != null && matrix.Size == 6) {
+ PdfNumber nm = (PdfNumber)PdfReader.GetPdfObject((PdfObject)matrix.ArrayList[4]);
+ if (nm != null)
+ cox = nm.FloatValue;
+ nm = (PdfNumber)PdfReader.GetPdfObject((PdfObject)matrix.ArrayList[5]);
+ if (nm != null)
+ coy = nm.FloatValue;
+ }
+ app.AddTemplateReference(iconReference, PdfName.FRM, icx, 0, 0, icy, xpos - cox * icx, ypos - coy * icy);
+ }
+ app.RestoreState();
+ }
+ if (!float.IsNaN(textX)) {
+ app.SaveState();
+ app.Rectangle(offX, offX, box.Width - 2 * offX, box.Height - 2 * offX);
+ app.Clip();
+ app.NewPath();
+ if (textColor == null)
+ app.ResetGrayFill();
+ else
+ app.SetColorFill(textColor);
+ app.BeginText();
+ app.SetFontAndSize(ufont, fsize);
+ app.SetTextMatrix(textX, textY);
+ app.ShowText(text);
+ app.EndText();
+ app.RestoreState();
+ }
+ return app;
+ }
+
+ /**
+ * Gets the pushbutton field.
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return the pushbutton field
+ */
+ public PdfFormField Field {
+ get {
+ PdfFormField field = PdfFormField.CreatePushButton(writer);
+ field.SetWidget(box, PdfAnnotation.HIGHLIGHT_INVERT);
+ if (fieldName != null) {
+ field.FieldName = fieldName;
+ if ((options & READ_ONLY) != 0)
+ field.SetFieldFlags(PdfFormField.FF_READ_ONLY);
+ if ((options & REQUIRED) != 0)
+ field.SetFieldFlags(PdfFormField.FF_REQUIRED);
+ }
+ if (text != null)
+ field.MKNormalCaption = text;
+ if (rotation != 0)
+ field.MKRotation = rotation;
+ field.BorderStyle = new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3));
+ PdfAppearance tpa = GetAppearance();
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, tpa);
+ PdfAppearance da = (PdfAppearance)tpa.Duplicate;
+ da.SetFontAndSize(RealFont, fontSize);
+ if (textColor == null)
+ da.SetGrayFill(0);
+ else
+ da.SetColorFill(textColor);
+ field.DefaultAppearanceString = da;
+ if (borderColor != null)
+ field.MKBorderColor = borderColor;
+ if (backgroundColor != null)
+ field.MKBackgroundColor = backgroundColor;
+ switch (visibility) {
+ case HIDDEN:
+ field.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN;
+ break;
+ case VISIBLE_BUT_DOES_NOT_PRINT:
+ break;
+ case HIDDEN_BUT_PRINTABLE:
+ field.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW;
+ break;
+ default:
+ field.Flags = PdfAnnotation.FLAGS_PRINT;
+ break;
+ }
+ if (tp != null)
+ field.MKNormalIcon = tp;
+ field.MKTextPosition = layout - 1;
+ PdfName scale = PdfName.A;
+ if (scaleIcon == SCALE_ICON_IS_TOO_BIG)
+ scale = PdfName.B;
+ else if (scaleIcon == SCALE_ICON_IS_TOO_SMALL)
+ scale = PdfName.S;
+ else if (scaleIcon == SCALE_ICON_NEVER)
+ scale = PdfName.N;
+ field.SetMKIconFit(scale, proportionalIcon ? PdfName.P : PdfName.A, iconHorizontalAdjustment,
+ iconVerticalAdjustment, iconFitToBounds);
+ return field;
+ }
+ }
+
+ /**
+ * If true
the icon will be scaled to fit fully within the bounds of the annotation,
+ * if false
the border width will be taken into account. The default
+ * is false
.
+ * @param iconFitToBounds if true
the icon will be scaled to fit fully within the bounds of the annotation,
+ * if false
the border width will be taken into account
+ */
+ public bool IconFitToBounds {
+ get {
+ return iconFitToBounds;
+ }
+ set {
+ iconFitToBounds = value;
+ }
+ }
+ /**
+ * Holds value of property iconReference.
+ */
+ private PRIndirectReference iconReference;
+
+ /**
+ * Sets the reference to an existing icon.
+ * @param iconReference the reference to an existing icon
+ */
+ public PRIndirectReference IconReference {
+ get {
+ return iconReference;
+ }
+ set {
+ iconReference = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/RadioCheckField.cs b/iTechSharp/iTextSharp/text/pdf/RadioCheckField.cs
new file mode 100644
index 0000000..f373fb0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/RadioCheckField.cs
@@ -0,0 +1,401 @@
+using System;
+/*
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Creates a radio or a check field.
+ *
+ * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
+ * PdfWriter writer = PdfWriter.GetInstance(document, new FileOutputStream("output.pdf"));
+ * document.Open();
+ * PdfContentByte cb = writer.GetDirectContent();
+ * RadioCheckField bt = new RadioCheckField(writer, new Rectangle(100, 100, 200, 200), "radio", "v1");
+ * bt.SetCheckType(RadioCheckField.TYPE_CIRCLE);
+ * bt.SetBackgroundColor(Color.CYAN);
+ * bt.SetBorderStyle(PdfBorderDictionary.STYLE_SOLID);
+ * bt.SetBorderColor(Color.red);
+ * bt.SetTextColor(Color.yellow);
+ * bt.SetBorderWidth(BaseField.BORDER_WIDTH_THICK);
+ * bt.SetChecked(false);
+ * PdfFormField f1 = bt.GetRadioField();
+ * bt.SetOnValue("v2");
+ * bt.SetChecked(true);
+ * bt.SetBox(new Rectangle(100, 300, 200, 400));
+ * PdfFormField f2 = bt.GetRadioField();
+ * bt.SetChecked(false);
+ * PdfFormField top = bt.GetRadioGroup(true, false);
+ * bt.SetOnValue("v3");
+ * bt.SetBox(new Rectangle(100, 500, 200, 600));
+ * PdfFormField f3 = bt.GetRadioField();
+ * top.AddKid(f1);
+ * top.AddKid(f2);
+ * top.AddKid(f3);
+ * writer.AddAnnotation(top);
+ * bt = new RadioCheckField(writer, new Rectangle(300, 300, 400, 400), "check1", "Yes");
+ * bt.SetCheckType(RadioCheckField.TYPE_CHECK);
+ * bt.SetBorderWidth(BaseField.BORDER_WIDTH_THIN);
+ * bt.SetBorderColor(Color.black);
+ * bt.SetBackgroundColor(Color.white);
+ * PdfFormField ck = bt.GetCheckField();
+ * writer.AddAnnotation(ck);
+ * document.Close();
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class RadioCheckField : BaseField {
+
+ /** A field with the symbol check */
+ public const int TYPE_CHECK = 1;
+ /** A field with the symbol circle */
+ public const int TYPE_CIRCLE = 2;
+ /** A field with the symbol cross */
+ public const int TYPE_CROSS = 3;
+ /** A field with the symbol diamond */
+ public const int TYPE_DIAMOND = 4;
+ /** A field with the symbol square */
+ public const int TYPE_SQUARE = 5;
+ /** A field with the symbol star */
+ public const int TYPE_STAR = 6;
+
+ private static String[] typeChars = {"4", "l", "8", "u", "n", "H"};
+
+ /**
+ * Holds value of property checkType.
+ */
+ private int checkType;
+
+ /**
+ * Holds value of property onValue.
+ */
+ private String onValue;
+
+ /**
+ * Holds value of property checked.
+ */
+ private bool vchecked;
+
+ /**
+ * Creates a new instance of RadioCheckField
+ * @param writer the document PdfWriter
+ * @param box the field location and dimensions
+ * @param fieldName the field name. It must not be null
+ * @param onValue the value when the field is checked
+ */
+ public RadioCheckField(PdfWriter writer, Rectangle box, String fieldName, String onValue) : base(writer, box, fieldName) {
+ OnValue = onValue;
+ CheckType = TYPE_CIRCLE;
+ }
+
+ /**
+ * Sets the checked symbol. It can be
+ * TYPE_CHECK
,
+ * TYPE_CIRCLE
,
+ * TYPE_CROSS
,
+ * TYPE_DIAMOND
,
+ * TYPE_SQUARE
and
+ * TYPE_STAR
.
+ * @param checkType the checked symbol
+ */
+ public int CheckType {
+ get {
+ return checkType;
+ }
+ set {
+ checkType = value;
+ if (checkType < TYPE_CHECK || checkType > TYPE_STAR)
+ checkType = TYPE_CIRCLE;
+ Text = typeChars[checkType - 1];
+ Font = BaseFont.CreateFont(BaseFont.ZAPFDINGBATS, BaseFont.WINANSI, false);
+ }
+ }
+
+ /**
+ * Sets the value when the field is checked.
+ * @param onValue the value when the field is checked
+ */
+ public string OnValue {
+ get {
+ return onValue;
+ }
+ set {
+ onValue = value;
+ }
+ }
+
+ /**
+ * Sets the state of the field to checked or unchecked.
+ * @param checked the state of the field, true
for checked
+ * and false
for unchecked
+ */
+ public bool Checked {
+ get {
+ return vchecked;
+ }
+ set {
+ vchecked = value;
+ }
+ }
+ /**
+ * Gets the field appearance.
+ * @param isRadio true
for a radio field and false
+ * for a check field
+ * @param on true
for the checked state, false
+ * otherwise
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return the appearance
+ */
+ public PdfAppearance GetAppearance(bool isRadio, bool on) {
+ if (isRadio && checkType == TYPE_CIRCLE)
+ return GetAppearanceRadioCircle(on);
+ PdfAppearance app = GetBorderAppearance();
+ if (!on)
+ return app;
+ BaseFont ufont = RealFont;
+ bool borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET;
+ float h = box.Height - borderWidth * 2;
+ float bw2 = borderWidth;
+ if (borderExtra) {
+ h -= borderWidth * 2;
+ bw2 *= 2;
+ }
+ float offsetX = (borderExtra ? 2 * borderWidth : borderWidth);
+ offsetX = Math.Max(offsetX, 1);
+ float offX = Math.Min(bw2, offsetX);
+ float wt = box.Width - 2 * offX;
+ float ht = box.Height - 2 * offX;
+ float fsize = fontSize;
+ if (fsize == 0) {
+ float bw = ufont.GetWidthPoint(text, 1);
+ if (bw == 0)
+ fsize = 12;
+ else
+ fsize = wt / bw;
+ float nfsize = h / (ufont.GetFontDescriptor(BaseFont.ASCENT, 1));
+ fsize = Math.Min(fsize, nfsize);
+ }
+ app.SaveState();
+ app.Rectangle(offX, offX, wt, ht);
+ app.Clip();
+ app.NewPath();
+ if (textColor == null)
+ app.ResetGrayFill();
+ else
+ app.SetColorFill(textColor);
+ app.BeginText();
+ app.SetFontAndSize(ufont, fsize);
+ app.SetTextMatrix((box.Width - ufont.GetWidthPoint(text, fsize)) / 2,
+ (box.Height - ufont.GetAscentPoint(text, fsize)) / 2);
+ app.ShowText(text);
+ app.EndText();
+ app.RestoreState();
+ return app;
+ }
+
+ /**
+ * Gets the special field appearance for the radio circle.
+ * @param on true
for the checked state, false
+ * otherwise
+ * @return the appearance
+ */
+ public PdfAppearance GetAppearanceRadioCircle(bool on) {
+ PdfAppearance app = PdfAppearance.CreateAppearance(writer, box.Width, box.Height);
+ switch (rotation) {
+ case 90:
+ app.SetMatrix(0, 1, -1, 0, box.Height, 0);
+ break;
+ case 180:
+ app.SetMatrix(-1, 0, 0, -1, box.Width, box.Height);
+ break;
+ case 270:
+ app.SetMatrix(0, -1, 1, 0, 0, box.Width);
+ break;
+ }
+ Rectangle boxc = new Rectangle(app.BoundingBox);
+ float cx = boxc.Width / 2;
+ float cy = boxc.Height / 2;
+ float r = (Math.Min(boxc.Width, boxc.Height) - borderWidth) / 2;
+ if (r <= 0)
+ return app;
+ if (backgroundColor != null) {
+ app.SetColorFill(backgroundColor);
+ app.Circle(cx, cy, r + borderWidth / 2);
+ app.Fill();
+ }
+ if (borderWidth > 0 && borderColor != null) {
+ app.SetLineWidth(borderWidth);
+ app.SetColorStroke(borderColor);
+ app.Circle(cx, cy, r);
+ app.Stroke();
+ }
+ if (on) {
+ if (textColor == null)
+ app.ResetGrayFill();
+ else
+ app.SetColorFill(textColor);
+ app.Circle(cx, cy, r / 2);
+ app.Fill();
+ }
+ return app;
+ }
+
+ /**
+ * Gets a radio group. It's composed of the field specific keys, without the widget
+ * ones. This field is to be used as a field aggregator with {@link PdfFormField#addKid(PdfFormField) AddKid()}.
+ * @param noToggleToOff if true
, exactly one radio button must be selected at all
+ * times; clicking the currently selected button has no effect.
+ * If false
, clicking
+ * the selected button deselects it, leaving no button selected.
+ * @param radiosInUnison if true
, a group of radio buttons within a radio button field that
+ * use the same value for the on state will turn on and off in unison; that is if
+ * one is checked, they are all checked. If false
, the buttons are mutually exclusive
+ * (the same behavior as HTML radio buttons)
+ * @return the radio group
+ */
+ public PdfFormField GetRadioGroup(bool noToggleToOff, bool radiosInUnison) {
+ PdfFormField field = PdfFormField.CreateRadioButton(writer, noToggleToOff);
+ if (radiosInUnison)
+ field.SetFieldFlags(PdfFormField.FF_RADIOSINUNISON);
+ field.FieldName = fieldName;
+ if ((options & READ_ONLY) != 0)
+ field.SetFieldFlags(PdfFormField.FF_READ_ONLY);
+ if ((options & REQUIRED) != 0)
+ field.SetFieldFlags(PdfFormField.FF_REQUIRED);
+ field.ValueAsName = vchecked ? onValue : "Off";
+ return field;
+ }
+
+ /**
+ * Gets the radio field. It's only composed of the widget keys and must be used
+ * with {@link #getRadioGroup(bool,bool)}.
+ * @return the radio field
+ * @throws IOException on error
+ * @throws DocumentException on error
+ */
+ public PdfFormField RadioField {
+ get {
+ return GetField(true);
+ }
+ }
+
+ /**
+ * Gets the check field.
+ * @return the check field
+ * @throws IOException on error
+ * @throws DocumentException on error
+ */
+ public PdfFormField CheckField {
+ get {
+ return GetField(false);
+ }
+ }
+
+ /**
+ * Gets a radio or check field.
+ * @param isRadio true
to get a radio field, false
to get
+ * a check field
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return the field
+ */
+ protected PdfFormField GetField(bool isRadio) {
+ PdfFormField field = null;
+ if (isRadio)
+ field = PdfFormField.CreateEmpty(writer);
+ else
+ field = PdfFormField.CreateCheckBox(writer);
+ field.SetWidget(box, PdfAnnotation.HIGHLIGHT_INVERT);
+ if (!isRadio) {
+ field.FieldName = fieldName;
+ if ((options & READ_ONLY) != 0)
+ field.SetFieldFlags(PdfFormField.FF_READ_ONLY);
+ if ((options & REQUIRED) != 0)
+ field.SetFieldFlags(PdfFormField.FF_REQUIRED);
+ field.ValueAsName = vchecked ? onValue : "Off";
+ }
+ if (text != null)
+ field.MKNormalCaption = text;
+ if (rotation != 0)
+ field.MKRotation = rotation;
+ field.BorderStyle = new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3));
+ PdfAppearance tpon = GetAppearance(isRadio, true);
+ PdfAppearance tpoff = GetAppearance(isRadio, false);
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, onValue, tpon);
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpoff);
+ field.AppearanceState = vchecked ? onValue : "Off";
+ PdfAppearance da = (PdfAppearance)tpon.Duplicate;
+ da.SetFontAndSize(RealFont, fontSize);
+ if (textColor == null)
+ da.SetGrayFill(0);
+ else
+ da.SetColorFill(textColor);
+ field.DefaultAppearanceString = da;
+ if (borderColor != null)
+ field.MKBorderColor = borderColor;
+ if (backgroundColor != null)
+ field.MKBackgroundColor = backgroundColor;
+ switch (visibility) {
+ case HIDDEN:
+ field.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN;
+ break;
+ case VISIBLE_BUT_DOES_NOT_PRINT:
+ break;
+ case HIDDEN_BUT_PRINTABLE:
+ field.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW;
+ break;
+ default:
+ field.Flags = PdfAnnotation.FLAGS_PRINT;
+ break;
+ }
+ return field;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/RandomAccessFileOrArray.cs b/iTechSharp/iTextSharp/text/pdf/RandomAccessFileOrArray.cs
new file mode 100644
index 0000000..ea6a7b0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/RandomAccessFileOrArray.cs
@@ -0,0 +1,607 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Net;
+/*
+ * $Id: RandomAccessFileOrArray.cs,v 1.9 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** An implementation of a RandomAccessFile for input only
+ * that accepts a file or a byte array as data source.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class RandomAccessFileOrArray {
+
+ internal FileStream rf;
+ internal String filename;
+ internal byte[] arrayIn;
+ internal int arrayInPtr;
+ internal byte back;
+ internal bool isBack = false;
+
+ /** Holds value of property startOffset. */
+ private int startOffset = 0;
+
+ public RandomAccessFileOrArray(String filename) : this(filename, false) {
+ }
+
+ public RandomAccessFileOrArray(String filename, bool forceRead) {
+ if (!File.Exists(filename)) {
+ if (filename.StartsWith("file:/") || filename.StartsWith("http://") || filename.StartsWith("https://")) {
+ Stream isp = WebRequest.Create(new Uri(filename)).GetResponse().GetResponseStream();
+ try {
+ this.arrayIn = InputStreamToArray(isp);
+ return;
+ }
+ finally {
+ try {isp.Close();}catch{}
+ }
+ }
+ else {
+ Stream isp = BaseFont.GetResourceStream(filename);
+ if (isp == null)
+ throw new IOException(filename + " not found as file or resource.");
+ try {
+ this.arrayIn = InputStreamToArray(isp);
+ return;
+ }
+ finally {
+ try {isp.Close();}catch{}
+ }
+ }
+ }
+ else if (forceRead) {
+ Stream s = null;
+ try {
+ s = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
+ this.arrayIn = InputStreamToArray(s);
+ }
+ finally {
+ try{if (s != null) s.Close();}catch{}
+ }
+ return;
+ }
+ this.filename = filename;
+ rf = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
+ }
+
+ public RandomAccessFileOrArray(Uri url) {
+ Stream isp = WebRequest.Create(url).GetResponse().GetResponseStream();
+ try {
+ this.arrayIn = InputStreamToArray(isp);
+ }
+ finally {
+ try {isp.Close();}catch{}
+ }
+ }
+
+ public RandomAccessFileOrArray(Stream isp) {
+ this.arrayIn = InputStreamToArray(isp);
+ }
+
+ public static byte[] InputStreamToArray(Stream isp) {
+ byte[] b = new byte[8192];
+ MemoryStream outp = new MemoryStream();
+ while (true) {
+ int read = isp.Read(b, 0, b.Length);
+ if (read < 1)
+ break;
+ outp.Write(b, 0, read);
+ }
+ return outp.ToArray();
+ }
+
+ public RandomAccessFileOrArray(byte[] arrayIn) {
+ this.arrayIn = arrayIn;
+ }
+
+ public RandomAccessFileOrArray(RandomAccessFileOrArray file) {
+ filename = file.filename;
+ arrayIn = file.arrayIn;
+ startOffset = file.startOffset;
+ }
+
+ public void PushBack(byte b) {
+ back = b;
+ isBack = true;
+ }
+
+ public int Read() {
+ if (isBack) {
+ isBack = false;
+ return back & 0xff;
+ }
+ if (arrayIn == null)
+ return rf.ReadByte();
+ else {
+ if (arrayInPtr >= arrayIn.Length)
+ return -1;
+ return arrayIn[arrayInPtr++] & 0xff;
+ }
+ }
+
+ public int Read(byte[] b, int off, int len) {
+ if (len == 0)
+ return 0;
+ int n = 0;
+ if (isBack) {
+ isBack = false;
+ if (len == 1) {
+ b[off] = back;
+ return 1;
+ }
+ else {
+ n = 1;
+ b[off++] = back;
+ --len;
+ }
+ }
+ if (arrayIn == null) {
+ return rf.Read(b, off, len) + n;
+ }
+ else {
+ if (arrayInPtr >= arrayIn.Length)
+ return -1;
+ if (arrayInPtr + len > arrayIn.Length)
+ len = arrayIn.Length - arrayInPtr;
+ Array.Copy(arrayIn, arrayInPtr, b, off, len);
+ arrayInPtr += len;
+ return len + n;
+ }
+ }
+
+ public int Read(byte[] b) {
+ return Read(b, 0, b.Length);
+ }
+
+ public void ReadFully(byte[] b) {
+ ReadFully(b, 0, b.Length);
+ }
+
+ public void ReadFully(byte[] b, int off, int len) {
+ if (len == 0)
+ return;
+ int n = 0;
+ do {
+ int count = Read(b, off + n, len - n);
+ if (count <= 0)
+ throw new EndOfStreamException();
+ n += count;
+ } while (n < len);
+ }
+
+ public long Skip(long n) {
+ return SkipBytes((int)n);
+ }
+
+ public int SkipBytes(int n) {
+ if (n <= 0) {
+ return 0;
+ }
+ int adj = 0;
+ if (isBack) {
+ isBack = false;
+ if (n == 1) {
+ return 1;
+ }
+ else {
+ --n;
+ adj = 1;
+ }
+ }
+ int pos;
+ int len;
+ int newpos;
+
+ pos = FilePointer;
+ len = Length;
+ newpos = pos + n;
+ if (newpos > len) {
+ newpos = len;
+ }
+ Seek(newpos);
+
+ /* return the actual number of bytes skipped */
+ return newpos - pos + adj;
+ }
+
+ public void ReOpen() {
+ if (filename != null && rf == null)
+ rf = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
+ Seek(0);
+ }
+
+ protected void InsureOpen() {
+ if (filename != null && rf == null) {
+ ReOpen();
+ }
+ }
+
+ public bool IsOpen() {
+ return (filename == null || rf != null);
+ }
+
+ public void Close() {
+ isBack = false;
+ if (rf != null) {
+ rf.Close();
+ rf = null;
+ }
+ }
+
+ public int Length {
+ get {
+ if (arrayIn == null) {
+ InsureOpen();
+ return (int)rf.Length - startOffset;
+ }
+ else
+ return arrayIn.Length - startOffset;
+ }
+ }
+
+ public void Seek(int pos) {
+ pos += startOffset;
+ isBack = false;
+ if (arrayIn == null) {
+ InsureOpen();
+ rf.Position = pos;
+ }
+ else
+ arrayInPtr = pos;
+ }
+
+ public void Seek(long pos) {
+ Seek((int)pos);
+ }
+
+ public int FilePointer {
+ get {
+ InsureOpen();
+ int n = isBack ? 1 : 0;
+ if (arrayIn == null) {
+ return (int)rf.Position - n - startOffset;
+ }
+ else
+ return arrayInPtr - n - startOffset;
+ }
+ }
+
+ public bool ReadBoolean() {
+ int ch = this.Read();
+ if (ch < 0)
+ throw new EndOfStreamException();
+ return (ch != 0);
+ }
+
+ public byte ReadByte() {
+ int ch = this.Read();
+ if (ch < 0)
+ throw new EndOfStreamException();
+ return (byte)(ch);
+ }
+
+ public int ReadUnsignedByte() {
+ int ch = this.Read();
+ if (ch < 0)
+ throw new EndOfStreamException();
+ return ch;
+ }
+
+ public short ReadShort() {
+ int ch1 = this.Read();
+ int ch2 = this.Read();
+ if ((ch1 | ch2) < 0)
+ throw new EndOfStreamException();
+ return (short)((ch1 << 8) + ch2);
+ }
+
+ /**
+ * Reads a signed 16-bit number from this stream in little-endian order.
+ * The method reads two
+ * bytes from this stream, starting at the current stream pointer.
+ * If the two bytes read, in order, are
+ * b1
and b2
, where each of the two values is
+ * between 0
and 255
, inclusive, then the
+ * result is equal to:
+ *
+ *
+ * (short)((b2 << 8) | b1)
+ *
b1
and b2
, where
+ * 0 <= b1, b2 <= 255
,
+ * then the result is equal to:
+ *
+ *
+ * (b2 << 8) | b1
+ *
b1
and b2
, where
+ * 0 <= b1, b2 <= 255
,
+ * then the result is equal to:
+ *
+ *
+ * (char)((b2 << 8) | b1)
+ *
b1
,
+ * b2
, b3
, and b4
, where
+ * 0 <= b1, b2, b3, b4 <= 255
,
+ * then the result is equal to:
+ *
+ *
+ * (b4 << 24) | (b3 << 16) + (b2 << 8) + b1
+ *
int
.
+ * @exception EOFException if this stream reaches the end before reading
+ * four bytes.
+ * @exception IOException if an I/O error occurs.
+ */
+ public int ReadIntLE() {
+ int ch1 = this.Read();
+ int ch2 = this.Read();
+ int ch3 = this.Read();
+ int ch4 = this.Read();
+ if ((ch1 | ch2 | ch3 | ch4) < 0)
+ throw new EndOfStreamException();
+ return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
+ }
+
+ /**
+ * Reads an unsigned 32-bit integer from this stream. This method reads 4
+ * bytes from the stream, starting at the current stream pointer.
+ * If the bytes read, in order, are b1
,
+ * b2
, b3
, and b4
, where
+ * 0 <= b1, b2, b3, b4 <= 255
,
+ * then the result is equal to:
+ *
+ *
+ * (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
+ *
long
.
+ * @exception EOFException if this stream reaches the end before reading
+ * four bytes.
+ * @exception IOException if an I/O error occurs.
+ */
+ public long ReadUnsignedInt() {
+ long ch1 = this.Read();
+ long ch2 = this.Read();
+ long ch3 = this.Read();
+ long ch4 = this.Read();
+ if ((ch1 | ch2 | ch3 | ch4) < 0)
+ throw new EndOfStreamException();
+ return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
+ }
+
+ public long ReadUnsignedIntLE() {
+ long ch1 = this.Read();
+ long ch2 = this.Read();
+ long ch3 = this.Read();
+ long ch4 = this.Read();
+ if ((ch1 | ch2 | ch3 | ch4) < 0)
+ throw new EndOfStreamException();
+ return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
+ }
+
+ public long ReadLong() {
+ return ((long)(ReadInt()) << 32) + (ReadInt() & 0xFFFFFFFFL);
+ }
+
+ public long ReadLongLE() {
+ int i1 = ReadIntLE();
+ int i2 = ReadIntLE();
+ return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL);
+ }
+
+ public float ReadFloat() {
+ int[] a = {ReadInt()};
+ float[] b = {0};
+ Buffer.BlockCopy(a, 0, b, 0, 4);
+ return b[0];
+ }
+
+ public float ReadFloatLE() {
+ int[] a = {ReadIntLE()};
+ float[] b = {0};
+ Buffer.BlockCopy(a, 0, b, 0, 4);
+ return b[0];
+ }
+
+ public double ReadDouble() {
+ long[] a = {ReadLong()};
+ double[] b = {0};
+ Buffer.BlockCopy(a, 0, b, 0, 8);
+ return b[0];
+ }
+
+ public double ReadDoubleLE() {
+ long[] a = {ReadLongLE()};
+ double[] b = {0};
+ Buffer.BlockCopy(a, 0, b, 0, 8);
+ return b[0];
+ }
+
+ public String ReadLine() {
+ StringBuilder input = new StringBuilder();
+ int c = -1;
+ bool eol = false;
+
+ while (!eol) {
+ switch (c = Read()) {
+ case -1:
+ case '\n':
+ eol = true;
+ break;
+ case '\r':
+ eol = true;
+ int cur = FilePointer;
+ if ((Read()) != '\n') {
+ Seek(cur);
+ }
+ break;
+ default:
+ input.Append((char)c);
+ break;
+ }
+ }
+
+ if ((c == -1) && (input.Length == 0)) {
+ return null;
+ }
+ return input.ToString();
+ }
+
+ public int StartOffset {
+ get {
+ return startOffset;
+ }
+ set {
+ startOffset = value;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/SequenceList.cs b/iTechSharp/iTextSharp/text/pdf/SequenceList.cs
new file mode 100644
index 0000000..04b6b7b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/SequenceList.cs
@@ -0,0 +1,317 @@
+using System;
+using System.Collections;
+using System.Text;
+using System.util;
+/*
+ * Copyright 2004 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * This class expands a string into a list of numbers. The main use is to select a
+ * range of pages.
+ *
+ * [!][o][odd][e][even]start-end
+ * Integer
+ */
+ public static ArrayList Expand(String ranges, int maxNumber) {
+ SequenceList parse = new SequenceList(ranges);
+ ArrayList list = new ArrayList();
+ bool sair = false;
+ while (!sair) {
+ sair = parse.GetAttributes();
+ if (parse.low == -1 && parse.high == -1 && !parse.even && !parse.odd)
+ continue;
+ if (parse.low < 1)
+ parse.low = 1;
+ if (parse.high < 1 || parse.high > maxNumber)
+ parse.high = maxNumber;
+ if (parse.low > maxNumber)
+ parse.low = maxNumber;
+
+ //System.out.Println("low="+parse.low+",high="+parse.high+",odd="+parse.odd+",even="+parse.even+",inverse="+parse.inverse);
+ int inc = 1;
+ if (parse.inverse) {
+ if (parse.low > parse.high) {
+ int t = parse.low;
+ parse.low = parse.high;
+ parse.high = t;
+ }
+ for (ListIterator it = new ListIterator(list); it.HasNext();) {
+ int n = (int)it.Next();
+ if (parse.even && (n & 1) == 1)
+ continue;
+ if (parse.odd && (n & 1) == 0)
+ continue;
+ if (n >= parse.low && n <= parse.high)
+ it.Remove();
+ }
+ }
+ else {
+ if (parse.low > parse.high) {
+ inc = -1;
+ if (parse.odd || parse.even) {
+ --inc;
+ if (parse.even)
+ parse.low &= ~1;
+ else
+ parse.low -= ((parse.low & 1) == 1 ? 0 : 1);
+ }
+ for (int k = parse.low; k >= parse.high; k += inc) {
+ list.Add(k);
+ }
+ }
+ else {
+ if (parse.odd || parse.even) {
+ ++inc;
+ if (parse.odd)
+ parse.low |= 1;
+ else
+ parse.low += ((parse.low & 1) == 1 ? 1 : 0);
+ }
+ for (int k = parse.low; k <= parse.high; k += inc)
+ list.Add(k);
+ }
+ }
+ }
+ return list;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/ShadingColor.cs b/iTechSharp/iTextSharp/text/pdf/ShadingColor.cs
new file mode 100644
index 0000000..3a4d7c3
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/ShadingColor.cs
@@ -0,0 +1,78 @@
+using System;
+
+/*
+ * Copyright 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Implements a shading pattern as a Color
.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class ShadingColor : ExtendedColor {
+
+ PdfShadingPattern shadingPattern;
+
+ public ShadingColor(PdfShadingPattern shadingPattern) : base(TYPE_SHADING, .5f, .5f, .5f) {
+ this.shadingPattern = shadingPattern;
+ }
+
+ public PdfShadingPattern PdfShadingPattern {
+ get {
+ return shadingPattern;
+ }
+ }
+
+ public override bool Equals(Object obj) {
+ return this == obj;
+ }
+
+ public override int GetHashCode() {
+ return shadingPattern.GetHashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/SimpleBookmark.cs b/iTechSharp/iTextSharp/text/pdf/SimpleBookmark.cs
new file mode 100644
index 0000000..c7c5a50
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/SimpleBookmark.cs
@@ -0,0 +1,799 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Text;
+using System.util;
+using iTextSharp.text.xml.simpleparser;
+
+/*
+ * Copyright 2003 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Bookmark processing in a simple way. It has some limitations, mainly the only
+ * action types supported are GoTo, GoToR, URI and Launch.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public sealed class SimpleBookmark : ISimpleXMLDocHandler {
+
+ private ArrayList topList;
+ private Stack attr = new Stack();
+
+ /** Creates a new instance of SimpleBookmark */
+ private SimpleBookmark() {
+ }
+
+ private static ArrayList BookmarkDepth(PdfReader reader, PdfDictionary outline, IntHashtable pages) {
+ ArrayList list = new ArrayList();
+ while (outline != null) {
+ Hashtable map = new Hashtable();
+ PdfString title = (PdfString)PdfReader.GetPdfObjectRelease(outline.Get(PdfName.TITLE));
+ map["Title"] = title.ToUnicodeString();
+ PdfArray color = (PdfArray)PdfReader.GetPdfObjectRelease(outline.Get(PdfName.C));
+ if (color != null && color.ArrayList.Count == 3) {
+ ByteBuffer outp = new ByteBuffer();
+ ArrayList arr = color.ArrayList;
+ outp.Append(((PdfNumber)arr[0]).FloatValue).Append(' ');
+ outp.Append(((PdfNumber)arr[1]).FloatValue).Append(' ');
+ outp.Append(((PdfNumber)arr[2]).FloatValue);
+ map["Color"] = PdfEncodings.ConvertToString(outp.ToByteArray(), null);
+ }
+ PdfNumber style = (PdfNumber)PdfReader.GetPdfObjectRelease(outline.Get(PdfName.F));
+ if (style != null) {
+ int f = style.IntValue;
+ String s = "";
+ if ((f & 1) != 0)
+ s += "italic ";
+ if ((f & 2) != 0)
+ s += "bold ";
+ s = s.Trim();
+ if (s.Length != 0)
+ map["Style"] = s;
+ }
+ PdfNumber count = (PdfNumber)PdfReader.GetPdfObjectRelease(outline.Get(PdfName.COUNT));
+ if (count != null && count.IntValue < 0)
+ map["Open"] = "false";
+ try {
+ PdfObject dest = PdfReader.GetPdfObjectRelease(outline.Get(PdfName.DEST));
+ if (dest != null) {
+ MapGotoBookmark(map, dest, pages); //changed by ujihara 2004-06-13
+ }
+ else {
+ PdfDictionary action = (PdfDictionary)PdfReader.GetPdfObjectRelease(outline.Get(PdfName.A));
+ if (action != null) {
+ if (PdfName.GOTO.Equals(PdfReader.GetPdfObjectRelease(action.Get(PdfName.S)))) {
+ dest = PdfReader.GetPdfObjectRelease(action.Get(PdfName.D));
+ if (dest != null) {
+ MapGotoBookmark(map, dest, pages);
+ }
+ }
+ else if (PdfName.URI.Equals(PdfReader.GetPdfObjectRelease(action.Get(PdfName.S)))) {
+ map["Action"] = "URI";
+ map["URI"] = ((PdfString)PdfReader.GetPdfObjectRelease(action.Get(PdfName.URI))).ToUnicodeString();
+ }
+ else if (PdfName.GOTOR.Equals(PdfReader.GetPdfObjectRelease(action.Get(PdfName.S)))) {
+ dest = PdfReader.GetPdfObjectRelease(action.Get(PdfName.D));
+ if (dest != null) {
+ if (dest.IsString())
+ map["Named"] = dest.ToString();
+ else if (dest.IsName())
+ map["NamedN"] = PdfName.DecodeName(dest.ToString());
+ else if (dest.IsArray()) {
+ ArrayList arr = ((PdfArray)dest).ArrayList;
+ StringBuilder s = new StringBuilder();
+ s.Append(arr[0].ToString());
+ s.Append(' ').Append(arr[1].ToString());
+ for (int k = 2; k < arr.Count; ++k)
+ s.Append(' ').Append(arr[k].ToString());
+ map["Page"] = s.ToString();
+ }
+ }
+ map["Action"] = "GoToR";
+ PdfObject file = PdfReader.GetPdfObjectRelease(action.Get(PdfName.F));
+ if (file != null) {
+ if (file.IsString())
+ map["File"] = ((PdfString)file).ToUnicodeString();
+ else if (file.IsDictionary()) {
+ file = PdfReader.GetPdfObject(((PdfDictionary)file).Get(PdfName.F));
+ if (file.IsString())
+ map["File"] = ((PdfString)file).ToUnicodeString();
+ }
+ }
+ PdfObject newWindow = PdfReader.GetPdfObjectRelease(action.Get(PdfName.NEWWINDOW));
+ if (newWindow != null)
+ map["NewWindow"] = newWindow.ToString();
+ }
+ else if (PdfName.LAUNCH.Equals(PdfReader.GetPdfObjectRelease(action.Get(PdfName.S)))) {
+ map["Action"] = "Launch";
+ PdfObject file = PdfReader.GetPdfObjectRelease(action.Get(PdfName.F));
+ if (file == null)
+ file = PdfReader.GetPdfObjectRelease(action.Get(PdfName.WIN));
+ if (file != null) {
+ if (file.IsString())
+ map["File"] = ((PdfString)file).ToUnicodeString();
+ else if (file.IsDictionary()) {
+ file = PdfReader.GetPdfObjectRelease(((PdfDictionary)file).Get(PdfName.F));
+ if (file.IsString())
+ map["File"] = ((PdfString)file).ToUnicodeString();
+ }
+ }
+ }
+ }
+ }
+ }
+ catch {
+ //empty on purpose
+ }
+ PdfDictionary first = (PdfDictionary)PdfReader.GetPdfObjectRelease(outline.Get(PdfName.FIRST));
+ if (first != null) {
+ map["Kids"] = BookmarkDepth(reader, first, pages);
+ }
+ list.Add(map);
+ outline = (PdfDictionary)PdfReader.GetPdfObjectRelease(outline.Get(PdfName.NEXT));
+ }
+ return list;
+ }
+
+ private static void MapGotoBookmark(Hashtable map, PdfObject dest, IntHashtable pages)
+ {
+ if (dest.IsString())
+ map["Named"] = dest.ToString();
+ else if (dest.IsName())
+ map["Named"] = PdfName.DecodeName(dest.ToString());
+ else if (dest.IsArray())
+ map["Page"] = MakeBookmarkParam((PdfArray)dest, pages); //changed by ujihara 2004-06-13
+ map["Action"] = "GoTo";
+ }
+
+ private static String MakeBookmarkParam(PdfArray dest, IntHashtable pages)
+ {
+ ArrayList arr = dest.ArrayList;
+ StringBuilder s = new StringBuilder();
+ s.Append(pages[GetNumber((PdfIndirectReference)arr[0])]); //changed by ujihara 2004-06-13
+ s.Append(' ').Append(arr[1].ToString().Substring(1));
+ for (int k = 2; k < arr.Count; ++k)
+ s.Append(' ').Append(arr[k].ToString());
+ return s.ToString();
+ }
+
+ /**
+ * Gets number of indirect. If type of directed indirect is PAGES, it refers PAGE object through KIDS.
+ * (Contributed by Kazuya Ujihara)
+ * @param indirect
+ * 2004-06-13
+ */
+ private static int GetNumber(PdfIndirectReference indirect)
+ {
+ PdfDictionary pdfObj = (PdfDictionary)PdfReader.GetPdfObjectRelease(indirect);
+ if (pdfObj.Contains(PdfName.TYPE) && pdfObj.Get(PdfName.TYPE).Equals(PdfName.PAGES) && pdfObj.Contains(PdfName.KIDS))
+ {
+ PdfArray kids = (PdfArray)pdfObj.Get(PdfName.KIDS);
+ indirect = (PdfIndirectReference)kids.ArrayList[0];
+ }
+ return indirect.Number;
+ }
+
+ /**
+ * Gets a List
with the bookmarks. It returns null
if
+ * the document doesn't have any bookmarks.
+ * @param reader the document
+ * @return a List
with the bookmarks or null
if the
+ * document doesn't have any
+ */
+ public static ArrayList GetBookmark(PdfReader reader) {
+ PdfDictionary catalog = reader.Catalog;
+ PdfObject obj = PdfReader.GetPdfObjectRelease(catalog.Get(PdfName.OUTLINES));
+ if (obj == null || !obj.IsDictionary())
+ return null;
+ PdfDictionary outlines = (PdfDictionary)obj;
+ IntHashtable pages = new IntHashtable();
+ int numPages = reader.NumberOfPages;
+ for (int k = 1; k <= numPages; ++k) {
+ pages[reader.GetPageOrigRef(k).Number] = k;
+ reader.ReleasePage(k);
+ }
+ return BookmarkDepth(reader, (PdfDictionary)PdfReader.GetPdfObjectRelease(outlines.Get(PdfName.FIRST)), pages);
+ }
+
+ /**
+ * Removes the bookmark entries for a number of page ranges. The page ranges
+ * consists of a number of pairs with the start/end page range. The page numbers
+ * are inclusive.
+ * @param list the bookmarks
+ * @param pageRange the page ranges, always in pairs.
+ */
+ public static void EliminatePages(ArrayList list, int[] pageRange) {
+ if (list == null)
+ return;
+
+ for (ListIterator it = new ListIterator(list); it.HasNext();) {
+ Hashtable map = (Hashtable)it.Next();
+ bool hit = false;
+ if ("GoTo".Equals(map["Action"])) {
+ String page = (String)map["Page"];
+ if (page != null) {
+ page = page.Trim();
+ int idx = page.IndexOf(' ');
+ int pageNum;
+ if (idx < 0)
+ pageNum = int.Parse(page);
+ else
+ pageNum = int.Parse(page.Substring(0, idx));
+ int len = pageRange.Length & 0x7ffffffe;
+ for (int k = 0; k < len; k += 2) {
+ if (pageNum >= pageRange[k] && pageNum <= pageRange[k + 1]) {
+ hit = true;
+ break;
+ }
+ }
+ }
+ }
+ ArrayList kids = (ArrayList)map["Kids"];
+ if (kids != null) {
+ EliminatePages(kids, pageRange);
+ if (kids.Count == 0) {
+ map.Remove("Kids");
+ kids = null;
+ }
+ }
+ if (hit) {
+ if (kids == null)
+ it.Remove();
+ else {
+ map.Remove("Action");
+ map.Remove("Page");
+ map.Remove("Named");
+ }
+ }
+ }
+ }
+
+ /**
+ * For the pages in range add the pageShift
to the page number.
+ * The page ranges
+ * consists of a number of pairs with the start/end page range. The page numbers
+ * are inclusive.
+ * @param list the bookmarks
+ * @param pageShift the number to add to the pages in range
+ * @param pageRange the page ranges, always in pairs. It can be null
+ * to include all the pages
+ */
+ public static void ShiftPageNumbers(ArrayList list, int pageShift, int[] pageRange) {
+ if (list == null)
+ return;
+ foreach (Hashtable map in list) {
+ if ("GoTo".Equals(map["Action"])) {
+ String page = (String)map["Page"];
+ if (page != null) {
+ page = page.Trim();
+ int idx = page.IndexOf(' ');
+ int pageNum;
+ if (idx < 0)
+ pageNum = int.Parse(page);
+ else
+ pageNum = int.Parse(page.Substring(0, idx));
+ bool hit = false;
+ if (pageRange == null)
+ hit = true;
+ else {
+ int len = pageRange.Length & 0x7ffffffe;
+ for (int k = 0; k < len; k += 2) {
+ if (pageNum >= pageRange[k] && pageNum <= pageRange[k + 1]) {
+ hit = true;
+ break;
+ }
+ }
+ }
+ if (hit) {
+ if (idx < 0)
+ page = (pageNum + pageShift) + "";
+ else
+ page = (pageNum + pageShift) + page.Substring(idx);
+ }
+ map["Page"] = page;
+ }
+ }
+ ArrayList kids = (ArrayList)map["Kids"];
+ if (kids != null)
+ ShiftPageNumbers(kids, pageShift, pageRange);
+ }
+ }
+
+ internal static void CreateOutlineAction(PdfDictionary outline, Hashtable map, PdfWriter writer, bool namedAsNames) {
+ try {
+ String action = (String)map["Action"];
+ if ("GoTo".Equals(action)) {
+ String p;
+ if ((p = (String)map["Named"]) != null) {
+ if (namedAsNames)
+ outline.Put(PdfName.DEST, new PdfName(p));
+ else
+ outline.Put(PdfName.DEST, new PdfString(p, null));
+ }
+ else if ((p = (String)map["Page"]) != null) {
+ PdfArray ar = new PdfArray();
+ StringTokenizer tk = new StringTokenizer(p);
+ int n = int.Parse(tk.NextToken());
+ ar.Add(writer.GetPageReference(n));
+ if (!tk.HasMoreTokens()) {
+ ar.Add(PdfName.XYZ);
+ ar.Add(new float[]{0, 10000, 0});
+ }
+ else {
+ String fn = tk.NextToken();
+ if (fn.StartsWith("/"))
+ fn = fn.Substring(1);
+ ar.Add(new PdfName(fn));
+ for (int k = 0; k < 4 && tk.HasMoreTokens(); ++k) {
+ fn = tk.NextToken();
+ if (fn.Equals("null"))
+ ar.Add(PdfNull.PDFNULL);
+ else
+ ar.Add(new PdfNumber(fn));
+ }
+ }
+ outline.Put(PdfName.DEST, ar);
+ }
+ }
+ else if ("GoToR".Equals(action)) {
+ String p;
+ PdfDictionary dic = new PdfDictionary();
+ if ((p = (String)map["Named"]) != null)
+ dic.Put(PdfName.D, new PdfString(p, null));
+ else if ((p = (String)map["NamedN"]) != null)
+ dic.Put(PdfName.D, new PdfName(p));
+ else if ((p = (String)map["Page"]) != null){
+ PdfArray ar = new PdfArray();
+ StringTokenizer tk = new StringTokenizer(p);
+ ar.Add(new PdfNumber(tk.NextToken()));
+ if (!tk.HasMoreTokens()) {
+ ar.Add(PdfName.XYZ);
+ ar.Add(new float[]{0, 10000, 0});
+ }
+ else {
+ String fn = tk.NextToken();
+ if (fn.StartsWith("/"))
+ fn = fn.Substring(1);
+ ar.Add(new PdfName(fn));
+ for (int k = 0; k < 4 && tk.HasMoreTokens(); ++k) {
+ fn = tk.NextToken();
+ if (fn.Equals("null"))
+ ar.Add(PdfNull.PDFNULL);
+ else
+ ar.Add(new PdfNumber(fn));
+ }
+ }
+ dic.Put(PdfName.D, ar);
+ }
+ String file = (String)map["File"];
+ if (dic.Size > 0 && file != null) {
+ dic.Put(PdfName.S, PdfName.GOTOR);
+ dic.Put(PdfName.F, new PdfString(file));
+ String nw = (String)map["NewWindow"];
+ if (nw != null) {
+ if (nw.Equals("true"))
+ dic.Put(PdfName.NEWWINDOW, PdfBoolean.PDFTRUE);
+ else if (nw.Equals("false"))
+ dic.Put(PdfName.NEWWINDOW, PdfBoolean.PDFFALSE);
+ }
+ outline.Put(PdfName.A, dic);
+ }
+ }
+ else if ("URI".Equals(action)) {
+ String uri = (String)map["URI"];
+ if (uri != null) {
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.S, PdfName.URI);
+ dic.Put(PdfName.URI, new PdfString(uri));
+ outline.Put(PdfName.A, dic);
+ }
+ }
+ else if ("Launch".Equals(action)) {
+ String file = (String)map["File"];
+ if (file != null) {
+ PdfDictionary dic = new PdfDictionary();
+ dic.Put(PdfName.S, PdfName.LAUNCH);
+ dic.Put(PdfName.F, new PdfString(file));
+ outline.Put(PdfName.A, dic);
+ }
+ }
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+
+ public static Object[] IterateOutlines(PdfWriter writer, PdfIndirectReference parent, ArrayList kids, bool namedAsNames) {
+ PdfIndirectReference[] refs = new PdfIndirectReference[kids.Count];
+ for (int k = 0; k < refs.Length; ++k)
+ refs[k] = writer.PdfIndirectReference;
+ int ptr = 0;
+ int count = 0;
+ foreach (Hashtable map in kids) {
+ Object[] lower = null;
+ ArrayList subKid = (ArrayList)map["Kids"];
+ if (subKid != null && subKid.Count > 0)
+ lower = IterateOutlines(writer, refs[ptr], subKid, namedAsNames);
+ PdfDictionary outline = new PdfDictionary();
+ ++count;
+ if (lower != null) {
+ outline.Put(PdfName.FIRST, (PdfIndirectReference)lower[0]);
+ outline.Put(PdfName.LAST, (PdfIndirectReference)lower[1]);
+ int n = (int)lower[2];
+ if ("false".Equals(map["Open"])) {
+ outline.Put(PdfName.COUNT, new PdfNumber(-n));
+ }
+ else {
+ outline.Put(PdfName.COUNT, new PdfNumber(n));
+ count += n;
+ }
+ }
+ outline.Put(PdfName.PARENT, parent);
+ if (ptr > 0)
+ outline.Put(PdfName.PREV, refs[ptr - 1]);
+ if (ptr < refs.Length - 1)
+ outline.Put(PdfName.NEXT, refs[ptr + 1]);
+ outline.Put(PdfName.TITLE, new PdfString((String)map["Title"], PdfObject.TEXT_UNICODE));
+ String color = (String)map["Color"];
+ if (color != null) {
+ try {
+ PdfArray arr = new PdfArray();
+ StringTokenizer tk = new StringTokenizer(color);
+ for (int k = 0; k < 3; ++k) {
+ float f = float.Parse(tk.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ if (f < 0) f = 0;
+ if (f > 1) f = 1;
+ arr.Add(new PdfNumber(f));
+ }
+ outline.Put(PdfName.C, arr);
+ } catch {} //in case it's malformed
+ }
+ String style = (String)map["Style"];
+ if (style != null) {
+ style = style.ToLower(System.Globalization.CultureInfo.InvariantCulture);
+ int bits = 0;
+ if (style.IndexOf("italic") >= 0)
+ bits |= 1;
+ if (style.IndexOf("bold") >= 0)
+ bits |= 2;
+ if (bits != 0)
+ outline.Put(PdfName.F, new PdfNumber(bits));
+ }
+ CreateOutlineAction(outline, map, writer, namedAsNames);
+ writer.AddToBody(outline, refs[ptr]);
+ ++ptr;
+ }
+ return new Object[]{refs[0], refs[refs.Length - 1], count};
+ }
+
+ /**
+ * Exports the bookmarks to XML. Only of use if the generation is to be include in
+ * some other XML document.
+ * @param list the bookmarks
+ * @param out the export destination. The writer is not closed
+ * @param indent the indentation level. Pretty printing significant only
+ * @param onlyASCII codes above 127 will always be escaped with &#nn; if true
,
+ * whatever the encoding
+ * @throws IOException on error
+ */
+ public static void ExportToXMLNode(ArrayList list, TextWriter outp, int indent, bool onlyASCII) {
+ String dep = "";
+ for (int k = 0; k < indent; ++k)
+ dep += " ";
+ foreach (Hashtable map in list) {
+ String title = null;
+ outp.Write(dep);
+ outp.Write("
+ * <?xml version='1.0' encoding='UTF-8'?>
+ * <!ELEMENT Title (#PCDATA|Title)*>
+ * <!ATTLIST Title
+ * Action CDATA #IMPLIED
+ * Open CDATA #IMPLIED
+ * Page CDATA #IMPLIED
+ * URI CDATA #IMPLIED
+ * File CDATA #IMPLIED
+ * Named CDATA #IMPLIED
+ * NamedN CDATA #IMPLIED
+ * NewWindow CDATA #IMPLIED
+ * Style CDATA #IMPLIED
+ * Color CDATA #IMPLIED
+ * >
+ * <!ELEMENT Bookmark (Title)*>
+ *
+ * @param list the bookmarks
+ * @param out the export destination. The stream is not closed
+ * @param encoding the encoding according to IANA conventions
+ * @param onlyASCII codes above 127 will always be escaped with &#nn; if true
,
+ * whatever the encoding
+ * @throws IOException on error
+ */
+ public static void ExportToXML(ArrayList list, Stream outp, String encoding, bool onlyASCII) {
+ StreamWriter wrt = new StreamWriter(outp, IanaEncodings.GetEncodingEncoding(encoding));
+ ExportToXML(list, wrt, encoding, onlyASCII);
+ }
+
+ /**
+ * Exports the bookmarks to XML.
+ * @param list the bookmarks
+ * @param wrt the export destination. The writer is not closed
+ * @param encoding the encoding according to IANA conventions
+ * @param onlyASCII codes above 127 will always be escaped with &#nn; if true
,
+ * whatever the encoding
+ * @throws IOException on error
+ */
+ public static void ExportToXML(ArrayList list, TextWriter wrt, String encoding, bool onlyASCII) {
+ wrt.Write("\n
+ * <?xml version='1.0' encoding='UTF-8'?>
+ * <!ELEMENT Name (#PCDATA)>
+ * <!ATTLIST Name
+ * Page CDATA #IMPLIED
+ * >
+ * <!ELEMENT Destination (Name)*>
+ *
+ * @param names the names
+ * @param outp the export destination. The stream is not closed
+ * @param encoding the encoding according to IANA conventions
+ * @param onlyASCII codes above 127 will always be escaped with &#nn; if true
,
+ * whatever the encoding
+ * @throws IOException on error
+ */
+ public static void ExportToXML(Hashtable names, Stream outp, String encoding, bool onlyASCII) {
+ StreamWriter wrt = new StreamWriter(outp, IanaEncodings.GetEncodingEncoding(encoding));
+ ExportToXML(names, wrt, encoding, onlyASCII);
+ }
+
+ /**
+ * Exports the bookmarks to XML.
+ * @param names the names
+ * @param wrt the export destination. The writer is not closed
+ * @param encoding the encoding according to IANA conventions
+ * @param onlyASCII codes above 127 will always be escaped with &#nn; if true
,
+ * whatever the encoding
+ * @throws IOException on error
+ */
+ public static void ExportToXML(Hashtable names, TextWriter wrt, String encoding, bool onlyASCII) {
+ wrt.Write("\nPdfContentByte
. All
+ * the members are copied by reference but the buffer stays different.
+ *
+ * @return a copy of this PdfContentByte
+ */
+ public override PdfContentByte Duplicate {
+ get {
+ return new StampContent((PdfStamperImp)writer, ps);
+ }
+ }
+
+ internal override PageResources PageResources {
+ get {
+ return pageResources;
+ }
+ }
+
+ internal override void AddAnnotation(PdfAnnotation annot) {
+ ((PdfStamperImp)writer).AddAnnotation(annot, ps.pageN);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/StandardDecryption.cs b/iTechSharp/iTextSharp/text/pdf/StandardDecryption.cs
new file mode 100644
index 0000000..0e4d27b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/StandardDecryption.cs
@@ -0,0 +1,111 @@
+using System;
+using iTextSharp.text.pdf.crypto;
+/*
+ * $Id: StandardDecryption.cs,v 1.3 2007/04/29 13:57:12 psoares33 Exp $
+ *
+ * Copyright 2006 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.crypto {
+
+ public class StandardDecryption {
+ protected ARCFOUREncryption arcfour;
+ protected AESCipher cipher;
+ private byte[] key;
+ private const int AES_128 = 4;
+ private bool aes;
+ private bool initiated;
+ private byte[] iv = new byte[16];
+ private int ivptr;
+
+ /** Creates a new instance of StandardDecryption */
+ public StandardDecryption(byte[] key, int off, int len, int revision) {
+ aes = revision == AES_128;
+ if (aes) {
+ this.key = new byte[len];
+ System.Array.Copy(key, off, this.key, 0, len);
+ }
+ else {
+ arcfour = new ARCFOUREncryption();
+ arcfour.PrepareARCFOURKey(key, off, len);
+ }
+ }
+
+ public byte[] Update(byte[] b, int off, int len) {
+ if (aes) {
+ if (initiated)
+ return cipher.Update(b, off, len);
+ else {
+ int left = Math.Min(iv.Length - ivptr, len);
+ System.Array.Copy(b, off, iv, ivptr, left);
+ off += left;
+ len -= left;
+ ivptr += left;
+ if (ivptr == iv.Length) {
+ cipher = new AESCipher(false, key, iv);
+ initiated = true;
+ if (len > 0)
+ return cipher.Update(b, off, len);
+ }
+ return null;
+ }
+ }
+ else {
+ byte[] b2 = new byte[len];
+ arcfour.EncryptARCFOUR(b, off, len, b2, 0);
+ return b2;
+ }
+ }
+
+ public byte[] Finish() {
+ if (aes) {
+ return cipher.DoFinal();
+ }
+ else
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/TextField.cs b/iTechSharp/iTextSharp/text/pdf/TextField.cs
new file mode 100644
index 0000000..587ccfe
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/TextField.cs
@@ -0,0 +1,641 @@
+using System;
+using System.Collections;
+using System.Text;
+/*
+ * Copyright 2003-2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /** Supports text, combo and list fields generating the correct appearances.
+ * All the option in the Acrobat GUI are supported in an easy to use API.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class TextField : BaseField {
+
+ /** Holds value of property defaultText. */
+ private String defaultText;
+
+ /** Holds value of property choices. */
+ private String[] choices;
+
+ /** Holds value of property choiceExports. */
+ private String[] choiceExports;
+
+ /** Holds value of property choiceSelection. */
+ private int choiceSelection;
+
+ private int topFirst;
+
+ private float extraMarginLeft;
+ private float extraMarginTop;
+
+ /** Creates a new TextField
.
+ * @param writer the document PdfWriter
+ * @param box the field location and dimensions
+ * @param fieldName the field name. If null
only the widget keys
+ * will be included in the field allowing it to be used as a kid field.
+ */
+ public TextField(PdfWriter writer, Rectangle box, String fieldName) : base(writer, box, fieldName) {
+ }
+
+ private static bool CheckRTL(String text) {
+ if (text == null || text.Length == 0)
+ return false;
+ char[] cc = text.ToCharArray();
+ for (int k = 0; k < cc.Length; ++k) {
+ int c = (int)cc[k];
+ if (c >= 0x590 && c < 0x0780)
+ return true;
+ }
+ return false;
+ }
+
+ private static void ChangeFontSize(Phrase p, float size) {
+ foreach (Chunk ck in p) {
+ ck.Font.Size = size;
+ }
+ }
+
+ private Phrase ComposePhrase(String text, BaseFont ufont, Color color, float fontSize) {
+ Phrase phrase = null;
+ if (extensionFont == null && (substitutionFonts == null || substitutionFonts.Count == 0))
+ phrase = new Phrase(new Chunk(text, new Font(ufont, fontSize, 0, color)));
+ else {
+ FontSelector fs = new FontSelector();
+ fs.AddFont(new Font(ufont, fontSize, 0, color));
+ if (extensionFont != null)
+ fs.AddFont(new Font(extensionFont, fontSize, 0, color));
+ if (substitutionFonts != null) {
+ foreach (BaseFont bf in substitutionFonts) {
+ fs.AddFont(new Font(bf, fontSize, 0, color));
+ }
+ }
+ phrase = fs.Process(text);
+ }
+ return phrase;
+ }
+
+ private static String RemoveCRLF(String text) {
+ if (text.IndexOf('\n') >= 0 || text.IndexOf('\r') >= 0) {
+ char[] p = text.ToCharArray();
+ StringBuilder sb = new StringBuilder(p.Length);
+ for (int k = 0; k < p.Length; ++k) {
+ char c = p[k];
+ if (c == '\n')
+ sb.Append(' ');
+ else if (c == '\r') {
+ sb.Append(' ');
+ if (k < p.Length - 1 && p[k + 1] == '\n')
+ ++k;
+ }
+ else
+ sb.Append(c);
+ }
+ return sb.ToString();
+ }
+ return text;
+ }
+
+ /**
+ * Gets the appearance for this TextField.
+ * @return the appearance object for this TextField
+ * @throws IOException
+ * @throws DocumentException
+ */
+ public PdfAppearance GetAppearance() {
+ PdfAppearance app = GetBorderAppearance();
+ app.BeginVariableText();
+ if (text == null || text.Length == 0) {
+ app.EndVariableText();
+ return app;
+ }
+ BaseFont ufont = RealFont;
+ bool borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET;
+ float h = box.Height - borderWidth * 2;
+ float bw2 = borderWidth;
+ if (borderExtra) {
+ h -= borderWidth * 2;
+ bw2 *= 2;
+ }
+ h -= extraMarginTop;
+ float offsetX = (borderExtra ? 2 * borderWidth : borderWidth);
+ offsetX = Math.Max(offsetX, 1);
+ float offX = Math.Min(bw2, offsetX);
+ app.SaveState();
+ app.Rectangle(offX, offX, box.Width - 2 * offX, box.Height - 2 * offX);
+ app.Clip();
+ app.NewPath();
+ Color fcolor = (textColor == null) ? GrayColor.GRAYBLACK : textColor;
+ String ptext = text; //fixed by Kazuya Ujihara (ujihara.jp)
+ if ((options & PASSWORD) != 0) {
+ ptext = new String('*', ptext.Length);
+ }
+ int rtl = CheckRTL(ptext) ? PdfWriter.RUN_DIRECTION_LTR : PdfWriter.RUN_DIRECTION_NO_BIDI;
+ if ((options & MULTILINE) == 0) {
+ ptext = RemoveCRLF(text);
+ }
+ Phrase phrase = ComposePhrase(ptext, ufont, fcolor, fontSize);
+ if ((options & MULTILINE) != 0) {
+ float usize = fontSize;
+ float width = box.Width - 4 * offsetX - extraMarginLeft;
+ float factor = ufont.GetFontDescriptor(BaseFont.BBOXURY, 1) - ufont.GetFontDescriptor(BaseFont.BBOXLLY, 1);
+ ColumnText ct = new ColumnText(null);
+ if (usize == 0) {
+ usize = h / factor;
+ if (usize > 4) {
+ if (usize > 12)
+ usize = 12;
+ float step = Math.Max((usize - 4) / 10, 0.2f);
+ ct.SetSimpleColumn(0, -h, width, 0);
+ ct.Alignment = alignment;
+ ct.RunDirection = rtl;
+ for (; usize > 4; usize -= step) {
+ ct.YLine = 0;
+ ChangeFontSize(phrase, usize);
+ ct.SetText(phrase);
+ ct.Leading = factor * usize;
+ int status = ct.Go(true);
+ if ((status & ColumnText.NO_MORE_COLUMN) == 0)
+ break;
+ }
+ }
+ if (usize < 4) {
+ usize = 4;
+ }
+ }
+ ChangeFontSize(phrase, usize);
+ ct.Canvas = app;
+ float leading = usize * factor;
+ float offsetY = offsetX + h - ufont.GetFontDescriptor(BaseFont.BBOXURY, usize);
+ ct.SetSimpleColumn(extraMarginLeft + 2 * offsetX, -20000, box.Width - 2 * offsetX, offsetY + leading);
+ ct.Leading = leading;
+ ct.Alignment = alignment;
+ ct.RunDirection = rtl;
+ ct.SetText(phrase);
+ ct.Go();
+ }
+ else {
+ float usize = fontSize;
+ if (usize == 0) {
+ float maxCalculatedSize = h / (ufont.GetFontDescriptor(BaseFont.BBOXURX, 1) - ufont.GetFontDescriptor(BaseFont.BBOXLLY, 1));
+ ChangeFontSize(phrase, 1);
+ float wd = ColumnText.GetWidth(phrase, rtl, 0);
+ if (wd == 0)
+ usize = maxCalculatedSize;
+ else
+ usize = (box.Width - extraMarginLeft - 4 * offsetX) / wd;
+ if (usize > maxCalculatedSize)
+ usize = maxCalculatedSize;
+ if (usize < 4)
+ usize = 4;
+ }
+ ChangeFontSize(phrase, usize);
+ float offsetY = offX + ((box.Height - 2*offX) - ufont.GetFontDescriptor(BaseFont.ASCENT, usize)) / 2;
+ if (offsetY < offX)
+ offsetY = offX;
+ if (offsetY - offX < -ufont.GetFontDescriptor(BaseFont.DESCENT, usize)) {
+ float ny = -ufont.GetFontDescriptor(BaseFont.DESCENT, usize) + offX;
+ float dy = box.Height - offX - ufont.GetFontDescriptor(BaseFont.ASCENT, usize);
+ offsetY = Math.Min(ny, Math.Max(offsetY, dy));
+ }
+ if ((options & COMB) != 0 && maxCharacterLength > 0) {
+ int textLen = Math.Min(maxCharacterLength, ptext.Length);
+ int position = 0;
+ if (alignment == Element.ALIGN_RIGHT) {
+ position = maxCharacterLength - textLen;
+ }
+ else if (alignment == Element.ALIGN_CENTER) {
+ position = (maxCharacterLength - textLen) / 2;
+ }
+ float step = (box.Width - extraMarginLeft) / maxCharacterLength;
+ float start = step / 2 + position * step;
+ if (textColor == null)
+ app.SetGrayFill(0);
+ else
+ app.SetColorFill(textColor);
+ app.BeginText();
+ foreach (Chunk ck in phrase) {
+ BaseFont bf = ck.Font.BaseFont;
+ app.SetFontAndSize(bf, usize);
+ StringBuilder sb = ck.Append("");
+ for (int j = 0; j < sb.Length; ++j) {
+ String c = sb.ToString(j, 1);
+ float wd = bf.GetWidthPoint(c, usize);
+ app.SetTextMatrix(extraMarginLeft + start - wd / 2, offsetY - extraMarginTop);
+ app.ShowText(c);
+ start += step;
+ }
+ }
+ app.EndText();
+ }
+ else {
+ if (alignment == Element.ALIGN_RIGHT) {
+ ColumnText.ShowTextAligned(app, Element.ALIGN_RIGHT, phrase, extraMarginLeft + box.Width - 2 * offsetX, offsetY - extraMarginTop, 0, rtl, 0);
+ }
+ else if (alignment == Element.ALIGN_CENTER) {
+ ColumnText.ShowTextAligned(app, Element.ALIGN_CENTER, phrase, extraMarginLeft + box.Width / 2, offsetY - extraMarginTop, 0, rtl, 0);
+ }
+ else
+ ColumnText.ShowTextAligned(app, Element.ALIGN_LEFT, phrase, extraMarginLeft + 2 * offsetX, offsetY - extraMarginTop, 0, rtl, 0);
+ }
+ }
+ app.RestoreState();
+ app.EndVariableText();
+ return app;
+ }
+
+ internal PdfAppearance GetListAppearance() {
+ PdfAppearance app = GetBorderAppearance();
+ app.BeginVariableText();
+ if (choices == null || choices.Length == 0) {
+ app.EndVariableText();
+ return app;
+ }
+ int topChoice = choiceSelection;
+ if (topChoice >= choices.Length) {
+ topChoice = choices.Length - 1;
+ }
+ if (topChoice < 0)
+ topChoice = 0;
+ BaseFont ufont = RealFont;
+ float usize = fontSize;
+ if (usize == 0)
+ usize = 12;
+ bool borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET;
+ float h = box.Height - borderWidth * 2;
+ if (borderExtra)
+ h -= borderWidth * 2;
+ float offsetX = (borderExtra ? 2 * borderWidth : borderWidth);
+ float leading = ufont.GetFontDescriptor(BaseFont.BBOXURY, usize) - ufont.GetFontDescriptor(BaseFont.BBOXLLY, usize);
+ int maxFit = (int)(h / leading) + 1;
+ int first = 0;
+ int last = 0;
+ last = topChoice + maxFit / 2 + 1;
+ first = last - maxFit;
+ if (first < 0) {
+ last += first;
+ first = 0;
+ }
+ // first = topChoice;
+ last = first + maxFit;
+ if (last > choices.Length)
+ last = choices.Length;
+ topFirst = first;
+ app.SaveState();
+ app.Rectangle(offsetX, offsetX, box.Width - 2 * offsetX, box.Height - 2 * offsetX);
+ app.Clip();
+ app.NewPath();
+ Color fcolor = (textColor == null) ? GrayColor.GRAYBLACK : textColor;
+ app.SetColorFill(new Color(10, 36, 106));
+ app.Rectangle(offsetX, offsetX + h - (topChoice - first + 1) * leading, box.Width - 2 * offsetX, leading);
+ app.Fill();
+ float xp = offsetX * 2;
+ float yp = offsetX + h - ufont.GetFontDescriptor(BaseFont.BBOXURY, usize);
+ for (int idx = first; idx < last; ++idx, yp -= leading) {
+ String ptext = choices[idx];
+ int rtl = CheckRTL(ptext) ? PdfWriter.RUN_DIRECTION_LTR : PdfWriter.RUN_DIRECTION_NO_BIDI;
+ ptext = RemoveCRLF(ptext);
+ Phrase phrase = ComposePhrase(ptext, ufont, (idx == topChoice) ? GrayColor.GRAYWHITE : fcolor, usize);
+ ColumnText.ShowTextAligned(app, Element.ALIGN_LEFT, phrase, xp, yp, 0, rtl, 0);
+ }
+ app.RestoreState();
+ app.EndVariableText();
+ return app;
+ }
+
+ /** Gets a new text field.
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return a new text field
+ */
+ public PdfFormField GetTextField() {
+ if (maxCharacterLength <= 0)
+ options &= ~COMB;
+ if ((options & COMB) != 0)
+ options &= ~MULTILINE;
+ PdfFormField field = PdfFormField.CreateTextField(writer, false, false, maxCharacterLength);
+ field.SetWidget(box, PdfAnnotation.HIGHLIGHT_INVERT);
+ switch (alignment) {
+ case Element.ALIGN_CENTER:
+ field.Quadding = PdfFormField.Q_CENTER;
+ break;
+ case Element.ALIGN_RIGHT:
+ field.Quadding = PdfFormField.Q_RIGHT;
+ break;
+ }
+ if (rotation != 0)
+ field.MKRotation = rotation;
+ if (fieldName != null) {
+ field.FieldName = fieldName;
+ if ((options & REQUIRED) == 0 && !"".Equals(text))
+ field.ValueAsString = text;
+ if (defaultText != null)
+ field.DefaultValueAsString = defaultText;
+ if ((options & READ_ONLY) != 0)
+ field.SetFieldFlags(PdfFormField.FF_READ_ONLY);
+ if ((options & REQUIRED) != 0)
+ field.SetFieldFlags(PdfFormField.FF_REQUIRED);
+ if ((options & MULTILINE) != 0)
+ field.SetFieldFlags(PdfFormField.FF_MULTILINE);
+ if ((options & DO_NOT_SCROLL) != 0)
+ field.SetFieldFlags(PdfFormField.FF_DONOTSCROLL);
+ if ((options & PASSWORD) != 0)
+ field.SetFieldFlags(PdfFormField.FF_PASSWORD);
+ if ((options & FILE_SELECTION) != 0)
+ field.SetFieldFlags(PdfFormField.FF_FILESELECT);
+ if ((options & DO_NOT_SPELL_CHECK) != 0)
+ field.SetFieldFlags(PdfFormField.FF_DONOTSPELLCHECK);
+ if ((options & COMB) != 0)
+ field.SetFieldFlags(PdfFormField.FF_COMB);
+ }
+ field.BorderStyle = new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3));
+ PdfAppearance tp = GetAppearance();
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
+ PdfAppearance da = (PdfAppearance)tp.Duplicate;
+ da.SetFontAndSize(RealFont, fontSize);
+ if (textColor == null)
+ da.SetGrayFill(0);
+ else
+ da.SetColorFill(textColor);
+ field.DefaultAppearanceString = da;
+ if (borderColor != null)
+ field.MKBorderColor = borderColor;
+ if (backgroundColor != null)
+ field.MKBackgroundColor = backgroundColor;
+ switch (visibility) {
+ case HIDDEN:
+ field.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN;
+ break;
+ case VISIBLE_BUT_DOES_NOT_PRINT:
+ break;
+ case HIDDEN_BUT_PRINTABLE:
+ field.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW;
+ break;
+ default:
+ field.Flags = PdfAnnotation.FLAGS_PRINT;
+ break;
+ }
+ return field;
+ }
+
+ /** Gets a new combo field.
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return a new combo field
+ */
+ public PdfFormField GetComboField() {
+ return GetChoiceField(false);
+ }
+
+ /** Gets a new list field.
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return a new list field
+ */
+ public PdfFormField GetListField() {
+ return GetChoiceField(true);
+ }
+
+ protected PdfFormField GetChoiceField(bool isList) {
+ options &= (~MULTILINE) & (~COMB);
+ String[] uchoices = choices;
+ if (uchoices == null)
+ uchoices = new String[0];
+ int topChoice = choiceSelection;
+ if (topChoice >= uchoices.Length)
+ topChoice = uchoices.Length - 1;
+ if (text == null) text = ""; //fixed by Kazuya Ujihara (ujihara.jp)
+ if (topChoice >= 0)
+ text = uchoices[topChoice];
+ if (topChoice < 0)
+ topChoice = 0;
+ PdfFormField field = null;
+ String[,] mix = null;
+ if (choiceExports == null) {
+ if (isList)
+ field = PdfFormField.CreateList(writer, uchoices, topChoice);
+ else
+ field = PdfFormField.CreateCombo(writer, (options & EDIT) != 0, uchoices, topChoice);
+ }
+ else {
+ mix = new String[uchoices.Length, 2];
+ for (int k = 0; k < mix.GetLength(0); ++k)
+ mix[k, 0] = mix[k, 1] = uchoices[k];
+ int top = Math.Min(uchoices.Length, choiceExports.Length);
+ for (int k = 0; k < top; ++k) {
+ if (choiceExports[k] != null)
+ mix[k, 0] = choiceExports[k];
+ }
+ if (isList)
+ field = PdfFormField.CreateList(writer, mix, topChoice);
+ else
+ field = PdfFormField.CreateCombo(writer, (options & EDIT) != 0, mix, topChoice);
+ }
+ field.SetWidget(box, PdfAnnotation.HIGHLIGHT_INVERT);
+ if (rotation != 0)
+ field.MKRotation = rotation;
+ if (fieldName != null) {
+ field.FieldName = fieldName;
+ if (uchoices.Length > 0) {
+ if (mix != null) {
+ field.ValueAsString = mix[topChoice, 0];
+ field.DefaultValueAsString = mix[topChoice, 0];
+ }
+ else {
+ field.ValueAsString = text;
+ field.DefaultValueAsString = text;
+ }
+ }
+ if ((options & READ_ONLY) != 0)
+ field.SetFieldFlags(PdfFormField.FF_READ_ONLY);
+ if ((options & REQUIRED) != 0)
+ field.SetFieldFlags(PdfFormField.FF_REQUIRED);
+ if ((options & DO_NOT_SPELL_CHECK) != 0)
+ field.SetFieldFlags(PdfFormField.FF_DONOTSPELLCHECK);
+ }
+ field.BorderStyle = new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3));
+ PdfAppearance tp;
+ if (isList) {
+ tp = GetListAppearance();
+ if (topFirst > 0)
+ field.Put(PdfName.TI, new PdfNumber(topFirst));
+ }
+ else
+ tp = GetAppearance();
+ field.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
+ PdfAppearance da = (PdfAppearance)tp.Duplicate;
+ da.SetFontAndSize(RealFont, fontSize);
+ if (textColor == null)
+ da.SetGrayFill(0);
+ else
+ da.SetColorFill(textColor);
+ field.DefaultAppearanceString = da;
+ if (borderColor != null)
+ field.MKBorderColor = borderColor;
+ if (backgroundColor != null)
+ field.MKBackgroundColor = backgroundColor;
+ switch (visibility) {
+ case HIDDEN:
+ field.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN;
+ break;
+ case VISIBLE_BUT_DOES_NOT_PRINT:
+ break;
+ case HIDDEN_BUT_PRINTABLE:
+ field.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW;
+ break;
+ default:
+ field.Flags = PdfAnnotation.FLAGS_PRINT;
+ break;
+ }
+ return field;
+ }
+
+ /** Sets the default text. It is only meaningful for text fields.
+ * @param defaultText the default text
+ */
+ public string DefaultText {
+ get {
+ return defaultText;
+ }
+ set {
+ defaultText = value;
+ }
+ }
+
+ /** Sets the choices to be presented to the user in list/combo
+ * fields.
+ * @param choices the choices to be presented to the user
+ */
+ public string[] Choices {
+ get {
+ return choices;
+ }
+ set {
+ choices = value;
+ }
+ }
+
+ /** Sets the export values in list/combo fields. If this array
+ * is null
then the choice values will also be used
+ * as the export values.
+ * @param choiceExports the export values in list/combo fields
+ */
+ public string[] ChoiceExports {
+ get {
+ return choiceExports;
+ }
+ set {
+ choiceExports = value;
+ }
+ }
+
+ /** Sets the zero based index of the selected item.
+ * @param choiceSelection the zero based index of the selected item
+ */
+ public int ChoiceSelection {
+ get {
+ return choiceSelection;
+ }
+ set {
+ choiceSelection = value;
+ }
+ }
+
+ internal int TopFirst {
+ get {
+ return topFirst;
+ }
+ }
+
+ /**
+ * Sets extra margins in text fields to better mimic the Acrobat layout.
+ * @param extraMarginLeft the extra marging left
+ * @param extraMarginTop the extra margin top
+ */
+ public void SetExtraMargin(float extraMarginLeft, float extraMarginTop) {
+ this.extraMarginLeft = extraMarginLeft;
+ this.extraMarginTop = extraMarginTop;
+ }
+
+ /**
+ * Holds value of property substitutionFonts.
+ */
+ private ArrayList substitutionFonts;
+
+ /**
+ * Sets a list of substitution fonts. The list is composed of BaseFont
and can also be null
. The fonts in this list will be used if the original
+ * font doesn't contain the needed glyphs.
+ * @param substitutionFonts the list
+ */
+ public ArrayList SubstitutionFonts {
+ set {
+ substitutionFonts = value;
+ }
+ get {
+ return substitutionFonts;
+ }
+ }
+
+ /**
+ * Holds value of property extensionFont.
+ */
+ private BaseFont extensionFont;
+
+ /**
+ * Sets the extensionFont. This font will be searched before the
+ * substitution fonts. It may be null
.
+ * @param extensionFont New value of property extensionFont.
+ */
+ public BaseFont ExtensionFont {
+ set {
+ extensionFont = value;
+ }
+ get {
+ return extensionFont;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/TrueTypeFont.cs b/iTechSharp/iTextSharp/text/pdf/TrueTypeFont.cs
new file mode 100644
index 0000000..23cb888
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/TrueTypeFont.cs
@@ -0,0 +1,1517 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * $Id: TrueTypeFont.cs,v 1.12 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Reads a Truetype font
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ internal class TrueTypeFont : BaseFont {
+
+ /** The code pages possible for a True Type font.
+ */
+ internal static string[] codePages = {
+ "1252 Latin 1",
+ "1250 Latin 2: Eastern Europe",
+ "1251 Cyrillic",
+ "1253 Greek",
+ "1254 Turkish",
+ "1255 Hebrew",
+ "1256 Arabic",
+ "1257 Windows Baltic",
+ "1258 Vietnamese",
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ "874 Thai",
+ "932 JIS/Japan",
+ "936 Chinese: Simplified chars--PRC and Singapore",
+ "949 Korean Wansung",
+ "950 Chinese: Traditional chars--Taiwan and Hong Kong",
+ "1361 Korean Johab",
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ "Macintosh Character Set (US Roman)",
+ "OEM Character Set",
+ "Symbol Character Set",
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ "869 IBM Greek",
+ "866 MS-DOS Russian",
+ "865 MS-DOS Nordic",
+ "864 Arabic",
+ "863 MS-DOS Canadian French",
+ "862 Hebrew",
+ "861 MS-DOS Icelandic",
+ "860 MS-DOS Portuguese",
+ "857 IBM Turkish",
+ "855 IBM Cyrillic; primarily Russian",
+ "852 Latin 2",
+ "775 MS-DOS Baltic",
+ "737 Greek; former 437 G",
+ "708 Arabic; ASMO 708",
+ "850 WE/Latin 1",
+ "437 US"};
+
+ protected bool justNames = false;
+ /** Contains the location of the several tables. The key is the name of
+ * the table and the value is an int[2]
where position 0
+ * is the offset from the start of the file and position 1 is the length
+ * of the table.
+ */
+ protected Hashtable tables;
+ /** The file in use.
+ */
+ protected RandomAccessFileOrArray rf;
+ /** The file name.
+ */
+ protected string fileName;
+
+ protected bool cff = false;
+
+ protected int cffOffset;
+
+ protected int cffLength;
+
+ /** The offset from the start of the file to the table directory.
+ * It is 0 for TTF and may vary for TTC depending on the chosen font.
+ */
+ protected int directoryOffset;
+ /** The index for the TTC font. It is an empty string
for a
+ * TTF file.
+ */
+ protected string ttcIndex;
+ /** The style modifier */
+ protected string style = "";
+ /** The content of table 'head'.
+ */
+ protected FontHeader head = new FontHeader();
+ /** The content of table 'hhea'.
+ */
+ protected HorizontalHeader hhea = new HorizontalHeader();
+ /** The content of table 'OS/2'.
+ */
+ protected WindowsMetrics os_2 = new WindowsMetrics();
+ /** The width of the glyphs. This is essentially the content of table
+ * 'hmtx' normalized to 1000 units.
+ */
+ protected int[] GlyphWidths;
+
+ protected int[][] bboxes;
+
+ /** The map containing the code information for the table 'cmap', encoding 1.0.
+ * The key is the code and the value is an int[2]
where position 0
+ * is the glyph number and position 1 is the glyph width normalized to 1000
+ * units.
+ */
+ protected Hashtable cmap10;
+ /** The map containing the code information for the table 'cmap', encoding 3.1
+ * in Unicode.
+ * int
[2] where position 0
+ * is the glyph number and position 1 is the glyph width normalized to 1000
+ * units.
+ */
+ protected Hashtable cmap31;
+
+
+ /// Integer
where the top 16 bits
+ * are the glyph number for the first character and the lower 16 bits are the
+ * glyph number for the second character. The value is the amount of kerning in
+ * normalized 1000 units as an Integer
. This value is usually negative.
+ */
+ protected IntHashtable kerning = new IntHashtable();
+ /**
+ * The font name.
+ * This name is usually extracted from the table 'name' with
+ * the 'Name ID' 6.
+ */
+ protected string fontName;
+
+ /** The full name of the font
+ */
+ protected string[][] fullName;
+
+ /** All the names auf the Names-Table
+ */
+ protected string[][] allNameEntries;
+
+ /** The family name of the font
+ */
+ protected string[][] familyName;
+ /** The italic angle. It is usually extracted from the 'post' table or in it's
+ * absence with the code:
+ *
+ * -Math.Atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI
+ *
+ */
+ protected double italicAngle;
+ /** true
if all the glyphs have the same width.
+ */
+ protected bool isFixedPitch = false;
+
+ protected int underlinePosition;
+
+ protected int underlineThickness;
+
+ /** The components of table 'head'.
+ */
+ protected class FontHeader {
+ /** A variable. */
+ internal int flags;
+ /** A variable. */
+ internal int unitsPerEm;
+ /** A variable. */
+ internal short xMin;
+ /** A variable. */
+ internal short yMin;
+ /** A variable. */
+ internal short xMax;
+ /** A variable. */
+ internal short yMax;
+ /** A variable. */
+ internal int macStyle;
+ }
+
+ /** The components of table 'hhea'.
+ */
+ protected class HorizontalHeader {
+ /** A variable. */
+ internal short Ascender;
+ /** A variable. */
+ internal short Descender;
+ /** A variable. */
+ internal short LineGap;
+ /** A variable. */
+ internal int advanceWidthMax;
+ /** A variable. */
+ internal short minLeftSideBearing;
+ /** A variable. */
+ internal short minRightSideBearing;
+ /** A variable. */
+ internal short xMaxExtent;
+ /** A variable. */
+ internal short caretSlopeRise;
+ /** A variable. */
+ internal short caretSlopeRun;
+ /** A variable. */
+ internal int numberOfHMetrics;
+ }
+
+ /** The components of table 'OS/2'.
+ */
+ protected class WindowsMetrics {
+ /** A variable. */
+ internal short xAvgCharWidth;
+ /** A variable. */
+ internal int usWeightClass;
+ /** A variable. */
+ internal int usWidthClass;
+ /** A variable. */
+ internal short fsType;
+ /** A variable. */
+ internal short ySubscriptXSize;
+ /** A variable. */
+ internal short ySubscriptYSize;
+ /** A variable. */
+ internal short ySubscriptXOffset;
+ /** A variable. */
+ internal short ySubscriptYOffset;
+ /** A variable. */
+ internal short ySuperscriptXSize;
+ /** A variable. */
+ internal short ySuperscriptYSize;
+ /** A variable. */
+ internal short ySuperscriptXOffset;
+ /** A variable. */
+ internal short ySuperscriptYOffset;
+ /** A variable. */
+ internal short yStrikeoutSize;
+ /** A variable. */
+ internal short yStrikeoutPosition;
+ /** A variable. */
+ internal short sFamilyClass;
+ /** A variable. */
+ internal byte[] panose = new byte[10];
+ /** A variable. */
+ internal byte[] achVendID = new byte[4];
+ /** A variable. */
+ internal int fsSelection;
+ /** A variable. */
+ internal int usFirstCharIndex;
+ /** A variable. */
+ internal int usLastCharIndex;
+ /** A variable. */
+ internal short sTypoAscender;
+ /** A variable. */
+ internal short sTypoDescender;
+ /** A variable. */
+ internal short sTypoLineGap;
+ /** A variable. */
+ internal int usWinAscent;
+ /** A variable. */
+ internal int usWinDescent;
+ /** A variable. */
+ internal int ulCodePageRange1;
+ /** A variable. */
+ internal int ulCodePageRange2;
+ /** A variable. */
+ internal int sCapHeight;
+ }
+
+ /** This constructor is present to allow extending the class.
+ */
+ protected TrueTypeFont() {
+ }
+
+ internal TrueTypeFont(string ttFile, string enc, bool emb, byte[] ttfAfm) : this(ttFile, enc, emb, ttfAfm, false) {}
+
+ /** Creates a new TrueType font.
+ * @param ttFile the location of the font on file. The file must end in '.ttf' or
+ * '.ttc' but can have modifiers after the name
+ * @param enc the encoding to be applied to this font
+ * @param emb true if the font is to be embedded in the PDF
+ * @param ttfAfm the font as a byte
array
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ internal TrueTypeFont(string ttFile, string enc, bool emb, byte[] ttfAfm, bool justNames) {
+ this.justNames = justNames;
+ string nameBase = GetBaseName(ttFile);
+ string ttcName = GetTTCName(nameBase);
+ if (nameBase.Length < ttFile.Length) {
+ style = ttFile.Substring(nameBase.Length);
+ }
+ encoding = enc;
+ embedded = emb;
+ fileName = ttcName;
+ FontType = FONT_TYPE_TT;
+ ttcIndex = "";
+ if (ttcName.Length < nameBase.Length)
+ ttcIndex = nameBase.Substring(ttcName.Length + 1);
+ if (fileName.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || fileName.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || fileName.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttc")) {
+ Process(ttfAfm);
+ if (!justNames && embedded && os_2.fsType == 2)
+ throw new DocumentException(fileName + style + " cannot be embedded due to licensing restrictions.");
+ }
+ else
+ throw new DocumentException(fileName + style + " is not a TTF, OTF or TTC font file.");
+ if (!encoding.StartsWith("#"))
+ PdfEncodings.ConvertToBytes(" ", enc); // check if the encoding exists
+ CreateEncoding();
+ }
+
+ /** Gets the name from a composed TTC file name.
+ * If I have for input "myfont.ttc,2" the return will
+ * be "myfont.ttc".
+ * @param name the full name
+ * @return the simple file name
+ */
+ protected static string GetTTCName(string name) {
+ int idx = name.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf(".ttc,");
+ if (idx < 0)
+ return name;
+ else
+ return name.Substring(0, idx + 4);
+ }
+
+
+ /**
+ * Reads the tables 'head', 'hhea', 'OS/2' and 'post' filling several variables.
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ internal void FillTables() {
+ int[] table_location;
+ table_location = (int[])tables["head"];
+ if (table_location == null)
+ throw new DocumentException("Table 'head' does not exist in " + fileName + style);
+ rf.Seek(table_location[0] + 16);
+ head.flags = rf.ReadUnsignedShort();
+ head.unitsPerEm = rf.ReadUnsignedShort();
+ rf.SkipBytes(16);
+ head.xMin = rf.ReadShort();
+ head.yMin = rf.ReadShort();
+ head.xMax = rf.ReadShort();
+ head.yMax = rf.ReadShort();
+ head.macStyle = rf.ReadUnsignedShort();
+
+ table_location = (int[])tables["hhea"];
+ if (table_location == null)
+ throw new DocumentException("Table 'hhea' does not exist " + fileName + style);
+ rf.Seek(table_location[0] + 4);
+ hhea.Ascender = rf.ReadShort();
+ hhea.Descender = rf.ReadShort();
+ hhea.LineGap = rf.ReadShort();
+ hhea.advanceWidthMax = rf.ReadUnsignedShort();
+ hhea.minLeftSideBearing = rf.ReadShort();
+ hhea.minRightSideBearing = rf.ReadShort();
+ hhea.xMaxExtent = rf.ReadShort();
+ hhea.caretSlopeRise = rf.ReadShort();
+ hhea.caretSlopeRun = rf.ReadShort();
+ rf.SkipBytes(12);
+ hhea.numberOfHMetrics = rf.ReadUnsignedShort();
+
+ table_location = (int[])tables["OS/2"];
+ if (table_location == null)
+ throw new DocumentException("Table 'OS/2' does not exist in " + fileName + style);
+ rf.Seek(table_location[0]);
+ int version = rf.ReadUnsignedShort();
+ os_2.xAvgCharWidth = rf.ReadShort();
+ os_2.usWeightClass = rf.ReadUnsignedShort();
+ os_2.usWidthClass = rf.ReadUnsignedShort();
+ os_2.fsType = rf.ReadShort();
+ os_2.ySubscriptXSize = rf.ReadShort();
+ os_2.ySubscriptYSize = rf.ReadShort();
+ os_2.ySubscriptXOffset = rf.ReadShort();
+ os_2.ySubscriptYOffset = rf.ReadShort();
+ os_2.ySuperscriptXSize = rf.ReadShort();
+ os_2.ySuperscriptYSize = rf.ReadShort();
+ os_2.ySuperscriptXOffset = rf.ReadShort();
+ os_2.ySuperscriptYOffset = rf.ReadShort();
+ os_2.yStrikeoutSize = rf.ReadShort();
+ os_2.yStrikeoutPosition = rf.ReadShort();
+ os_2.sFamilyClass = rf.ReadShort();
+ rf.ReadFully(os_2.panose);
+ rf.SkipBytes(16);
+ rf.ReadFully(os_2.achVendID);
+ os_2.fsSelection = rf.ReadUnsignedShort();
+ os_2.usFirstCharIndex = rf.ReadUnsignedShort();
+ os_2.usLastCharIndex = rf.ReadUnsignedShort();
+ os_2.sTypoAscender = rf.ReadShort();
+ os_2.sTypoDescender = rf.ReadShort();
+ if (os_2.sTypoDescender > 0)
+ os_2.sTypoDescender = (short)(-os_2.sTypoDescender);
+ os_2.sTypoLineGap = rf.ReadShort();
+ os_2.usWinAscent = rf.ReadUnsignedShort();
+ os_2.usWinDescent = rf.ReadUnsignedShort();
+ os_2.ulCodePageRange1 = 0;
+ os_2.ulCodePageRange2 = 0;
+ if (version > 0) {
+ os_2.ulCodePageRange1 = rf.ReadInt();
+ os_2.ulCodePageRange2 = rf.ReadInt();
+ }
+ if (version > 1) {
+ rf.SkipBytes(2);
+ os_2.sCapHeight = rf.ReadShort();
+ }
+ else
+ os_2.sCapHeight = (int)(0.7 * head.unitsPerEm);
+
+ table_location = (int[])tables["post"];
+ if (table_location == null) {
+ italicAngle = -Math.Atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI;
+ return;
+ }
+ rf.Seek(table_location[0] + 4);
+ short mantissa = rf.ReadShort();
+ int fraction = rf.ReadUnsignedShort();
+ italicAngle = (double)mantissa + (double)fraction / 16384.0;
+ underlinePosition = rf.ReadShort();
+ underlineThickness = rf.ReadShort();
+ isFixedPitch = rf.ReadInt() != 0;
+ }
+
+ /**
+ * Gets the Postscript font name.
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ * @return the Postscript font name
+ */
+ internal string BaseFont {
+ get {
+ int[] table_location;
+ table_location = (int[])tables["name"];
+ if (table_location == null)
+ throw new DocumentException("Table 'name' does not exist in " + fileName + style);
+ rf.Seek(table_location[0] + 2);
+ int numRecords = rf.ReadUnsignedShort();
+ int startOfStorage = rf.ReadUnsignedShort();
+ for (int k = 0; k < numRecords; ++k) {
+ int platformID = rf.ReadUnsignedShort();
+ int platformEncodingID = rf.ReadUnsignedShort();
+ int languageID = rf.ReadUnsignedShort();
+ int nameID = rf.ReadUnsignedShort();
+ int length = rf.ReadUnsignedShort();
+ int offset = rf.ReadUnsignedShort();
+ if (nameID == 6) {
+ rf.Seek(table_location[0] + startOfStorage + offset);
+ if (platformID == 0 || platformID == 3)
+ return ReadUnicodeString(length);
+ else
+ return ReadStandardString(length);
+ }
+ }
+ FileInfo file = new FileInfo(fileName);
+ return file.Name.Replace(' ', '-');
+ }
+ }
+
+ /** Extracts the names of the font in all the languages available.
+ * @param id the name id to retrieve
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ internal string[][] GetNames(int id) {
+ int[] table_location;
+ table_location = (int[])tables["name"];
+ if (table_location == null)
+ throw new DocumentException("Table 'name' does not exist in " + fileName + style);
+ rf.Seek(table_location[0] + 2);
+ int numRecords = rf.ReadUnsignedShort();
+ int startOfStorage = rf.ReadUnsignedShort();
+ ArrayList names = new ArrayList();
+ for (int k = 0; k < numRecords; ++k) {
+ int platformID = rf.ReadUnsignedShort();
+ int platformEncodingID = rf.ReadUnsignedShort();
+ int languageID = rf.ReadUnsignedShort();
+ int nameID = rf.ReadUnsignedShort();
+ int length = rf.ReadUnsignedShort();
+ int offset = rf.ReadUnsignedShort();
+ if (nameID == id) {
+ int pos = rf.FilePointer;
+ rf.Seek(table_location[0] + startOfStorage + offset);
+ string name;
+ if (platformID == 0 || platformID == 3 || (platformID == 2 && platformEncodingID == 1)){
+ name = ReadUnicodeString(length);
+ }
+ else {
+ name = ReadStandardString(length);
+ }
+ names.Add(new string[]{platformID.ToString(),
+ platformEncodingID.ToString(), languageID.ToString(), name});
+ rf.Seek(pos);
+ }
+ }
+ string[][] thisName = new string[names.Count][];
+ for (int k = 0; k < names.Count; ++k)
+ thisName[k] = (string[])names[k];
+ return thisName;
+ }
+
+ /** Extracts all the names of the names-Table
+ * @param id the name id to retrieve
+ * @throws DocumentException on error
+ * @throws IOException on error
+ */
+ internal string[][] GetAllNames() {
+ int[] table_location;
+ table_location = (int[])tables["name"];
+ if (table_location == null)
+ throw new DocumentException("Table 'name' does not exist in " + fileName + style);
+ rf.Seek(table_location[0] + 2);
+ int numRecords = rf.ReadUnsignedShort();
+ int startOfStorage = rf.ReadUnsignedShort();
+ ArrayList names = new ArrayList();
+ for (int k = 0; k < numRecords; ++k) {
+ int platformID = rf.ReadUnsignedShort();
+ int platformEncodingID = rf.ReadUnsignedShort();
+ int languageID = rf.ReadUnsignedShort();
+ int nameID = rf.ReadUnsignedShort();
+ int length = rf.ReadUnsignedShort();
+ int offset = rf.ReadUnsignedShort();
+ int pos = rf.FilePointer;
+ rf.Seek(table_location[0] + startOfStorage + offset);
+ String name;
+ if (platformID == 0 || platformID == 3 || (platformID == 2 && platformEncodingID == 1)){
+ name = ReadUnicodeString(length);
+ }
+ else {
+ name = ReadStandardString(length);
+ }
+ names.Add(new String[]{nameID.ToString(), platformID.ToString(),
+ platformEncodingID.ToString(), languageID.ToString(), name});
+ rf.Seek(pos);
+ }
+ string[][] thisName = new string[names.Count][];
+ for (int k = 0; k < names.Count; ++k)
+ thisName[k] = (string[])names[k];
+ return thisName;
+ }
+
+ internal void CheckCff() {
+ int[] table_location;
+ table_location = (int[])tables["CFF "];
+ if (table_location != null) {
+ cff = true;
+ cffOffset = table_location[0];
+ cffLength = table_location[1];
+ }
+ }
+
+ /** Reads the font data.
+ * @param ttfAfm the font as a byte
array, possibly null
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ internal void Process(byte[] ttfAfm) {
+ tables = new Hashtable();
+
+ try {
+ if (ttfAfm == null)
+ rf = new RandomAccessFileOrArray(fileName);
+ else
+ rf = new RandomAccessFileOrArray(ttfAfm);
+ if (ttcIndex.Length > 0) {
+ int dirIdx = int.Parse(ttcIndex);
+ if (dirIdx < 0)
+ throw new DocumentException("The font index for " + fileName + " must be positive.");
+ string mainTag = ReadStandardString(4);
+ if (!mainTag.Equals("ttcf"))
+ throw new DocumentException(fileName + " is not a valid TTC file.");
+ rf.SkipBytes(4);
+ int dirCount = rf.ReadInt();
+ if (dirIdx >= dirCount)
+ throw new DocumentException("The font index for " + fileName + " must be between 0 and " + (dirCount - 1) + ". It was " + dirIdx + ".");
+ rf.SkipBytes(dirIdx * 4);
+ directoryOffset = rf.ReadInt();
+ }
+ rf.Seek(directoryOffset);
+ int ttId = rf.ReadInt();
+ if (ttId != 0x00010000 && ttId != 0x4F54544F)
+ throw new DocumentException(fileName + " is not a valid TTF or OTF file.");
+ int num_tables = rf.ReadUnsignedShort();
+ rf.SkipBytes(6);
+ for (int k = 0; k < num_tables; ++k) {
+ string tag = ReadStandardString(4);
+ rf.SkipBytes(4);
+ int[] table_location = new int[2];
+ table_location[0] = rf.ReadInt();
+ table_location[1] = rf.ReadInt();
+ tables[tag] = table_location;
+ }
+ CheckCff();
+ fontName = BaseFont;
+ fullName = GetNames(4); //full name
+ familyName = GetNames(1); //family name
+ allNameEntries = GetAllNames();
+ if (!justNames) {
+ FillTables();
+ ReadGlyphWidths();
+ ReadCMaps();
+ ReadKerning();
+ ReadBbox();
+ GlyphWidths = null;
+ }
+ }
+ finally {
+ if (rf != null) {
+ rf.Close();
+ if (!embedded)
+ rf = null;
+ }
+ }
+ }
+
+ /** Reads a string
from the font file as bytes using the Cp1252
+ * encoding.
+ * @param length the length of bytes to read
+ * @return the string
read
+ * @throws IOException the font file could not be read
+ */
+ protected string ReadStandardString(int length) {
+ byte[] buf = new byte[length];
+ rf.ReadFully(buf);
+ return System.Text.Encoding.GetEncoding(1252).GetString(buf);
+ }
+
+ /** Reads a Unicode string
from the font file. Each character is
+ * represented by two bytes.
+ * @param length the length of bytes to read. The string
will have length
/2
+ * characters
+ * @return the string
read
+ * @throws IOException the font file could not be read
+ */
+ protected string ReadUnicodeString(int length) {
+ StringBuilder buf = new StringBuilder();
+ length /= 2;
+ for (int k = 0; k < length; ++k) {
+ buf.Append(rf.ReadChar());
+ }
+ return buf.ToString();
+ }
+
+ /** Reads the glyphs widths. The widths are extracted from the table 'hmtx'.
+ * The glyphs are normalized to 1000 units.
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ protected void ReadGlyphWidths() {
+ int[] table_location;
+ table_location = (int[])tables["hmtx"];
+ if (table_location == null)
+ throw new DocumentException("Table 'hmtx' does not exist in " + fileName + style);
+ rf.Seek(table_location[0]);
+ GlyphWidths = new int[hhea.numberOfHMetrics];
+ for (int k = 0; k < hhea.numberOfHMetrics; ++k) {
+ GlyphWidths[k] = (rf.ReadUnsignedShort() * 1000) / head.unitsPerEm;
+ rf.ReadUnsignedShort();
+ }
+ }
+
+ /** Gets a glyph width.
+ * @param glyph the glyph to get the width of
+ * @return the width of the glyph in normalized 1000 units
+ */
+ protected int GetGlyphWidth(int glyph) {
+ if (glyph >= GlyphWidths.Length)
+ glyph = GlyphWidths.Length - 1;
+ return GlyphWidths[glyph];
+ }
+
+ private void ReadBbox() {
+ int[] tableLocation;
+ tableLocation = (int[])tables["head"];
+ if (tableLocation == null)
+ throw new DocumentException("Table 'head' does not exist in " + fileName + style);
+ rf.Seek(tableLocation[0] + TrueTypeFontSubSet.HEAD_LOCA_FORMAT_OFFSET);
+ bool locaShortTable = (rf.ReadUnsignedShort() == 0);
+ tableLocation = (int[])tables["loca"];
+ if (tableLocation == null)
+ return;
+ rf.Seek(tableLocation[0]);
+ int[] locaTable;
+ if (locaShortTable) {
+ int entries = tableLocation[1] / 2;
+ locaTable = new int[entries];
+ for (int k = 0; k < entries; ++k)
+ locaTable[k] = rf.ReadUnsignedShort() * 2;
+ }
+ else {
+ int entries = tableLocation[1] / 4;
+ locaTable = new int[entries];
+ for (int k = 0; k < entries; ++k)
+ locaTable[k] = rf.ReadInt();
+ }
+ tableLocation = (int[])tables["glyf"];
+ if (tableLocation == null)
+ throw new DocumentException("Table 'glyf' does not exist in " + fileName + style);
+ int tableGlyphOffset = tableLocation[0];
+ bboxes = new int[locaTable.Length - 1][];
+ for (int glyph = 0; glyph < locaTable.Length - 1; ++glyph) {
+ int start = locaTable[glyph];
+ if (start != locaTable[glyph + 1]) {
+ rf.Seek(tableGlyphOffset + start + 2);
+ bboxes[glyph] = new int[]{
+ (rf.ReadShort() * 1000) / head.unitsPerEm,
+ (rf.ReadShort() * 1000) / head.unitsPerEm,
+ (rf.ReadShort() * 1000) / head.unitsPerEm,
+ (rf.ReadShort() * 1000) / head.unitsPerEm};
+ }
+ }
+ }
+
+ /** Reads the several maps from the table 'cmap'. The maps of interest are 1.0 for symbolic
+ * fonts and 3.1 for all others. A symbolic font is defined as having the map 3.0.
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ internal void ReadCMaps() {
+ int[] table_location;
+ table_location = (int[])tables["cmap"];
+ if (table_location == null)
+ throw new DocumentException("Table 'cmap' does not exist in " + fileName + style);
+ rf.Seek(table_location[0]);
+ rf.SkipBytes(2);
+ int num_tables = rf.ReadUnsignedShort();
+ fontSpecific = false;
+ int map10 = 0;
+ int map31 = 0;
+ int map30 = 0;
+
+ //add by james for cmap Ext.b
+ int mapExt = 0;
+
+ for (int k = 0; k < num_tables; ++k) {
+ int platId = rf.ReadUnsignedShort();
+ int platSpecId = rf.ReadUnsignedShort();
+ int offset = rf.ReadInt();
+ if (platId == 3 && platSpecId == 0) {
+ fontSpecific = true;
+ map30 = offset;
+ }
+ else if (platId == 3 && platSpecId == 1) {
+ map31 = offset;
+ }
+ else if (platId == 3 && platSpecId == 10)
+ {
+ mapExt = offset;
+ }
+
+ if (platId == 1 && platSpecId == 0) {
+ map10 = offset;
+ }
+
+
+ }
+ if (map10 > 0) {
+ rf.Seek(table_location[0] + map10);
+ int format = rf.ReadUnsignedShort();
+ switch (format) {
+ case 0:
+ cmap10 = ReadFormat0();
+ break;
+ case 4:
+ cmap10 = ReadFormat4();
+ break;
+ case 6:
+ cmap10 = ReadFormat6();
+ break;
+ }
+ }
+ if (map31 > 0) {
+ rf.Seek(table_location[0] + map31);
+ int format = rf.ReadUnsignedShort();
+ if (format == 4) {
+ cmap31 = ReadFormat4();
+ }
+ }
+ if (map30 > 0) {
+ rf.Seek(table_location[0] + map30);
+ int format = rf.ReadUnsignedShort();
+ if (format == 4) {
+ cmap10 = ReadFormat4();
+ }
+ }
+ if (mapExt > 0) {
+ rf.Seek(table_location[0] + mapExt);
+ int format = rf.ReadUnsignedShort();
+ switch (format) {
+ case 0:
+ cmapExt = ReadFormat0();
+ break;
+ case 4:
+ cmapExt = ReadFormat4();
+ break;
+ case 6:
+ cmapExt = ReadFormat6();
+ break;
+ case 12:
+ cmapExt = ReadFormat12();
+ break;
+ }
+ }
+ }
+
+ internal Hashtable ReadFormat12() {
+ Hashtable h = new Hashtable();
+ rf.SkipBytes(2);
+ int table_lenght = rf.ReadInt();
+ rf.SkipBytes(4);
+ int nGroups = rf.ReadInt();
+ for (int k = 0; k < nGroups; k++) {
+ int startCharCode = rf.ReadInt();
+ int endCharCode = rf.ReadInt();
+ int startGlyphID = rf.ReadInt();
+ for (int i = startCharCode; i <= endCharCode; i++) {
+ int[] r = new int[2];
+ r[0] = startGlyphID;
+ r[1] = GetGlyphWidth(r[0]);
+ h[i] = r;
+ startGlyphID++;
+ }
+ }
+ return h;
+ }
+
+ /** The information in the maps of the table 'cmap' is coded in several formats.
+ * Format 0 is the Apple standard character to glyph index mapping table.
+ * @return a Hashtable
representing this map
+ * @throws IOException the font file could not be read
+ */
+ internal Hashtable ReadFormat0() {
+ Hashtable h = new Hashtable();
+ rf.SkipBytes(4);
+ for (int k = 0; k < 256; ++k) {
+ int[] r = new int[2];
+ r[0] = rf.ReadUnsignedByte();
+ r[1] = GetGlyphWidth(r[0]);
+ h[k] = r;
+ }
+ return h;
+ }
+
+ /** The information in the maps of the table 'cmap' is coded in several formats.
+ * Format 4 is the Microsoft standard character to glyph index mapping table.
+ * @return a Hashtable
representing this map
+ * @throws IOException the font file could not be read
+ */
+ internal Hashtable ReadFormat4() {
+ Hashtable h = new Hashtable();
+ int table_lenght = rf.ReadUnsignedShort();
+ rf.SkipBytes(2);
+ int segCount = rf.ReadUnsignedShort() / 2;
+ rf.SkipBytes(6);
+ int[] endCount = new int[segCount];
+ for (int k = 0; k < segCount; ++k) {
+ endCount[k] = rf.ReadUnsignedShort();
+ }
+ rf.SkipBytes(2);
+ int[] startCount = new int[segCount];
+ for (int k = 0; k < segCount; ++k) {
+ startCount[k] = rf.ReadUnsignedShort();
+ }
+ int[] idDelta = new int[segCount];
+ for (int k = 0; k < segCount; ++k) {
+ idDelta[k] = rf.ReadUnsignedShort();
+ }
+ int[] idRO = new int[segCount];
+ for (int k = 0; k < segCount; ++k) {
+ idRO[k] = rf.ReadUnsignedShort();
+ }
+ int[] glyphId = new int[table_lenght / 2 - 8 - segCount * 4];
+ for (int k = 0; k < glyphId.Length; ++k) {
+ glyphId[k] = rf.ReadUnsignedShort();
+ }
+ for (int k = 0; k < segCount; ++k) {
+ int glyph;
+ for (int j = startCount[k]; j <= endCount[k] && j != 0xFFFF; ++j) {
+ if (idRO[k] == 0) {
+ glyph = (j + idDelta[k]) & 0xFFFF;
+ }
+ else {
+ int idx = k + idRO[k] / 2 - segCount + j - startCount[k];
+ if (idx >= glyphId.Length)
+ continue;
+ glyph = (glyphId[idx] + idDelta[k]) & 0xFFFF;
+ }
+ int[] r = new int[2];
+ r[0] = glyph;
+ r[1] = GetGlyphWidth(r[0]);
+ h[fontSpecific ? ((j & 0xff00) == 0xf000 ? j & 0xff : j) : j] = r;
+ }
+ }
+ return h;
+ }
+
+ /** The information in the maps of the table 'cmap' is coded in several formats.
+ * Format 6 is a trimmed table mapping. It is similar to format 0 but can have
+ * less than 256 entries.
+ * @return a Hashtable
representing this map
+ * @throws IOException the font file could not be read
+ */
+ internal Hashtable ReadFormat6() {
+ Hashtable h = new Hashtable();
+ rf.SkipBytes(4);
+ int start_code = rf.ReadUnsignedShort();
+ int code_count = rf.ReadUnsignedShort();
+ for (int k = 0; k < code_count; ++k) {
+ int[] r = new int[2];
+ r[0] = rf.ReadUnsignedShort();
+ r[1] = GetGlyphWidth(r[0]);
+ h[k + start_code] = r;
+ }
+ return h;
+ }
+
+ /** Reads the kerning information from the 'kern' table.
+ * @throws IOException the font file could not be read
+ */
+ internal void ReadKerning() {
+ int[] table_location;
+ table_location = (int[])tables["kern"];
+ if (table_location == null)
+ return;
+ rf.Seek(table_location[0] + 2);
+ int nTables = rf.ReadUnsignedShort();
+ int checkpoint = table_location[0] + 4;
+ int length = 0;
+ for (int k = 0; k < nTables; ++k) {
+ checkpoint += length;
+ rf.Seek(checkpoint);
+ rf.SkipBytes(2);
+ length = rf.ReadUnsignedShort();
+ int coverage = rf.ReadUnsignedShort();
+ if ((coverage & 0xfff7) == 0x0001) {
+ int nPairs = rf.ReadUnsignedShort();
+ rf.SkipBytes(6);
+ for (int j = 0; j < nPairs; ++j) {
+ int pair = rf.ReadInt();
+ int value = ((int)rf.ReadShort() * 1000) / head.unitsPerEm;
+ kerning[pair] = value;
+ }
+ }
+ }
+ }
+
+ /** Gets the kerning between two Unicode chars.
+ * @param char1 the first char
+ * @param char2 the second char
+ * @return the kerning to be applied
+ */
+ public override int GetKerning(int char1, int char2) {
+ int[] metrics = GetMetricsTT(char1);
+ if (metrics == null)
+ return 0;
+ int c1 = metrics[0];
+ metrics = GetMetricsTT(char2);
+ if (metrics == null)
+ return 0;
+ int c2 = metrics[0];
+ return kerning[(c1 << 16) + c2];
+ }
+
+ /** Gets the width from the font according to the unicode char c
.
+ * If the name
is null it's a symbolic font.
+ * @param c the unicode char
+ * @param name the glyph name
+ * @return the width of the char
+ */
+ internal override int GetRawWidth(int c, string name) {
+ int[] metric = GetMetricsTT(c);
+ if (metric == null)
+ return 0;
+ return metric[1];
+ }
+
+ /** Generates the font descriptor for this font.
+ * @return the PdfDictionary containing the font descriptor or null
+ * @param subsetPrefix the subset prefix
+ * @param fontStream the indirect reference to a PdfStream containing the font or null
+ * @throws DocumentException if there is an error
+ */
+ protected PdfDictionary GetFontDescriptor(PdfIndirectReference fontStream, string subsetPrefix, PdfIndirectReference cidset) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR);
+ dic.Put(PdfName.ASCENT, new PdfNumber((int)os_2.sTypoAscender * 1000 / head.unitsPerEm));
+ dic.Put(PdfName.CAPHEIGHT, new PdfNumber((int)os_2.sCapHeight * 1000 / head.unitsPerEm));
+ dic.Put(PdfName.DESCENT, new PdfNumber((int)os_2.sTypoDescender * 1000 / head.unitsPerEm));
+ dic.Put(PdfName.FONTBBOX, new PdfRectangle(
+ (int)head.xMin * 1000 / head.unitsPerEm,
+ (int)head.yMin * 1000 / head.unitsPerEm,
+ (int)head.xMax * 1000 / head.unitsPerEm,
+ (int)head.yMax * 1000 / head.unitsPerEm));
+ if (cidset != null)
+ dic.Put(PdfName.CIDSET, cidset);
+ if (cff) {
+ if (encoding.StartsWith("Identity-"))
+ dic.Put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName+"-"+encoding));
+ else
+ dic.Put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName + style));
+ }
+ else
+ dic.Put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName + style));
+ dic.Put(PdfName.ITALICANGLE, new PdfNumber(italicAngle));
+ dic.Put(PdfName.STEMV, new PdfNumber(80));
+ if (fontStream != null) {
+ if (cff)
+ dic.Put(PdfName.FONTFILE3, fontStream);
+ else
+ dic.Put(PdfName.FONTFILE2, fontStream);
+ }
+ int flags = 0;
+ if (isFixedPitch)
+ flags |= 1;
+ flags |= fontSpecific ? 4 : 32;
+ if ((head.macStyle & 2) != 0)
+ flags |= 64;
+ if ((head.macStyle & 1) != 0)
+ flags |= 262144;
+ dic.Put(PdfName.FLAGS, new PdfNumber(flags));
+
+ return dic;
+ }
+
+ /** Generates the font dictionary for this font.
+ * @return the PdfDictionary containing the font dictionary
+ * @param subsetPrefix the subset prefx
+ * @param firstChar the first valid character
+ * @param lastChar the last valid character
+ * @param shortTag a 256 bytes long byte
array where each unused byte is represented by 0
+ * @param fontDescriptor the indirect reference to a PdfDictionary containing the font descriptor or null
+ * @throws DocumentException if there is an error
+ */
+ protected PdfDictionary GetFontBaseType(PdfIndirectReference fontDescriptor, string subsetPrefix, int firstChar, int lastChar, byte[] shortTag) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONT);
+ if (cff) {
+ dic.Put(PdfName.SUBTYPE, PdfName.TYPE1);
+ dic.Put(PdfName.BASEFONT, new PdfName(fontName + style));
+ }
+ else {
+ dic.Put(PdfName.SUBTYPE, PdfName.TRUETYPE);
+ dic.Put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName + style));
+ }
+ dic.Put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName + style));
+ if (!fontSpecific) {
+ for (int k = firstChar; k <= lastChar; ++k) {
+ if (!differences[k].Equals(notdef)) {
+ firstChar = k;
+ break;
+ }
+ }
+ if (encoding.Equals(CP1252) || encoding.Equals(MACROMAN))
+ dic.Put(PdfName.ENCODING, encoding.Equals(CP1252) ? PdfName.WIN_ANSI_ENCODING : PdfName.MAC_ROMAN_ENCODING);
+ else {
+ PdfDictionary enc = new PdfDictionary(PdfName.ENCODING);
+ PdfArray dif = new PdfArray();
+ bool gap = true;
+ for (int k = firstChar; k <= lastChar; ++k) {
+ if (shortTag[k] != 0) {
+ if (gap) {
+ dif.Add(new PdfNumber(k));
+ gap = false;
+ }
+ dif.Add(new PdfName(differences[k]));
+ }
+ else
+ gap = true;
+ }
+ enc.Put(PdfName.DIFFERENCES, dif);
+ dic.Put(PdfName.ENCODING, enc);
+ }
+ }
+ dic.Put(PdfName.FIRSTCHAR, new PdfNumber(firstChar));
+ dic.Put(PdfName.LASTCHAR, new PdfNumber(lastChar));
+ PdfArray wd = new PdfArray();
+ for (int k = firstChar; k <= lastChar; ++k) {
+ if (shortTag[k] == 0)
+ wd.Add(new PdfNumber(0));
+ else
+ wd.Add(new PdfNumber(widths[k]));
+ }
+ dic.Put(PdfName.WIDTHS, wd);
+ if (fontDescriptor != null)
+ dic.Put(PdfName.FONTDESCRIPTOR, fontDescriptor);
+ return dic;
+ }
+
+ protected byte[] GetFullFont() {
+ RandomAccessFileOrArray rf2 = null;
+ try {
+ rf2 = new RandomAccessFileOrArray(rf);
+ rf2.ReOpen();
+ byte[] b = new byte[rf2.Length];
+ rf2.ReadFully(b);
+ return b;
+ }
+ finally {
+ try {if (rf2 != null) rf2.Close();} catch {}
+ }
+ }
+
+ protected static int[] CompactRanges(ArrayList ranges) {
+ ArrayList simp = new ArrayList();
+ for (int k = 0; k < ranges.Count; ++k) {
+ int[] r = (int[])ranges[k];
+ for (int j = 0; j < r.Length; j += 2) {
+ simp.Add(new int[]{Math.Max(0, Math.Min(r[j], r[j + 1])), Math.Min(0xffff, Math.Max(r[j], r[j + 1]))});
+ }
+ }
+ for (int k1 = 0; k1 < simp.Count - 1; ++k1) {
+ for (int k2 = k1 + 1; k2 < simp.Count; ++k2) {
+ int[] r1 = (int[])simp[k1];
+ int[] r2 = (int[])simp[k2];
+ if ((r1[0] >= r2[0] && r1[0] <= r2[1]) || (r1[1] >= r2[0] && r1[0] <= r2[1])) {
+ r1[0] = Math.Min(r1[0], r2[0]);
+ r1[1] = Math.Max(r1[1], r2[1]);
+ simp.RemoveAt(k2);
+ --k2;
+ }
+ }
+ }
+ int[] s = new int[simp.Count * 2];
+ for (int k = 0; k < simp.Count; ++k) {
+ int[] r = (int[])simp[k];
+ s[k * 2] = r[0];
+ s[k * 2 + 1] = r[1];
+ }
+ return s;
+ }
+
+ protected void AddRangeUni(Hashtable longTag, bool includeMetrics, bool subsetp) {
+ if (!subsetp && (subsetRanges != null || directoryOffset > 0)) {
+ int[] rg = (subsetRanges == null && directoryOffset > 0) ? new int[]{0, 0xffff} : CompactRanges(subsetRanges);
+ Hashtable usemap;
+ if (!fontSpecific && cmap31 != null)
+ usemap = cmap31;
+ else if (fontSpecific && cmap10 != null)
+ usemap = cmap10;
+ else if (cmap31 != null)
+ usemap = cmap31;
+ else
+ usemap = cmap10;
+ foreach (DictionaryEntry e in usemap) {
+ int[] v = (int[])e.Value;
+ int gi = (int)v[0];
+ if (longTag.ContainsKey(gi))
+ continue;
+ int c = (int)e.Key;
+ bool skip = true;
+ for (int k = 0; k < rg.Length; k += 2) {
+ if (c >= rg[k] && c <= rg[k + 1]) {
+ skip = false;
+ break;
+ }
+ }
+ if (!skip)
+ longTag[gi] = includeMetrics ? new int[]{v[0], v[1], c} : null;
+ }
+ }
+ }
+
+ /** Outputs to the writer the font dictionaries and streams.
+ * @param writer the writer for this document
+ * @param ref the font indirect reference
+ * @param params several parameters that depend on the font type
+ * @throws IOException on error
+ * @throws DocumentException error in generating the object
+ */
+ internal override void WriteFont(PdfWriter writer, PdfIndirectReference piref, Object[] parms) {
+ int firstChar = (int)parms[0];
+ int lastChar = (int)parms[1];
+ byte[] shortTag = (byte[])parms[2];
+ bool subsetp = (bool)parms[3] && subset;
+ if (!subsetp) {
+ firstChar = 0;
+ lastChar = shortTag.Length - 1;
+ for (int k = 0; k < shortTag.Length; ++k)
+ shortTag[k] = 1;
+ }
+ PdfIndirectReference ind_font = null;
+ PdfObject pobj = null;
+ PdfIndirectObject obj = null;
+ string subsetPrefix = "";
+ if (embedded) {
+ if (cff) {
+ RandomAccessFileOrArray rf2 = new RandomAccessFileOrArray(rf);
+ byte[] b = new byte[cffLength];
+ try {
+ rf2.ReOpen();
+ rf2.Seek(cffOffset);
+ rf2.ReadFully(b);
+ }
+ finally {
+ try {
+ rf2.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ pobj = new StreamFont(b, "Type1C");
+ obj = writer.AddToBody(pobj);
+ ind_font = obj.IndirectReference;
+ }
+ else {
+ if (subsetp)
+ subsetPrefix = CreateSubsetPrefix();
+ Hashtable glyphs = new Hashtable();
+ for (int k = firstChar; k <= lastChar; ++k) {
+ if (shortTag[k] != 0) {
+ int[] metrics = null;
+ if (specialMap != null) {
+ int[] cd = GlyphList.NameToUnicode(differences[k]);
+ if (cd != null)
+ metrics = GetMetricsTT(cd[0]);
+ }
+ else {
+ if (fontSpecific)
+ metrics = GetMetricsTT(k);
+ else
+ metrics = GetMetricsTT(unicodeDifferences[k]);
+ }
+ if (metrics != null)
+ glyphs[metrics[0]] = null;
+ }
+ }
+ AddRangeUni(glyphs, false, subsetp);
+ byte[] b = null;
+ if (subsetp || directoryOffset != 0 || subsetRanges != null) {
+ TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), glyphs, directoryOffset, true, !subsetp);
+ b = sb.Process();
+ }
+ else {
+ b = GetFullFont();
+ }
+ int[] lengths = new int[]{b.Length};
+ pobj = new StreamFont(b, lengths);
+ obj = writer.AddToBody(pobj);
+ ind_font = obj.IndirectReference;
+ }
+ }
+ pobj = GetFontDescriptor(ind_font, subsetPrefix, null);
+ if (pobj != null){
+ obj = writer.AddToBody(pobj);
+ ind_font = obj.IndirectReference;
+ }
+ pobj = GetFontBaseType(ind_font, subsetPrefix, firstChar, lastChar, shortTag);
+ writer.AddToBody(pobj, piref);
+ }
+
+ /** Gets the font parameter identified by key
. Valid values
+ * for key
are ASCENT
, CAPHEIGHT
, DESCENT
+ * and ITALICANGLE
.
+ * @param key the parameter to be extracted
+ * @param fontSize the font size in points
+ * @return the parameter in points
+ */
+ public override float GetFontDescriptor(int key, float fontSize) {
+ switch (key) {
+ case ASCENT:
+ return (float)os_2.sTypoAscender * fontSize / (float)head.unitsPerEm;
+ case CAPHEIGHT:
+ return (float)os_2.sCapHeight * fontSize / (float)head.unitsPerEm;
+ case DESCENT:
+ return (float)os_2.sTypoDescender * fontSize / (float)head.unitsPerEm;
+ case ITALICANGLE:
+ return (float)italicAngle;
+ case BBOXLLX:
+ return fontSize * (int)head.xMin / head.unitsPerEm;
+ case BBOXLLY:
+ return fontSize * (int)head.yMin / head.unitsPerEm;
+ case BBOXURX:
+ return fontSize * (int)head.xMax / head.unitsPerEm;
+ case BBOXURY:
+ return fontSize * (int)head.yMax / head.unitsPerEm;
+ case AWT_ASCENT:
+ return fontSize * (int)hhea.Ascender / head.unitsPerEm;
+ case AWT_DESCENT:
+ return fontSize * (int)hhea.Descender / head.unitsPerEm;
+ case AWT_LEADING:
+ return fontSize * (int)hhea.LineGap / head.unitsPerEm;
+ case AWT_MAXADVANCE:
+ return fontSize * (int)hhea.advanceWidthMax / head.unitsPerEm;
+ case UNDERLINE_POSITION:
+ return (underlinePosition - underlineThickness / 2) * fontSize / head.unitsPerEm;
+ case UNDERLINE_THICKNESS:
+ return underlineThickness * fontSize / head.unitsPerEm;
+ case STRIKETHROUGH_POSITION:
+ return os_2.yStrikeoutPosition * fontSize / head.unitsPerEm;
+ case STRIKETHROUGH_THICKNESS:
+ return os_2.yStrikeoutSize * fontSize / head.unitsPerEm;
+ case SUBSCRIPT_SIZE:
+ return os_2.ySubscriptYSize * fontSize / head.unitsPerEm;
+ case SUBSCRIPT_OFFSET:
+ return -os_2.ySubscriptYOffset * fontSize / head.unitsPerEm;
+ case SUPERSCRIPT_SIZE:
+ return os_2.ySuperscriptYSize * fontSize / head.unitsPerEm;
+ case SUPERSCRIPT_OFFSET:
+ return os_2.ySuperscriptYOffset * fontSize / head.unitsPerEm;
+ }
+ return 0;
+ }
+
+ /** Gets the glyph index and metrics for a character.
+ * @param c the character
+ * @return an int
array with {glyph index, width}
+ */
+ public virtual int[] GetMetricsTT(int c) {
+ if (cmapExt != null)
+ return (int[])cmapExt[c];
+ if (!fontSpecific && cmap31 != null)
+ return (int[])cmap31[c];
+ if (fontSpecific && cmap10 != null)
+ return (int[])cmap10[c];
+ if (cmap31 != null)
+ return (int[])cmap31[c];
+ if (cmap10 != null)
+ return (int[])cmap10[c];
+ return null;
+ }
+
+ /** Gets the postscript font name.
+ * @return the postscript font name
+ */
+ public override string PostscriptFontName {
+ get {
+ return fontName;
+ }
+ set {
+ fontName = value;
+ }
+ }
+
+ /** Gets the code pages supported by the font.
+ * @return the code pages supported by the font
+ */
+ public override string[] CodePagesSupported {
+ get {
+ long cp = (((long)os_2.ulCodePageRange2) << 32) + ((long)os_2.ulCodePageRange1 & 0xffffffffL);
+ int count = 0;
+ long bit = 1;
+ for (int k = 0; k < 64; ++k) {
+ if ((cp & bit) != 0 && codePages[k] != null)
+ ++count;
+ bit <<= 1;
+ }
+ string[] ret = new string[count];
+ count = 0;
+ bit = 1;
+ for (int k = 0; k < 64; ++k) {
+ if ((cp & bit) != 0 && codePages[k] != null)
+ ret[count++] = codePages[k];
+ bit <<= 1;
+ }
+ return ret;
+ }
+ }
+
+ /** Gets the full name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public override string[][] FullFontName {
+ get {
+ return fullName;
+ }
+ }
+
+ /** Gets all the entries of the Names-Table. If it is a True Type font
+ * each array element will have {Name ID, Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public override string[][] AllNameEntries {
+ get {
+ return allNameEntries;
+ }
+ }
+
+ /** Gets the family name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the family name of the font
+ */
+ public override string[][] FamilyFontName {
+ get {
+ return familyName;
+ }
+ }
+
+ /** Checks if the font has any kerning pairs.
+ * @return true
if the font has any kerning pairs
+ */
+ public override bool HasKernPairs() {
+ return kerning.Size > 0;
+ }
+
+ /**
+ * Sets the kerning between two Unicode chars.
+ * @param char1 the first char
+ * @param char2 the second char
+ * @param kern the kerning to apply in normalized 1000 units
+ * @return true
if the kerning was applied, false
otherwise
+ */
+ public override bool SetKerning(int char1, int char2, int kern) {
+ int[] metrics = GetMetricsTT(char1);
+ if (metrics == null)
+ return false;
+ int c1 = metrics[0];
+ metrics = GetMetricsTT(char2);
+ if (metrics == null)
+ return false;
+ int c2 = metrics[0];
+ kerning[(c1 << 16) + c2] = kern;
+ return true;
+ }
+
+ protected override int[] GetRawCharBBox(int c, String name) {
+ Hashtable map = null;
+ if (name == null || cmap31 == null)
+ map = cmap10;
+ else
+ map = cmap31;
+ if (map == null)
+ return null;
+ int[] metric = (int[])map[c];
+ if (metric == null || bboxes == null)
+ return null;
+ return bboxes[metric[0]];
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/TrueTypeFontSubSet.cs b/iTechSharp/iTextSharp/text/pdf/TrueTypeFontSubSet.cs
new file mode 100644
index 0000000..e5f37fb
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/TrueTypeFontSubSet.cs
@@ -0,0 +1,423 @@
+using System;
+using System.IO;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ * $Id: TrueTypeFontSubSet.cs,v 1.4 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Subsets a True Type font by removing the unneeded glyphs from
+ * the font.
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ internal class TrueTypeFontSubSet {
+ internal static string[] tableNamesSimple = {"cvt ", "fpgm", "glyf", "head",
+ "hhea", "hmtx", "loca", "maxp", "prep"};
+ internal static string[] tableNamesCmap = {"cmap", "cvt ", "fpgm", "glyf", "head",
+ "hhea", "hmtx", "loca", "maxp", "prep"};
+ internal static string[] tableNamesExtra = {"OS/2", "cmap", "cvt ", "fpgm", "glyf", "head",
+ "hhea", "hmtx", "loca", "maxp", "name, prep"};
+ internal static int[] entrySelectors = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4};
+ internal static int TABLE_CHECKSUM = 0;
+ internal static int TABLE_OFFSET = 1;
+ internal static int TABLE_LENGTH = 2;
+ internal static int HEAD_LOCA_FORMAT_OFFSET = 51;
+
+ internal static int ARG_1_AND_2_ARE_WORDS = 1;
+ internal static int WE_HAVE_A_SCALE = 8;
+ internal static int MORE_COMPONENTS = 32;
+ internal static int WE_HAVE_AN_X_AND_Y_SCALE = 64;
+ internal static int WE_HAVE_A_TWO_BY_TWO = 128;
+
+
+ /** Contains the location of the several tables. The key is the name of
+ * the table and the value is an int[3]
where position 0
+ * is the checksum, position 1 is the offset from the start of the file
+ * and position 2 is the length of the table.
+ */
+ protected Hashtable tableDirectory;
+ /** The file in use.
+ */
+ protected RandomAccessFileOrArray rf;
+ /** The file name.
+ */
+ protected string fileName;
+ protected bool includeCmap;
+ protected bool includeExtras;
+ protected bool locaShortTable;
+ protected int[] locaTable;
+ protected Hashtable glyphsUsed;
+ protected ArrayList glyphsInList;
+ protected int tableGlyphOffset;
+ protected int[] newLocaTable;
+ protected byte[] newLocaTableOut;
+ protected byte[] newGlyfTable;
+ protected int glyfTableRealSize;
+ protected int locaTableRealSize;
+ protected byte[] outFont;
+ protected int fontPtr;
+ protected int directoryOffset;
+
+ /** Creates a new TrueTypeFontSubSet
+ * @param directoryOffset The offset from the start of the file to the table directory
+ * @param fileName the file name of the font
+ * @param glyphsUsed the glyphs used
+ * @param includeCmap true
if the table cmap is to be included in the generated font
+ */
+ internal TrueTypeFontSubSet(string fileName, RandomAccessFileOrArray rf, Hashtable glyphsUsed, int directoryOffset, bool includeCmap, bool includeExtras) {
+ this.fileName = fileName;
+ this.rf = rf;
+ this.glyphsUsed = glyphsUsed;
+ this.includeCmap = includeCmap;
+ this.includeExtras = includeExtras;
+ this.directoryOffset = directoryOffset;
+ glyphsInList = new ArrayList(glyphsUsed.Keys);
+ }
+
+ /** Does the actual work of subsetting the font.
+ * @throws IOException on error
+ * @throws DocumentException on error
+ * @return the subset font
+ */
+ internal byte[] Process() {
+ try {
+ rf.ReOpen();
+ CreateTableDirectory();
+ ReadLoca();
+ FlatGlyphs();
+ CreateNewGlyphTables();
+ LocaTobytes();
+ AssembleFont();
+ return outFont;
+ }
+ finally {
+ try {
+ rf.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+
+ protected void AssembleFont() {
+ int[] tableLocation;
+ int fullFontSize = 0;
+ string[] tableNames;
+ if (includeExtras)
+ tableNames = tableNamesExtra;
+ else {
+ if (includeCmap)
+ tableNames = tableNamesCmap;
+ else
+ tableNames = tableNamesSimple;
+ }
+ int tablesUsed = 2;
+ int len = 0;
+ for (int k = 0; k < tableNames.Length; ++k) {
+ string name = tableNames[k];
+ if (name.Equals("glyf") || name.Equals("loca"))
+ continue;
+ tableLocation = (int[])tableDirectory[name];
+ if (tableLocation == null)
+ continue;
+ ++tablesUsed;
+ fullFontSize += (tableLocation[TABLE_LENGTH] + 3) & (~3);
+ }
+ fullFontSize += newLocaTableOut.Length;
+ fullFontSize += newGlyfTable.Length;
+ int iref = 16 * tablesUsed + 12;
+ fullFontSize += iref;
+ outFont = new byte[fullFontSize];
+ fontPtr = 0;
+ WriteFontInt(0x00010000);
+ WriteFontShort(tablesUsed);
+ int selector = entrySelectors[tablesUsed];
+ WriteFontShort((1 << selector) * 16);
+ WriteFontShort(selector);
+ WriteFontShort((tablesUsed - (1 << selector)) * 16);
+ for (int k = 0; k < tableNames.Length; ++k) {
+ string name = tableNames[k];
+ tableLocation = (int[])tableDirectory[name];
+ if (tableLocation == null)
+ continue;
+ WriteFontString(name);
+ if (name.Equals("glyf")) {
+ WriteFontInt(CalculateChecksum(newGlyfTable));
+ len = glyfTableRealSize;
+ }
+ else if (name.Equals("loca")) {
+ WriteFontInt(CalculateChecksum(newLocaTableOut));
+ len = locaTableRealSize;
+ }
+ else {
+ WriteFontInt(tableLocation[TABLE_CHECKSUM]);
+ len = tableLocation[TABLE_LENGTH];
+ }
+ WriteFontInt(iref);
+ WriteFontInt(len);
+ iref += (len + 3) & (~3);
+ }
+ for (int k = 0; k < tableNames.Length; ++k) {
+ string name = tableNames[k];
+ tableLocation = (int[])tableDirectory[name];
+ if (tableLocation == null)
+ continue;
+ if (name.Equals("glyf")) {
+ Array.Copy(newGlyfTable, 0, outFont, fontPtr, newGlyfTable.Length);
+ fontPtr += newGlyfTable.Length;
+ newGlyfTable = null;
+ }
+ else if (name.Equals("loca")) {
+ Array.Copy(newLocaTableOut, 0, outFont, fontPtr, newLocaTableOut.Length);
+ fontPtr += newLocaTableOut.Length;
+ newLocaTableOut = null;
+ }
+ else {
+ rf.Seek(tableLocation[TABLE_OFFSET]);
+ rf.ReadFully(outFont, fontPtr, tableLocation[TABLE_LENGTH]);
+ fontPtr += (tableLocation[TABLE_LENGTH] + 3) & (~3);
+ }
+ }
+ }
+
+ protected void CreateTableDirectory() {
+ tableDirectory = new Hashtable();
+ rf.Seek(directoryOffset);
+ int id = rf.ReadInt();
+ if (id != 0x00010000)
+ throw new DocumentException(fileName + " is not a true type file.");
+ int num_tables = rf.ReadUnsignedShort();
+ rf.SkipBytes(6);
+ for (int k = 0; k < num_tables; ++k) {
+ string tag = ReadStandardString(4);
+ int[] tableLocation = new int[3];
+ tableLocation[TABLE_CHECKSUM] = rf.ReadInt();
+ tableLocation[TABLE_OFFSET] = rf.ReadInt();
+ tableLocation[TABLE_LENGTH] = rf.ReadInt();
+ tableDirectory[tag] = tableLocation;
+ }
+ }
+
+ protected void ReadLoca() {
+ int[] tableLocation;
+ tableLocation = (int[])tableDirectory["head"];
+ if (tableLocation == null)
+ throw new DocumentException("Table 'head' does not exist in " + fileName);
+ rf.Seek(tableLocation[TABLE_OFFSET] + HEAD_LOCA_FORMAT_OFFSET);
+ locaShortTable = (rf.ReadUnsignedShort() == 0);
+ tableLocation = (int[])tableDirectory["loca"];
+ if (tableLocation == null)
+ throw new DocumentException("Table 'loca' does not exist in " + fileName);
+ rf.Seek(tableLocation[TABLE_OFFSET]);
+ if (locaShortTable) {
+ int entries = tableLocation[TABLE_LENGTH] / 2;
+ locaTable = new int[entries];
+ for (int k = 0; k < entries; ++k)
+ locaTable[k] = rf.ReadUnsignedShort() * 2;
+ }
+ else {
+ int entries = tableLocation[TABLE_LENGTH] / 4;
+ locaTable = new int[entries];
+ for (int k = 0; k < entries; ++k)
+ locaTable[k] = rf.ReadInt();
+ }
+ }
+
+ protected void CreateNewGlyphTables() {
+ newLocaTable = new int[locaTable.Length];
+ int[] activeGlyphs = new int[glyphsInList.Count];
+ for (int k = 0; k < activeGlyphs.Length; ++k)
+ activeGlyphs[k] = (int)glyphsInList[k];
+ Array.Sort(activeGlyphs);
+ int glyfSize = 0;
+ for (int k = 0; k < activeGlyphs.Length; ++k) {
+ int glyph = activeGlyphs[k];
+ glyfSize += locaTable[glyph + 1] - locaTable[glyph];
+ }
+ glyfTableRealSize = glyfSize;
+ glyfSize = (glyfSize + 3) & (~3);
+ newGlyfTable = new byte[glyfSize];
+ int glyfPtr = 0;
+ int listGlyf = 0;
+ for (int k = 0; k < newLocaTable.Length; ++k) {
+ newLocaTable[k] = glyfPtr;
+ if (listGlyf < activeGlyphs.Length && activeGlyphs[listGlyf] == k) {
+ ++listGlyf;
+ newLocaTable[k] = glyfPtr;
+ int start = locaTable[k];
+ int len = locaTable[k + 1] - start;
+ if (len > 0) {
+ rf.Seek(tableGlyphOffset + start);
+ rf.ReadFully(newGlyfTable, glyfPtr, len);
+ glyfPtr += len;
+ }
+ }
+ }
+ }
+
+ protected void LocaTobytes() {
+ if (locaShortTable)
+ locaTableRealSize = newLocaTable.Length * 2;
+ else
+ locaTableRealSize = newLocaTable.Length * 4;
+ newLocaTableOut = new byte[(locaTableRealSize + 3) & (~3)];
+ outFont = newLocaTableOut;
+ fontPtr = 0;
+ for (int k = 0; k < newLocaTable.Length; ++k) {
+ if (locaShortTable)
+ WriteFontShort(newLocaTable[k] / 2);
+ else
+ WriteFontInt(newLocaTable[k]);
+ }
+
+ }
+
+ protected void FlatGlyphs() {
+ int[] tableLocation;
+ tableLocation = (int[])tableDirectory["glyf"];
+ if (tableLocation == null)
+ throw new DocumentException("Table 'glyf' does not exist in " + fileName);
+ int glyph0 = 0;
+ if (!glyphsUsed.ContainsKey(glyph0)) {
+ glyphsUsed[glyph0] = null;
+ glyphsInList.Add(glyph0);
+ }
+ tableGlyphOffset = tableLocation[TABLE_OFFSET];
+ for (int k = 0; k < glyphsInList.Count; ++k) {
+ int glyph = (int)glyphsInList[k];
+ CheckGlyphComposite(glyph);
+ }
+ }
+
+ protected void CheckGlyphComposite(int glyph) {
+ int start = locaTable[glyph];
+ if (start == locaTable[glyph + 1]) // no contour
+ return;
+ rf.Seek(tableGlyphOffset + start);
+ int numContours = rf.ReadShort();
+ if (numContours >= 0)
+ return;
+ rf.SkipBytes(8);
+ for(;;) {
+ int flags = rf.ReadUnsignedShort();
+ int cGlyph = rf.ReadUnsignedShort();
+ if (!glyphsUsed.ContainsKey(cGlyph)) {
+ glyphsUsed[cGlyph] = null;
+ glyphsInList.Add(cGlyph);
+ }
+ if ((flags & MORE_COMPONENTS) == 0)
+ return;
+ int skip;
+ if ((flags & ARG_1_AND_2_ARE_WORDS) != 0)
+ skip = 4;
+ else
+ skip = 2;
+ if ((flags & WE_HAVE_A_SCALE) != 0)
+ skip += 2;
+ else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0)
+ skip += 4;
+ if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0)
+ skip += 8;
+ rf.SkipBytes(skip);
+ }
+ }
+
+ /** Reads a string
from the font file as bytes using the Cp1252
+ * encoding.
+ * @param length the length of bytes to read
+ * @return the string
read
+ * @throws IOException the font file could not be read
+ */
+ protected string ReadStandardString(int length) {
+ byte[] buf = new byte[length];
+ rf.ReadFully(buf);
+ return System.Text.Encoding.GetEncoding(1252).GetString(buf);
+ }
+
+ protected void WriteFontShort(int n) {
+ outFont[fontPtr++] = (byte)(n >> 8);
+ outFont[fontPtr++] = (byte)(n);
+ }
+
+ protected void WriteFontInt(int n) {
+ outFont[fontPtr++] = (byte)(n >> 24);
+ outFont[fontPtr++] = (byte)(n >> 16);
+ outFont[fontPtr++] = (byte)(n >> 8);
+ outFont[fontPtr++] = (byte)(n);
+ }
+
+ protected void WriteFontString(string s) {
+ byte[] b = PdfEncodings.ConvertToBytes(s, BaseFont.WINANSI);
+ Array.Copy(b, 0, outFont, fontPtr, b.Length);
+ fontPtr += b.Length;
+ }
+
+ protected int CalculateChecksum(byte[] b) {
+ int len = b.Length / 4;
+ int v0 = 0;
+ int v1 = 0;
+ int v2 = 0;
+ int v3 = 0;
+ int ptr = 0;
+ for (int k = 0; k < len; ++k) {
+ v3 += (int)b[ptr++] & 0xff;
+ v2 += (int)b[ptr++] & 0xff;
+ v1 += (int)b[ptr++] & 0xff;
+ v0 += (int)b[ptr++] & 0xff;
+ }
+ return v0 + (v1 << 8) + (v2 << 16) + (v3 << 24);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/TrueTypeFontUnicode.cs b/iTechSharp/iTextSharp/text/pdf/TrueTypeFontUnicode.cs
new file mode 100644
index 0000000..1feb9f9
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/TrueTypeFontUnicode.cs
@@ -0,0 +1,487 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+
+/*
+ * $Id: TrueTypeFontUnicode.cs,v 1.12 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Represents a True Type font with Unicode encoding. All the character
+ * in the font can be used directly by using the encoding Identity-H or
+ * Identity-V. This is the only way to represent some character sets such
+ * as Thai.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ internal class TrueTypeFontUnicode : TrueTypeFont, IComparer {
+
+ /** true
if the encoding is vertical.
+ */
+ bool vertical = false;
+
+ /** Creates a new TrueType font addressed by Unicode characters. The font
+ * will always be embedded.
+ * @param ttFile the location of the font on file. The file must end in '.ttf'.
+ * The modifiers after the name are ignored.
+ * @param enc the encoding to be applied to this font
+ * @param emb true if the font is to be embedded in the PDF
+ * @param ttfAfm the font as a byte
array
+ * @throws DocumentException the font is invalid
+ * @throws IOException the font file could not be read
+ */
+ internal TrueTypeFontUnicode(string ttFile, string enc, bool emb, byte[] ttfAfm) {
+ string nameBase = GetBaseName(ttFile);
+ string ttcName = GetTTCName(nameBase);
+ if (nameBase.Length < ttFile.Length) {
+ style = ttFile.Substring(nameBase.Length);
+ }
+ encoding = enc;
+ embedded = emb;
+ fileName = ttcName;
+ ttcIndex = "";
+ if (ttcName.Length < nameBase.Length)
+ ttcIndex = nameBase.Substring(ttcName.Length + 1);
+ FontType = FONT_TYPE_TTUNI;
+ if ((fileName.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || fileName.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || fileName.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttc")) && ((enc.Equals(IDENTITY_H) || enc.Equals(IDENTITY_V)) && emb)) {
+ Process(ttfAfm);
+ if (os_2.fsType == 2)
+ throw new DocumentException(fileName + style + " cannot be embedded due to licensing restrictions.");
+ // Sivan
+ if ((cmap31 == null && !fontSpecific) || (cmap10 == null && fontSpecific))
+ directTextToByte=true;
+ //throw new DocumentException(fileName + " " + style + " does not contain an usable cmap.");
+ if (fontSpecific) {
+ fontSpecific = false;
+ String tempEncoding = encoding;
+ encoding = "";
+ CreateEncoding();
+ encoding = tempEncoding;
+ fontSpecific = true;
+ }
+ }
+ else
+ throw new DocumentException(fileName + " " + style + " is not a TTF font file.");
+ vertical = enc.EndsWith("V");
+ }
+
+ /**
+ * Gets the width of a char
in normalized 1000 units.
+ * @param char1 the unicode char
to get the width of
+ * @return the width in normalized 1000 units
+ */
+ public override int GetWidth(int char1) {
+ if (vertical)
+ return 1000;
+ if (fontSpecific) {
+ if ((char1 & 0xff00) == 0 || (char1 & 0xff00) == 0xf000)
+ return GetRawWidth(char1 & 0xff, null);
+ else
+ return 0;
+ }
+ else {
+ return GetRawWidth(char1, encoding);
+ }
+ }
+
+ /**
+ * Gets the width of a string
in normalized 1000 units.
+ * @param text the string
to get the witdth of
+ * @return the width in normalized 1000 units
+ */
+ public override int GetWidth(string text) {
+ if (vertical)
+ return text.Length * 1000;
+ int total = 0;
+ if (fontSpecific) {
+ char[] cc = text.ToCharArray();
+ int len = cc.Length;
+ for (int k = 0; k < len; ++k) {
+ char c = cc[k];
+ if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000)
+ total += GetRawWidth(c & 0xff, null);
+ }
+ }
+ else {
+ int len = text.Length;
+ for (int k = 0; k < len; ++k) {
+ if (Utilities.IsSurrogatePair(text, k)) {
+ total += GetRawWidth(Utilities.ConvertToUtf32(text, k), encoding);
+ ++k;
+ }
+ else
+ total += GetRawWidth(text[k], encoding);
+ }
+ }
+ return total;
+ }
+
+ /** Creates a ToUnicode CMap to allow copy and paste from Acrobat.
+ * @param metrics metrics[0] contains the glyph index and metrics[2]
+ * contains the Unicode code
+ * @throws DocumentException on error
+ * @return the stream representing this CMap or null
+ */
+ private PdfStream GetToUnicode(Object[] metrics) {
+ if (metrics.Length == 0)
+ return null;
+ StringBuilder buf = new StringBuilder(
+ "/CIDInit /ProcSet findresource begin\n" +
+ "12 dict begin\n" +
+ "begincmap\n" +
+ "/CIDSystemInfo\n" +
+ "<< /Registry (TTX+0)\n" +
+ "/Ordering (T42UV)\n" +
+ "/Supplement 0\n" +
+ ">> def\n" +
+ "/CMapName /TTX+0 def\n" +
+ "/CMapType 2 def\n" +
+ "1 begincodespacerange\n" +
+ "<0000>null
+ */
+ internal override byte[] ConvertToBytes(string text) {
+ return null;
+ }
+
+ internal override byte[] ConvertToBytes(int char1) {
+ return null;
+ }
+
+ /** Gets the glyph index and metrics for a character.
+ * @param c the character
+ * @return an int
array with {glyph index, width}
+ */
+ public override int[] GetMetricsTT(int c) {
+ if (cmapExt != null)
+ return (int[])cmapExt[c];
+ Hashtable map = null;
+ if (fontSpecific)
+ map = cmap10;
+ else
+ map = cmap31;
+ if (map == null)
+ return null;
+ if (fontSpecific) {
+ if ((c & 0xffffff00) == 0 || (c & 0xffffff00) == 0xf000)
+ return (int[])map[c & 0xff];
+ else
+ return null;
+ }
+ else
+ return (int[])map[c];
+ }
+
+ /**
+ * Checks if a character exists in this font.
+ * @param c the character to check
+ * @return true
if the character has a glyph,
+ * false
otherwise
+ */
+ public override bool CharExists(int c) {
+ return GetMetricsTT(c) != null;
+ }
+
+ /**
+ * Sets the character advance.
+ * @param c the character
+ * @param advance the character advance normalized to 1000 units
+ * @return true
if the advance was set,
+ * false
otherwise
+ */
+ public override bool SetCharAdvance(int c, int advance) {
+ int[] m = GetMetricsTT(c);
+ if (m == null)
+ return false;
+ m[1] = advance;
+ return true;
+ }
+
+ public override int[] GetCharBBox(int c) {
+ if (bboxes == null)
+ return null;
+ int[] m = GetMetricsTT(c);
+ if (m == null)
+ return null;
+ return bboxes[m[0]];
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/Type1Font.cs b/iTechSharp/iTextSharp/text/pdf/Type1Font.cs
new file mode 100644
index 0000000..dcd94fd
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/Type1Font.cs
@@ -0,0 +1,796 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.util;
+
+/*
+ * $Id: Type1Font.cs,v 1.13 2008/05/13 11:25:23 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /** Reads a Type1 font
+ *
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ internal class Type1Font : BaseFont {
+ /** The PFB file if the input was made with a byte
array.
+ */
+ protected byte[] pfb;
+ /** The Postscript font name.
+ */
+ private string FontName;
+ /** The full name of the font.
+ */
+ private string FullName;
+ /** The family name of the font.
+ */
+ private string FamilyName;
+ /** The weight of the font: normal, bold, etc.
+ */
+ private string Weight = "";
+ /** The italic angle of the font, usually 0.0 or negative.
+ */
+ private float ItalicAngle = 0.0f;
+ /** true
if all the characters have the same
+ * width.
+ */
+ private bool IsFixedPitch = false;
+ /** The character set of the font.
+ */
+ private string CharacterSet;
+ /** The llx of the FontBox.
+ */
+ private int llx = -50;
+ /** The lly of the FontBox.
+ */
+ private int lly = -200;
+ /** The lurx of the FontBox.
+ */
+ private int urx = 1000;
+ /** The ury of the FontBox.
+ */
+ private int ury = 900;
+ /** The underline position.
+ */
+ private int UnderlinePosition = -100;
+ /** The underline thickness.
+ */
+ private int UnderlineThickness = 50;
+ /** The font's encoding name. This encoding is 'StandardEncoding' or
+ * 'AdobeStandardEncoding' for a font that can be totally encoded
+ * according to the characters names. For all other names the
+ * font is treated as symbolic.
+ */
+ private string EncodingScheme = "FontSpecific";
+ /** A variable.
+ */
+ private int CapHeight = 700;
+ /** A variable.
+ */
+ private int XHeight = 480;
+ /** A variable.
+ */
+ private int Ascender = 800;
+ /** A variable.
+ */
+ private int Descender = -200;
+ /** A variable.
+ */
+ private int StdHW;
+ /** A variable.
+ */
+ private int StdVW = 80;
+
+ /** Represents the section CharMetrics in the AFM file. Each
+ * value of this array contains a Object[4]
with an
+ * Integer, Integer, String and int[]. This is the code, width, name and char bbox.
+ * The key is the name of the char and also an Integer with the char number.
+ */
+ private Hashtable CharMetrics = new Hashtable();
+ /** Represents the section KernPairs in the AFM file. The key is
+ * the name of the first character and the value is a Object[]
+ * with 2 elements for each kern pair. Position 0 is the name of
+ * the second character and position 1 is the kerning distance. This is
+ * repeated for all the pairs.
+ */
+ private Hashtable KernPairs = new Hashtable();
+ /** The file in use.
+ */
+ private string fileName;
+ /** true
if this font is one of the 14 built in fonts.
+ */
+ private bool builtinFont = false;
+ /** Types of records in a PFB file. ASCII is 1 and BINARY is 2.
+ * They have to appear in the PFB file in this sequence.
+ */
+ private static readonly int[] PFB_TYPES = {1, 2, 1};
+
+ /** Creates a new Type1 font.
+ * @param ttfAfm the AFM file if the input is made with a byte
array
+ * @param pfb the PFB file if the input is made with a byte
array
+ * @param afmFile the name of one of the 14 built-in fonts or the location of an AFM file. The file must end in '.afm'
+ * @param enc the encoding to be applied to this font
+ * @param emb true if the font is to be embedded in the PDF
+ * @throws DocumentException the AFM file is invalid
+ * @throws IOException the AFM file could not be read
+ */
+ internal Type1Font(string afmFile, string enc, bool emb, byte[] ttfAfm, byte[] pfb) {
+ if (emb && ttfAfm != null && pfb == null)
+ throw new DocumentException("Two byte arrays are needed if the Type1 font is embedded.");
+ if (emb && ttfAfm != null)
+ this.pfb = pfb;
+ encoding = enc;
+ embedded = emb;
+ fileName = afmFile;
+ FontType = FONT_TYPE_T1;
+ RandomAccessFileOrArray rf = null;
+ Stream istr = null;
+ if (BuiltinFonts14.ContainsKey(afmFile)) {
+ embedded = false;
+ builtinFont = true;
+ byte[] buf = new byte[1024];
+ try {
+ istr = GetResourceStream(RESOURCE_PATH + afmFile + ".afm");
+ if (istr == null) {
+ Console.Error.WriteLine(afmFile + " not found as resource.");
+ throw new DocumentException(afmFile + " not found as resource.");
+ }
+ MemoryStream ostr = new MemoryStream();
+ while (true) {
+ int size = istr.Read(buf, 0, buf.Length);
+ if (size == 0)
+ break;
+ ostr.Write(buf, 0, size);
+ }
+ buf = ostr.ToArray();
+ }
+ finally {
+ if (istr != null) {
+ try {
+ istr.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+ try {
+ rf = new RandomAccessFileOrArray(buf);
+ Process(rf);
+ }
+ finally {
+ if (rf != null) {
+ try {
+ rf.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+ }
+ else if (afmFile.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".afm")) {
+ try {
+ if (ttfAfm == null)
+ rf = new RandomAccessFileOrArray(afmFile);
+ else
+ rf = new RandomAccessFileOrArray(ttfAfm);
+ Process(rf);
+ }
+ finally {
+ if (rf != null) {
+ try {
+ rf.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+ }
+ else if (afmFile.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".pfm")) {
+ try {
+ MemoryStream ba = new MemoryStream();
+ if (ttfAfm == null)
+ rf = new RandomAccessFileOrArray(afmFile);
+ else
+ rf = new RandomAccessFileOrArray(ttfAfm);
+ Pfm2afm.Convert(rf, ba);
+ rf.Close();
+ rf = new RandomAccessFileOrArray(ba.ToArray());
+ Process(rf);
+ }
+ finally {
+ if (rf != null) {
+ try {
+ rf.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+ }
+ else
+ throw new DocumentException(afmFile + " is not an AFM or PFM font file.");
+ EncodingScheme = EncodingScheme.Trim();
+ if (EncodingScheme.Equals("AdobeStandardEncoding") || EncodingScheme.Equals("StandardEncoding")) {
+ fontSpecific = false;
+ }
+ if (!encoding.StartsWith("#"))
+ PdfEncodings.ConvertToBytes(" ", enc); // check if the encoding exists
+ CreateEncoding();
+ }
+
+ /** Gets the width from the font according to the name
or,
+ * if the name
is null, meaning it is a symbolic font,
+ * the char c
.
+ * @param c the char if the font is symbolic
+ * @param name the glyph name
+ * @return the width of the char
+ */
+ internal override int GetRawWidth(int c, string name) {
+ Object[] metrics;
+ if (name == null) { // font specific
+ metrics = (Object[])CharMetrics[c];
+ }
+ else {
+ if (name.Equals(".notdef"))
+ return 0;
+ metrics = (Object[])CharMetrics[name];
+ }
+ if (metrics != null)
+ return (int)metrics[1];
+ return 0;
+ }
+
+ /** Gets the kerning between two Unicode characters. The characters
+ * are converted to names and this names are used to find the kerning
+ * pairs in the Hashtable
KernPairs
.
+ * @param char1 the first char
+ * @param char2 the second char
+ * @return the kerning to be applied
+ */
+ public override int GetKerning(int char1, int char2) {
+ string first = GlyphList.UnicodeToName((int)char1);
+ if (first == null)
+ return 0;
+ string second = GlyphList.UnicodeToName((int)char2);
+ if (second == null)
+ return 0;
+ Object[] obj = (Object[])KernPairs[first];
+ if (obj == null)
+ return 0;
+ for (int k = 0; k < obj.Length; k += 2) {
+ if (second.Equals(obj[k]))
+ return (int)obj[k + 1];
+ }
+ return 0;
+ }
+
+
+ /** Reads the font metrics
+ * @param rf the AFM file
+ * @throws DocumentException the AFM file is invalid
+ * @throws IOException the AFM file could not be read
+ */
+ public void Process(RandomAccessFileOrArray rf) {
+ string line;
+ bool isMetrics = false;
+ while ((line = rf.ReadLine()) != null) {
+ StringTokenizer tok = new StringTokenizer(line, " ,\n\r\t\f");
+ if (!tok.HasMoreTokens())
+ continue;
+ string ident = tok.NextToken();
+ if (ident.Equals("FontName"))
+ FontName = tok.NextToken("\u00ff").Substring(1);
+ else if (ident.Equals("FullName"))
+ FullName = tok.NextToken("\u00ff").Substring(1);
+ else if (ident.Equals("FamilyName"))
+ FamilyName = tok.NextToken("\u00ff").Substring(1);
+ else if (ident.Equals("Weight"))
+ Weight = tok.NextToken("\u00ff").Substring(1);
+ else if (ident.Equals("ItalicAngle"))
+ ItalicAngle = float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("IsFixedPitch"))
+ IsFixedPitch = tok.NextToken().Equals("true");
+ else if (ident.Equals("CharacterSet"))
+ CharacterSet = tok.NextToken("\u00ff").Substring(1);
+ else if (ident.Equals("FontBBox")) {
+ llx = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ lly = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ urx = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ ury = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ else if (ident.Equals("UnderlinePosition"))
+ UnderlinePosition = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("UnderlineThickness"))
+ UnderlineThickness = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("EncodingScheme"))
+ EncodingScheme = tok.NextToken("\u00ff").Substring(1);
+ else if (ident.Equals("CapHeight"))
+ CapHeight = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("XHeight"))
+ XHeight = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("Ascender"))
+ Ascender = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("Descender"))
+ Descender = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("StdHW"))
+ StdHW = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("StdVW"))
+ StdVW = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("StartCharMetrics")) {
+ isMetrics = true;
+ break;
+ }
+ }
+ if (!isMetrics)
+ throw new DocumentException("Missing StartCharMetrics in " + fileName);
+ while ((line = rf.ReadLine()) != null) {
+ StringTokenizer tok = new StringTokenizer(line);
+ if (!tok.HasMoreTokens())
+ continue;
+ string ident = tok.NextToken();
+ if (ident.Equals("EndCharMetrics")) {
+ isMetrics = false;
+ break;
+ }
+ int C = -1;
+ int WX = 250;
+ string N = "";
+ int[] B = null;
+
+ tok = new StringTokenizer(line, ";");
+ while (tok.HasMoreTokens())
+ {
+ StringTokenizer tokc = new StringTokenizer(tok.NextToken());
+ if (!tokc.HasMoreTokens())
+ continue;
+ ident = tokc.NextToken();
+ if (ident.Equals("C"))
+ C = int.Parse(tokc.NextToken());
+ else if (ident.Equals("WX"))
+ WX = (int)float.Parse(tokc.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ else if (ident.Equals("N"))
+ N = tokc.NextToken();
+ else if (ident.Equals("B")) {
+ B = new int[]{int.Parse(tokc.NextToken()),
+ int.Parse(tokc.NextToken()),
+ int.Parse(tokc.NextToken()),
+ int.Parse(tokc.NextToken())};
+ }
+ }
+ Object[] metrics = new Object[]{C, WX, N, B};
+ if (C >= 0)
+ CharMetrics[C] = metrics;
+ CharMetrics[N] = metrics;
+ }
+ if (isMetrics)
+ throw new DocumentException("Missing EndCharMetrics in " + fileName);
+ if (!CharMetrics.ContainsKey("nonbreakingspace")) {
+ Object[] space = (Object[])CharMetrics["space"];
+ if (space != null)
+ CharMetrics["nonbreakingspace"] = space;
+ }
+ while ((line = rf.ReadLine()) != null) {
+ StringTokenizer tok = new StringTokenizer(line);
+ if (!tok.HasMoreTokens())
+ continue;
+ string ident = tok.NextToken();
+ if (ident.Equals("EndFontMetrics"))
+ return;
+ if (ident.Equals("StartKernPairs")) {
+ isMetrics = true;
+ break;
+ }
+ }
+ if (!isMetrics)
+ throw new DocumentException("Missing EndFontMetrics in " + fileName);
+ while ((line = rf.ReadLine()) != null) {
+ StringTokenizer tok = new StringTokenizer(line);
+ if (!tok.HasMoreTokens())
+ continue;
+ string ident = tok.NextToken();
+ if (ident.Equals("KPX")) {
+ string first = tok.NextToken();
+ string second = tok.NextToken();
+ int width = (int)float.Parse(tok.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
+ Object[] relates = (Object[])KernPairs[first];
+ if (relates == null)
+ KernPairs[first] = new Object[]{second, width};
+ else {
+ int n = relates.Length;
+ Object[] relates2 = new Object[n + 2];
+ Array.Copy(relates, 0, relates2, 0, n);
+ relates2[n] = second;
+ relates2[n + 1] = width;
+ KernPairs[first] = relates2;
+ }
+ }
+ else if (ident.Equals("EndKernPairs")) {
+ isMetrics = false;
+ break;
+ }
+ }
+ if (isMetrics)
+ throw new DocumentException("Missing EndKernPairs in " + fileName);
+ rf.Close();
+ }
+
+ /** If the embedded flag is false
or if the font is
+ * one of the 14 built in types, it returns null
,
+ * otherwise the font is read and output in a PdfStream object.
+ * @return the PdfStream containing the font or null
+ * @throws DocumentException if there is an error reading the font
+ */
+ private PdfStream GetFontStream() {
+ if (builtinFont || !embedded)
+ return null;
+ RandomAccessFileOrArray rf = null;
+ try {
+ string filePfb = fileName.Substring(0, fileName.Length - 3) + "pfb";
+ if (pfb == null)
+ rf = new RandomAccessFileOrArray(filePfb);
+ else
+ rf = new RandomAccessFileOrArray(pfb);
+ int fileLength = rf.Length;
+ byte[] st = new byte[fileLength - 18];
+ int[] lengths = new int[3];
+ int bytePtr = 0;
+ for (int k = 0; k < 3; ++k) {
+ if (rf.Read() != 0x80)
+ throw new DocumentException("Start marker missing in " + filePfb);
+ if (rf.Read() != PFB_TYPES[k])
+ throw new DocumentException("Incorrect segment type in " + filePfb);
+ int size = rf.Read();
+ size += rf.Read() << 8;
+ size += rf.Read() << 16;
+ size += rf.Read() << 24;
+ lengths[k] = size;
+ while (size != 0) {
+ int got = rf.Read(st, bytePtr, size);
+ if (got < 0)
+ throw new DocumentException("Premature end in " + filePfb);
+ bytePtr += got;
+ size -= got;
+ }
+ }
+ return new StreamFont(st, lengths);
+ }
+ finally {
+ if (rf != null) {
+ try {
+ rf.Close();
+ }
+ catch {
+ // empty on purpose
+ }
+ }
+ }
+ }
+
+ /** Generates the font descriptor for this font or null
if it is
+ * one of the 14 built in fonts.
+ * @param fontStream the indirect reference to a PdfStream containing the font or null
+ * @return the PdfDictionary containing the font descriptor or null
+ */
+ public PdfDictionary GetFontDescriptor(PdfIndirectReference fontStream) {
+ if (builtinFont)
+ return null;
+ PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR);
+ dic.Put(PdfName.ASCENT, new PdfNumber(Ascender));
+ dic.Put(PdfName.CAPHEIGHT, new PdfNumber(CapHeight));
+ dic.Put(PdfName.DESCENT, new PdfNumber(Descender));
+ dic.Put(PdfName.FONTBBOX, new PdfRectangle(llx, lly, urx, ury));
+ dic.Put(PdfName.FONTNAME, new PdfName(FontName));
+ dic.Put(PdfName.ITALICANGLE, new PdfNumber(ItalicAngle));
+ dic.Put(PdfName.STEMV, new PdfNumber(StdVW));
+ if (fontStream != null)
+ dic.Put(PdfName.FONTFILE, fontStream);
+ int flags = 0;
+ if (IsFixedPitch)
+ flags |= 1;
+ flags |= fontSpecific ? 4 : 32;
+ if (ItalicAngle < 0)
+ flags |= 64;
+ if (FontName.IndexOf("Caps") >= 0 || FontName.EndsWith("SC"))
+ flags |= 131072;
+ if (Weight.Equals("Bold"))
+ flags |= 262144;
+ dic.Put(PdfName.FLAGS, new PdfNumber(flags));
+
+ return dic;
+ }
+
+ /** Generates the font dictionary for this font.
+ * @return the PdfDictionary containing the font dictionary
+ * @param firstChar the first valid character
+ * @param lastChar the last valid character
+ * @param shortTag a 256 bytes long byte
array where each unused byte is represented by 0
+ * @param fontDescriptor the indirect reference to a PdfDictionary containing the font descriptor or null
+ */
+ private PdfDictionary GetFontBaseType(PdfIndirectReference fontDescriptor, int firstChar, int lastChar, byte[] shortTag) {
+ PdfDictionary dic = new PdfDictionary(PdfName.FONT);
+ dic.Put(PdfName.SUBTYPE, PdfName.TYPE1);
+ dic.Put(PdfName.BASEFONT, new PdfName(FontName));
+ bool stdEncoding = encoding.Equals(CP1252) || encoding.Equals(MACROMAN);
+ if (!fontSpecific || specialMap != null) {
+ for (int k = firstChar; k <= lastChar; ++k) {
+ if (!differences[k].Equals(notdef)) {
+ firstChar = k;
+ break;
+ }
+ }
+ if (stdEncoding)
+ dic.Put(PdfName.ENCODING, encoding.Equals(CP1252) ? PdfName.WIN_ANSI_ENCODING : PdfName.MAC_ROMAN_ENCODING);
+ else {
+ PdfDictionary enc = new PdfDictionary(PdfName.ENCODING);
+ PdfArray dif = new PdfArray();
+ bool gap = true;
+ for (int k = firstChar; k <= lastChar; ++k) {
+ if (shortTag[k] != 0) {
+ if (gap) {
+ dif.Add(new PdfNumber(k));
+ gap = false;
+ }
+ dif.Add(new PdfName(differences[k]));
+ }
+ else
+ gap = true;
+ }
+ enc.Put(PdfName.DIFFERENCES, dif);
+ dic.Put(PdfName.ENCODING, enc);
+ }
+ }
+ if (specialMap != null || forceWidthsOutput || !(builtinFont && (fontSpecific || stdEncoding))) {
+ dic.Put(PdfName.FIRSTCHAR, new PdfNumber(firstChar));
+ dic.Put(PdfName.LASTCHAR, new PdfNumber(lastChar));
+ PdfArray wd = new PdfArray();
+ for (int k = firstChar; k <= lastChar; ++k) {
+ if (shortTag[k] == 0)
+ wd.Add(new PdfNumber(0));
+ else
+ wd.Add(new PdfNumber(widths[k]));
+ }
+ dic.Put(PdfName.WIDTHS, wd);
+ }
+ if (!builtinFont && fontDescriptor != null)
+ dic.Put(PdfName.FONTDESCRIPTOR, fontDescriptor);
+ return dic;
+ }
+
+ /** Outputs to the writer the font dictionaries and streams.
+ * @param writer the writer for this document
+ * @param ref the font indirect reference
+ * @param parms several parameters that depend on the font type
+ * @throws IOException on error
+ * @throws DocumentException error in generating the object
+ */
+ internal override void WriteFont(PdfWriter writer, PdfIndirectReference piref, Object[] parms) {
+ int firstChar = (int)parms[0];
+ int lastChar = (int)parms[1];
+ byte[] shortTag = (byte[])parms[2];
+ bool subsetp = (bool)parms[3] && subset;
+ if (!subsetp) {
+ firstChar = 0;
+ lastChar = shortTag.Length - 1;
+ for (int k = 0; k < shortTag.Length; ++k)
+ shortTag[k] = 1;
+ }
+ PdfIndirectReference ind_font = null;
+ PdfObject pobj = null;
+ PdfIndirectObject obj = null;
+ pobj = GetFontStream();
+ if (pobj != null){
+ obj = writer.AddToBody(pobj);
+ ind_font = obj.IndirectReference;
+ }
+ pobj = GetFontDescriptor(ind_font);
+ if (pobj != null){
+ obj = writer.AddToBody(pobj);
+ ind_font = obj.IndirectReference;
+ }
+ pobj = GetFontBaseType(ind_font, firstChar, lastChar, shortTag);
+ writer.AddToBody(pobj, piref);
+ }
+
+ /** Gets the font parameter identified by key
. Valid values
+ * for key
are ASCENT
, CAPHEIGHT
, DESCENT
,
+ * ITALICANGLE
, BBOXLLX
, BBOXLLY
, BBOXURX
+ * and BBOXURY
.
+ * @param key the parameter to be extracted
+ * @param fontSize the font size in points
+ * @return the parameter in points
+ */
+ public override float GetFontDescriptor(int key, float fontSize) {
+ switch (key) {
+ case AWT_ASCENT:
+ case ASCENT:
+ return Ascender * fontSize / 1000;
+ case CAPHEIGHT:
+ return CapHeight * fontSize / 1000;
+ case AWT_DESCENT:
+ case DESCENT:
+ return Descender * fontSize / 1000;
+ case ITALICANGLE:
+ return ItalicAngle;
+ case BBOXLLX:
+ return llx * fontSize / 1000;
+ case BBOXLLY:
+ return lly * fontSize / 1000;
+ case BBOXURX:
+ return urx * fontSize / 1000;
+ case BBOXURY:
+ return ury * fontSize / 1000;
+ case AWT_LEADING:
+ return 0;
+ case AWT_MAXADVANCE:
+ return (urx - llx) * fontSize / 1000;
+ case UNDERLINE_POSITION:
+ return UnderlinePosition * fontSize / 1000;
+ case UNDERLINE_THICKNESS:
+ return UnderlineThickness * fontSize / 1000;
+ }
+ return 0;
+ }
+
+ /** Gets the postscript font name.
+ * @return the postscript font name
+ */
+ public override string PostscriptFontName {
+ get {
+ return FontName;
+ }
+ set {
+ FontName = value;
+ }
+ }
+
+ /** Gets the full name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public override string[][] FullFontName {
+ get {
+ return new string[][]{new string[] {"", "", "", FullName}};
+ }
+ }
+
+ /** Gets all the entries of the names-table. If it is a True Type font
+ * each array element will have {Name ID, Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"4", "", "", "",
+ * font name}.
+ * @return the full name of the font
+ */
+ public override string[][] AllNameEntries {
+ get {
+ return new string[][]{new string[]{"4", "", "", "", FullName}};
+ }
+ }
+
+ /** Gets the family name of the font. If it is a True Type font
+ * each array element will have {Platform ID, Platform Encoding ID,
+ * Language ID, font name}. The interpretation of this values can be
+ * found in the Open Type specification, chapter 2, in the 'name' table.
+ * For the other fonts the array has a single element with {"", "", "",
+ * font name}.
+ * @return the family name of the font
+ */
+ public override string[][] FamilyFontName {
+ get {
+ return new string[][]{new string[] {"", "", "", FamilyName}};
+ }
+ }
+
+ /** Checks if the font has any kerning pairs.
+ * @return true
if the font has any kerning pairs
+ */
+ public override bool HasKernPairs() {
+ return KernPairs.Count > 0;
+ }
+
+ /**
+ * Sets the kerning between two Unicode chars.
+ * @param char1 the first char
+ * @param char2 the second char
+ * @param kern the kerning to apply in normalized 1000 units
+ * @return true
if the kerning was applied, false
otherwise
+ */
+ public override bool SetKerning(int char1, int char2, int kern) {
+ String first = GlyphList.UnicodeToName((int)char1);
+ if (first == null)
+ return false;
+ String second = GlyphList.UnicodeToName((int)char2);
+ if (second == null)
+ return false;
+ Object[] obj = (Object[])KernPairs[first];
+ if (obj == null) {
+ obj = new Object[]{second, kern};
+ KernPairs[first] = obj;
+ return true;
+ }
+ for (int k = 0; k < obj.Length; k += 2) {
+ if (second.Equals(obj[k])) {
+ obj[k + 1] = kern;
+ return true;
+ }
+ }
+ int size = obj.Length;
+ Object[] obj2 = new Object[size + 2];
+ Array.Copy(obj, 0, obj2, 0, size);
+ obj2[size] = second;
+ obj2[size + 1] = kern;
+ KernPairs[first] = obj2;
+ return true;
+ }
+
+ protected override int[] GetRawCharBBox(int c, String name) {
+ Object[] metrics;
+ if (name == null) { // font specific
+ metrics = (Object[])CharMetrics[c];
+ }
+ else {
+ if (name.Equals(".notdef"))
+ return null;
+ metrics = (Object[])CharMetrics[name];
+ }
+ if (metrics != null)
+ return ((int[])(metrics[3]));
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/Type3Font.cs b/iTechSharp/iTextSharp/text/pdf/Type3Font.cs
new file mode 100644
index 0000000..a707102
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/Type3Font.cs
@@ -0,0 +1,317 @@
+using System;
+using System.Collections;
+/*
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * A class to support Type3 fonts.
+ */
+ public class Type3Font : BaseFont {
+
+ private bool[] usedSlot;
+ private IntHashtable widths3 = new IntHashtable();
+ private Hashtable char2glyph = new Hashtable();
+ private PdfWriter writer;
+ private float llx = float.NaN, lly, urx, ury;
+ private PageResources pageResources = new PageResources();
+ private bool colorized;
+
+ /**
+ * Creates a Type3 font.
+ * @param writer the writer
+ * @param chars an array of chars corresponding to the glyphs used (not used, prisent for compability only)
+ * @param colorized if true
the font may specify color, if false
no color commands are allowed
+ * and only images as masks can be used
+ */
+ public Type3Font(PdfWriter writer, char[] chars, bool colorized) : this(writer, colorized) {
+ }
+
+ /**
+ * Creates a Type3 font. This implementation assumes that the /FontMatrix is
+ * [0.001 0 0 0.001 0 0] or a 1000-unit glyph coordinate system.
+ *
+ * Document document = new Document(PageSize.A4);
+ * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("type3.pdf"));
+ * document.open();
+ * Type3Font t3 = new Type3Font(writer, false);
+ * PdfContentByte g = t3.defineGlyph('a', 1000, 0, 0, 750, 750);
+ * g.rectangle(0, 0, 750, 750);
+ * g.fill();
+ * g = t3.defineGlyph('b', 1000, 0, 0, 750, 750);
+ * g.moveTo(0, 0);
+ * g.lineTo(375, 750);
+ * g.lineTo(750, 0);
+ * g.fill();
+ * Font f = new Font(t3, 12);
+ * document.add(new Paragraph("ababab", f));
+ * document.close();
+ *
+ * @param writer the writer
+ * @param colorized if true
the font may specify color, if false
no color commands are allowed
+ * and only images as masks can be used
+ */
+ public Type3Font(PdfWriter writer, bool colorized) {
+ this.writer = writer;
+ this.colorized = colorized;
+ fontType = FONT_TYPE_T3;
+ usedSlot = new bool[256];
+ }
+
+ /**
+ * Defines a glyph. If the character was already defined it will return the same content
+ * @param c the character to match this glyph.
+ * @param wx the advance this character will have
+ * @param llx the X lower left corner of the glyph bounding box. If the colorize
option is
+ * true
the value is ignored
+ * @param lly the Y lower left corner of the glyph bounding box. If the colorize
option is
+ * true
the value is ignored
+ * @param urx the X upper right corner of the glyph bounding box. If the colorize
option is
+ * true
the value is ignored
+ * @param ury the Y upper right corner of the glyph bounding box. If the colorize
option is
+ * true
the value is ignored
+ * @return a content where the glyph can be defined
+ */
+ public PdfContentByte DefineGlyph(char c, float wx, float llx, float lly, float urx, float ury) {
+ if (c == 0 || c > 255)
+ throw new ArgumentException("The char " + (int)c + " doesn't belong in this Type3 font");
+ usedSlot[c] = true;
+ Type3Glyph glyph = (Type3Glyph)char2glyph[c];
+ if (glyph != null)
+ return glyph;
+ widths3[c] = (int)wx;
+ if (!colorized) {
+ if (float.IsNaN(this.llx)) {
+ this.llx = llx;
+ this.lly = lly;
+ this.urx = urx;
+ this.ury = ury;
+ }
+ else {
+ this.llx = Math.Min(this.llx, llx);
+ this.lly = Math.Min(this.lly, lly);
+ this.urx = Math.Max(this.urx, urx);
+ this.ury = Math.Max(this.ury, ury);
+ }
+ }
+ glyph = new Type3Glyph(writer, pageResources, wx, llx, lly, urx, ury, colorized);
+ char2glyph[c] = glyph;
+ return glyph;
+ }
+
+ public override String[][] FamilyFontName {
+ get {
+ return FullFontName;
+ }
+ }
+
+ public override float GetFontDescriptor(int key, float fontSize) {
+ return 0;
+ }
+
+ public override String[][] FullFontName {
+ get {
+ return new string[][]{new string[]{"", "", "", ""}};
+ }
+ }
+
+ public override string[][] AllNameEntries {
+ get {
+ return new string[][]{new string[]{"4", "", "", "", ""}};
+ }
+ }
+
+ public override int GetKerning(int char1, int char2) {
+ return 0;
+ }
+
+ public override string PostscriptFontName {
+ get {
+ return "";
+ }
+ set {
+ }
+ }
+
+ protected override int[] GetRawCharBBox(int c, String name) {
+ return null;
+ }
+
+ internal override int GetRawWidth(int c, String name) {
+ return 0;
+ }
+
+ public override bool HasKernPairs() {
+ return false;
+ }
+
+ public override bool SetKerning(int char1, int char2, int kern) {
+ return false;
+ }
+
+ internal override void WriteFont(PdfWriter writer, PdfIndirectReference piRef, Object[] oParams) {
+ if (this.writer != writer)
+ throw new ArgumentException("Type3 font used with the wrong PdfWriter");
+ // Get first & lastchar ...
+ int firstChar = 0;
+ while( firstChar < usedSlot.Length && !usedSlot[firstChar] ) firstChar++;
+
+ if ( firstChar == usedSlot.Length ) {
+ throw new DocumentException( "No glyphs defined for Type3 font" );
+ }
+ int lastChar = usedSlot.Length - 1;
+ while( lastChar >= firstChar && !usedSlot[lastChar] ) lastChar--;
+
+ int[] widths = new int[lastChar - firstChar + 1];
+ int[] invOrd = new int[lastChar - firstChar + 1];
+
+ int invOrdIndx = 0, w = 0;
+ for( int u = firstChar; u<=lastChar; u++, w++ ) {
+ if ( usedSlot[u] ) {
+ invOrd[invOrdIndx++] = u;
+ widths[w] = widths3[u];
+ }
+ }
+ PdfArray diffs = new PdfArray();
+ PdfDictionary charprocs = new PdfDictionary();
+ int last = -1;
+ for (int k = 0; k < invOrdIndx; ++k) {
+ int c = invOrd[k];
+ if (c > last) {
+ last = c;
+ diffs.Add(new PdfNumber(last));
+ }
+ ++last;
+ int c2 = invOrd[k];
+ String s = GlyphList.UnicodeToName(c2);
+ if (s == null)
+ s = "a" + c2;
+ PdfName n = new PdfName(s);
+ diffs.Add(n);
+ Type3Glyph glyph = (Type3Glyph)char2glyph[(char)c2];
+ PdfStream stream = new PdfStream(glyph.ToPdf(null));
+ stream.FlateCompress();
+ PdfIndirectReference refp = writer.AddToBody(stream).IndirectReference;
+ charprocs.Put(n, refp);
+ }
+ PdfDictionary font = new PdfDictionary(PdfName.FONT);
+ font.Put(PdfName.SUBTYPE, PdfName.TYPE3);
+ if (colorized)
+ font.Put(PdfName.FONTBBOX, new PdfRectangle(0, 0, 0, 0));
+ else
+ font.Put(PdfName.FONTBBOX, new PdfRectangle(llx, lly, urx, ury));
+ font.Put(PdfName.FONTMATRIX, new PdfArray(new float[]{0.001f, 0, 0, 0.001f, 0, 0}));
+ font.Put(PdfName.CHARPROCS, writer.AddToBody(charprocs).IndirectReference);
+ PdfDictionary encoding = new PdfDictionary();
+ encoding.Put(PdfName.DIFFERENCES, diffs);
+ font.Put(PdfName.ENCODING, writer.AddToBody(encoding).IndirectReference);
+ font.Put(PdfName.FIRSTCHAR, new PdfNumber(firstChar));
+ font.Put(PdfName.LASTCHAR, new PdfNumber(lastChar));
+ font.Put(PdfName.WIDTHS, writer.AddToBody(new PdfArray(widths)).IndirectReference);
+ if (pageResources.HasResources())
+ font.Put(PdfName.RESOURCES, writer.AddToBody(pageResources.Resources).IndirectReference);
+ writer.AddToBody(font, piRef);
+ }
+
+ internal override byte[] ConvertToBytes(String text) {
+ char[] cc = text.ToCharArray();
+ byte[] b = new byte[cc.Length];
+ int p = 0;
+ for (int k = 0; k < cc.Length; ++k) {
+ char c = cc[k];
+ if (CharExists(c))
+ b[p++] = (byte)c;
+ }
+ if (b.Length == p)
+ return b;
+ byte[] b2 = new byte[p];
+ Array.Copy(b, 0, b2, 0, p);
+ return b2;
+ }
+
+ internal override byte[] ConvertToBytes(int char1) {
+ if (CharExists(char1))
+ return new byte[]{(byte)char1};
+ else return new byte[0];
+ }
+
+ public override int GetWidth(int char1) {
+ if (!widths3.ContainsKey(char1))
+ throw new ArgumentException("The char " + (int)char1 + " is not defined in a Type3 font");
+ return widths3[char1];
+ }
+
+ public override int GetWidth(String text) {
+ char[] c = text.ToCharArray();
+ int total = 0;
+ for (int k = 0; k < c.Length; ++k)
+ total += GetWidth(c[k]);
+ return total;
+ }
+
+ public override int[] GetCharBBox(int c) {
+ return null;
+ }
+
+ public override bool CharExists(int c) {
+ if ( c > 0 && c < 256 ) {
+ return usedSlot[c];
+ } else {
+ return false;
+ }
+ }
+
+ public override bool SetCharAdvance(int c, int advance) {
+ return false;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/Type3Glyph.cs b/iTechSharp/iTextSharp/text/pdf/Type3Glyph.cs
new file mode 100644
index 0000000..cce6c71
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/Type3Glyph.cs
@@ -0,0 +1,94 @@
+using System;
+/*
+ * Copyright 2005 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * The content where Type3 glyphs are written to.
+ */
+ public sealed class Type3Glyph : PdfContentByte {
+
+ private PageResources pageResources;
+ private bool colorized;
+
+ private Type3Glyph() : base(null) {
+ }
+
+ internal Type3Glyph(PdfWriter writer, PageResources pageResources, float wx, float llx, float lly, float urx, float ury, bool colorized) : base(writer) {
+ this.pageResources = pageResources;
+ this.colorized = colorized;
+ if (colorized) {
+ content.Append(wx).Append(" 0 d0\n");
+ }
+ else {
+ content.Append(wx).Append(" 0 ").Append(llx).Append(' ').Append(lly).Append(' ').Append(urx).Append(' ').Append(ury).Append(" d1\n");
+ }
+ }
+
+ internal override PageResources PageResources {
+ get {
+ return pageResources;
+ }
+ }
+
+ public override void AddImage(Image image, float a, float b, float c, float d, float e, float f, bool inlineImage) {
+ if (!colorized && (!image.IsMask() || !(image.Bpc == 1 || image.Bpc > 0xff)))
+ throw new DocumentException("Not colorized Typed3 fonts only accept mask images.");
+ base.AddImage(image, a, b, c, d, e, f, inlineImage);
+ }
+
+ public PdfContentByte GetDuplicate() {
+ Type3Glyph dup = new Type3Glyph();
+ dup.writer = writer;
+ dup.pdf = pdf;
+ dup.pageResources = pageResources;
+ dup.colorized = colorized;
+ return dup;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/VerticalText.cs b/iTechSharp/iTextSharp/text/pdf/VerticalText.cs
new file mode 100644
index 0000000..05ce4c0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/VerticalText.cs
@@ -0,0 +1,344 @@
+using System;
+using System.Collections;
+
+using iTextSharp.text;
+
+/*
+ *
+ * Copyright 2002 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.pdf {
+
+ /** Writes text vertically. Note that the naming is done according
+ * to horizontal text although it referrs to vertical text.
+ * A line with the alignment Element.LEFT_ALIGN will actually
+ * be top aligned.
+ */
+ public class VerticalText {
+
+ /** Signals that there are no more text available. */
+ public static int NO_MORE_TEXT = 1;
+
+ /** Signals that there is no more column. */
+ public static int NO_MORE_COLUMN = 2;
+
+ /** The chunks that form the text. */
+ protected ArrayList chunks = new ArrayList();
+
+ /** The PdfContent
where the text will be written to. */
+ protected PdfContentByte text;
+
+ /** The column Element. Default is left Element. */
+ protected int alignment = Element.ALIGN_LEFT;
+
+ /** Marks the chunks to be eliminated when the line is written. */
+ protected int currentChunkMarker = -1;
+
+ /** The chunk created by the splitting. */
+ protected PdfChunk currentStandbyChunk;
+
+ /** The chunk created by the splitting. */
+ protected string splittedChunkText;
+
+ /** The leading
+ */
+ protected float leading;
+
+ /** The X coordinate.
+ */
+ protected float startX;
+
+ /** The Y coordinate.
+ */
+ protected float startY;
+
+ /** The maximum number of vertical lines.
+ */
+ protected int maxLines;
+
+ /** The height of the text.
+ */
+ protected float height;
+
+ /** Creates new VerticalText
+ * @param text the place where the text will be written to. Can
+ * be a template.
+ */
+ public VerticalText(PdfContentByte text) {
+ this.text = text;
+ }
+
+ /**
+ * Adds a Phrase
to the current text array.
+ * @param phrase the text
+ */
+ public void AddText(Phrase phrase) {
+ foreach(Chunk c in phrase.Chunks) {
+ chunks.Add(new PdfChunk(c, null));
+ }
+ }
+
+ /**
+ * Adds a Chunk
to the current text array.
+ * @param chunk the text
+ */
+ public void AddText(Chunk chunk) {
+ chunks.Add(new PdfChunk(chunk, null));
+ }
+
+ /** Sets the layout.
+ * @param startX the top right X line position
+ * @param startY the top right Y line position
+ * @param height the height of the lines
+ * @param maxLines the maximum number of lines
+ * @param leading the separation between the lines
+ */
+ public void SetVerticalLayout(float startX, float startY, float height, int maxLines, float leading) {
+ this.startX = startX;
+ this.startY = startY;
+ this.height = height;
+ this.maxLines = maxLines;
+ Leading = leading;
+ }
+
+ /** Gets the separation between the vertical lines.
+ * @return the vertical line separation
+ */
+ public float Leading {
+ get {
+ return leading;
+ }
+
+ set {
+ this.leading = value;
+ }
+ }
+
+ /**
+ * Creates a line from the chunk array.
+ * @param width the width of the line
+ * @return the line or null if no more chunks
+ */
+ protected PdfLine CreateLine(float width) {
+ if (chunks.Count == 0)
+ return null;
+ splittedChunkText = null;
+ currentStandbyChunk = null;
+ PdfLine line = new PdfLine(0, width, alignment, 0);
+ string total;
+ for (currentChunkMarker = 0; currentChunkMarker < chunks.Count; ++currentChunkMarker) {
+ PdfChunk original = (PdfChunk)(chunks[currentChunkMarker]);
+ total = original.ToString();
+ currentStandbyChunk = line.Add(original);
+ if (currentStandbyChunk != null) {
+ splittedChunkText = original.ToString();
+ original.Value = total;
+ return line;
+ }
+ }
+ return line;
+ }
+
+ /**
+ * Normalizes the list of chunks when the line is accepted.
+ */
+ protected void ShortenChunkArray() {
+ if (currentChunkMarker < 0)
+ return;
+ if (currentChunkMarker >= chunks.Count) {
+ chunks.Clear();
+ return;
+ }
+ PdfChunk split = (PdfChunk)(chunks[currentChunkMarker]);
+ split.Value = splittedChunkText;
+ chunks[currentChunkMarker] = currentStandbyChunk;
+ for (int j = currentChunkMarker - 1; j >= 0; --j)
+ chunks.RemoveAt(j);
+ }
+
+ /**
+ * Outputs the lines to the document. It is equivalent to go(false)
.
+ * @return returns the result of the operation. It can be NO_MORE_TEXT
+ * and/or NO_MORE_COLUMN
+ * @throws DocumentException on error
+ */
+ public int Go() {
+ return Go(false);
+ }
+
+ /**
+ * Outputs the lines to the document. The output can be simulated.
+ * @param simulate true
to simulate the writting to the document
+ * @return returns the result of the operation. It can be NO_MORE_TEXT
+ * and/or NO_MORE_COLUMN
+ * @throws DocumentException on error
+ */
+ public int Go(bool simulate) {
+ bool dirty = false;
+ PdfContentByte graphics = null;
+ if (text != null) {
+ graphics = text.Duplicate;
+ }
+ else if (!simulate)
+ throw new Exception("VerticalText.go with simulate==false and text==null.");
+ int status = 0;
+ for (;;) {
+ if (maxLines <= 0) {
+ status = NO_MORE_COLUMN;
+ if (chunks.Count == 0)
+ status |= NO_MORE_TEXT;
+ break;
+ }
+ if (chunks.Count == 0) {
+ status = NO_MORE_TEXT;
+ break;
+ }
+ PdfLine line = CreateLine(height);
+ if (!simulate && !dirty) {
+ text.BeginText();
+ dirty = true;
+ }
+ ShortenChunkArray();
+ if (!simulate) {
+ text.SetTextMatrix(startX, startY - line.IndentLeft);
+ WriteLine(line, text, graphics);
+ }
+ --maxLines;
+ startX -= leading;
+ }
+ if (dirty) {
+ text.EndText();
+ text.Add(graphics);
+ }
+ return status;
+ }
+
+ internal void WriteLine(PdfLine line, PdfContentByte text, PdfContentByte graphics) {
+ PdfFont currentFont = null;
+ foreach(PdfChunk chunk in line) {
+ if (chunk.Font.CompareTo(currentFont) != 0) {
+ currentFont = chunk.Font;
+ text.SetFontAndSize(currentFont.Font, currentFont.Size);
+ }
+ Color color = chunk.Color;
+ if (color != null)
+ text.SetColorFill(color);
+ text.ShowText(chunk.ToString());
+ if (color != null)
+ text.ResetRGBColorFill();
+ }
+ }
+
+ /** Sets the new text origin.
+ * @param startX the X coordinate
+ * @param startY the Y coordinate
+ */
+ public void SetOrigin(float startX, float startY) {
+ this.startX = startX;
+ this.startY = startY;
+ }
+
+ /** Gets the X coordinate where the next line will be writen. This value will change
+ * after each call to go()
.
+ * @return the X coordinate
+ */
+ public float OriginX {
+ get {
+ return startX;
+ }
+ }
+
+ /** Gets the Y coordinate where the next line will be writen.
+ * @return the Y coordinate
+ */
+ public float OriginY {
+ get {
+ return startY;
+ }
+ }
+
+ /** Gets the maximum number of available lines. This value will change
+ * after each call to go()
.
+ * @return Value of property maxLines.
+ */
+ public int MaxLines {
+ get {
+ return maxLines;
+ }
+
+ set {
+ this.maxLines = value;
+ }
+ }
+
+ /** Gets the height of the line
+ * @return the height
+ */
+ public float Height {
+ get {
+ return height;
+ }
+
+ set {
+ this.height = value;
+ }
+ }
+
+ /**
+ * Gets the Element.
+ * @return the alignment
+ */
+ public int Alignment {
+ get {
+ return alignment;
+ }
+
+ set {
+ this.alignment = value;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/XfaForm.cs b/iTechSharp/iTextSharp/text/pdf/XfaForm.cs
new file mode 100644
index 0000000..d3b044b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/XfaForm.cs
@@ -0,0 +1,995 @@
+using System;
+using System.Collections;
+using System.Text;
+using System.IO;
+using System.Xml;
+/*
+ * $Id: XfaForm.cs,v 1.7 2007/05/21 10:55:28 psoares33 Exp $
+ *
+ * Copyright 2006 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+
+ /**
+ * Processes XFA forms.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class XfaForm {
+
+ private Xml2SomTemplate templateSom;
+ private Xml2SomDatasets datasetsSom;
+ private AcroFieldsSearch acroFieldsSom;
+ private PdfReader reader;
+ private bool xfaPresent;
+ private XmlDocument domDocument;
+ private bool changed;
+ private XmlNode datasetsNode;
+ public const String XFA_DATA_SCHEMA = "http://www.xfa.org/schema/xfa-data/1.0/";
+
+ /**
+ * An empty constructor to build on.
+ */
+ public XfaForm() {
+ }
+
+ /**
+ * A constructor from a PdfReader
. It basically does everything
+ * from finding the XFA stream to the XML parsing.
+ * @param reader the reader
+ * @throws java.io.IOException on error
+ * @throws javax.xml.parsers.ParserConfigurationException on error
+ * @throws org.xml.sax.SAXException on error
+ */
+ public XfaForm(PdfReader reader) {
+ this.reader = reader;
+ PdfDictionary af = (PdfDictionary)PdfReader.GetPdfObjectRelease(reader.Catalog.Get(PdfName.ACROFORM));
+ if (af == null) {
+ xfaPresent = false;
+ return;
+ }
+ PdfObject xfa = PdfReader.GetPdfObjectRelease(af.Get(PdfName.XFA));
+ if (xfa == null) {
+ xfaPresent = false;
+ return;
+ }
+ xfaPresent = true;
+ MemoryStream bout = new MemoryStream();
+ if (xfa.IsArray()) {
+ ArrayList ar = ((PdfArray)xfa).ArrayList;
+ for (int k = 1; k < ar.Count; k += 2) {
+ PdfObject ob = PdfReader.GetPdfObject((PdfObject)ar[k]);
+ if (ob is PRStream) {
+ byte[] b = PdfReader.GetStreamBytes((PRStream)ob);
+ bout.Write(b, 0, b.Length);
+ }
+ }
+ }
+ else if (xfa is PRStream) {
+ byte[] b = PdfReader.GetStreamBytes((PRStream)xfa);
+ bout.Write(b, 0, b.Length);
+ }
+ bout.Seek(0, SeekOrigin.Begin);
+ XmlTextReader xtr = new XmlTextReader(bout);
+ domDocument = new XmlDocument();
+ domDocument.Load(xtr);
+ XmlNode n = domDocument.FirstChild;
+ while (n.NodeType != XmlNodeType.Element)
+ n = n.NextSibling;
+ n = n.FirstChild;
+ while (n != null) {
+ if (n.NodeType == XmlNodeType.Element) {
+ String s = n.LocalName;
+ if (s.Equals("template")) {
+ templateSom = new Xml2SomTemplate(n);
+ }
+ else if (s.Equals("datasets")) {
+ datasetsNode = n;
+ datasetsSom = new Xml2SomDatasets(n.FirstChild);
+ }
+ }
+ n = n.NextSibling;
+ }
+ }
+
+ /**
+ * Sets the XFA key from a byte array. The old XFA is erased.
+ * @param xfaData the data
+ * @param reader the reader
+ * @param writer the writer
+ * @throws java.io.IOException on error
+ */
+ public static void SetXfa(byte[] xfaData, PdfReader reader, PdfWriter writer) {
+ PdfDictionary af = (PdfDictionary)PdfReader.GetPdfObjectRelease(reader.Catalog.Get(PdfName.ACROFORM));
+ if (af == null) {
+ return;
+ }
+ reader.KillXref(af.Get(PdfName.XFA));
+ PdfStream str = new PdfStream(xfaData);
+ str.FlateCompress();
+ PdfIndirectReference refe = writer.AddToBody(str).IndirectReference;
+ af.Put(PdfName.XFA, refe);
+ }
+
+ /**
+ * Sets the XFA key from the instance data. The old XFA is erased.
+ * @param writer the writer
+ * @throws java.io.IOException on error
+ */
+ public void SetXfa(PdfWriter writer) {
+ SetXfa(SerializeDoc(domDocument), reader, writer);
+ }
+
+ /**
+ * Serializes a XML document to a byte array.
+ * @param n the XML document
+ * @throws java.io.IOException on error
+ * @return the serialized XML document
+ */
+ public static byte[] SerializeDoc(XmlNode n) {
+ MemoryStream fout = new MemoryStream();
+ XmlTextWriter xw = new XmlTextWriter(fout, new UTF8Encoding(false));
+ xw.WriteNode(new XmlNodeReader(n), true);
+ xw.Close();
+ return fout.ToArray();
+ }
+
+ /**
+ * Returns true
if it is a XFA form.
+ * @return true
if it is a XFA form
+ */
+ public bool XfaPresent {
+ get {
+ return xfaPresent;
+ }
+ set {
+ xfaPresent = value;
+ }
+ }
+
+ /**
+ * Gets the top level DOM document.
+ * @return the top level DOM document
+ */
+ public XmlDocument DomDocument {
+ get {
+ return domDocument;
+ }
+ set {
+ domDocument = value;
+ }
+ }
+
+
+ /**
+ * Finds the complete field name contained in the "classic" forms from a partial
+ * name.
+ * @param name the complete or partial name
+ * @param af the fields
+ * @return the complete name or null
if not found
+ */
+ public String FindFieldName(String name, AcroFields af) {
+ Hashtable items = af.Fields;
+ if (items.ContainsKey(name))
+ return name;
+ if (acroFieldsSom == null) {
+ acroFieldsSom = new AcroFieldsSearch(items.Keys);
+ }
+ if (acroFieldsSom.AcroShort2LongName.ContainsKey(name))
+ return (String)acroFieldsSom.AcroShort2LongName[name];
+ return acroFieldsSom.InverseSearchGlobal(Xml2Som.SplitParts(name));
+ }
+
+ /**
+ * Finds the complete SOM name contained in the datasets section from a
+ * possibly partial name.
+ * @param name the complete or partial name
+ * @return the complete name or null
if not found
+ */
+ public String FindDatasetsName(String name) {
+ if (datasetsSom.Name2Node.ContainsKey(name))
+ return name;
+ return datasetsSom.InverseSearchGlobal(Xml2Som.SplitParts(name));
+ }
+
+ /**
+ * Finds the Node
contained in the datasets section from a
+ * possibly partial name.
+ * @param name the complete or partial name
+ * @return the Node
or null
if not found
+ */
+ public XmlNode FindDatasetsNode(String name) {
+ if (name == null)
+ return null;
+ name = FindDatasetsName(name);
+ if (name == null)
+ return null;
+ return (XmlNode)datasetsSom.Name2Node[name];
+ }
+
+ /**
+ * Gets all the text contained in the child nodes of this node.
+ * @param n the Node
+ * @return the text found or "" if no text was found
+ */
+ public static String GetNodeText(XmlNode n) {
+ if (n == null)
+ return "";
+ return GetNodeText(n, "");
+
+ }
+
+ private static String GetNodeText(XmlNode n, String name) {
+ XmlNode n2 = n.FirstChild;
+ while (n2 != null) {
+ if (n2.NodeType == XmlNodeType.Element) {
+ name = GetNodeText(n2, name);
+ }
+ else if (n2.NodeType == XmlNodeType.Text) {
+ name += n2.Value;
+ }
+ n2 = n2.NextSibling;
+ }
+ return name;
+ }
+
+ /**
+ * Sets the text of this node. All the child's node are deleted and a new
+ * child text node is created.
+ * @param n the Node
to add the text to
+ * @param text the text to add
+ */
+ public void SetNodeText(XmlNode n, String text) {
+ if (n == null)
+ return;
+ XmlNode nc = null;
+ while ((nc = n.FirstChild) != null) {
+ n.RemoveChild(nc);
+ }
+ n.Attributes.RemoveNamedItem("dataNode", XFA_DATA_SCHEMA);
+ n.AppendChild(domDocument.CreateTextNode(text));
+ changed = true;
+ }
+
+ /**
+ * Sets the PdfReader
to be used by this instance.
+ * @param reader the PdfReader
to be used by this instance
+ */
+ public PdfReader Reader {
+ set {
+ reader = value;
+ }
+ get {
+ return reader;
+ }
+ }
+
+ /**
+ * Checks if this XFA form was changed.
+ * @return true
if this XFA form was changed
+ */
+ public bool Changed {
+ get {
+ return changed;
+ }
+ set {
+ changed = value;
+ }
+ }
+
+ /**
+ * A structure to store each part of a SOM name and link it to the next part
+ * beginning from the lower hierarchie.
+ */
+ public class InverseStore {
+ protected internal ArrayList part = new ArrayList();
+ protected internal ArrayList follow = new ArrayList();
+
+ /**
+ * Gets the full name by traversing the hiearchie using only the
+ * index 0.
+ * @return the full name
+ */
+ public String DefaultName {
+ get {
+ InverseStore store = this;
+ while (true) {
+ Object obj = store.follow[0];
+ if (obj is String)
+ return (String)obj;
+ store = (InverseStore)obj;
+ }
+ }
+ }
+
+ /**
+ * Search the current node for a similar name. A similar name starts
+ * with the same name but has a differnt index. For example, "detail[3]"
+ * is similar to "detail[9]". The main use is to discard names that
+ * correspond to out of bounds records.
+ * @param name the name to search
+ * @return true
if a similitude was found
+ */
+ public bool IsSimilar(String name) {
+ int idx = name.IndexOf('[');
+ name = name.Substring(0, idx + 1);
+ foreach (String n in part) {
+ if (n.StartsWith(name))
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Another stack implementation. The main use is to facilitate
+ * the porting to other languages.
+ */
+ public class Stack2 : ArrayList {
+ /**
+ * Looks at the object at the top of this stack without removing it from the stack.
+ * @return the object at the top of this stack
+ */
+ public Object Peek() {
+ if (Count == 0)
+ throw new InvalidOperationException();
+ return this[Count - 1];
+ }
+
+ /**
+ * Removes the object at the top of this stack and returns that object as the value of this function.
+ * @return the object at the top of this stack
+ */
+ public Object Pop() {
+ if (Count == 0)
+ throw new InvalidOperationException();
+ Object ret = this[Count - 1];
+ RemoveAt(Count - 1);
+ return ret;
+ }
+
+ /**
+ * Pushes an item onto the top of this stack.
+ * @param item the item to be pushed onto this stack
+ * @return the item
argument
+ */
+ public Object Push(Object item) {
+ Add(item);
+ return item;
+ }
+
+ /**
+ * Tests if this stack is empty.
+ * @return true
if and only if this stack contains no items; false
otherwise
+ */
+ public bool Empty() {
+ return Count == 0;
+ }
+ }
+
+ /**
+ * A class for some basic SOM processing.
+ */
+ public class Xml2Som {
+ /**
+ * The order the names appear in the XML, depth first.
+ */
+ protected ArrayList order;
+ /**
+ * The mapping of full names to nodes.
+ */
+ protected Hashtable name2Node;
+ /**
+ * The data to do a search from the bottom hierarchie.
+ */
+ protected Hashtable inverseSearch;
+ /**
+ * A stack to be used when parsing.
+ */
+ protected Stack2 stack;
+ /**
+ * A temporary store for the repetition count.
+ */
+ protected int anform;
+
+ /**
+ * Escapes a SOM string fragment replacing "." with "\.".
+ * @param s the unescaped string
+ * @return the escaped string
+ */
+ public static String EscapeSom(String s) {
+ int idx = s.IndexOf('.');
+ if (idx < 0)
+ return s;
+ StringBuilder sb = new StringBuilder();
+ int last = 0;
+ while (idx >= 0) {
+ sb.Append(s.Substring(last, idx - last));
+ sb.Append('\\');
+ last = idx;
+ idx = s.IndexOf('.', idx + 1);
+ }
+ sb.Append(s.Substring(last));
+ return sb.ToString();
+ }
+
+ /**
+ * Unescapes a SOM string fragment replacing "\." with ".".
+ * @param s the escaped string
+ * @return the unescaped string
+ */
+ public static String UnescapeSom(String s) {
+ int idx = s.IndexOf('\\');
+ if (idx < 0)
+ return s;
+ StringBuilder sb = new StringBuilder();
+ int last = 0;
+ while (idx >= 0) {
+ sb.Append(s.Substring(last, idx - last));
+ last = idx + 1;
+ idx = s.IndexOf('\\', idx + 1);
+ }
+ sb.Append(s.Substring(last));
+ return sb.ToString();
+ }
+
+ /**
+ * Outputs the stack as the sequence of elements separated
+ * by '.'.
+ * @return the stack as the sequence of elements separated by '.'
+ */
+ protected String PrintStack() {
+ if (stack.Empty())
+ return "";
+ StringBuilder s = new StringBuilder();
+ foreach (String part in stack)
+ s.Append('.').Append(part);
+ return s.ToString(1, s.Length - 1);
+ }
+
+ /**
+ * Gets the name with the #subform
removed.
+ * @param s the long name
+ * @return the short name
+ */
+ public static String GetShortName(String s) {
+ int idx = s.IndexOf(".#subform[");
+ if (idx < 0)
+ return s;
+ int last = 0;
+ StringBuilder sb = new StringBuilder();
+ while (idx >= 0) {
+ sb.Append(s.Substring(last, idx - last));
+ idx = s.IndexOf("]", idx + 10);
+ if (idx < 0)
+ return sb.ToString();
+ last = idx + 1;
+ idx = s.IndexOf(".#subform[", last);
+ }
+ sb.Append(s.Substring(last));
+ return sb.ToString();
+ }
+
+ /**
+ * Adds a SOM name to the search node chain.
+ * @param unstack the SOM name
+ */
+ public void InverseSearchAdd(String unstack) {
+ InverseSearchAdd(inverseSearch, stack, unstack);
+ }
+
+ /**
+ * Adds a SOM name to the search node chain.
+ * @param inverseSearch the start point
+ * @param stack the stack with the separeted SOM parts
+ * @param unstack the full name
+ */
+ public static void InverseSearchAdd(Hashtable inverseSearch, Stack2 stack, String unstack) {
+ String last = (String)stack.Peek();
+ InverseStore store = (InverseStore)inverseSearch[last];
+ if (store == null) {
+ store = new InverseStore();
+ inverseSearch[last] = store;
+ }
+ for (int k = stack.Count - 2; k >= 0; --k) {
+ last = (String)stack[k];
+ InverseStore store2;
+ int idx = store.part.IndexOf(last);
+ if (idx < 0) {
+ store.part.Add(last);
+ store2 = new InverseStore();
+ store.follow.Add(store2);
+ }
+ else
+ store2 = (InverseStore)store.follow[idx];
+ store = store2;
+ }
+ store.part.Add("");
+ store.follow.Add(unstack);
+ }
+
+ /**
+ * Searchs the SOM hiearchie from the bottom.
+ * @param parts the SOM parts
+ * @return the full name or null
if not found
+ */
+ public String InverseSearchGlobal(ArrayList parts) {
+ if (parts.Count == 0)
+ return null;
+ InverseStore store = (InverseStore)inverseSearch[parts[parts.Count - 1]];
+ if (store == null)
+ return null;
+ for (int k = parts.Count - 2; k >= 0; --k) {
+ String part = (String)parts[k];
+ int idx = store.part.IndexOf(part);
+ if (idx < 0) {
+ if (store.IsSimilar(part))
+ return null;
+ return store.DefaultName;
+ }
+ store = (InverseStore)store.follow[idx];
+ }
+ return store.DefaultName;
+ }
+
+ /**
+ * Splits a SOM name in the individual parts.
+ * @param name the full SOM name
+ * @return the split name
+ */
+ public static Stack2 SplitParts(String name) {
+ while (name.StartsWith("."))
+ name = name.Substring(1);
+ Stack2 parts = new Stack2();
+ int last = 0;
+ int pos = 0;
+ String part;
+ while (true) {
+ pos = last;
+ while (true) {
+ pos = name.IndexOf('.', pos);
+ if (pos < 0)
+ break;
+ if (name[pos - 1] == '\\')
+ ++pos;
+ else
+ break;
+ }
+ if (pos < 0)
+ break;
+ part = name.Substring(last, pos - last);
+ if (!part.EndsWith("]"))
+ part += "[0]";
+ parts.Add(part);
+ last = pos + 1;
+ }
+ part = name.Substring(last);
+ if (!part.EndsWith("]"))
+ part += "[0]";
+ parts.Add(part);
+ return parts;
+ }
+
+ /**
+ * Gets the order the names appear in the XML, depth first.
+ * @return the order the names appear in the XML, depth first
+ */
+ public ArrayList Order {
+ get {
+ return order;
+ }
+ set {
+ order = value;
+ }
+ }
+
+ /**
+ * Gets the mapping of full names to nodes.
+ * @return the mapping of full names to nodes
+ */
+ public Hashtable Name2Node {
+ get {
+ return name2Node;
+ }
+ set {
+ name2Node = value;
+ }
+ }
+
+ /**
+ * Gets the data to do a search from the bottom hierarchie.
+ * @return the data to do a search from the bottom hierarchie
+ */
+ public Hashtable InverseSearch {
+ get {
+ return inverseSearch;
+ }
+ set {
+ inverseSearch = value;
+ }
+ }
+ }
+
+ /**
+ * Processes the datasets section in the XFA form.
+ */
+ public class Xml2SomDatasets : Xml2Som {
+ /**
+ * Creates a new instance from the datasets node. This expects
+ * not the datasets but the data node that comes below.
+ * @param n the datasets node
+ */
+ public Xml2SomDatasets(XmlNode n) {
+ order = new ArrayList();
+ name2Node = new Hashtable();
+ stack = new Stack2();
+ anform = 0;
+ inverseSearch = new Hashtable();
+ ProcessDatasetsInternal(n);
+ }
+
+ /**
+ * Inserts a new Node
that will match the short name.
+ * @param n the datasets top Node
+ * @param shortName the short name
+ * @return the new Node
of the inserted name
+ */
+ public XmlNode InsertNode(XmlNode n, String shortName) {
+ Stack2 stack = SplitParts(shortName);
+ XmlDocument doc = n.OwnerDocument;
+ XmlNode n2 = null;
+ n = n.FirstChild;
+ for (int k = 0; k < stack.Count; ++k) {
+ String part = (String)stack[k];
+ int idx = part.LastIndexOf('[');
+ String name = part.Substring(0, idx);
+ idx = int.Parse(part.Substring(idx + 1, part.Length - idx - 2));
+ int found = -1;
+ for (n2 = n.FirstChild; n2 != null; n2 = n2.NextSibling) {
+ if (n2.NodeType == XmlNodeType.Element) {
+ String s = EscapeSom(n2.LocalName);
+ if (s.Equals(name)) {
+ ++found;
+ if (found == idx)
+ break;
+ }
+ }
+ }
+ for (; found < idx; ++found) {
+ n2 = doc.CreateElement(name);
+ n2 = n.AppendChild(n2);
+ XmlNode attr = doc.CreateNode(XmlNodeType.Attribute, "dataNode", XFA_DATA_SCHEMA);
+ attr.Value = "dataGroup";
+ n2.Attributes.SetNamedItem(attr);
+ }
+ n = n2;
+ }
+ InverseSearchAdd(inverseSearch, stack, shortName);
+ name2Node[shortName] = n2;
+ order.Add(shortName);
+ return n2;
+ }
+
+ private static bool HasChildren(XmlNode n) {
+ XmlNode dataNodeN = n.Attributes.GetNamedItem("dataNode", XFA_DATA_SCHEMA);
+ if (dataNodeN != null) {
+ String dataNode = dataNodeN.Value;
+ if ("dataGroup".Equals(dataNode))
+ return true;
+ else if ("dataValue".Equals(dataNode))
+ return false;
+ }
+ if (!n.HasChildNodes)
+ return false;
+ XmlNode n2 = n.FirstChild;
+ while (n2 != null) {
+ if (n2.NodeType == XmlNodeType.Element) {
+ return true;
+ }
+ n2 = n2.NextSibling;
+ }
+ return false;
+ }
+
+ private void ProcessDatasetsInternal(XmlNode n) {
+ Hashtable ss = new Hashtable();
+ XmlNode n2 = n.FirstChild;
+ while (n2 != null) {
+ if (n2.NodeType == XmlNodeType.Element) {
+ String s = EscapeSom(n2.LocalName);
+ int i;
+ if (ss[s] == null)
+ i = 0;
+ else
+ i = (int)ss[s] + 1;
+ ss[s] = i;
+ if (HasChildren(n2)) {
+ stack.Push(s + "[" + i.ToString() + "]");
+ ProcessDatasetsInternal(n2);
+ stack.Pop();
+ }
+ else {
+ stack.Push(s + "[" + i.ToString() + "]");
+ String unstack = PrintStack();
+ order.Add(unstack);
+ InverseSearchAdd(unstack);
+ name2Node[unstack] = n2;
+ stack.Pop();
+ }
+ }
+ n2 = n2.NextSibling;
+ }
+ }
+ }
+
+ /**
+ * A class to process "classic" fields.
+ */
+ public class AcroFieldsSearch : Xml2Som {
+ private Hashtable acroShort2LongName;
+
+ /**
+ * Creates a new instance from a Collection with the full names.
+ * @param items the Collection
+ */
+ public AcroFieldsSearch(ICollection items) {
+ inverseSearch = new Hashtable();
+ acroShort2LongName = new Hashtable();
+ foreach (String itemName in items) {
+ String itemShort = GetShortName(itemName);
+ acroShort2LongName[itemShort] = itemName;
+ InverseSearchAdd(inverseSearch, SplitParts(itemShort), itemName);
+ }
+ }
+
+ /**
+ * Gets the mapping from short names to long names. A long
+ * name may contain the #subform name part.
+ * @return the mapping from short names to long names
+ */
+ public Hashtable AcroShort2LongName {
+ get {
+ return acroShort2LongName;
+ }
+ set {
+ acroShort2LongName = value;
+ }
+ }
+ }
+
+ /**
+ * Processes the template section in the XFA form.
+ */
+ public class Xml2SomTemplate : Xml2Som {
+ private bool dynamicForm;
+ private int templateLevel;
+
+ /**
+ * Creates a new instance from the datasets node.
+ * @param n the template node
+ */
+ public Xml2SomTemplate(XmlNode n) {
+ order = new ArrayList();
+ name2Node = new Hashtable();
+ stack = new Stack2();
+ anform = 0;
+ templateLevel = 0;
+ inverseSearch = new Hashtable();
+ ProcessTemplate(n, null);
+ }
+
+ /**
+ * Gets the field type as described in the template
section of the XFA.
+ * @param s the exact template name
+ * @return the field type or null
if not found
+ */
+ public String GetFieldType(String s) {
+ XmlNode n = (XmlNode)name2Node[s];
+ if (n == null)
+ return null;
+ if (n.LocalName.Equals("exclGroup"))
+ return "exclGroup";
+ XmlNode ui = n.FirstChild;
+ while (ui != null) {
+ if (ui.NodeType == XmlNodeType.Element && ui.LocalName.Equals("ui")) {
+ break;
+ }
+ ui = ui.NextSibling;
+ }
+ if (ui == null)
+ return null;
+ XmlNode type = ui.FirstChild;
+ while (type != null) {
+ if (type.NodeType == XmlNodeType.Element && !(type.LocalName.Equals("extras") && type.LocalName.Equals("picture"))) {
+ return type.LocalName;
+ }
+ type = type.NextSibling;
+ }
+ return null;
+ }
+
+ private void ProcessTemplate(XmlNode n, Hashtable ff) {
+ if (ff == null)
+ ff = new Hashtable();
+ Hashtable ss = new Hashtable();
+ XmlNode n2 = n.FirstChild;
+ while (n2 != null) {
+ if (n2.NodeType == XmlNodeType.Element) {
+ String s = n2.LocalName;
+ if (s.Equals("subform")) {
+ XmlNode name = n2.Attributes.GetNamedItem("name");
+ String nn = "#subform";
+ bool annon = true;
+ if (name != null) {
+ nn = EscapeSom(name.Value);
+ annon = false;
+ }
+ int i;
+ if (annon) {
+ i = anform;
+ ++anform;
+ }
+ else {
+ if (ss[nn] == null)
+ i = 0;
+ else
+ i = (int)ss[nn] + 1;
+ ss[nn] = i;
+ }
+ stack.Push(nn + "[" + i.ToString() + "]");
+ ++templateLevel;
+ if (annon)
+ ProcessTemplate(n2, ff);
+ else
+ ProcessTemplate(n2, null);
+ --templateLevel;
+ stack.Pop();
+ }
+ else if (s.Equals("field") || s.Equals("exclGroup")) {
+ XmlNode name = n2.Attributes.GetNamedItem("name");
+ if (name != null) {
+ String nn = EscapeSom(name.Value);
+ int i;
+ if (ff[nn] == null)
+ i = 0;
+ else
+ i = (int)ff[nn] + 1;
+ ff[nn] = i;
+ stack.Push(nn + "[" + i.ToString() + "]");
+ String unstack = PrintStack();
+ order.Add(unstack);
+ InverseSearchAdd(unstack);
+ name2Node[unstack] = n2;
+ stack.Pop();
+ }
+ }
+ else if (!dynamicForm && templateLevel > 0 && s.Equals("occur")) {
+ int initial = 1;
+ int min = 1;
+ int max = 1;
+ XmlNode a = n2.Attributes.GetNamedItem("initial");
+ if (a != null)
+ try{initial = int.Parse(a.Value.Trim());}catch{};
+ a = n2.Attributes.GetNamedItem("min");
+ if (a != null)
+ try{min = int.Parse(a.Value.Trim());}catch{};
+ a = n2.Attributes.GetNamedItem("max");
+ if (a != null)
+ try{max = int.Parse(a.Value.Trim());}catch{};
+ if (initial != min || min != max)
+ dynamicForm = true;
+ }
+ }
+ n2 = n2.NextSibling;
+ }
+ }
+
+ /**
+ * true
if it's a dynamic form; false
+ * if it's a static form.
+ * @return true
if it's a dynamic form; false
+ * if it's a static form
+ */
+ public bool DynamicForm {
+ get {
+ return dynamicForm;
+ }
+ set {
+ dynamicForm = value;
+ }
+ }
+ }
+
+ /**
+ * Gets the class that contains the template processing section of the XFA.
+ * @return the class that contains the template processing section of the XFA
+ */
+ public Xml2SomTemplate TemplateSom {
+ get {
+ return templateSom;
+ }
+ set {
+ templateSom = value;
+ }
+ }
+
+ /**
+ * Gets the class that contains the datasets processing section of the XFA.
+ * @return the class that contains the datasets processing section of the XFA
+ */
+ public Xml2SomDatasets DatasetsSom {
+ get {
+ return datasetsSom;
+ }
+ set {
+ datasetsSom = value;
+ }
+ }
+
+ /**
+ * Gets the class that contains the "classic" fields processing.
+ * @return the class that contains the "classic" fields processing
+ */
+ public AcroFieldsSearch AcroFieldsSom {
+ get {
+ return acroFieldsSom;
+ }
+ set {
+ acroFieldsSom = value;
+ }
+ }
+
+ /**
+ * Gets the Node
that corresponds to the datasets part.
+ * @return the Node
that corresponds to the datasets part
+ */
+ public XmlNode DatasetsNode {
+ get {
+ return datasetsNode;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/XfdfReader.cs b/iTechSharp/iTextSharp/text/pdf/XfdfReader.cs
new file mode 100644
index 0000000..69d95b1
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/XfdfReader.cs
@@ -0,0 +1,223 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text.xml.simpleparser;
+/*
+ *
+ * Copyright 2004 by Leonard Rosenthol.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf {
+ /**
+ * Reads a XFDF.
+ * @author Leonard Rosenthol (leonardr@pdfsages.com)
+ */
+ public class XfdfReader : ISimpleXMLDocHandler {
+ // stuff used during parsing to handle state
+ private bool foundRoot = false;
+ private Stackr fieldNames = new Stackr();
+ private Stackr fieldValues = new Stackr();
+
+ // storage for the field list and their values
+ internal Hashtable fields;
+
+ // storage for the path to referenced PDF, if any
+ internal String fileSpec;
+
+ /** Reads an XFDF form.
+ * @param filename the file name of the form
+ * @throws IOException on error
+ */
+ public XfdfReader(String filename) {
+ FileStream fin = null;
+ try {
+ fin = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
+ SimpleXMLParser.Parse(this, fin);
+ }
+ finally {
+ try{if (fin != null) fin.Close();}catch{}
+ }
+ }
+
+ /** Reads an XFDF form.
+ * @param xfdfIn the byte array with the form
+ * @throws IOException on error
+ */
+ public XfdfReader(byte[] xfdfIn) {
+ SimpleXMLParser.Parse( this, new MemoryStream(xfdfIn));
+ }
+
+ /** Gets all the fields. The map is keyed by the fully qualified
+ * field name and the value is a merged PdfDictionary
+ * with the field content.
+ * @return all the fields
+ */
+ public Hashtable Fields {
+ get {
+ return fields;
+ }
+ }
+
+ /** Gets the field value.
+ * @param name the fully qualified field name
+ * @return the field's value
+ */
+ public String GetField(String name) {
+ return (String)fields[name];
+ }
+
+ /** Gets the field value or null
if the field does not
+ * exist or has no value defined.
+ * @param name the fully qualified field name
+ * @return the field value or null
+ */
+ public String GetFieldValue(String name) {
+ String field = (String)fields[name];
+ if (field == null)
+ return null;
+ else
+ return field;
+ }
+
+ /** Gets the PDF file specification contained in the FDF.
+ * @return the PDF file specification contained in the FDF
+ */
+ public String FileSpec {
+ get {
+ return fileSpec;
+ }
+ }
+
+ /**
+ * Called when a start tag is found.
+ * @param tag the tag name
+ * @param h the tag's attributes
+ */
+ public void StartElement(String tag, Hashtable h) {
+ if ( !foundRoot ) {
+ if (!tag.Equals("xfdf"))
+ throw new Exception("Root element is not Bookmark.");
+ else
+ foundRoot = true;
+ }
+
+ if ( tag.Equals("xfdf") ){
+
+ } else if ( tag.Equals("f") ) {
+ fileSpec = (String)h[ "href" ];
+ } else if ( tag.Equals("fields") ) {
+ fields = new Hashtable(); // init it!
+ } else if ( tag.Equals("field") ) {
+ String fName = (String) h[ "name" ];
+ fieldNames.Push( fName );
+ } else if ( tag.Equals("value") ) {
+ fieldValues.Push("");
+ }
+ }
+ /**
+ * Called when an end tag is found.
+ * @param tag the tag name
+ */
+ public void EndElement(String tag) {
+ if ( tag.Equals("value") ) {
+ String fName = "";
+ for (int k = 0; k < fieldNames.Count; ++k) {
+ fName += "." + (String)fieldNames[k];
+ }
+ if (fName.StartsWith("."))
+ fName = fName.Substring(1);
+ String fVal = (String) fieldValues.Pop();
+ fields[fName] = fVal;
+ }
+ else if (tag.Equals("field") ) {
+ if (fieldNames.Count != 0)
+ fieldNames.Pop();
+ }
+ }
+
+ /**
+ * Called when the document starts to be parsed.
+ */
+ public void StartDocument()
+ {
+ fileSpec = ""; // and this too...
+ }
+ /**
+ * Called after the document is parsed.
+ */
+ public void EndDocument()
+ {
+
+ }
+ /**
+ * Called when a text element is found.
+ * @param str the text element, probably a fragment.
+ */
+ public void Text(String str)
+ {
+ if (fieldNames.Count == 0 || fieldValues.Count == 0)
+ return;
+
+ String val = (String)fieldValues.Pop();
+ val += str;
+ fieldValues.Push(val);
+ }
+
+ internal class Stackr : ArrayList {
+ internal void Push(object obj) {
+ Add(obj);
+ }
+
+ internal object Pop() {
+ if (Count == 0)
+ throw new InvalidOperationException("The stack is empty.");
+ object obj = this[Count - 1];
+ RemoveAt(Count - 1);
+ return obj;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/codec/BmpImage.cs b/iTechSharp/iTextSharp/text/pdf/codec/BmpImage.cs
new file mode 100644
index 0000000..0e1deb0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/codec/BmpImage.cs
@@ -0,0 +1,1278 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Net;
+using System.util;
+using iTextSharp.text;
+/*
+ * Copyright 2003-2008 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ *
+ * This code was originally released in 2001 by SUN (see class
+ * com.sun.media.imageioimpl.plugins.bmp.BMPImageReader.java)
+ * using the BSD license in a specific wording. In a mail dating from
+ * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission
+ * to use the code under the following version of the BSD license:
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for
+ * use in the design, construction, operation or maintenance of any
+ * nuclear facility.
+ */
+
+namespace iTextSharp.text.pdf.codec {
+ /** Reads a BMP image. All types of BMP can be read.
+ * int
from an Stream
.
+ *
+ * @param is an Stream
+ * @return the value of an int
+ */
+
+ public static int GetInt(Stream isp) {
+ return (isp.ReadByte() << 24) + (isp.ReadByte() << 16) + (isp.ReadByte() << 8) + isp.ReadByte();
+ }
+
+ /**
+ * Gets a word
from an Stream
.
+ *
+ * @param is an Stream
+ * @return the value of an int
+ */
+
+ public static int GetWord(Stream isp) {
+ return (isp.ReadByte() << 8) + isp.ReadByte();
+ }
+
+ /**
+ * Gets a String
from an Stream
.
+ *
+ * @param is an Stream
+ * @return the value of an int
+ */
+
+ public static String GetString(Stream isp) {
+ StringBuilder buf = new StringBuilder();
+ for (int i = 0; i < 4; i++) {
+ buf.Append((char)isp.ReadByte());
+ }
+ return buf.ToString();
+ }
+
+ private static void ReadFully(Stream inp, byte[] b, int offset, int count) {
+ while (count > 0) {
+ int n = inp.Read(b, offset, count);
+ if (n <= 0)
+ throw new IOException("Insufficient data.");
+ count -= n;
+ offset += n;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/codec/TIFFConstants.cs b/iTechSharp/iTextSharp/text/pdf/codec/TIFFConstants.cs
new file mode 100644
index 0000000..4b7ee46
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/codec/TIFFConstants.cs
@@ -0,0 +1,282 @@
+using System;
+/*
+ * Copyright 2003-2005 by Paulo Soares.
+ *
+ * This list of constants was originally released with libtiff
+ * under the following license:
+ *
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+namespace iTextSharp.text.pdf.codec {
+/**
+ * A list of constants used in class TIFFImage.
+ */
+ public class TIFFConstants {
+
+ /*
+ * TIFF Tag Definitions (from tifflib).
+ */
+ public const int TIFFTAG_SUBFILETYPE = 254; /* subfile data descriptor */
+ public const int FILETYPE_REDUCEDIMAGE = 0x1; /* reduced resolution version */
+ public const int FILETYPE_PAGE = 0x2; /* one page of many */
+ public const int FILETYPE_MASK = 0x4; /* transparency mask */
+ public const int TIFFTAG_OSUBFILETYPE = 255; /* +kind of data in subfile */
+ public const int OFILETYPE_IMAGE = 1; /* full resolution image data */
+ public const int OFILETYPE_REDUCEDIMAGE = 2; /* reduced size image data */
+ public const int OFILETYPE_PAGE = 3; /* one page of many */
+ public const int TIFFTAG_IMAGEWIDTH = 256; /* image width in pixels */
+ public const int TIFFTAG_IMAGELENGTH = 257; /* image height in pixels */
+ public const int TIFFTAG_BITSPERSAMPLE = 258; /* bits per channel (sample) */
+ public const int TIFFTAG_COMPRESSION = 259; /* data compression technique */
+ public const int COMPRESSION_NONE = 1; /* dump mode */
+ public const int COMPRESSION_CCITTRLE = 2; /* CCITT modified Huffman RLE */
+ public const int COMPRESSION_CCITTFAX3 = 3; /* CCITT Group 3 fax encoding */
+ public const int COMPRESSION_CCITTFAX4 = 4; /* CCITT Group 4 fax encoding */
+ public const int COMPRESSION_LZW = 5; /* Lempel-Ziv & Welch */
+ public const int COMPRESSION_OJPEG = 6; /* !6.0 JPEG */
+ public const int COMPRESSION_JPEG = 7; /* %JPEG DCT compression */
+ public const int COMPRESSION_NEXT = 32766; /* NeXT 2-bit RLE */
+ public const int COMPRESSION_CCITTRLEW = 32771; /* #1 w/ word alignment */
+ public const int COMPRESSION_PACKBITS = 32773; /* Macintosh RLE */
+ public const int COMPRESSION_THUNDERSCAN = 32809; /* ThunderScan RLE */
+ /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT SeekableStream
.
+ */
+ public static int GetNumDirectories(RandomAccessFileOrArray stream)
+ {
+ long pointer = stream.FilePointer; // Save stream pointer
+
+ stream.Seek(0L);
+ int endian = stream.ReadUnsignedShort();
+ if (!IsValidEndianTag(endian)) {
+ throw new ArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
+ }
+ bool isBigEndian = (endian == 0x4d4d);
+ int magic = ReadUnsignedShort(stream, isBigEndian);
+ if (magic != 42) {
+ throw new
+ ArgumentException("Bad magic number, should be 42.");
+ }
+
+ stream.Seek(4L);
+ long offset = ReadUnsignedInt(stream, isBigEndian);
+
+ int numDirectories = 0;
+ while (offset != 0L) {
+ ++numDirectories;
+
+ // EOFException means IFD was probably not properly terminated.
+ try {
+ stream.Seek(offset);
+ int entries = ReadUnsignedShort(stream, isBigEndian);
+ stream.Skip(12*entries);
+ offset = ReadUnsignedInt(stream, isBigEndian);
+ } catch (EndOfStreamException) {
+ //numDirectories--;
+ break;
+ }
+ }
+
+ stream.Seek(pointer); // Reset stream pointer
+ return numDirectories;
+ }
+
+ /**
+ * Returns a bool indicating whether the byte order used in the
+ * the TIFF file is big-endian (i.e. whether the byte order is from
+ * the most significant to the least significant)
+ */
+ public bool IsBigEndian() {
+ return isBigEndian;
+ }
+
+ /**
+ * Returns the offset of the IFD corresponding to this
+ * TIFFDirectory
.
+ */
+ public long GetIFDOffset() {
+ return IFDOffset;
+ }
+
+ /**
+ * Returns the offset of the next IFD after the IFD corresponding to this
+ * TIFFDirectory
.
+ */
+ public long GetNextIFDOffset() {
+ return nextIFDOffset;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/codec/TIFFFaxDecoder.cs b/iTechSharp/iTextSharp/text/pdf/codec/TIFFFaxDecoder.cs
new file mode 100644
index 0000000..434a208
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/codec/TIFFFaxDecoder.cs
@@ -0,0 +1,1502 @@
+using System;
+/*
+ * Copyright 2003-2008 by Paulo Soares.
+ *
+ * This code was originally released in 2001 by SUN (see class
+ * com.sun.media.imageioimpl.plugins.tiff.TIFFFaxDecompressor.java)
+ * using the BSD license in a specific wording. In a mail dating from
+ * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission
+ * to use the code under the following version of the BSD license:
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for
+ * use in the design, construction, operation or maintenance of any
+ * nuclear facility.
+ */
+
+namespace iTextSharp.text.pdf.codec {
+ public class TIFFFaxDecoder {
+
+ private int bitPointer, bytePointer;
+ private byte[] data;
+ private int w, h;
+ private int fillOrder;
+
+ // Data structures needed to store changing elements for the previous
+ // and the current scanline
+ private int changingElemSize = 0;
+ private int[] prevChangingElems;
+ private int[] currChangingElems;
+
+ // Element at which to start search in getNextChangingElement
+ private int lastChangingElement = 0;
+
+ private int compression = 2;
+
+ // Variables set by T4Options
+ private int uncompressedMode = 0;
+ private int fillBits = 0;
+ private int oneD;
+
+ static int[] table1 = {
+ 0x00, // 0 bits are left in first byte - SHOULD NOT HAPPEN
+ 0x01, // 1 bits are left in first byte
+ 0x03, // 2 bits are left in first byte
+ 0x07, // 3 bits are left in first byte
+ 0x0f, // 4 bits are left in first byte
+ 0x1f, // 5 bits are left in first byte
+ 0x3f, // 6 bits are left in first byte
+ 0x7f, // 7 bits are left in first byte
+ 0xff // 8 bits are left in first byte
+ };
+
+ static int[] table2 = {
+ 0x00, // 0
+ 0x80, // 1
+ 0xc0, // 2
+ 0xe0, // 3
+ 0xf0, // 4
+ 0xf8, // 5
+ 0xfc, // 6
+ 0xfe, // 7
+ 0xff // 8
+ };
+
+ // Table to be used when fillOrder = 2, for flipping bytes.
+ internal static byte[] flipTable = {
+ 0, 256-128, 64, 256-64, 32, 256-96, 96, 256-32,
+ 16, 256-112, 80, 256-48, 48, 256-80, 112, 256-16,
+ 8, 256-120, 72, 256-56, 40, 256-88, 104, 256-24,
+ 24, 256-104, 88, 256-40, 56, 256-72, 120, 256-8,
+ 4, 256-124, 68, 256-60, 36, 256-92, 100, 256-28,
+ 20, 256-108, 84, 256-44, 52, 256-76, 116, 256-12,
+ 12, 256-116, 76, 256-52, 44, 256-84, 108, 256-20,
+ 28, 256-100, 92, 256-36, 60, 256-68, 124, 256-4,
+ 2, 256-126, 66, 256-62, 34, 256-94, 98, 256-30,
+ 18, 256-110, 82, 256-46, 50, 256-78, 114, 256-14,
+ 10, 256-118, 74, 256-54, 42, 256-86, 106, 256-22,
+ 26, 256-102, 90, 256-38, 58, 256-70, 122, 256-6,
+ 6, 256-122, 70, 256-58, 38, 256-90, 102, 256-26,
+ 22, 256-106, 86, 256-42, 54, 256-74, 118, 256-10,
+ 14, 256-114, 78, 256-50, 46, 256-82, 110, 256-18,
+ 30, 256-98, 94, 256-34, 62, 256-66, 126, 256-2,
+ 1, 256-127, 65, 256-63, 33, 256-95, 97, 256-31,
+ 17, 256-111, 81, 256-47, 49, 256-79, 113, 256-15,
+ 9, 256-119, 73, 256-55, 41, 256-87, 105, 256-23,
+ 25, 256-103, 89, 256-39, 57, 256-71, 121, 256-7,
+ 5, 256-123, 69, 256-59, 37, 256-91, 101, 256-27,
+ 21, 256-107, 85, 256-43, 53, 256-75, 117, 256-11,
+ 13, 256-115, 77, 256-51, 45, 256-83, 109, 256-19,
+ 29, 256-99, 93, 256-35, 61, 256-67, 125, 256-3,
+ 3, 256-125, 67, 256-61, 35, 256-93, 99, 256-29,
+ 19, 256-109, 83, 256-45, 51, 256-77, 115, 256-13,
+ 11, 256-117, 75, 256-53, 43, 256-85, 107, 256-21,
+ 27, 256-101, 91, 256-37, 59, 256-69, 123, 256-5,
+ 7, 256-121, 71, 256-57, 39, 256-89, 103, 256-25,
+ 23, 256-105, 87, 256-41, 55, 256-73, 119, 256-9,
+ 15, 256-113, 79, 256-49, 47, 256-81, 111, 256-17,
+ 31, 256-97, 95, 256-33, 63, 256-65, 127, 256-1,
+ };
+
+ // The main 10 bit white runs lookup table
+ static short[] white = {
+ // 0 - 7
+ 6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225,
+ // 8 - 15
+ 944, 944, 944, 944, 976, 976, 976, 976,
+ // 16 - 23
+ 1456, 1456, 1456, 1456, 1488, 1488, 1488, 1488,
+ // 24 - 31
+ 718, 718, 718, 718, 718, 718, 718, 718,
+ // 32 - 39
+ 750, 750, 750, 750, 750, 750, 750, 750,
+ // 40 - 47
+ 1520, 1520, 1520, 1520, 1552, 1552, 1552, 1552,
+ // 48 - 55
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ // 56 - 63
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ // 64 - 71
+ 654, 654, 654, 654, 654, 654, 654, 654,
+ // 72 - 79
+ 1072, 1072, 1072, 1072, 1104, 1104, 1104, 1104,
+ // 80 - 87
+ 1136, 1136, 1136, 1136, 1168, 1168, 1168, 1168,
+ // 88 - 95
+ 1200, 1200, 1200, 1200, 1232, 1232, 1232, 1232,
+ // 96 - 103
+ 622, 622, 622, 622, 622, 622, 622, 622,
+ // 104 - 111
+ 1008, 1008, 1008, 1008, 1040, 1040, 1040, 1040,
+ // 112 - 119
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ // 120 - 127
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ // 128 - 135
+ 396, 396, 396, 396, 396, 396, 396, 396,
+ // 136 - 143
+ 396, 396, 396, 396, 396, 396, 396, 396,
+ // 144 - 151
+ 1712, 1712, 1712, 1712, 1744, 1744, 1744, 1744,
+ // 152 - 159
+ 846, 846, 846, 846, 846, 846, 846, 846,
+ // 160 - 167
+ 1264, 1264, 1264, 1264, 1296, 1296, 1296, 1296,
+ // 168 - 175
+ 1328, 1328, 1328, 1328, 1360, 1360, 1360, 1360,
+ // 176 - 183
+ 1392, 1392, 1392, 1392, 1424, 1424, 1424, 1424,
+ // 184 - 191
+ 686, 686, 686, 686, 686, 686, 686, 686,
+ // 192 - 199
+ 910, 910, 910, 910, 910, 910, 910, 910,
+ // 200 - 207
+ 1968, 1968, 1968, 1968, 2000, 2000, 2000, 2000,
+ // 208 - 215
+ 2032, 2032, 2032, 2032, 16, 16, 16, 16,
+ // 216 - 223
+ 10257, 10257, 10257, 10257, 12305, 12305, 12305, 12305,
+ // 224 - 231
+ 330, 330, 330, 330, 330, 330, 330, 330,
+ // 232 - 239
+ 330, 330, 330, 330, 330, 330, 330, 330,
+ // 240 - 247
+ 330, 330, 330, 330, 330, 330, 330, 330,
+ // 248 - 255
+ 330, 330, 330, 330, 330, 330, 330, 330,
+ // 256 - 263
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ // 264 - 271
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ // 272 - 279
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ // 280 - 287
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ // 288 - 295
+ 878, 878, 878, 878, 878, 878, 878, 878,
+ // 296 - 303
+ 1904, 1904, 1904, 1904, 1936, 1936, 1936, 1936,
+ // 304 - 311
+ -18413, -18413, -16365, -16365, -14317, -14317, -10221, -10221,
+ // 312 - 319
+ 590, 590, 590, 590, 590, 590, 590, 590,
+ // 320 - 327
+ 782, 782, 782, 782, 782, 782, 782, 782,
+ // 328 - 335
+ 1584, 1584, 1584, 1584, 1616, 1616, 1616, 1616,
+ // 336 - 343
+ 1648, 1648, 1648, 1648, 1680, 1680, 1680, 1680,
+ // 344 - 351
+ 814, 814, 814, 814, 814, 814, 814, 814,
+ // 352 - 359
+ 1776, 1776, 1776, 1776, 1808, 1808, 1808, 1808,
+ // 360 - 367
+ 1840, 1840, 1840, 1840, 1872, 1872, 1872, 1872,
+ // 368 - 375
+ 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,
+ // 376 - 383
+ 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,
+ // 384 - 391
+ -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,
+ // 392 - 399
+ -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,
+ // 400 - 407
+ 14353, 14353, 14353, 14353, 16401, 16401, 16401, 16401,
+ // 408 - 415
+ 22547, 22547, 24595, 24595, 20497, 20497, 20497, 20497,
+ // 416 - 423
+ 18449, 18449, 18449, 18449, 26643, 26643, 28691, 28691,
+ // 424 - 431
+ 30739, 30739, -32749, -32749, -30701, -30701, -28653, -28653,
+ // 432 - 439
+ -26605, -26605, -24557, -24557, -22509, -22509, -20461, -20461,
+ // 440 - 447
+ 8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207,
+ // 448 - 455
+ 72, 72, 72, 72, 72, 72, 72, 72,
+ // 456 - 463
+ 72, 72, 72, 72, 72, 72, 72, 72,
+ // 464 - 471
+ 72, 72, 72, 72, 72, 72, 72, 72,
+ // 472 - 479
+ 72, 72, 72, 72, 72, 72, 72, 72,
+ // 480 - 487
+ 72, 72, 72, 72, 72, 72, 72, 72,
+ // 488 - 495
+ 72, 72, 72, 72, 72, 72, 72, 72,
+ // 496 - 503
+ 72, 72, 72, 72, 72, 72, 72, 72,
+ // 504 - 511
+ 72, 72, 72, 72, 72, 72, 72, 72,
+ // 512 - 519
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ // 520 - 527
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ // 528 - 535
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ // 536 - 543
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ // 544 - 551
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ // 552 - 559
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ // 560 - 567
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ // 568 - 575
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ // 576 - 583
+ 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
+ // 584 - 591
+ 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
+ // 592 - 599
+ 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
+ // 600 - 607
+ 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
+ // 608 - 615
+ 266, 266, 266, 266, 266, 266, 266, 266,
+ // 616 - 623
+ 266, 266, 266, 266, 266, 266, 266, 266,
+ // 624 - 631
+ 266, 266, 266, 266, 266, 266, 266, 266,
+ // 632 - 639
+ 266, 266, 266, 266, 266, 266, 266, 266,
+ // 640 - 647
+ 298, 298, 298, 298, 298, 298, 298, 298,
+ // 648 - 655
+ 298, 298, 298, 298, 298, 298, 298, 298,
+ // 656 - 663
+ 298, 298, 298, 298, 298, 298, 298, 298,
+ // 664 - 671
+ 298, 298, 298, 298, 298, 298, 298, 298,
+ // 672 - 679
+ 524, 524, 524, 524, 524, 524, 524, 524,
+ // 680 - 687
+ 524, 524, 524, 524, 524, 524, 524, 524,
+ // 688 - 695
+ 556, 556, 556, 556, 556, 556, 556, 556,
+ // 696 - 703
+ 556, 556, 556, 556, 556, 556, 556, 556,
+ // 704 - 711
+ 136, 136, 136, 136, 136, 136, 136, 136,
+ // 712 - 719
+ 136, 136, 136, 136, 136, 136, 136, 136,
+ // 720 - 727
+ 136, 136, 136, 136, 136, 136, 136, 136,
+ // 728 - 735
+ 136, 136, 136, 136, 136, 136, 136, 136,
+ // 736 - 743
+ 136, 136, 136, 136, 136, 136, 136, 136,
+ // 744 - 751
+ 136, 136, 136, 136, 136, 136, 136, 136,
+ // 752 - 759
+ 136, 136, 136, 136, 136, 136, 136, 136,
+ // 760 - 767
+ 136, 136, 136, 136, 136, 136, 136, 136,
+ // 768 - 775
+ 168, 168, 168, 168, 168, 168, 168, 168,
+ // 776 - 783
+ 168, 168, 168, 168, 168, 168, 168, 168,
+ // 784 - 791
+ 168, 168, 168, 168, 168, 168, 168, 168,
+ // 792 - 799
+ 168, 168, 168, 168, 168, 168, 168, 168,
+ // 800 - 807
+ 168, 168, 168, 168, 168, 168, 168, 168,
+ // 808 - 815
+ 168, 168, 168, 168, 168, 168, 168, 168,
+ // 816 - 823
+ 168, 168, 168, 168, 168, 168, 168, 168,
+ // 824 - 831
+ 168, 168, 168, 168, 168, 168, 168, 168,
+ // 832 - 839
+ 460, 460, 460, 460, 460, 460, 460, 460,
+ // 840 - 847
+ 460, 460, 460, 460, 460, 460, 460, 460,
+ // 848 - 855
+ 492, 492, 492, 492, 492, 492, 492, 492,
+ // 856 - 863
+ 492, 492, 492, 492, 492, 492, 492, 492,
+ // 864 - 871
+ 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
+ // 872 - 879
+ 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
+ // 880 - 887
+ 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
+ // 888 - 895
+ 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
+ // 896 - 903
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ // 904 - 911
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ // 912 - 919
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ // 920 - 927
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ // 928 - 935
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ // 936 - 943
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ // 944 - 951
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ // 952 - 959
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ // 960 - 967
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ // 968 - 975
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ // 976 - 983
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ // 984 - 991
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ // 992 - 999
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ // 1000 - 1007
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ // 1008 - 1015
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ // 1016 - 1023
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ };
+
+ // Additional make up codes for both White and Black runs
+ static short[] additionalMakeup = {
+ 28679, 28679, 31752, unchecked((short)32777),
+ unchecked((short)33801), unchecked((short)34825), unchecked((short)35849), unchecked((short)36873),
+ unchecked((short)29703), unchecked((short)29703), unchecked((short)30727), unchecked((short)30727),
+ unchecked((short)37897), unchecked((short)38921), unchecked((short)39945), unchecked((short)40969)
+ };
+
+ // Initial black run look up table, uses the first 4 bits of a code
+ static short[] initBlack = {
+ // 0 - 7
+ 3226, 6412, 200, 168, 38, 38, 134, 134,
+ // 8 - 15
+ 100, 100, 100, 100, 68, 68, 68, 68
+ };
+
+ //
+ static short[] twoBitBlack = {292, 260, 226, 226}; // 0 - 3
+
+ // Main black run table, using the last 9 bits of possible 13 bit code
+ static short[] black = {
+ // 0 - 7
+ 62, 62, 30, 30, 0, 0, 0, 0,
+ // 8 - 15
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ // 16 - 23
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ // 24 - 31
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ // 32 - 39
+ 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
+ // 40 - 47
+ 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
+ // 48 - 55
+ 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
+ // 56 - 63
+ 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
+ // 64 - 71
+ 588, 588, 588, 588, 588, 588, 588, 588,
+ // 72 - 79
+ 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776,
+ // 80 - 87
+ 1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904,
+ // 88 - 95
+ 1936, 1936, -16365, -14317, 782, 782, 782, 782,
+ // 96 - 103
+ 814, 814, 814, 814, -12269, -10221, 10257, 10257,
+ // 104 - 111
+ 12305, 12305, 14353, 14353, 16403, 18451, 1712, 1712,
+ // 112 - 119
+ 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605,
+ // 120 - 127
+ 2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061,
+ // 128 - 135
+ 424, 424, 424, 424, 424, 424, 424, 424,
+ // 136 - 143
+ 424, 424, 424, 424, 424, 424, 424, 424,
+ // 144 - 151
+ 424, 424, 424, 424, 424, 424, 424, 424,
+ // 152 - 159
+ 424, 424, 424, 424, 424, 424, 424, 424,
+ // 160 - 167
+ 750, 750, 750, 750, 1616, 1616, 1648, 1648,
+ // 168 - 175
+ 1424, 1424, 1456, 1456, 1488, 1488, 1520, 1520,
+ // 176 - 183
+ 1840, 1840, 1872, 1872, 1968, 1968, 8209, 8209,
+ // 184 - 191
+ 524, 524, 524, 524, 524, 524, 524, 524,
+ // 192 - 199
+ 556, 556, 556, 556, 556, 556, 556, 556,
+ // 200 - 207
+ 1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032,
+ // 208 - 215
+ 976, 976, 1008, 1008, 1040, 1040, 1072, 1072,
+ // 216 - 223
+ 1296, 1296, 1328, 1328, 718, 718, 718, 718,
+ // 224 - 231
+ 456, 456, 456, 456, 456, 456, 456, 456,
+ // 232 - 239
+ 456, 456, 456, 456, 456, 456, 456, 456,
+ // 240 - 247
+ 456, 456, 456, 456, 456, 456, 456, 456,
+ // 248 - 255
+ 456, 456, 456, 456, 456, 456, 456, 456,
+ // 256 - 263
+ 326, 326, 326, 326, 326, 326, 326, 326,
+ // 264 - 271
+ 326, 326, 326, 326, 326, 326, 326, 326,
+ // 272 - 279
+ 326, 326, 326, 326, 326, 326, 326, 326,
+ // 280 - 287
+ 326, 326, 326, 326, 326, 326, 326, 326,
+ // 288 - 295
+ 326, 326, 326, 326, 326, 326, 326, 326,
+ // 296 - 303
+ 326, 326, 326, 326, 326, 326, 326, 326,
+ // 304 - 311
+ 326, 326, 326, 326, 326, 326, 326, 326,
+ // 312 - 319
+ 326, 326, 326, 326, 326, 326, 326, 326,
+ // 320 - 327
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ // 328 - 335
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ // 336 - 343
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ // 344 - 351
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ // 352 - 359
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ // 360 - 367
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ // 368 - 375
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ // 376 - 383
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ // 384 - 391
+ 490, 490, 490, 490, 490, 490, 490, 490,
+ // 392 - 399
+ 490, 490, 490, 490, 490, 490, 490, 490,
+ // 400 - 407
+ 4113, 4113, 6161, 6161, 848, 848, 880, 880,
+ // 408 - 415
+ 912, 912, 944, 944, 622, 622, 622, 622,
+ // 416 - 423
+ 654, 654, 654, 654, 1104, 1104, 1136, 1136,
+ // 424 - 431
+ 1168, 1168, 1200, 1200, 1232, 1232, 1264, 1264,
+ // 432 - 439
+ 686, 686, 686, 686, 1360, 1360, 1392, 1392,
+ // 440 - 447
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ // 448 - 455
+ 390, 390, 390, 390, 390, 390, 390, 390,
+ // 456 - 463
+ 390, 390, 390, 390, 390, 390, 390, 390,
+ // 464 - 471
+ 390, 390, 390, 390, 390, 390, 390, 390,
+ // 472 - 479
+ 390, 390, 390, 390, 390, 390, 390, 390,
+ // 480 - 487
+ 390, 390, 390, 390, 390, 390, 390, 390,
+ // 488 - 495
+ 390, 390, 390, 390, 390, 390, 390, 390,
+ // 496 - 503
+ 390, 390, 390, 390, 390, 390, 390, 390,
+ // 504 - 511
+ 390, 390, 390, 390, 390, 390, 390, 390,
+ };
+
+ static byte[] twoDCodes = {
+ // 0 - 7
+ 80, 88, 23, 71, 30, 30, 62, 62,
+ // 8 - 15
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ // 16 - 23
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ // 24 - 31
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ // 32 - 39
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ // 40 - 47
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ // 48 - 55
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ // 56 - 63
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ // 64 - 71
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ // 72 - 79
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ // 80 - 87
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ // 88 - 95
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ // 96 - 103
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ // 104 - 111
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ // 112 - 119
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ // 120 - 127
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ };
+
+ /**
+ * @param fillOrder The fill order of the compressed data bytes.
+ * @param w
+ * @param h
+ */
+ public TIFFFaxDecoder(int fillOrder, int w, int h) {
+ this.fillOrder = fillOrder;
+ this.w = w;
+ this.h = h;
+
+ this.bitPointer = 0;
+ this.bytePointer = 0;
+ this.prevChangingElems = new int[w];
+ this.currChangingElems = new int[w];
+ }
+
+ public static void ReverseBits(byte[] b) {
+ for (int k = 0; k < b.Length; ++k)
+ b[k] = flipTable[b[k] & 0xff];
+ }
+
+
+ // One-dimensional decoding methods
+
+ public void Decode1D(byte[] buffer, byte[] compData,
+ int startX, int height) {
+ this.data = compData;
+
+ int lineOffset = 0;
+ int scanlineStride = (w + 7)/8;
+
+ bitPointer = 0;
+ bytePointer = 0;
+
+ for (int i = 0; i < height; i++) {
+ DecodeNextScanline(buffer, lineOffset, startX);
+ lineOffset += scanlineStride;
+ }
+ }
+
+ public void DecodeNextScanline(byte[] buffer,
+ int lineOffset, int bitOffset) {
+ int bits = 0, code = 0, isT = 0;
+ int current, entry, twoBits;
+ bool isWhite = true;
+
+ // Initialize starting of the changing elements array
+ changingElemSize = 0;
+
+ // While scanline not complete
+ while (bitOffset < w) {
+ while (isWhite) {
+ // White run
+ current = NextNBits(10);
+ entry = white[current];
+
+ // Get the 3 fields from the entry
+ isT = entry & 0x0001;
+ bits = (entry >> 1) & 0x0f;
+
+ if (bits == 12) { // Additional Make up code
+ // Get the next 2 bits
+ twoBits = NextLesserThan8Bits(2);
+ // Consolidate the 2 new bits and last 2 bits into 4 bits
+ current = ((current << 2) & 0x000c) | twoBits;
+ entry = additionalMakeup[current];
+ bits = (entry >> 1) & 0x07; // 3 bits 0000 0111
+ code = (entry >> 4) & 0x0fff; // 12 bits
+ bitOffset += code; // Skip white run
+
+ UpdatePointer(4 - bits);
+ } else if (bits == 0) { // ERROR
+ throw new Exception("Invalid code encountered.");
+ } else if (bits == 15) { // EOL
+ throw new Exception("EOL code word encountered in White run.");
+ } else {
+ // 11 bits - 0000 0111 1111 1111 = 0x07ff
+ code = (entry >> 5) & 0x07ff;
+ bitOffset += code;
+
+ UpdatePointer(10 - bits);
+ if (isT == 0) {
+ isWhite = false;
+ currChangingElems[changingElemSize++] = bitOffset;
+ }
+ }
+ }
+
+ // Check whether this run completed one width, if so
+ // advance to next byte boundary for compression = 2.
+ if (bitOffset == w) {
+ if (compression == 2) {
+ AdvancePointer();
+ }
+ break;
+ }
+
+ while (isWhite == false) {
+ // Black run
+ current = NextLesserThan8Bits(4);
+ entry = initBlack[current];
+
+ // Get the 3 fields from the entry
+ isT = entry & 0x0001;
+ bits = (entry >> 1) & 0x000f;
+ code = (entry >> 5) & 0x07ff;
+
+ if (code == 100) {
+ current = NextNBits(9);
+ entry = black[current];
+
+ // Get the 3 fields from the entry
+ isT = entry & 0x0001;
+ bits = (entry >> 1) & 0x000f;
+ code = (entry >> 5) & 0x07ff;
+
+ if (bits == 12) {
+ // Additional makeup codes
+ UpdatePointer(5);
+ current = NextLesserThan8Bits(4);
+ entry = additionalMakeup[current];
+ bits = (entry >> 1) & 0x07; // 3 bits 0000 0111
+ code = (entry >> 4) & 0x0fff; // 12 bits
+
+ SetToBlack(buffer, lineOffset, bitOffset, code);
+ bitOffset += code;
+
+ UpdatePointer(4 - bits);
+ } else if (bits == 15) {
+ // EOL code
+ throw new Exception("EOL code word encountered in Black run.");
+ } else {
+ SetToBlack(buffer, lineOffset, bitOffset, code);
+ bitOffset += code;
+
+ UpdatePointer(9 - bits);
+ if (isT == 0) {
+ isWhite = true;
+ currChangingElems[changingElemSize++] = bitOffset;
+ }
+ }
+ } else if (code == 200) {
+ // Is a Terminating code
+ current = NextLesserThan8Bits(2);
+ entry = twoBitBlack[current];
+ code = (entry >> 5) & 0x07ff;
+ bits = (entry >> 1) & 0x0f;
+
+ SetToBlack(buffer, lineOffset, bitOffset, code);
+ bitOffset += code;
+
+ UpdatePointer(2 - bits);
+ isWhite = true;
+ currChangingElems[changingElemSize++] = bitOffset;
+ } else {
+ // Is a Terminating code
+ SetToBlack(buffer, lineOffset, bitOffset, code);
+ bitOffset += code;
+
+ UpdatePointer(4 - bits);
+ isWhite = true;
+ currChangingElems[changingElemSize++] = bitOffset;
+ }
+ }
+
+ // Check whether this run completed one width
+ if (bitOffset == w) {
+ if (compression == 2) {
+ AdvancePointer();
+ }
+ break;
+ }
+ }
+
+ currChangingElems[changingElemSize++] = bitOffset;
+ }
+
+ // Two-dimensional decoding methods
+
+ public void Decode2D(byte[] buffer,
+ byte[] compData,
+ int startX,
+ int height,
+ long tiffT4Options) {
+ this.data = compData;
+ compression = 3;
+
+ bitPointer = 0;
+ bytePointer = 0;
+
+ int scanlineStride = (w + 7)/8;
+
+ int a0, a1, b1, b2;
+ int[] b = new int[2];
+ int entry, code, bits;
+ bool isWhite;
+ int currIndex = 0;
+ int[] temp;
+
+ // fillBits - dealt with this in readEOL
+ // 1D/2D encoding - dealt with this in readEOL
+
+ // uncompressedMode - haven't dealt with this yet.
+
+
+ oneD = (int)(tiffT4Options & 0x01);
+ uncompressedMode = (int)((tiffT4Options & 0x02) >> 1);
+ fillBits = (int)((tiffT4Options & 0x04) >> 2);
+
+ // The data must start with an EOL code
+ if (ReadEOL(true) != 1) {
+ throw new Exception("First scanline must be 1D encoded.");
+ }
+
+ int lineOffset = 0;
+ int bitOffset;
+
+ // Then the 1D encoded scanline data will occur, changing elements
+ // array gets set.
+ DecodeNextScanline(buffer, lineOffset, startX);
+ lineOffset += scanlineStride;
+
+ for (int lines = 1; lines < height; lines++) {
+
+ // Every line must begin with an EOL followed by a bit which
+ // indicates whether the following scanline is 1D or 2D encoded.
+ if (ReadEOL(false) == 0) {
+ // 2D encoded scanline follows
+
+ // Initialize previous scanlines changing elements, and
+ // initialize current scanline's changing elements array
+ temp = prevChangingElems;
+ prevChangingElems = currChangingElems;
+ currChangingElems = temp;
+ currIndex = 0;
+
+ // a0 has to be set just before the start of this scanline.
+ a0 = -1;
+ isWhite = true;
+ bitOffset = startX;
+
+ lastChangingElement = 0;
+
+ while (bitOffset < w) {
+ // Get the next changing element
+ GetNextChangingElement(a0, isWhite, b);
+
+ b1 = b[0];
+ b2 = b[1];
+
+ // Get the next seven bits
+ entry = NextLesserThan8Bits(7);
+
+ // Run these through the 2DCodes table
+ entry = (int)(twoDCodes[entry] & 0xff);
+
+ // Get the code and the number of bits used up
+ code = (entry & 0x78) >> 3;
+ bits = entry & 0x07;
+
+ if (code == 0) {
+ if (!isWhite) {
+ SetToBlack(buffer, lineOffset, bitOffset,
+ b2 - bitOffset);
+ }
+ bitOffset = a0 = b2;
+
+ // Set pointer to consume the correct number of bits.
+ UpdatePointer(7 - bits);
+ } else if (code == 1) {
+ // Horizontal
+ UpdatePointer(7 - bits);
+
+ // identify the next 2 codes.
+ int number;
+ if (isWhite) {
+ number = DecodeWhiteCodeWord();
+ bitOffset += number;
+ currChangingElems[currIndex++] = bitOffset;
+
+ number = DecodeBlackCodeWord();
+ SetToBlack(buffer, lineOffset, bitOffset, number);
+ bitOffset += number;
+ currChangingElems[currIndex++] = bitOffset;
+ } else {
+ number = DecodeBlackCodeWord();
+ SetToBlack(buffer, lineOffset, bitOffset, number);
+ bitOffset += number;
+ currChangingElems[currIndex++] = bitOffset;
+
+ number = DecodeWhiteCodeWord();
+ bitOffset += number;
+ currChangingElems[currIndex++] = bitOffset;
+ }
+
+ a0 = bitOffset;
+ } else if (code <= 8) {
+ // Vertical
+ a1 = b1 + (code - 5);
+
+ currChangingElems[currIndex++] = a1;
+
+ // We write the current color till a1 - 1 pos,
+ // since a1 is where the next color starts
+ if (!isWhite) {
+ SetToBlack(buffer, lineOffset, bitOffset,
+ a1 - bitOffset);
+ }
+ bitOffset = a0 = a1;
+ isWhite = !isWhite;
+
+ UpdatePointer(7 - bits);
+ } else {
+ throw new Exception("Invalid code encountered while decoding 2D group 3 compressed data.");
+ }
+ }
+
+ // Add the changing element beyond the current scanline for the
+ // other color too
+ currChangingElems[currIndex++] = bitOffset;
+ changingElemSize = currIndex;
+ } else {
+ // 1D encoded scanline follows
+ DecodeNextScanline(buffer, lineOffset, startX);
+ }
+
+ lineOffset += scanlineStride;
+ }
+ }
+
+ public void DecodeT6(byte[] buffer,
+ byte[] compData,
+ int startX,
+ int height,
+ long tiffT6Options) {
+ this.data = compData;
+ compression = 4;
+
+ bitPointer = 0;
+ bytePointer = 0;
+
+ int scanlineStride = (w + 7)/8;
+
+ int a0, a1, b1, b2;
+ int entry, code, bits;
+ bool isWhite;
+ int currIndex;
+ int[] temp;
+
+ // Return values from getNextChangingElement
+ int[] b = new int[2];
+
+ // uncompressedMode - have written some code for this, but this
+ // has not been tested due to lack of test images using this optional
+
+ uncompressedMode = (int)((tiffT6Options & 0x02) >> 1);
+
+ // Local cached reference
+ int[] cce = currChangingElems;
+
+ // Assume invisible preceding row of all white pixels and insert
+ // both black and white changing elements beyond the end of this
+ // imaginary scanline.
+ changingElemSize = 0;
+ cce[changingElemSize++] = w;
+ cce[changingElemSize++] = w;
+
+ int lineOffset = 0;
+ int bitOffset;
+
+ for (int lines = 0; lines < height; lines++) {
+ // a0 has to be set just before the start of the scanline.
+ a0 = -1;
+ isWhite = true;
+
+ // Assign the changing elements of the previous scanline to
+ // prevChangingElems and start putting this new scanline's
+ // changing elements into the currChangingElems.
+ temp = prevChangingElems;
+ prevChangingElems = currChangingElems;
+ cce = currChangingElems = temp;
+ currIndex = 0;
+
+ // Start decoding the scanline at startX in the raster
+ bitOffset = startX;
+
+ // Reset search start position for getNextChangingElement
+ lastChangingElement = 0;
+
+ // Till one whole scanline is decoded
+ while (bitOffset < w) {
+ // Get the next changing element
+ GetNextChangingElement(a0, isWhite, b);
+ b1 = b[0];
+ b2 = b[1];
+
+ // Get the next seven bits
+ entry = NextLesserThan8Bits(7);
+ // Run these through the 2DCodes table
+ entry = (int)(twoDCodes[entry] & 0xff);
+
+ // Get the code and the number of bits used up
+ code = (entry & 0x78) >> 3;
+ bits = entry & 0x07;
+
+ if (code == 0) { // Pass
+ // We always assume WhiteIsZero format for fax.
+ if (!isWhite) {
+ SetToBlack(buffer, lineOffset, bitOffset,
+ b2 - bitOffset);
+ }
+ bitOffset = a0 = b2;
+
+ // Set pointer to only consume the correct number of bits.
+ UpdatePointer(7 - bits);
+ } else if (code == 1) { // Horizontal
+ // Set pointer to only consume the correct number of bits.
+ UpdatePointer(7 - bits);
+
+ // identify the next 2 alternating color codes.
+ int number;
+ if (isWhite) {
+ // Following are white and black runs
+ number = DecodeWhiteCodeWord();
+ bitOffset += number;
+ cce[currIndex++] = bitOffset;
+
+ number = DecodeBlackCodeWord();
+ SetToBlack(buffer, lineOffset, bitOffset, number);
+ bitOffset += number;
+ cce[currIndex++] = bitOffset;
+ } else {
+ // First a black run and then a white run follows
+ number = DecodeBlackCodeWord();
+ SetToBlack(buffer, lineOffset, bitOffset, number);
+ bitOffset += number;
+ cce[currIndex++] = bitOffset;
+
+ number = DecodeWhiteCodeWord();
+ bitOffset += number;
+ cce[currIndex++] = bitOffset;
+ }
+
+ a0 = bitOffset;
+ } else if (code <= 8) { // Vertical
+ a1 = b1 + (code - 5);
+ cce[currIndex++] = a1;
+
+ // We write the current color till a1 - 1 pos,
+ // since a1 is where the next color starts
+ if (!isWhite) {
+ SetToBlack(buffer, lineOffset, bitOffset,
+ a1 - bitOffset);
+ }
+ bitOffset = a0 = a1;
+ isWhite = !isWhite;
+
+ UpdatePointer(7 - bits);
+ } else if (code == 11) {
+ if (NextLesserThan8Bits(3) != 7) {
+ throw new Exception("Invalid code encountered while decoding 2D group 4 compressed data.");
+ }
+
+ int zeros = 0;
+ bool exit = false;
+
+ while (!exit) {
+ while (NextLesserThan8Bits(1) != 1) {
+ zeros++;
+ }
+
+ if (zeros > 5) {
+ // Exit code
+
+ // Zeros before exit code
+ zeros = zeros - 6;
+
+ if (!isWhite && (zeros > 0)) {
+ cce[currIndex++] = bitOffset;
+ }
+
+ // Zeros before the exit code
+ bitOffset += zeros;
+ if (zeros > 0) {
+ // Some zeros have been written
+ isWhite = true;
+ }
+
+ // Read in the bit which specifies the color of
+ // the following run
+ if (NextLesserThan8Bits(1) == 0) {
+ if (!isWhite) {
+ cce[currIndex++] = bitOffset;
+ }
+ isWhite = true;
+ } else {
+ if (isWhite) {
+ cce[currIndex++] = bitOffset;
+ }
+ isWhite = false;
+ }
+
+ exit = true;
+ }
+
+ if (zeros == 5) {
+ if (!isWhite) {
+ cce[currIndex++] = bitOffset;
+ }
+ bitOffset += zeros;
+
+ // Last thing written was white
+ isWhite = true;
+ } else {
+ bitOffset += zeros;
+
+ cce[currIndex++] = bitOffset;
+ SetToBlack(buffer, lineOffset, bitOffset, 1);
+ ++bitOffset;
+
+ // Last thing written was black
+ isWhite = false;
+ }
+
+ }
+ } else {
+ //micah_tessler@yahoo.com
+ //Microsoft TIFF renderers seem to treat unknown codes as line-breaks
+ //That is, they give up on the current line and move on to the next one
+ //set bitOffset to w to move on to the next scan line.
+ bitOffset = w;
+ UpdatePointer(7 - bits);
+ }
+ }
+
+ // Add the changing element beyond the current scanline for the
+ // other color too
+ //make sure that the index does not exceed the bounds of the array
+ if (currIndex < cce.Length)
+ cce[currIndex++] = bitOffset;
+
+ // Number of changing elements in this scanline.
+ changingElemSize = currIndex;
+
+ lineOffset += scanlineStride;
+ }
+ }
+
+ private void SetToBlack(byte[] buffer,
+ int lineOffset, int bitOffset,
+ int numBits) {
+ int bitNum = 8*lineOffset + bitOffset;
+ int lastBit = bitNum + numBits;
+
+ int byteNum = bitNum >> 3;
+
+ // Handle bits in first byte
+ int shift = bitNum & 0x7;
+ if (shift > 0) {
+ int maskVal = 1 << (7 - shift);
+ byte val = buffer[byteNum];
+ while (maskVal > 0 && bitNum < lastBit) {
+ val |= (byte)maskVal;
+ maskVal >>= 1;
+ ++bitNum;
+ }
+ buffer[byteNum] = val;
+ }
+
+ // Fill in 8 bits at a time
+ byteNum = bitNum >> 3;
+ while (bitNum < lastBit - 7) {
+ buffer[byteNum++] = (byte)255;
+ bitNum += 8;
+ }
+
+ // Fill in remaining bits
+ while (bitNum < lastBit) {
+ byteNum = bitNum >> 3;
+ buffer[byteNum] |= (byte)(1 << (7 - (bitNum & 0x7)));
+ ++bitNum;
+ }
+ }
+
+ // Returns run length
+ private int DecodeWhiteCodeWord() {
+ int current, entry, bits, isT, twoBits, code = -1;
+ int runLength = 0;
+ bool isWhite = true;
+
+ while (isWhite) {
+ current = NextNBits(10);
+ entry = white[current];
+
+ // Get the 3 fields from the entry
+ isT = entry & 0x0001;
+ bits = (entry >> 1) & 0x0f;
+
+ if (bits == 12) { // Additional Make up code
+ // Get the next 2 bits
+ twoBits = NextLesserThan8Bits(2);
+ // Consolidate the 2 new bits and last 2 bits into 4 bits
+ current = ((current << 2) & 0x000c) | twoBits;
+ entry = additionalMakeup[current];
+ bits = (entry >> 1) & 0x07; // 3 bits 0000 0111
+ code = (entry >> 4) & 0x0fff; // 12 bits
+ runLength += code;
+ UpdatePointer(4 - bits);
+ } else if (bits == 0) { // ERROR
+ throw new Exception("Invalid code encountered.");
+ } else if (bits == 15) { // EOL
+ throw new Exception("EOL code word encountered in White run.");
+ } else {
+ // 11 bits - 0000 0111 1111 1111 = 0x07ff
+ code = (entry >> 5) & 0x07ff;
+ runLength += code;
+ UpdatePointer(10 - bits);
+ if (isT == 0) {
+ isWhite = false;
+ }
+ }
+ }
+
+ return runLength;
+ }
+
+ // Returns run length
+ private int DecodeBlackCodeWord() {
+ int current, entry, bits, isT, code = -1;
+ int runLength = 0;
+ bool isWhite = false;
+
+ while (!isWhite) {
+ current = NextLesserThan8Bits(4);
+ entry = initBlack[current];
+
+ // Get the 3 fields from the entry
+ isT = entry & 0x0001;
+ bits = (entry >> 1) & 0x000f;
+ code = (entry >> 5) & 0x07ff;
+
+ if (code == 100) {
+ current = NextNBits(9);
+ entry = black[current];
+
+ // Get the 3 fields from the entry
+ isT = entry & 0x0001;
+ bits = (entry >> 1) & 0x000f;
+ code = (entry >> 5) & 0x07ff;
+
+ if (bits == 12) {
+ // Additional makeup codes
+ UpdatePointer(5);
+ current = NextLesserThan8Bits(4);
+ entry = additionalMakeup[current];
+ bits = (entry >> 1) & 0x07; // 3 bits 0000 0111
+ code = (entry >> 4) & 0x0fff; // 12 bits
+ runLength += code;
+
+ UpdatePointer(4 - bits);
+ } else if (bits == 15) {
+ // EOL code
+ throw new Exception("EOL code word encountered in Black run.");
+ } else {
+ runLength += code;
+ UpdatePointer(9 - bits);
+ if (isT == 0) {
+ isWhite = true;
+ }
+ }
+ } else if (code == 200) {
+ // Is a Terminating code
+ current = NextLesserThan8Bits(2);
+ entry = twoBitBlack[current];
+ code = (entry >> 5) & 0x07ff;
+ runLength += code;
+ bits = (entry >> 1) & 0x0f;
+ UpdatePointer(2 - bits);
+ isWhite = true;
+ } else {
+ // Is a Terminating code
+ runLength += code;
+ UpdatePointer(4 - bits);
+ isWhite = true;
+ }
+ }
+
+ return runLength;
+ }
+
+ private int ReadEOL(bool isFirstEOL) {
+ if (fillBits == 0) {
+ int next12Bits = NextNBits(12);
+ if (isFirstEOL && next12Bits == 0) {
+
+ // Might have the case of EOL padding being used even
+ // though it was not flagged in the T4Options field.
+ // This was observed to be the case in TIFFs produced
+ // by a well known vendor who shall remain nameless.
+
+ if (NextNBits(4) == 1) {
+
+ // EOL must be padded: reset the fillBits flag.
+
+ fillBits = 1;
+ return 1;
+ }
+ }
+ if (next12Bits != 1) {
+ throw new Exception("Scanline must begin with EOL code word.");
+ }
+ } else if (fillBits == 1) {
+
+ // First EOL code word xxxx 0000 0000 0001 will occur
+ // As many fill bits will be present as required to make
+ // the EOL code of 12 bits end on a byte boundary.
+
+ int bitsLeft = 8 - bitPointer;
+
+ if (NextNBits(bitsLeft) != 0) {
+ throw new Exception("All fill bits preceding EOL code must be 0.");
+ }
+
+ // If the number of bitsLeft is less than 8, then to have a 12
+ // bit EOL sequence, two more bytes are certainly going to be
+ // required. The first of them has to be all zeros, so ensure
+ // that.
+ if (bitsLeft < 4) {
+ if (NextNBits(8) != 0) {
+ throw new Exception("All fill bits preceding EOL code must be 0.");
+ }
+ }
+
+ // There might be a random number of fill bytes with 0s, so
+ // loop till the EOL of 0000 0001 is found, as long as all
+ // the bytes preceding it are 0's.
+ int n;
+ while ((n = NextNBits(8)) != 1) {
+
+ // If not all zeros
+ if (n != 0) {
+ throw new Exception("All fill bits preceding EOL code must be 0.");
+ }
+ }
+ }
+
+ // If one dimensional encoding mode, then always return 1
+ if (oneD == 0) {
+ return 1;
+ } else {
+ // Otherwise for 2D encoding mode,
+ // The next one bit signifies 1D/2D encoding of next line.
+ return NextLesserThan8Bits(1);
+ }
+ }
+
+ private void GetNextChangingElement(int a0, bool isWhite, int[] ret) {
+ // Local copies of instance variables
+ int[] pce = this.prevChangingElems;
+ int ces = this.changingElemSize;
+
+ // If the previous match was at an odd element, we still
+ // have to search the preceeding element.
+ // int start = lastChangingElement & ~0x1;
+ int start = lastChangingElement > 0 ? lastChangingElement - 1 : 0;
+ if (isWhite) {
+ start &= ~0x1; // Search even numbered elements
+ } else {
+ start |= 0x1; // Search odd numbered elements
+ }
+
+ int i = start;
+ for (; i < ces; i += 2) {
+ int temp = pce[i];
+ if (temp > a0) {
+ lastChangingElement = i;
+ ret[0] = temp;
+ break;
+ }
+ }
+
+ if (i + 1 < ces) {
+ ret[1] = pce[i + 1];
+ }
+ }
+
+ private int NextNBits(int bitsToGet) {
+ byte b, next, next2next;
+ int l = data.Length - 1;
+ int bp = this.bytePointer;
+
+ if (fillOrder == 1) {
+ b = data[bp];
+
+ if (bp == l) {
+ next = 0x00;
+ next2next = 0x00;
+ } else if ((bp + 1) == l) {
+ next = data[bp + 1];
+ next2next = 0x00;
+ } else {
+ next = data[bp + 1];
+ next2next = data[bp + 2];
+ }
+ } else if (fillOrder == 2) {
+ b = flipTable[data[bp] & 0xff];
+
+ if (bp == l) {
+ next = 0x00;
+ next2next = 0x00;
+ } else if ((bp + 1) == l) {
+ next = flipTable[data[bp + 1] & 0xff];
+ next2next = 0x00;
+ } else {
+ next = flipTable[data[bp + 1] & 0xff];
+ next2next = flipTable[data[bp + 2] & 0xff];
+ }
+ } else {
+ throw new Exception("TIFF_FILL_ORDER tag must be either 1 or 2.");
+ }
+
+ int bitsLeft = 8 - bitPointer;
+ int bitsFromNextByte = bitsToGet - bitsLeft;
+ int bitsFromNext2NextByte = 0;
+ if (bitsFromNextByte > 8) {
+ bitsFromNext2NextByte = bitsFromNextByte - 8;
+ bitsFromNextByte = 8;
+ }
+
+ bytePointer++;
+
+ int i1 = (b & table1[bitsLeft]) << (bitsToGet - bitsLeft);
+ int i2 = (next & table2[bitsFromNextByte]) >> (8 - bitsFromNextByte);
+
+ int i3 = 0;
+ if (bitsFromNext2NextByte != 0) {
+ i2 <<= bitsFromNext2NextByte;
+ i3 = (next2next & table2[bitsFromNext2NextByte]) >>
+ (8 - bitsFromNext2NextByte);
+ i2 |= i3;
+ bytePointer++;
+ bitPointer = bitsFromNext2NextByte;
+ } else {
+ if (bitsFromNextByte == 8) {
+ bitPointer = 0;
+ bytePointer++;
+ } else {
+ bitPointer = bitsFromNextByte;
+ }
+ }
+
+ int i = i1 | i2;
+ return i;
+ }
+
+ private int NextLesserThan8Bits(int bitsToGet) {
+ byte b, next;
+ int l = data.Length - 1;
+ int bp = this.bytePointer;
+
+ if (fillOrder == 1) {
+ b = data[bp];
+ if (bp == l) {
+ next = 0x00;
+ } else {
+ next = data[bp + 1];
+ }
+ } else if (fillOrder == 2) {
+ b = flipTable[data[bp] & 0xff];
+ if (bp == l) {
+ next = 0x00;
+ } else {
+ next = flipTable[data[bp + 1] & 0xff];
+ }
+ } else {
+ throw new Exception("TIFF_FILL_ORDER tag must be either 1 or 2.");
+ }
+
+ int bitsLeft = 8 - bitPointer;
+ int bitsFromNextByte = bitsToGet - bitsLeft;
+
+ int shift = bitsLeft - bitsToGet;
+ int i1, i2;
+ if (shift >= 0) {
+ i1 = (b & table1[bitsLeft]) >> shift;
+ bitPointer += bitsToGet;
+ if (bitPointer == 8) {
+ bitPointer = 0;
+ bytePointer++;
+ }
+ } else {
+ i1 = (b & table1[bitsLeft]) << (-shift);
+ i2 = (next & table2[bitsFromNextByte]) >> (8 - bitsFromNextByte);
+
+ i1 |= i2;
+ bytePointer++;
+ bitPointer = bitsFromNextByte;
+ }
+
+ return i1;
+ }
+
+ // Move pointer backwards by given amount of bits
+ private void UpdatePointer(int bitsToMoveBack) {
+ int i = bitPointer - bitsToMoveBack;
+
+ if (i < 0) {
+ bytePointer--;
+ bitPointer = 8 + i;
+ } else {
+ bitPointer = i;
+ }
+ }
+
+ // Move to the next byte boundary
+ private bool AdvancePointer() {
+ if (bitPointer != 0) {
+ bytePointer++;
+ bitPointer = 0;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/codec/TIFFField.cs b/iTechSharp/iTextSharp/text/pdf/codec/TIFFField.cs
new file mode 100644
index 0000000..22aa0b6
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/codec/TIFFField.cs
@@ -0,0 +1,487 @@
+using System;
+/*
+ * Copyright 2003-2008 by Paulo Soares.
+ *
+ * This code was originally released in 2001 by SUN (see class
+ * com.sun.media.imageio.plugins.tiff.TIFFField.java)
+ * using the BSD license in a specific wording. In a mail dating from
+ * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission
+ * to use the code under the following version of the BSD license:
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for
+ * use in the design, construction, operation or maintenance of any
+ * nuclear facility.
+ */
+
+namespace iTextSharp.text.pdf.codec {
+ /**
+ * A class representing a field in a TIFF 6.0 Image File Directory.
+ *
+ *
+ *
+ */
+ public TIFFField(int tag, int type, int count, Object data) {
+ this.tag = tag;
+ this.type = type;
+ this.count = count;
+ this.data = data;
+ }
+
+ /**
+ * Returns the tag number, between 0 and 65535.
+ */
+ public int GetTag() {
+ return tag;
+ }
+
+ /**
+ * Returns the type of the data stored in the IFD.
+ * For a TIFF6.0 file, the value will equal one of the
+ * TIFF_ constants defined in this class. For future
+ * revisions of TIFF, higher values are possible.
+ *
+ */
+ public new int GetType() {
+ return type;
+ }
+
+ /**
+ * Returns the number of elements in the IFD.
+ */
+ public int GetCount() {
+ return count;
+ }
+
+ /**
+ * Returns the data as an uninterpreted array of bytes.
+ * The type of the field must be one of TIFF_BYTE, TIFF_SBYTE,
+ * or TIFF_UNDEFINED;
+ *
+ *
+ * TIFF type Java type
+ *
+ * TIFF_BYTE byte
+ *
+ * TIFF_ASCII String
+ *
+ * TIFF_SHORT char
+ *
+ * TIFF_LONG long
+ *
+ * TIFF_RATIONAL long[2]
+ *
+ * TIFF_SBYTE byte
+ *
+ * TIFF_UNDEFINED byte
+ *
+ * TIFF_SSHORT short
+ *
+ * TIFF_SLONG int
+ *
+ * TIFF_SRATIONAL int[2]
+ *
+ * TIFF_FLOAT float
+ *
+ * TIFF_DOUBLE double
+ * TIFFField
with another
+ * TIFFField
by comparing the tags.
+ *
+ * equals()
.
+ *
+ * @throws IllegalArgumentException if the parameter is null
.
+ * @throws ClassCastException if the parameter is not a
+ * TIFFField
.
+ */
+ public int CompareTo(Object o) {
+ if (o == null) {
+ throw new ArgumentException();
+ }
+
+ int oTag = ((TIFFField)o).GetTag();
+
+ if (tag < oTag) {
+ return -1;
+ } else if (tag > oTag) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/codec/TIFFLZWDecoder.cs b/iTechSharp/iTextSharp/text/pdf/codec/TIFFLZWDecoder.cs
new file mode 100644
index 0000000..b192dd0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/codec/TIFFLZWDecoder.cs
@@ -0,0 +1,272 @@
+using System;
+/*
+ * Copyright 2003-2008 by Paulo Soares.
+ *
+ * This code was originally released in 2001 by SUN (see class
+ * com.sun.media.imageioimpl.plugins.tiff.TIFFLZWDecompressor.java)
+ * using the BSD license in a specific wording. In a mail dating from
+ * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission
+ * to use the code under the following version of the BSD license:
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for
+ * use in the design, construction, operation or maintenance of any
+ * nuclear facility.
+ */
+
+namespace iTextSharp.text.pdf.codec {
+ /**
+ * A class for performing LZW decoding.
+ *
+ *
+ */
+ public class TIFFLZWDecoder {
+
+ byte[][] stringTable;
+ byte[] data = null;
+ byte[] uncompData;
+ int tableIndex, bitsToGet = 9;
+ int bytePointer;
+ int dstIndex;
+ int w, h;
+ int predictor, samplesPerPixel;
+ int nextData = 0;
+ int nextBits = 0;
+
+ int[] andTable = {
+ 511,
+ 1023,
+ 2047,
+ 4095
+ };
+
+ public TIFFLZWDecoder(int w, int predictor, int samplesPerPixel) {
+ this.w = w;
+ this.predictor = predictor;
+ this.samplesPerPixel = samplesPerPixel;
+ }
+
+ /**
+ * Method to decode LZW compressed data.
+ *
+ * @param data The compressed data.
+ * @param uncompData Array to return the uncompressed data in.
+ * @param h The number of rows the compressed data contains.
+ */
+ public byte[] Decode(byte[] data, byte[] uncompData, int h) {
+
+ if (data[0] == (byte)0x00 && data[1] == (byte)0x01) {
+ throw new InvalidOperationException("TIFF 5.0-style LZW codes are not supported.");
+ }
+
+ InitializeStringTable();
+
+ this.data = data;
+ this.h = h;
+ this.uncompData = uncompData;
+
+ // Initialize pointers
+ bytePointer = 0;
+ dstIndex = 0;
+
+
+ nextData = 0;
+ nextBits = 0;
+
+ int code, oldCode = 0;
+ byte[] strn;
+
+ while ( ((code = GetNextCode()) != 257) &&
+ dstIndex < uncompData.Length) {
+
+ if (code == 256) {
+
+ InitializeStringTable();
+ code = GetNextCode();
+
+ if (code == 257) {
+ break;
+ }
+
+ WriteString(stringTable[code]);
+ oldCode = code;
+
+ } else {
+
+ if (code < tableIndex) {
+
+ strn = stringTable[code];
+
+ WriteString(strn);
+ AddStringToTable(stringTable[oldCode], strn[0]);
+ oldCode = code;
+
+ } else {
+
+ strn = stringTable[oldCode];
+ strn = ComposeString(strn, strn[0]);
+ WriteString(strn);
+ AddStringToTable(strn);
+ oldCode = code;
+ }
+
+ }
+
+ }
+
+ // Horizontal Differencing Predictor
+ if (predictor == 2) {
+
+ int count;
+ for (int j = 0; j < h; j++) {
+
+ count = samplesPerPixel * (j * w + 1);
+
+ for (int i = samplesPerPixel; i < w * samplesPerPixel; i++) {
+
+ uncompData[count] += uncompData[count - samplesPerPixel];
+ count++;
+ }
+ }
+ }
+
+ return uncompData;
+ }
+
+
+ /**
+ * Initialize the string table.
+ */
+ public void InitializeStringTable() {
+
+ stringTable = new byte[4096][];
+
+ for (int i=0; i<256; i++) {
+ stringTable[i] = new byte[1];
+ stringTable[i][0] = (byte)i;
+ }
+
+ tableIndex = 258;
+ bitsToGet = 9;
+ }
+
+ /**
+ * Write out the string just uncompressed.
+ */
+ public void WriteString(byte[] strn) {
+ // Fix for broken tiff files
+ int max = uncompData.Length - dstIndex;
+ if (strn.Length < max)
+ max = strn.Length;
+ System.Array.Copy(strn, 0, uncompData, dstIndex, max);
+ dstIndex += max;
+ }
+
+ /**
+ * Add a new string to the string table.
+ */
+ public void AddStringToTable(byte[] oldString, byte newString) {
+ int length = oldString.Length;
+ byte[] strn = new byte[length + 1];
+ Array.Copy(oldString, 0, strn, 0, length);
+ strn[length] = newString;
+
+ // Add this new String to the table
+ stringTable[tableIndex++] = strn;
+
+ if (tableIndex == 511) {
+ bitsToGet = 10;
+ } else if (tableIndex == 1023) {
+ bitsToGet = 11;
+ } else if (tableIndex == 2047) {
+ bitsToGet = 12;
+ }
+ }
+
+ /**
+ * Add a new string to the string table.
+ */
+ public void AddStringToTable(byte[] strn) {
+
+ // Add this new String to the table
+ stringTable[tableIndex++] = strn;
+
+ if (tableIndex == 511) {
+ bitsToGet = 10;
+ } else if (tableIndex == 1023) {
+ bitsToGet = 11;
+ } else if (tableIndex == 2047) {
+ bitsToGet = 12;
+ }
+ }
+
+ /**
+ * Append newString
to the end of oldString
.
+ */
+ public byte[] ComposeString(byte[] oldString, byte newString) {
+ int length = oldString.Length;
+ byte[] strn = new byte[length + 1];
+ Array.Copy(oldString, 0, strn, 0, length);
+ strn[length] = newString;
+
+ return strn;
+ }
+
+ // Returns the next 9, 10, 11 or 12 bits
+ public int GetNextCode() {
+ // Attempt to get the next code. The exception is caught to make
+ // this robust to cases wherein the EndOfInformation code has been
+ // omitted from a strip. Examples of such cases have been observed
+ // in practice.
+ try {
+ nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
+ nextBits += 8;
+
+ if (nextBits < bitsToGet) {
+ nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
+ nextBits += 8;
+ }
+
+ int code =
+ (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet-9];
+ nextBits -= bitsToGet;
+
+ return code;
+ } catch (IndexOutOfRangeException) {
+ // Strip not terminated as expected: return EndOfInformation code.
+ return 257;
+ }
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/codec/TiffImage.cs b/iTechSharp/iTextSharp/text/pdf/codec/TiffImage.cs
new file mode 100644
index 0000000..f178d8c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/codec/TiffImage.cs
@@ -0,0 +1,546 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.pdf;
+using System.util.zlib;
+/*
+ * Copyright 2003 by Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.codec {
+ /** Reads TIFF images
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public class TiffImage {
+
+ /** Gets the number of pages the TIFF document has.
+ * @param s the file source
+ * @return the number of pages
+ */
+ public static int GetNumberOfPages(RandomAccessFileOrArray s) {
+ return TIFFDirectory.GetNumDirectories(s);
+ }
+
+ static int GetDpi(TIFFField fd, int resolutionUnit) {
+ if (fd == null)
+ return 0;
+ long[] res = fd.GetAsRational(0);
+ float frac = (float)res[0] / (float)res[1];
+ int dpi = 0;
+ switch (resolutionUnit) {
+ case TIFFConstants.RESUNIT_INCH:
+ case TIFFConstants.RESUNIT_NONE:
+ dpi = (int)(frac + 0.5);
+ break;
+ case TIFFConstants.RESUNIT_CENTIMETER:
+ dpi = (int)(frac * 2.54 + 0.5);
+ break;
+ }
+ return dpi;
+ }
+
+ /** Reads a page from a TIFF image. Direct mode is not used.
+ * @param s the file source
+ * @param page the page to get. The first page is 1
+ * @return the Image
+ */
+ public static Image GetTiffImage(RandomAccessFileOrArray s, int page) {
+ return GetTiffImage(s, page, false);
+ }
+
+ /** Reads a page from a TIFF image.
+ * @param s the file source
+ * @param page the page to get. The first page is 1
+ * @param direct for single strip, CCITT images, generate the image
+ * by direct byte copying. It's faster but may not work
+ * every time
+ * @return the Image
+ */
+ public static Image GetTiffImage(RandomAccessFileOrArray s, int page, bool direct) {
+ if (page < 1)
+ throw new ArgumentException("The page number must be >= 1.");
+ TIFFDirectory dir = new TIFFDirectory(s, page - 1);
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH))
+ throw new ArgumentException("Tiles are not supported.");
+ int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
+ switch (compression) {
+ case TIFFConstants.COMPRESSION_CCITTRLEW:
+ case TIFFConstants.COMPRESSION_CCITTRLE:
+ case TIFFConstants.COMPRESSION_CCITTFAX3:
+ case TIFFConstants.COMPRESSION_CCITTFAX4:
+ break;
+ default:
+ return GetTiffImageColor(dir, s);
+ }
+ float rotation = 0;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) {
+ int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
+ if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
+ rotation = (float)Math.PI;
+ else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
+ rotation = (float)(Math.PI / 2.0);
+ else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
+ rotation = -(float)(Math.PI / 2.0);
+ }
+
+ Image img = null;
+ long tiffT4Options = 0;
+ long tiffT6Options = 0;
+ int fillOrder = 1;
+ int h = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
+ int w = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
+ int dpiX = 0;
+ int dpiY = 0;
+ float XYRatio = 0;
+ int resolutionUnit = TIFFConstants.RESUNIT_INCH;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
+ resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
+ dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
+ dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
+ if (resolutionUnit == TIFFConstants.RESUNIT_NONE) {
+ if (dpiY != 0)
+ XYRatio = (float)dpiX / (float)dpiY;
+ dpiX = 0;
+ dpiY = 0;
+ }
+ int rowsStrip = h;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP))
+ rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
+ if (rowsStrip <= 0 || rowsStrip > h)
+ rowsStrip = h;
+ long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
+ long[] size = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
+ if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip) { // some TIFF producers are really lousy, so...
+ size = new long[]{s.Length - (int)offset[0]};
+ }
+ bool reverse = false;
+ TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);
+ if (fillOrderField != null)
+ fillOrder = fillOrderField.GetAsInt(0);
+ reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
+ int paramsn = 0;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PHOTOMETRIC)) {
+ long photo = dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
+ if (photo == TIFFConstants.PHOTOMETRIC_MINISBLACK)
+ paramsn |= Image.CCITT_BLACKIS1;
+ }
+ int imagecomp = 0;
+ switch (compression) {
+ case TIFFConstants.COMPRESSION_CCITTRLEW:
+ case TIFFConstants.COMPRESSION_CCITTRLE:
+ imagecomp = Image.CCITTG3_1D;
+ paramsn |= Image.CCITT_ENCODEDBYTEALIGN | Image.CCITT_ENDOFBLOCK;
+ break;
+ case TIFFConstants.COMPRESSION_CCITTFAX3:
+ imagecomp = Image.CCITTG3_1D;
+ paramsn |= Image.CCITT_ENDOFLINE | Image.CCITT_ENDOFBLOCK;
+ TIFFField t4OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP3OPTIONS);
+ if (t4OptionsField != null) {
+ tiffT4Options = t4OptionsField.GetAsLong(0);
+ if ((tiffT4Options & TIFFConstants.GROUP3OPT_2DENCODING) != 0)
+ imagecomp = Image.CCITTG3_2D;
+ if ((tiffT4Options & TIFFConstants.GROUP3OPT_FILLBITS) != 0)
+ paramsn |= Image.CCITT_ENCODEDBYTEALIGN;
+ }
+ break;
+ case TIFFConstants.COMPRESSION_CCITTFAX4:
+ imagecomp = Image.CCITTG4;
+ TIFFField t6OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP4OPTIONS);
+ if (t6OptionsField != null)
+ tiffT6Options = t6OptionsField.GetAsLong(0);
+ break;
+ }
+ if (direct && rowsStrip == h) { //single strip, direct
+ byte[] im = new byte[(int)size[0]];
+ s.Seek(offset[0]);
+ s.ReadFully(im);
+ img = Image.GetInstance(w, h, false, imagecomp, paramsn, im);
+ img.Inverted = true;
+ }
+ else {
+ int rowsLeft = h;
+ CCITTG4Encoder g4 = new CCITTG4Encoder(w);
+ for (int k = 0; k < offset.Length; ++k) {
+ byte[] im = new byte[(int)size[k]];
+ s.Seek(offset[k]);
+ s.ReadFully(im);
+ int height = Math.Min(rowsStrip, rowsLeft);
+ TIFFFaxDecoder decoder = new TIFFFaxDecoder(fillOrder, w, height);
+ byte[] outBuf = new byte[(w + 7) / 8 * height];
+ switch (compression) {
+ case TIFFConstants.COMPRESSION_CCITTRLEW:
+ case TIFFConstants.COMPRESSION_CCITTRLE:
+ decoder.Decode1D(outBuf, im, 0, height);
+ g4.Fax4Encode(outBuf, height);
+ break;
+ case TIFFConstants.COMPRESSION_CCITTFAX3:
+ try {
+ decoder.Decode2D(outBuf, im, 0, height, tiffT4Options);
+ }
+ catch (Exception e) {
+ // let's flip the fill bits and try again...
+ tiffT4Options ^= TIFFConstants.GROUP3OPT_FILLBITS;
+ try {
+ decoder.Decode2D(outBuf, im, 0, height, tiffT4Options);
+ }
+ catch {
+ throw e;
+ }
+ }
+ g4.Fax4Encode(outBuf, height);
+ break;
+ case TIFFConstants.COMPRESSION_CCITTFAX4:
+ decoder.DecodeT6(outBuf, im, 0, height, tiffT6Options);
+ g4.Fax4Encode(outBuf, height);
+ break;
+ }
+ rowsLeft -= rowsStrip;
+ }
+ byte[] g4pic = g4.Close();
+ img = Image.GetInstance(w, h, false, Image.CCITTG4, paramsn & Image.CCITT_BLACKIS1, g4pic);
+ }
+ img.SetDpi(dpiX, dpiY);
+ img.XYRatio = XYRatio;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) {
+ try {
+ TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
+ ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes());
+ if (icc_prof.NumComponents == 1)
+ img.TagICC = icc_prof;
+ }
+ catch {
+ //empty
+ }
+ }
+ img.OriginalType = Image.ORIGINAL_TIFF;
+ if (rotation != 0)
+ img.InitialRotation = rotation;
+ return img;
+ }
+
+ protected static Image GetTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s) {
+ int predictor = 1;
+ TIFFLZWDecoder lzwDecoder = null;
+ int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
+ switch (compression) {
+ case TIFFConstants.COMPRESSION_NONE:
+ case TIFFConstants.COMPRESSION_LZW:
+ case TIFFConstants.COMPRESSION_PACKBITS:
+ case TIFFConstants.COMPRESSION_DEFLATE:
+ case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
+ case TIFFConstants.COMPRESSION_OJPEG:
+ case TIFFConstants.COMPRESSION_JPEG:
+ break;
+ default:
+ throw new ArgumentException("The compression " + compression + " is not supported.");
+ }
+ int photometric = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
+ switch (photometric) {
+ case TIFFConstants.PHOTOMETRIC_MINISWHITE:
+ case TIFFConstants.PHOTOMETRIC_MINISBLACK:
+ case TIFFConstants.PHOTOMETRIC_RGB:
+ case TIFFConstants.PHOTOMETRIC_SEPARATED:
+ case TIFFConstants.PHOTOMETRIC_PALETTE:
+ break;
+ default:
+ if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
+ throw new ArgumentException("The photometric " + photometric + " is not supported.");
+ break;
+ }
+ float rotation = 0;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) {
+ int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
+ if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
+ rotation = (float)Math.PI;
+ else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
+ rotation = (float)(Math.PI / 2.0);
+ else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
+ rotation = -(float)(Math.PI / 2.0);
+ }
+
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG)
+ && dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG) == TIFFConstants.PLANARCONFIG_SEPARATE)
+ throw new ArgumentException("Planar images are not supported.");
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES))
+ throw new ArgumentException("Extra samples are not supported.");
+ int samplePerPixel = 1;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL)) // 1,3,4
+ samplePerPixel = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL);
+ int bitsPerSample = 1;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE))
+ bitsPerSample = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE);
+ switch (bitsPerSample) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ break;
+ default:
+ throw new ArgumentException("Bits per sample " + bitsPerSample + " is not supported.");
+ }
+ Image img = null;
+
+ int h = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
+ int w = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
+ int dpiX = 0;
+ int dpiY = 0;
+ int resolutionUnit = TIFFConstants.RESUNIT_INCH;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
+ resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
+ dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
+ dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
+ int fillOrder = 1;
+ bool reverse = false;
+ TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);
+ if (fillOrderField != null)
+ fillOrder = fillOrderField.GetAsInt(0);
+ reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
+ int rowsStrip = h;
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) //another hack for broken tiffs
+ rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
+ if (rowsStrip <= 0 || rowsStrip > h)
+ rowsStrip = h;
+ long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
+ long[] size = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
+ if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip) { // some TIFF producers are really lousy, so...
+ size = new long[]{s.Length - (int)offset[0]};
+ }
+ if (compression == TIFFConstants.COMPRESSION_LZW) {
+ TIFFField predictorField = dir.GetField(TIFFConstants.TIFFTAG_PREDICTOR);
+ if (predictorField != null) {
+ predictor = predictorField.GetAsInt(0);
+ if (predictor != 1 && predictor != 2) {
+ throw new Exception("Illegal value for Predictor in TIFF file.");
+ }
+ if (predictor == 2 && bitsPerSample != 8) {
+ throw new Exception(bitsPerSample + "-bit samples are not supported for Horizontal differencing Predictor.");
+ }
+ }
+ lzwDecoder = new TIFFLZWDecoder(w, predictor,
+ samplePerPixel);
+ }
+ int rowsLeft = h;
+ MemoryStream stream = null;
+ ZDeflaterOutputStream zip = null;
+ CCITTG4Encoder g4 = null;
+ if (bitsPerSample == 1 && samplePerPixel == 1) {
+ g4 = new CCITTG4Encoder(w);
+ }
+ else {
+ stream = new MemoryStream();
+ if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
+ zip = new ZDeflaterOutputStream(stream);
+ }
+ if (compression == TIFFConstants.COMPRESSION_OJPEG) {
+
+ // Assume that the TIFFTAG_JPEGIFBYTECOUNT tag is optional, since it's obsolete and
+ // is often missing
+
+ if ((!dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET))) {
+ throw new IOException("Missing tag(s) for OJPEG compression.");
+ }
+ int jpegOffset = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET);
+ int jpegLength = s.Length - jpegOffset;
+
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT)) {
+ jpegLength = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT) +
+ (int)size[0];
+ }
+
+ byte[] jpeg = new byte[Math.Min(jpegLength, s.Length - jpegOffset)];
+
+ int posFilePointer = s.FilePointer;
+ posFilePointer += jpegOffset;
+ s.Seek(posFilePointer);
+ s.ReadFully(jpeg);
+ img = new Jpeg(jpeg);
+ }
+ else if (compression == TIFFConstants.COMPRESSION_JPEG) {
+ if (size.Length > 1)
+ throw new IOException("Compression JPEG is only supported with a single strip. This image has " + size.Length + " strips.");
+ byte[] jpeg = new byte[(int)size[0]];
+ s.Seek(offset[0]);
+ s.ReadFully(jpeg);
+ img = new Jpeg(jpeg);
+ }
+ else {
+ for (int k = 0; k < offset.Length; ++k) {
+ byte[] im = new byte[(int)size[k]];
+ s.Seek(offset[k]);
+ s.ReadFully(im);
+ int height = Math.Min(rowsStrip, rowsLeft);
+ byte[] outBuf = null;
+ if (compression != TIFFConstants.COMPRESSION_NONE)
+ outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height];
+ if (reverse)
+ TIFFFaxDecoder.ReverseBits(im);
+ switch (compression) {
+ case TIFFConstants.COMPRESSION_DEFLATE:
+ case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
+ Inflate(im, outBuf);
+ break;
+ case TIFFConstants.COMPRESSION_NONE:
+ outBuf = im;
+ break;
+ case TIFFConstants.COMPRESSION_PACKBITS:
+ DecodePackbits(im, outBuf);
+ break;
+ case TIFFConstants.COMPRESSION_LZW:
+ lzwDecoder.Decode(im, outBuf, height);
+ break;
+ }
+ if (bitsPerSample == 1 && samplePerPixel == 1) {
+ g4.Fax4Encode(outBuf, height);
+ }
+ else {
+ zip.Write(outBuf, 0, outBuf.Length);
+ }
+ rowsLeft -= rowsStrip;
+ }
+ if (bitsPerSample == 1 && samplePerPixel == 1) {
+ img = Image.GetInstance(w, h, false, Image.CCITTG4,
+ photometric == TIFFConstants.PHOTOMETRIC_MINISBLACK ? Image.CCITT_BLACKIS1 : 0, g4.Close());
+ }
+ else {
+ zip.Close();
+ img = Image.GetInstance(w, h, samplePerPixel, bitsPerSample, stream.ToArray());
+ img.Deflated = true;
+ }
+ }
+ img.SetDpi(dpiX, dpiY);
+ if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) {
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) {
+ try {
+ TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
+ ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes());
+ if (samplePerPixel == icc_prof.NumComponents)
+ img.TagICC = icc_prof;
+ }
+ catch {
+ //empty
+ }
+ }
+ if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COLORMAP)) {
+ TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_COLORMAP);
+ char[] rgb = fd.GetAsChars();
+ byte[] palette = new byte[rgb.Length];
+ int gColor = rgb.Length / 3;
+ int bColor = gColor * 2;
+ for (int k = 0; k < gColor; ++k) {
+ palette[k * 3] = (byte)(rgb[k] >> 8);
+ palette[k * 3 + 1] = (byte)(rgb[k + gColor] >> 8);
+ palette[k * 3 + 2] = (byte)(rgb[k + bColor] >> 8);
+ }
+ PdfArray indexed = new PdfArray();
+ indexed.Add(PdfName.INDEXED);
+ indexed.Add(PdfName.DEVICERGB);
+ indexed.Add(new PdfNumber(gColor - 1));
+ indexed.Add(new PdfString(palette));
+ PdfDictionary additional = new PdfDictionary();
+ additional.Put(PdfName.COLORSPACE, indexed);
+ img.Additional = additional;
+ }
+ img.OriginalType = Image.ORIGINAL_TIFF;
+ }
+ if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE)
+ img.Inverted = true;
+ if (rotation != 0)
+ img.InitialRotation = rotation;
+ return img;
+ }
+
+ static long[] GetArrayLongShort(TIFFDirectory dir, int tag) {
+ TIFFField field = dir.GetField(tag);
+ if (field == null)
+ return null;
+ long[] offset;
+ if (field.GetType() == TIFFField.TIFF_LONG)
+ offset = field.GetAsLongs();
+ else { // must be short
+ char[] temp = field.GetAsChars();
+ offset = new long[temp.Length];
+ for (int k = 0; k < temp.Length; ++k)
+ offset[k] = temp[k];
+ }
+ return offset;
+ }
+
+ // Uncompress packbits compressed image data.
+ public static void DecodePackbits(byte[] data, byte[] dst) {
+ int srcCount = 0, dstCount = 0;
+ sbyte repeat, b;
+
+ try {
+ while (dstCount < dst.Length) {
+ b = (sbyte)data[srcCount++];
+ if (b >= 0 && b <= 127) {
+ // literal run packet
+ for (int i=0; i<(b + 1); i++) {
+ dst[dstCount++] = data[srcCount++];
+ }
+
+ } else if (b <= -1 && b >= -127) {
+ // 2 byte encoded run packet
+ repeat = (sbyte)data[srcCount++];
+ for (int i=0; i<(-b + 1); i++) {
+ dst[dstCount++] = (byte)repeat;
+ }
+ } else {
+ // no-op packet. Do nothing
+ srcCount++;
+ }
+ }
+ }
+ catch {
+ }
+ }
+
+ public static void Inflate(byte[] deflated, byte[] inflated) {
+ byte[] outp = PdfReader.FlateDecode(deflated);
+ System.Array.Copy(outp, 0, inflated, 0, Math.Min(outp.Length, inflated.Length));
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/pdf/codec/wmf/InputMeta.cs b/iTechSharp/iTextSharp/text/pdf/codec/wmf/InputMeta.cs
new file mode 100644
index 0000000..55faf1b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/codec/wmf/InputMeta.cs
@@ -0,0 +1,117 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+
+/*
+ * $Id: InputMeta.cs,v 1.4 2008/05/13 11:25:36 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.codec.wmf {
+ /// PdfWriter
for this document
+ * @param document
+ * the document
+ */
+ public virtual void OnOpenDocument(PdfWriter writer, Document document) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnOpenDocument(writer, document);
+ }
+ }
+
+ /**
+ * Called when a page is initialized.
+ * onEndPage
to avoid infinite loops.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ */
+ public virtual void OnStartPage(PdfWriter writer, Document document) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnStartPage(writer, document);
+ }
+ }
+
+ /**
+ * Called when a page is finished, just before being written to the
+ * document.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ */
+ public virtual void OnEndPage(PdfWriter writer, Document document) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnEndPage(writer, document);
+ }
+ }
+
+ /**
+ * Called when the document is closed.
+ * PdfWriter
for this document
+ * @param document
+ * the document
+ */
+ public virtual void OnCloseDocument(PdfWriter writer, Document document) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnCloseDocument(writer, document);
+ }
+ }
+
+ /**
+ * Called when a Paragraph is written.
+ * paragraphPosition
will hold the height at which the
+ * paragraph will be written to. This is useful to insert bookmarks with
+ * more control.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ * @param paragraphPosition
+ * the position the paragraph will be written to
+ */
+ public virtual void OnParagraph(PdfWriter writer, Document document,
+ float paragraphPosition) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnParagraph(writer, document, paragraphPosition);
+ }
+ }
+
+ /**
+ * Called when a Paragraph is written.
+ * paragraphPosition
will hold the height of the end of the
+ * paragraph.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ * @param paragraphPosition
+ * the position of the end of the paragraph
+ */
+ public virtual void OnParagraphEnd(PdfWriter writer, Document document,
+ float paragraphPosition) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnParagraphEnd(writer, document, paragraphPosition);
+ }
+ }
+
+ /**
+ * Called when a Chapter is written.
+ * position
will hold the height at which the chapter will be
+ * written to.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ * @param paragraphPosition
+ * the position the chapter will be written to
+ * @param title
+ * the title of the Chapter
+ */
+ public virtual void OnChapter(PdfWriter writer, Document document,
+ float paragraphPosition, Paragraph title) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnChapter(writer, document, paragraphPosition, title);
+ }
+ }
+
+ /**
+ * Called when the end of a Chapter is reached.
+ * position
will hold the height of the end of the chapter.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ * @param position
+ * the position of the end of the chapter.
+ */
+ public virtual void OnChapterEnd(PdfWriter writer, Document document, float position) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnChapterEnd(writer, document, position);
+ }
+ }
+
+ /**
+ * Called when a Section is written.
+ * position
will hold the height at which the section will be
+ * written to.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ * @param paragraphPosition
+ * the position the section will be written to
+ * @param depth
+ * the number depth of the Section
+ * @param title
+ * the title of the section
+ */
+ public virtual void OnSection(PdfWriter writer, Document document,
+ float paragraphPosition, int depth, Paragraph title) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnSection(writer, document, paragraphPosition, depth, title);
+ }
+ }
+
+ /**
+ * Called when the end of a Section is reached.
+ * position
will hold the height of the section end.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ * @param position
+ * the position of the end of the section
+ */
+ public virtual void OnSectionEnd(PdfWriter writer, Document document, float position) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnSectionEnd(writer, document, position);
+ }
+ }
+
+ /**
+ * Called when a Chunk
with a generic tag is written.
+ * Chunk
location to generate
+ * bookmarks, for example.
+ *
+ * @param writer
+ * the PdfWriter
for this document
+ * @param document
+ * the document
+ * @param rect
+ * the Rectangle
containing the Chunk
+ *
+ * @param text
+ * the text of the tag
+ */
+ public virtual void OnGenericTag(PdfWriter writer, Document document,
+ Rectangle rect, String text) {
+ foreach (IPdfPageEvent eventa in events) {
+ eventa.OnGenericTag(writer, document, rect, text);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Courier-Bold.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Courier-Bold.afm
new file mode 100644
index 0000000..352ace5
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Courier-Bold.afm
@@ -0,0 +1,342 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Mon Jun 23 16:28:00 1997
+Comment UniqueID 43048
+Comment VMusage 41139 52164
+FontName Courier-Bold
+FullName Courier Bold
+FamilyName Courier
+Weight Bold
+ItalicAngle 0
+IsFixedPitch true
+CharacterSet ExtendedRoman
+FontBBox -113 -250 749 801
+UnderlinePosition -100
+UnderlineThickness 50
+Version 003.000
+Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 439
+Ascender 629
+Descender -157
+StdHW 84
+StdVW 106
+StartCharMetrics 315
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ;
+C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ;
+C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ;
+C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ;
+C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ;
+C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ;
+C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ;
+C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ;
+C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ;
+C 43 ; WX 600 ; N plus ; B 71 39 529 478 ;
+C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ;
+C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ;
+C 46 ; WX 600 ; N period ; B 192 -15 408 171 ;
+C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ;
+C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ;
+C 49 ; WX 600 ; N one ; B 81 0 539 616 ;
+C 50 ; WX 600 ; N two ; B 61 0 499 616 ;
+C 51 ; WX 600 ; N three ; B 63 -15 501 616 ;
+C 52 ; WX 600 ; N four ; B 53 0 507 616 ;
+C 53 ; WX 600 ; N five ; B 70 -15 521 601 ;
+C 54 ; WX 600 ; N six ; B 90 -15 521 616 ;
+C 55 ; WX 600 ; N seven ; B 55 0 494 601 ;
+C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ;
+C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ;
+C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ;
+C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ;
+C 60 ; WX 600 ; N less ; B 66 15 523 501 ;
+C 61 ; WX 600 ; N equal ; B 71 118 529 398 ;
+C 62 ; WX 600 ; N greater ; B 77 15 534 501 ;
+C 63 ; WX 600 ; N question ; B 98 -14 501 580 ;
+C 64 ; WX 600 ; N at ; B 16 -15 584 616 ;
+C 65 ; WX 600 ; N A ; B -9 0 609 562 ;
+C 66 ; WX 600 ; N B ; B 30 0 573 562 ;
+C 67 ; WX 600 ; N C ; B 22 -18 560 580 ;
+C 68 ; WX 600 ; N D ; B 30 0 594 562 ;
+C 69 ; WX 600 ; N E ; B 25 0 560 562 ;
+C 70 ; WX 600 ; N F ; B 39 0 570 562 ;
+C 71 ; WX 600 ; N G ; B 22 -18 594 580 ;
+C 72 ; WX 600 ; N H ; B 20 0 580 562 ;
+C 73 ; WX 600 ; N I ; B 77 0 523 562 ;
+C 74 ; WX 600 ; N J ; B 37 -18 601 562 ;
+C 75 ; WX 600 ; N K ; B 21 0 599 562 ;
+C 76 ; WX 600 ; N L ; B 39 0 578 562 ;
+C 77 ; WX 600 ; N M ; B -2 0 602 562 ;
+C 78 ; WX 600 ; N N ; B 8 -12 610 562 ;
+C 79 ; WX 600 ; N O ; B 22 -18 578 580 ;
+C 80 ; WX 600 ; N P ; B 48 0 559 562 ;
+C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ;
+C 82 ; WX 600 ; N R ; B 24 0 599 562 ;
+C 83 ; WX 600 ; N S ; B 47 -22 553 582 ;
+C 84 ; WX 600 ; N T ; B 21 0 579 562 ;
+C 85 ; WX 600 ; N U ; B 4 -18 596 562 ;
+C 86 ; WX 600 ; N V ; B -13 0 613 562 ;
+C 87 ; WX 600 ; N W ; B -18 0 618 562 ;
+C 88 ; WX 600 ; N X ; B 12 0 588 562 ;
+C 89 ; WX 600 ; N Y ; B 12 0 589 562 ;
+C 90 ; WX 600 ; N Z ; B 62 0 539 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ;
+C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ;
+C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ;
+C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ;
+C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ;
+C 97 ; WX 600 ; N a ; B 35 -15 570 454 ;
+C 98 ; WX 600 ; N b ; B 0 -15 584 626 ;
+C 99 ; WX 600 ; N c ; B 40 -15 545 459 ;
+C 100 ; WX 600 ; N d ; B 20 -15 591 626 ;
+C 101 ; WX 600 ; N e ; B 40 -15 563 454 ;
+C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 30 -146 580 454 ;
+C 104 ; WX 600 ; N h ; B 5 0 592 626 ;
+C 105 ; WX 600 ; N i ; B 77 0 523 658 ;
+C 106 ; WX 600 ; N j ; B 63 -146 440 658 ;
+C 107 ; WX 600 ; N k ; B 20 0 585 626 ;
+C 108 ; WX 600 ; N l ; B 77 0 523 626 ;
+C 109 ; WX 600 ; N m ; B -22 0 626 454 ;
+C 110 ; WX 600 ; N n ; B 18 0 592 454 ;
+C 111 ; WX 600 ; N o ; B 30 -15 570 454 ;
+C 112 ; WX 600 ; N p ; B -1 -142 570 454 ;
+C 113 ; WX 600 ; N q ; B 20 -142 591 454 ;
+C 114 ; WX 600 ; N r ; B 47 0 580 454 ;
+C 115 ; WX 600 ; N s ; B 68 -17 535 459 ;
+C 116 ; WX 600 ; N t ; B 47 -15 532 562 ;
+C 117 ; WX 600 ; N u ; B -1 -15 569 439 ;
+C 118 ; WX 600 ; N v ; B -1 0 601 439 ;
+C 119 ; WX 600 ; N w ; B -18 0 618 439 ;
+C 120 ; WX 600 ; N x ; B 6 0 594 439 ;
+C 121 ; WX 600 ; N y ; B -4 -142 601 439 ;
+C 122 ; WX 600 ; N z ; B 81 0 520 439 ;
+C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ;
+C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ;
+C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ;
+C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ;
+C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ;
+C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ;
+C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ;
+C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ;
+C 165 ; WX 600 ; N yen ; B 10 0 590 562 ;
+C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ;
+C 167 ; WX 600 ; N section ; B 83 -70 517 580 ;
+C 168 ; WX 600 ; N currency ; B 54 49 546 517 ;
+C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ;
+C 174 ; WX 600 ; N fi ; B 12 0 593 626 ;
+C 175 ; WX 600 ; N fl ; B 12 0 593 626 ;
+C 177 ; WX 600 ; N endash ; B 65 203 535 313 ;
+C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ;
+C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ;
+C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ;
+C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ;
+C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ;
+C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ;
+C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ;
+C 193 ; WX 600 ; N grave ; B 132 508 395 661 ;
+C 194 ; WX 600 ; N acute ; B 205 508 468 661 ;
+C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ;
+C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ;
+C 197 ; WX 600 ; N macron ; B 88 505 512 585 ;
+C 198 ; WX 600 ; N breve ; B 83 468 517 631 ;
+C 199 ; WX 600 ; N dotaccent ; B 230 498 370 638 ;
+C 200 ; WX 600 ; N dieresis ; B 128 498 472 638 ;
+C 202 ; WX 600 ; N ring ; B 198 481 402 678 ;
+C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ;
+C 206 ; WX 600 ; N ogonek ; B 169 -199 400 0 ;
+C 207 ; WX 600 ; N caron ; B 103 493 497 667 ;
+C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ;
+C 225 ; WX 600 ; N AE ; B -29 0 602 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ;
+C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ;
+C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ;
+C 234 ; WX 600 ; N OE ; B -25 0 595 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ;
+C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ;
+C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ;
+C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ;
+C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ;
+C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ;
+C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ;
+C -1 ; WX 600 ; N Idieresis ; B 77 0 523 761 ;
+C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ;
+C -1 ; WX 600 ; N abreve ; B 35 -15 570 661 ;
+C -1 ; WX 600 ; N uhungarumlaut ; B -1 -15 628 661 ;
+C -1 ; WX 600 ; N ecaron ; B 40 -15 563 667 ;
+C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 761 ;
+C -1 ; WX 600 ; N divide ; B 71 16 529 500 ;
+C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ;
+C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ;
+C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ;
+C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ;
+C -1 ; WX 600 ; N scommaaccent ; B 68 -250 535 459 ;
+C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ;
+C -1 ; WX 600 ; N Uring ; B 4 -18 596 801 ;
+C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 761 ;
+C -1 ; WX 600 ; N aogonek ; B 35 -199 586 454 ;
+C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ;
+C -1 ; WX 600 ; N uogonek ; B -1 -199 585 439 ;
+C -1 ; WX 600 ; N Edieresis ; B 25 0 560 761 ;
+C -1 ; WX 600 ; N Dcroat ; B 30 0 594 562 ;
+C -1 ; WX 600 ; N commaaccent ; B 205 -250 397 -57 ;
+C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N Emacron ; B 25 0 560 708 ;
+C -1 ; WX 600 ; N ccaron ; B 40 -15 545 667 ;
+C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ;
+C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 610 562 ;
+C -1 ; WX 600 ; N lacute ; B 77 0 523 801 ;
+C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ;
+C -1 ; WX 600 ; N Tcommaaccent ; B 21 -250 579 562 ;
+C -1 ; WX 600 ; N Cacute ; B 22 -18 560 784 ;
+C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ;
+C -1 ; WX 600 ; N Edotaccent ; B 25 0 560 761 ;
+C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ;
+C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ;
+C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ;
+C -1 ; WX 600 ; N lozenge ; B 66 0 534 740 ;
+C -1 ; WX 600 ; N Rcaron ; B 24 0 599 790 ;
+C -1 ; WX 600 ; N Gcommaaccent ; B 22 -250 594 580 ;
+C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ;
+C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ;
+C -1 ; WX 600 ; N Amacron ; B -9 0 609 708 ;
+C -1 ; WX 600 ; N rcaron ; B 47 0 580 667 ;
+C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ;
+C -1 ; WX 600 ; N Zdotaccent ; B 62 0 539 761 ;
+C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ;
+C -1 ; WX 600 ; N Omacron ; B 22 -18 578 708 ;
+C -1 ; WX 600 ; N Racute ; B 24 0 599 784 ;
+C -1 ; WX 600 ; N Sacute ; B 47 -22 553 784 ;
+C -1 ; WX 600 ; N dcaron ; B 20 -15 727 626 ;
+C -1 ; WX 600 ; N Umacron ; B 4 -18 596 708 ;
+C -1 ; WX 600 ; N uring ; B -1 -15 569 678 ;
+C -1 ; WX 600 ; N threebaseior ; B 138 222 433 616 ;
+C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ;
+C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ;
+C -1 ; WX 600 ; N Abreve ; B -9 0 609 784 ;
+C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ;
+C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ;
+C -1 ; WX 600 ; N Tcaron ; B 21 0 579 790 ;
+C -1 ; WX 600 ; N partialdiff ; B 63 -38 537 728 ;
+C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 638 ;
+C -1 ; WX 600 ; N Nacute ; B 8 -12 610 784 ;
+C -1 ; WX 600 ; N icircumflex ; B 73 0 523 657 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ;
+C -1 ; WX 600 ; N adieresis ; B 35 -15 570 638 ;
+C -1 ; WX 600 ; N edieresis ; B 40 -15 563 638 ;
+C -1 ; WX 600 ; N cacute ; B 40 -15 545 661 ;
+C -1 ; WX 600 ; N nacute ; B 18 0 592 661 ;
+C -1 ; WX 600 ; N umacron ; B -1 -15 569 585 ;
+C -1 ; WX 600 ; N Ncaron ; B 8 -12 610 790 ;
+C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ;
+C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ;
+C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ;
+C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N Gbreve ; B 22 -18 594 784 ;
+C -1 ; WX 600 ; N Idotaccent ; B 77 0 523 761 ;
+C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ;
+C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ;
+C -1 ; WX 600 ; N racute ; B 47 0 580 661 ;
+C -1 ; WX 600 ; N omacron ; B 30 -15 570 585 ;
+C -1 ; WX 600 ; N Zacute ; B 62 0 539 784 ;
+C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ;
+C -1 ; WX 600 ; N greaterequal ; B 26 0 523 696 ;
+C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ;
+C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ;
+C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 523 626 ;
+C -1 ; WX 600 ; N tcaron ; B 47 -15 532 703 ;
+C -1 ; WX 600 ; N eogonek ; B 40 -199 563 454 ;
+C -1 ; WX 600 ; N Uogonek ; B 4 -199 596 562 ;
+C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ;
+C -1 ; WX 600 ; N Adieresis ; B -9 0 609 761 ;
+C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ;
+C -1 ; WX 600 ; N zacute ; B 81 0 520 661 ;
+C -1 ; WX 600 ; N iogonek ; B 77 -199 523 658 ;
+C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ;
+C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ;
+C -1 ; WX 600 ; N amacron ; B 35 -15 570 585 ;
+C -1 ; WX 600 ; N sacute ; B 68 -17 535 661 ;
+C -1 ; WX 600 ; N idieresis ; B 77 0 523 618 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ;
+C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ;
+C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ;
+C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ;
+C -1 ; WX 600 ; N twobaseior ; B 143 230 436 616 ;
+C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 761 ;
+C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ;
+C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ;
+C -1 ; WX 600 ; N ohungarumlaut ; B 30 -15 668 661 ;
+C -1 ; WX 600 ; N Eogonek ; B 25 -199 576 562 ;
+C -1 ; WX 600 ; N dcroat ; B 20 -15 591 626 ;
+C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ;
+C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ;
+C -1 ; WX 600 ; N lcaron ; B 77 0 597 626 ;
+C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 599 562 ;
+C -1 ; WX 600 ; N Lacute ; B 39 0 578 784 ;
+C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ;
+C -1 ; WX 600 ; N edotaccent ; B 40 -15 563 638 ;
+C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ;
+C -1 ; WX 600 ; N Imacron ; B 77 0 523 708 ;
+C -1 ; WX 600 ; N Lcaron ; B 39 0 637 562 ;
+C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ;
+C -1 ; WX 600 ; N lessequal ; B 26 0 523 696 ;
+C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ;
+C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ;
+C -1 ; WX 600 ; N Uhungarumlaut ; B 4 -18 638 784 ;
+C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ;
+C -1 ; WX 600 ; N emacron ; B 40 -15 563 585 ;
+C -1 ; WX 600 ; N gbreve ; B 30 -146 580 661 ;
+C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ;
+C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ;
+C -1 ; WX 600 ; N Scommaaccent ; B 47 -250 553 582 ;
+C -1 ; WX 600 ; N Ohungarumlaut ; B 22 -18 628 784 ;
+C -1 ; WX 600 ; N degree ; B 86 243 474 616 ;
+C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ;
+C -1 ; WX 600 ; N Ccaron ; B 22 -18 560 790 ;
+C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ;
+C -1 ; WX 600 ; N radical ; B -19 -104 473 778 ;
+C -1 ; WX 600 ; N Dcaron ; B 30 0 594 790 ;
+C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 580 454 ;
+C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ;
+C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ;
+C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 599 562 ;
+C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 578 562 ;
+C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ;
+C -1 ; WX 600 ; N Aogonek ; B -9 -199 625 562 ;
+C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ;
+C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ;
+C -1 ; WX 600 ; N zdotaccent ; B 81 0 520 638 ;
+C -1 ; WX 600 ; N Ecaron ; B 25 0 560 790 ;
+C -1 ; WX 600 ; N Iogonek ; B 77 -199 523 562 ;
+C -1 ; WX 600 ; N kcommaaccent ; B 20 -250 585 626 ;
+C -1 ; WX 600 ; N minus ; B 71 203 529 313 ;
+C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ;
+C -1 ; WX 600 ; N ncaron ; B 18 0 592 667 ;
+C -1 ; WX 600 ; N tcommaaccent ; B 47 -250 532 562 ;
+C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ;
+C -1 ; WX 600 ; N odieresis ; B 30 -15 570 638 ;
+C -1 ; WX 600 ; N udieresis ; B -1 -15 569 638 ;
+C -1 ; WX 600 ; N notequal ; B 12 -47 537 563 ;
+C -1 ; WX 600 ; N gcommaaccent ; B 30 -146 580 714 ;
+C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ;
+C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ;
+C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 592 454 ;
+C -1 ; WX 600 ; N onebaseior ; B 153 230 447 616 ;
+C -1 ; WX 600 ; N imacron ; B 77 0 523 585 ;
+C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Courier-BoldOblique.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Courier-BoldOblique.afm
new file mode 100644
index 0000000..33738a8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Courier-BoldOblique.afm
@@ -0,0 +1,342 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Mon Jun 23 16:28:46 1997
+Comment UniqueID 43049
+Comment VMusage 17529 79244
+FontName Courier-BoldOblique
+FullName Courier Bold Oblique
+FamilyName Courier
+Weight Bold
+ItalicAngle -12
+IsFixedPitch true
+CharacterSet ExtendedRoman
+FontBBox -57 -250 869 801
+UnderlinePosition -100
+UnderlineThickness 50
+Version 003.000
+Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 439
+Ascender 629
+Descender -157
+StdHW 84
+StdVW 106
+StartCharMetrics 315
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 215 -15 495 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 211 277 585 562 ;
+C 35 ; WX 600 ; N numbersign ; B 88 -45 641 651 ;
+C 36 ; WX 600 ; N dollar ; B 87 -126 630 666 ;
+C 37 ; WX 600 ; N percent ; B 101 -15 625 616 ;
+C 38 ; WX 600 ; N ampersand ; B 61 -15 595 543 ;
+C 39 ; WX 600 ; N quoteright ; B 229 277 543 562 ;
+C 40 ; WX 600 ; N parenleft ; B 265 -102 592 616 ;
+C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ;
+C 42 ; WX 600 ; N asterisk ; B 179 219 598 601 ;
+C 43 ; WX 600 ; N plus ; B 114 39 596 478 ;
+C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ;
+C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ;
+C 46 ; WX 600 ; N period ; B 206 -15 427 171 ;
+C 47 ; WX 600 ; N slash ; B 90 -77 626 626 ;
+C 48 ; WX 600 ; N zero ; B 135 -15 593 616 ;
+C 49 ; WX 600 ; N one ; B 93 0 562 616 ;
+C 50 ; WX 600 ; N two ; B 61 0 594 616 ;
+C 51 ; WX 600 ; N three ; B 71 -15 571 616 ;
+C 52 ; WX 600 ; N four ; B 81 0 559 616 ;
+C 53 ; WX 600 ; N five ; B 77 -15 621 601 ;
+C 54 ; WX 600 ; N six ; B 135 -15 652 616 ;
+C 55 ; WX 600 ; N seven ; B 147 0 622 601 ;
+C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ;
+C 57 ; WX 600 ; N nine ; B 75 -15 592 616 ;
+C 58 ; WX 600 ; N colon ; B 205 -15 480 425 ;
+C 59 ; WX 600 ; N semicolon ; B 99 -111 481 425 ;
+C 60 ; WX 600 ; N less ; B 120 15 613 501 ;
+C 61 ; WX 600 ; N equal ; B 96 118 614 398 ;
+C 62 ; WX 600 ; N greater ; B 97 15 589 501 ;
+C 63 ; WX 600 ; N question ; B 183 -14 592 580 ;
+C 64 ; WX 600 ; N at ; B 65 -15 642 616 ;
+C 65 ; WX 600 ; N A ; B -9 0 632 562 ;
+C 66 ; WX 600 ; N B ; B 30 0 630 562 ;
+C 67 ; WX 600 ; N C ; B 74 -18 675 580 ;
+C 68 ; WX 600 ; N D ; B 30 0 664 562 ;
+C 69 ; WX 600 ; N E ; B 25 0 670 562 ;
+C 70 ; WX 600 ; N F ; B 39 0 684 562 ;
+C 71 ; WX 600 ; N G ; B 74 -18 675 580 ;
+C 72 ; WX 600 ; N H ; B 20 0 700 562 ;
+C 73 ; WX 600 ; N I ; B 77 0 643 562 ;
+C 74 ; WX 600 ; N J ; B 58 -18 721 562 ;
+C 75 ; WX 600 ; N K ; B 21 0 692 562 ;
+C 76 ; WX 600 ; N L ; B 39 0 636 562 ;
+C 77 ; WX 600 ; N M ; B -2 0 722 562 ;
+C 78 ; WX 600 ; N N ; B 8 -12 730 562 ;
+C 79 ; WX 600 ; N O ; B 74 -18 645 580 ;
+C 80 ; WX 600 ; N P ; B 48 0 643 562 ;
+C 81 ; WX 600 ; N Q ; B 83 -138 636 580 ;
+C 82 ; WX 600 ; N R ; B 24 0 617 562 ;
+C 83 ; WX 600 ; N S ; B 54 -22 673 582 ;
+C 84 ; WX 600 ; N T ; B 86 0 679 562 ;
+C 85 ; WX 600 ; N U ; B 101 -18 716 562 ;
+C 86 ; WX 600 ; N V ; B 84 0 733 562 ;
+C 87 ; WX 600 ; N W ; B 79 0 738 562 ;
+C 88 ; WX 600 ; N X ; B 12 0 690 562 ;
+C 89 ; WX 600 ; N Y ; B 109 0 709 562 ;
+C 90 ; WX 600 ; N Z ; B 62 0 637 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ;
+C 92 ; WX 600 ; N backslash ; B 222 -77 496 626 ;
+C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ;
+C 94 ; WX 600 ; N asciicircum ; B 171 250 556 616 ;
+C 95 ; WX 600 ; N underscore ; B -27 -125 585 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ;
+C 97 ; WX 600 ; N a ; B 61 -15 593 454 ;
+C 98 ; WX 600 ; N b ; B 13 -15 636 626 ;
+C 99 ; WX 600 ; N c ; B 81 -15 631 459 ;
+C 100 ; WX 600 ; N d ; B 60 -15 645 626 ;
+C 101 ; WX 600 ; N e ; B 81 -15 605 454 ;
+C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 40 -146 674 454 ;
+C 104 ; WX 600 ; N h ; B 18 0 615 626 ;
+C 105 ; WX 600 ; N i ; B 77 0 546 658 ;
+C 106 ; WX 600 ; N j ; B 36 -146 580 658 ;
+C 107 ; WX 600 ; N k ; B 33 0 643 626 ;
+C 108 ; WX 600 ; N l ; B 77 0 546 626 ;
+C 109 ; WX 600 ; N m ; B -22 0 649 454 ;
+C 110 ; WX 600 ; N n ; B 18 0 615 454 ;
+C 111 ; WX 600 ; N o ; B 71 -15 622 454 ;
+C 112 ; WX 600 ; N p ; B -32 -142 622 454 ;
+C 113 ; WX 600 ; N q ; B 60 -142 685 454 ;
+C 114 ; WX 600 ; N r ; B 47 0 655 454 ;
+C 115 ; WX 600 ; N s ; B 66 -17 608 459 ;
+C 116 ; WX 600 ; N t ; B 118 -15 567 562 ;
+C 117 ; WX 600 ; N u ; B 70 -15 592 439 ;
+C 118 ; WX 600 ; N v ; B 70 0 695 439 ;
+C 119 ; WX 600 ; N w ; B 53 0 712 439 ;
+C 120 ; WX 600 ; N x ; B 6 0 671 439 ;
+C 121 ; WX 600 ; N y ; B -21 -142 695 439 ;
+C 122 ; WX 600 ; N z ; B 81 0 614 439 ;
+C 123 ; WX 600 ; N braceleft ; B 203 -102 595 616 ;
+C 124 ; WX 600 ; N bar ; B 201 -250 505 750 ;
+C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ;
+C 126 ; WX 600 ; N asciitilde ; B 120 153 590 356 ;
+C 161 ; WX 600 ; N exclamdown ; B 196 -146 477 449 ;
+C 162 ; WX 600 ; N cent ; B 121 -49 605 614 ;
+C 163 ; WX 600 ; N sterling ; B 106 -28 650 611 ;
+C 164 ; WX 600 ; N fraction ; B 22 -60 708 661 ;
+C 165 ; WX 600 ; N yen ; B 98 0 710 562 ;
+C 166 ; WX 600 ; N florin ; B -57 -131 702 616 ;
+C 167 ; WX 600 ; N section ; B 74 -70 620 580 ;
+C 168 ; WX 600 ; N currency ; B 77 49 644 517 ;
+C 169 ; WX 600 ; N quotesingle ; B 303 277 493 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 62 70 639 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 195 70 545 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 165 70 514 446 ;
+C 174 ; WX 600 ; N fi ; B 12 0 644 626 ;
+C 175 ; WX 600 ; N fl ; B 12 0 644 626 ;
+C 177 ; WX 600 ; N endash ; B 108 203 602 313 ;
+C 178 ; WX 600 ; N dagger ; B 175 -70 586 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 121 -70 587 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 248 165 461 351 ;
+C 182 ; WX 600 ; N paragraph ; B 61 -70 700 580 ;
+C 183 ; WX 600 ; N bullet ; B 196 132 523 430 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 144 -142 458 143 ;
+C 185 ; WX 600 ; N quotedblbase ; B 34 -142 560 143 ;
+C 186 ; WX 600 ; N quotedblright ; B 119 277 645 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 71 70 647 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 35 -15 587 116 ;
+C 189 ; WX 600 ; N perthousand ; B -45 -15 743 616 ;
+C 191 ; WX 600 ; N questiondown ; B 100 -146 509 449 ;
+C 193 ; WX 600 ; N grave ; B 272 508 503 661 ;
+C 194 ; WX 600 ; N acute ; B 312 508 609 661 ;
+C 195 ; WX 600 ; N circumflex ; B 212 483 607 657 ;
+C 196 ; WX 600 ; N tilde ; B 199 493 643 636 ;
+C 197 ; WX 600 ; N macron ; B 195 505 637 585 ;
+C 198 ; WX 600 ; N breve ; B 217 468 652 631 ;
+C 199 ; WX 600 ; N dotaccent ; B 348 498 493 638 ;
+C 200 ; WX 600 ; N dieresis ; B 246 498 595 638 ;
+C 202 ; WX 600 ; N ring ; B 319 481 528 678 ;
+C 203 ; WX 600 ; N cedilla ; B 168 -206 368 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 171 488 729 661 ;
+C 206 ; WX 600 ; N ogonek ; B 143 -199 367 0 ;
+C 207 ; WX 600 ; N caron ; B 238 493 633 667 ;
+C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ;
+C 225 ; WX 600 ; N AE ; B -29 0 708 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 188 196 526 580 ;
+C 232 ; WX 600 ; N Lslash ; B 39 0 636 562 ;
+C 233 ; WX 600 ; N Oslash ; B 48 -22 673 584 ;
+C 234 ; WX 600 ; N OE ; B 26 0 701 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 188 196 543 580 ;
+C 241 ; WX 600 ; N ae ; B 21 -15 652 454 ;
+C 245 ; WX 600 ; N dotlessi ; B 77 0 546 439 ;
+C 248 ; WX 600 ; N lslash ; B 77 0 587 626 ;
+C 249 ; WX 600 ; N oslash ; B 54 -24 638 463 ;
+C 250 ; WX 600 ; N oe ; B 18 -15 662 454 ;
+C 251 ; WX 600 ; N germandbls ; B 22 -15 629 626 ;
+C -1 ; WX 600 ; N Idieresis ; B 77 0 643 761 ;
+C -1 ; WX 600 ; N eacute ; B 81 -15 609 661 ;
+C -1 ; WX 600 ; N abreve ; B 61 -15 658 661 ;
+C -1 ; WX 600 ; N uhungarumlaut ; B 70 -15 769 661 ;
+C -1 ; WX 600 ; N ecaron ; B 81 -15 633 667 ;
+C -1 ; WX 600 ; N Ydieresis ; B 109 0 709 761 ;
+C -1 ; WX 600 ; N divide ; B 114 16 596 500 ;
+C -1 ; WX 600 ; N Yacute ; B 109 0 709 784 ;
+C -1 ; WX 600 ; N Acircumflex ; B -9 0 632 780 ;
+C -1 ; WX 600 ; N aacute ; B 61 -15 609 661 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 716 780 ;
+C -1 ; WX 600 ; N yacute ; B -21 -142 695 661 ;
+C -1 ; WX 600 ; N scommaaccent ; B 66 -250 608 459 ;
+C -1 ; WX 600 ; N ecircumflex ; B 81 -15 607 657 ;
+C -1 ; WX 600 ; N Uring ; B 101 -18 716 801 ;
+C -1 ; WX 600 ; N Udieresis ; B 101 -18 716 761 ;
+C -1 ; WX 600 ; N aogonek ; B 61 -199 593 454 ;
+C -1 ; WX 600 ; N Uacute ; B 101 -18 716 784 ;
+C -1 ; WX 600 ; N uogonek ; B 70 -199 592 439 ;
+C -1 ; WX 600 ; N Edieresis ; B 25 0 670 761 ;
+C -1 ; WX 600 ; N Dcroat ; B 30 0 664 562 ;
+C -1 ; WX 600 ; N commaaccent ; B 151 -250 385 -57 ;
+C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N Emacron ; B 25 0 670 708 ;
+C -1 ; WX 600 ; N ccaron ; B 81 -15 633 667 ;
+C -1 ; WX 600 ; N aring ; B 61 -15 593 678 ;
+C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 730 562 ;
+C -1 ; WX 600 ; N lacute ; B 77 0 639 801 ;
+C -1 ; WX 600 ; N agrave ; B 61 -15 593 661 ;
+C -1 ; WX 600 ; N Tcommaaccent ; B 86 -250 679 562 ;
+C -1 ; WX 600 ; N Cacute ; B 74 -18 675 784 ;
+C -1 ; WX 600 ; N atilde ; B 61 -15 643 636 ;
+C -1 ; WX 600 ; N Edotaccent ; B 25 0 670 761 ;
+C -1 ; WX 600 ; N scaron ; B 66 -17 633 667 ;
+C -1 ; WX 600 ; N scedilla ; B 66 -206 608 459 ;
+C -1 ; WX 600 ; N iacute ; B 77 0 609 661 ;
+C -1 ; WX 600 ; N lozenge ; B 145 0 614 740 ;
+C -1 ; WX 600 ; N Rcaron ; B 24 0 659 790 ;
+C -1 ; WX 600 ; N Gcommaaccent ; B 74 -250 675 580 ;
+C -1 ; WX 600 ; N ucircumflex ; B 70 -15 597 657 ;
+C -1 ; WX 600 ; N acircumflex ; B 61 -15 607 657 ;
+C -1 ; WX 600 ; N Amacron ; B -9 0 633 708 ;
+C -1 ; WX 600 ; N rcaron ; B 47 0 655 667 ;
+C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ;
+C -1 ; WX 600 ; N Zdotaccent ; B 62 0 637 761 ;
+C -1 ; WX 600 ; N Thorn ; B 48 0 620 562 ;
+C -1 ; WX 600 ; N Omacron ; B 74 -18 663 708 ;
+C -1 ; WX 600 ; N Racute ; B 24 0 665 784 ;
+C -1 ; WX 600 ; N Sacute ; B 54 -22 673 784 ;
+C -1 ; WX 600 ; N dcaron ; B 60 -15 861 626 ;
+C -1 ; WX 600 ; N Umacron ; B 101 -18 716 708 ;
+C -1 ; WX 600 ; N uring ; B 70 -15 592 678 ;
+C -1 ; WX 600 ; N threebaseior ; B 193 222 526 616 ;
+C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ;
+C -1 ; WX 600 ; N Agrave ; B -9 0 632 784 ;
+C -1 ; WX 600 ; N Abreve ; B -9 0 684 784 ;
+C -1 ; WX 600 ; N multiply ; B 104 39 606 478 ;
+C -1 ; WX 600 ; N uacute ; B 70 -15 599 661 ;
+C -1 ; WX 600 ; N Tcaron ; B 86 0 679 790 ;
+C -1 ; WX 600 ; N partialdiff ; B 91 -38 627 728 ;
+C -1 ; WX 600 ; N ydieresis ; B -21 -142 695 638 ;
+C -1 ; WX 600 ; N Nacute ; B 8 -12 730 784 ;
+C -1 ; WX 600 ; N icircumflex ; B 77 0 577 657 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 25 0 670 780 ;
+C -1 ; WX 600 ; N adieresis ; B 61 -15 595 638 ;
+C -1 ; WX 600 ; N edieresis ; B 81 -15 605 638 ;
+C -1 ; WX 600 ; N cacute ; B 81 -15 649 661 ;
+C -1 ; WX 600 ; N nacute ; B 18 0 639 661 ;
+C -1 ; WX 600 ; N umacron ; B 70 -15 637 585 ;
+C -1 ; WX 600 ; N Ncaron ; B 8 -12 730 790 ;
+C -1 ; WX 600 ; N Iacute ; B 77 0 643 784 ;
+C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ;
+C -1 ; WX 600 ; N brokenbar ; B 217 -175 489 675 ;
+C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N Gbreve ; B 74 -18 684 784 ;
+C -1 ; WX 600 ; N Idotaccent ; B 77 0 643 761 ;
+C -1 ; WX 600 ; N summation ; B 15 -10 672 706 ;
+C -1 ; WX 600 ; N Egrave ; B 25 0 670 784 ;
+C -1 ; WX 600 ; N racute ; B 47 0 655 661 ;
+C -1 ; WX 600 ; N omacron ; B 71 -15 637 585 ;
+C -1 ; WX 600 ; N Zacute ; B 62 0 665 784 ;
+C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ;
+C -1 ; WX 600 ; N greaterequal ; B 26 0 627 696 ;
+C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ;
+C -1 ; WX 600 ; N Ccedilla ; B 74 -206 675 580 ;
+C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 546 626 ;
+C -1 ; WX 600 ; N tcaron ; B 118 -15 627 703 ;
+C -1 ; WX 600 ; N eogonek ; B 81 -199 605 454 ;
+C -1 ; WX 600 ; N Uogonek ; B 101 -199 716 562 ;
+C -1 ; WX 600 ; N Aacute ; B -9 0 655 784 ;
+C -1 ; WX 600 ; N Adieresis ; B -9 0 632 761 ;
+C -1 ; WX 600 ; N egrave ; B 81 -15 605 661 ;
+C -1 ; WX 600 ; N zacute ; B 81 0 614 661 ;
+C -1 ; WX 600 ; N iogonek ; B 77 -199 546 658 ;
+C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ;
+C -1 ; WX 600 ; N oacute ; B 71 -15 649 661 ;
+C -1 ; WX 600 ; N amacron ; B 61 -15 637 585 ;
+C -1 ; WX 600 ; N sacute ; B 66 -17 609 661 ;
+C -1 ; WX 600 ; N idieresis ; B 77 0 561 618 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ;
+C -1 ; WX 600 ; N Ugrave ; B 101 -18 716 784 ;
+C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ;
+C -1 ; WX 600 ; N thorn ; B -32 -142 622 626 ;
+C -1 ; WX 600 ; N twobaseior ; B 191 230 542 616 ;
+C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 761 ;
+C -1 ; WX 600 ; N mu ; B 49 -142 592 439 ;
+C -1 ; WX 600 ; N igrave ; B 77 0 546 661 ;
+C -1 ; WX 600 ; N ohungarumlaut ; B 71 -15 809 661 ;
+C -1 ; WX 600 ; N Eogonek ; B 25 -199 670 562 ;
+C -1 ; WX 600 ; N dcroat ; B 60 -15 712 626 ;
+C -1 ; WX 600 ; N threequarters ; B 8 -60 699 661 ;
+C -1 ; WX 600 ; N Scedilla ; B 54 -206 673 582 ;
+C -1 ; WX 600 ; N lcaron ; B 77 0 731 626 ;
+C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 692 562 ;
+C -1 ; WX 600 ; N Lacute ; B 39 0 636 784 ;
+C -1 ; WX 600 ; N trademark ; B 86 230 869 562 ;
+C -1 ; WX 600 ; N edotaccent ; B 81 -15 605 638 ;
+C -1 ; WX 600 ; N Igrave ; B 77 0 643 784 ;
+C -1 ; WX 600 ; N Imacron ; B 77 0 663 708 ;
+C -1 ; WX 600 ; N Lcaron ; B 39 0 757 562 ;
+C -1 ; WX 600 ; N onehalf ; B 22 -60 716 661 ;
+C -1 ; WX 600 ; N lessequal ; B 26 0 671 696 ;
+C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ;
+C -1 ; WX 600 ; N ntilde ; B 18 0 643 636 ;
+C -1 ; WX 600 ; N Uhungarumlaut ; B 101 -18 805 784 ;
+C -1 ; WX 600 ; N Eacute ; B 25 0 670 784 ;
+C -1 ; WX 600 ; N emacron ; B 81 -15 637 585 ;
+C -1 ; WX 600 ; N gbreve ; B 40 -146 674 661 ;
+C -1 ; WX 600 ; N onequarter ; B 13 -60 707 661 ;
+C -1 ; WX 600 ; N Scaron ; B 54 -22 689 790 ;
+C -1 ; WX 600 ; N Scommaaccent ; B 54 -250 673 582 ;
+C -1 ; WX 600 ; N Ohungarumlaut ; B 74 -18 795 784 ;
+C -1 ; WX 600 ; N degree ; B 173 243 570 616 ;
+C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ;
+C -1 ; WX 600 ; N Ccaron ; B 74 -18 689 790 ;
+C -1 ; WX 600 ; N ugrave ; B 70 -15 592 661 ;
+C -1 ; WX 600 ; N radical ; B 67 -104 635 778 ;
+C -1 ; WX 600 ; N Dcaron ; B 30 0 664 790 ;
+C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 655 454 ;
+C -1 ; WX 600 ; N Ntilde ; B 8 -12 730 759 ;
+C -1 ; WX 600 ; N otilde ; B 71 -15 643 636 ;
+C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 617 562 ;
+C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 636 562 ;
+C -1 ; WX 600 ; N Atilde ; B -9 0 669 759 ;
+C -1 ; WX 600 ; N Aogonek ; B -9 -199 632 562 ;
+C -1 ; WX 600 ; N Aring ; B -9 0 632 801 ;
+C -1 ; WX 600 ; N Otilde ; B 74 -18 669 759 ;
+C -1 ; WX 600 ; N zdotaccent ; B 81 0 614 638 ;
+C -1 ; WX 600 ; N Ecaron ; B 25 0 670 790 ;
+C -1 ; WX 600 ; N Iogonek ; B 77 -199 643 562 ;
+C -1 ; WX 600 ; N kcommaaccent ; B 33 -250 643 626 ;
+C -1 ; WX 600 ; N minus ; B 114 203 596 313 ;
+C -1 ; WX 600 ; N Icircumflex ; B 77 0 643 780 ;
+C -1 ; WX 600 ; N ncaron ; B 18 0 633 667 ;
+C -1 ; WX 600 ; N tcommaaccent ; B 118 -250 567 562 ;
+C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ;
+C -1 ; WX 600 ; N odieresis ; B 71 -15 622 638 ;
+C -1 ; WX 600 ; N udieresis ; B 70 -15 595 638 ;
+C -1 ; WX 600 ; N notequal ; B 30 -47 626 563 ;
+C -1 ; WX 600 ; N gcommaaccent ; B 40 -146 674 714 ;
+C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ;
+C -1 ; WX 600 ; N zcaron ; B 81 0 643 667 ;
+C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 615 454 ;
+C -1 ; WX 600 ; N onebaseior ; B 212 230 514 616 ;
+C -1 ; WX 600 ; N imacron ; B 77 0 575 585 ;
+C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Courier-Oblique.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Courier-Oblique.afm
new file mode 100644
index 0000000..def637d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Courier-Oblique.afm
@@ -0,0 +1,342 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 17:37:52 1997
+Comment UniqueID 43051
+Comment VMusage 16248 75829
+FontName Courier-Oblique
+FullName Courier Oblique
+FamilyName Courier
+Weight Medium
+ItalicAngle -12
+IsFixedPitch true
+CharacterSet ExtendedRoman
+FontBBox -27 -250 849 805
+UnderlinePosition -100
+UnderlineThickness 50
+Version 003.000
+Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 426
+Ascender 629
+Descender -157
+StdHW 51
+StdVW 51
+StartCharMetrics 315
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ;
+C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ;
+C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ;
+C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ;
+C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ;
+C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ;
+C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ;
+C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ;
+C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ;
+C 43 ; WX 600 ; N plus ; B 129 44 580 470 ;
+C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ;
+C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ;
+C 46 ; WX 600 ; N period ; B 238 -15 382 109 ;
+C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ;
+C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ;
+C 49 ; WX 600 ; N one ; B 98 0 515 622 ;
+C 50 ; WX 600 ; N two ; B 70 0 568 622 ;
+C 51 ; WX 600 ; N three ; B 82 -15 538 622 ;
+C 52 ; WX 600 ; N four ; B 108 0 541 622 ;
+C 53 ; WX 600 ; N five ; B 99 -15 589 607 ;
+C 54 ; WX 600 ; N six ; B 155 -15 629 622 ;
+C 55 ; WX 600 ; N seven ; B 182 0 612 607 ;
+C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ;
+C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ;
+C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ;
+C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ;
+C 60 ; WX 600 ; N less ; B 96 42 610 472 ;
+C 61 ; WX 600 ; N equal ; B 109 138 600 376 ;
+C 62 ; WX 600 ; N greater ; B 85 42 599 472 ;
+C 63 ; WX 600 ; N question ; B 222 -15 583 572 ;
+C 64 ; WX 600 ; N at ; B 127 -15 582 622 ;
+C 65 ; WX 600 ; N A ; B 3 0 607 562 ;
+C 66 ; WX 600 ; N B ; B 43 0 616 562 ;
+C 67 ; WX 600 ; N C ; B 93 -18 655 580 ;
+C 68 ; WX 600 ; N D ; B 43 0 645 562 ;
+C 69 ; WX 600 ; N E ; B 53 0 660 562 ;
+C 70 ; WX 600 ; N F ; B 53 0 660 562 ;
+C 71 ; WX 600 ; N G ; B 83 -18 645 580 ;
+C 72 ; WX 600 ; N H ; B 32 0 687 562 ;
+C 73 ; WX 600 ; N I ; B 96 0 623 562 ;
+C 74 ; WX 600 ; N J ; B 52 -18 685 562 ;
+C 75 ; WX 600 ; N K ; B 38 0 671 562 ;
+C 76 ; WX 600 ; N L ; B 47 0 607 562 ;
+C 77 ; WX 600 ; N M ; B 4 0 715 562 ;
+C 78 ; WX 600 ; N N ; B 7 -13 712 562 ;
+C 79 ; WX 600 ; N O ; B 94 -18 625 580 ;
+C 80 ; WX 600 ; N P ; B 79 0 644 562 ;
+C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ;
+C 82 ; WX 600 ; N R ; B 38 0 598 562 ;
+C 83 ; WX 600 ; N S ; B 76 -20 650 580 ;
+C 84 ; WX 600 ; N T ; B 108 0 665 562 ;
+C 85 ; WX 600 ; N U ; B 125 -18 702 562 ;
+C 86 ; WX 600 ; N V ; B 105 -13 723 562 ;
+C 87 ; WX 600 ; N W ; B 106 -13 722 562 ;
+C 88 ; WX 600 ; N X ; B 23 0 675 562 ;
+C 89 ; WX 600 ; N Y ; B 133 0 695 562 ;
+C 90 ; WX 600 ; N Z ; B 86 0 610 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ;
+C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ;
+C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ;
+C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ;
+C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ;
+C 97 ; WX 600 ; N a ; B 76 -15 569 441 ;
+C 98 ; WX 600 ; N b ; B 29 -15 625 629 ;
+C 99 ; WX 600 ; N c ; B 106 -15 608 441 ;
+C 100 ; WX 600 ; N d ; B 85 -15 640 629 ;
+C 101 ; WX 600 ; N e ; B 106 -15 598 441 ;
+C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 61 -157 657 441 ;
+C 104 ; WX 600 ; N h ; B 33 0 592 629 ;
+C 105 ; WX 600 ; N i ; B 95 0 515 657 ;
+C 106 ; WX 600 ; N j ; B 52 -157 550 657 ;
+C 107 ; WX 600 ; N k ; B 58 0 633 629 ;
+C 108 ; WX 600 ; N l ; B 95 0 515 629 ;
+C 109 ; WX 600 ; N m ; B -5 0 615 441 ;
+C 110 ; WX 600 ; N n ; B 26 0 585 441 ;
+C 111 ; WX 600 ; N o ; B 102 -15 588 441 ;
+C 112 ; WX 600 ; N p ; B -24 -157 605 441 ;
+C 113 ; WX 600 ; N q ; B 85 -157 682 441 ;
+C 114 ; WX 600 ; N r ; B 60 0 636 441 ;
+C 115 ; WX 600 ; N s ; B 78 -15 584 441 ;
+C 116 ; WX 600 ; N t ; B 167 -15 561 561 ;
+C 117 ; WX 600 ; N u ; B 101 -15 572 426 ;
+C 118 ; WX 600 ; N v ; B 90 -10 681 426 ;
+C 119 ; WX 600 ; N w ; B 76 -10 695 426 ;
+C 120 ; WX 600 ; N x ; B 20 0 655 426 ;
+C 121 ; WX 600 ; N y ; B -4 -157 683 426 ;
+C 122 ; WX 600 ; N z ; B 99 0 593 426 ;
+C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ;
+C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ;
+C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ;
+C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ;
+C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ;
+C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ;
+C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ;
+C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ;
+C 165 ; WX 600 ; N yen ; B 120 0 693 562 ;
+C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ;
+C 167 ; WX 600 ; N section ; B 104 -78 590 580 ;
+C 168 ; WX 600 ; N currency ; B 94 58 628 506 ;
+C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ;
+C 174 ; WX 600 ; N fi ; B 3 0 619 629 ;
+C 175 ; WX 600 ; N fl ; B 3 0 619 629 ;
+C 177 ; WX 600 ; N endash ; B 124 231 586 285 ;
+C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ;
+C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ;
+C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ;
+C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ;
+C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ;
+C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ;
+C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ;
+C 193 ; WX 600 ; N grave ; B 294 497 484 672 ;
+C 194 ; WX 600 ; N acute ; B 348 497 612 672 ;
+C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ;
+C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ;
+C 197 ; WX 600 ; N macron ; B 232 525 600 565 ;
+C 198 ; WX 600 ; N breve ; B 279 501 576 609 ;
+C 199 ; WX 600 ; N dotaccent ; B 373 537 478 640 ;
+C 200 ; WX 600 ; N dieresis ; B 272 537 579 640 ;
+C 202 ; WX 600 ; N ring ; B 332 463 500 627 ;
+C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ;
+C 206 ; WX 600 ; N ogonek ; B 189 -172 377 4 ;
+C 207 ; WX 600 ; N caron ; B 262 492 614 669 ;
+C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ;
+C 225 ; WX 600 ; N AE ; B 3 0 655 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ;
+C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ;
+C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ;
+C 234 ; WX 600 ; N OE ; B 59 0 672 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ;
+C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ;
+C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ;
+C 248 ; WX 600 ; N lslash ; B 95 0 587 629 ;
+C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ;
+C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ;
+C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ;
+C -1 ; WX 600 ; N Idieresis ; B 96 0 623 753 ;
+C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ;
+C -1 ; WX 600 ; N abreve ; B 76 -15 576 609 ;
+C -1 ; WX 600 ; N uhungarumlaut ; B 101 -15 723 672 ;
+C -1 ; WX 600 ; N ecaron ; B 106 -15 614 669 ;
+C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 753 ;
+C -1 ; WX 600 ; N divide ; B 136 48 573 467 ;
+C -1 ; WX 600 ; N Yacute ; B 133 0 695 805 ;
+C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 787 ;
+C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 787 ;
+C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ;
+C -1 ; WX 600 ; N scommaaccent ; B 78 -250 584 441 ;
+C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ;
+C -1 ; WX 600 ; N Uring ; B 125 -18 702 760 ;
+C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 753 ;
+C -1 ; WX 600 ; N aogonek ; B 76 -172 569 441 ;
+C -1 ; WX 600 ; N Uacute ; B 125 -18 702 805 ;
+C -1 ; WX 600 ; N uogonek ; B 101 -172 572 426 ;
+C -1 ; WX 600 ; N Edieresis ; B 53 0 660 753 ;
+C -1 ; WX 600 ; N Dcroat ; B 43 0 645 562 ;
+C -1 ; WX 600 ; N commaaccent ; B 145 -250 323 -58 ;
+C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N Emacron ; B 53 0 660 698 ;
+C -1 ; WX 600 ; N ccaron ; B 106 -15 614 669 ;
+C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ;
+C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 712 562 ;
+C -1 ; WX 600 ; N lacute ; B 95 0 640 805 ;
+C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ;
+C -1 ; WX 600 ; N Tcommaaccent ; B 108 -250 665 562 ;
+C -1 ; WX 600 ; N Cacute ; B 93 -18 655 805 ;
+C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ;
+C -1 ; WX 600 ; N Edotaccent ; B 53 0 660 753 ;
+C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ;
+C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ;
+C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ;
+C -1 ; WX 600 ; N lozenge ; B 94 0 519 706 ;
+C -1 ; WX 600 ; N Rcaron ; B 38 0 642 802 ;
+C -1 ; WX 600 ; N Gcommaaccent ; B 83 -250 645 580 ;
+C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ;
+C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ;
+C -1 ; WX 600 ; N Amacron ; B 3 0 607 698 ;
+C -1 ; WX 600 ; N rcaron ; B 60 0 636 669 ;
+C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ;
+C -1 ; WX 600 ; N Zdotaccent ; B 86 0 610 753 ;
+C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ;
+C -1 ; WX 600 ; N Omacron ; B 94 -18 628 698 ;
+C -1 ; WX 600 ; N Racute ; B 38 0 670 805 ;
+C -1 ; WX 600 ; N Sacute ; B 76 -20 650 805 ;
+C -1 ; WX 600 ; N dcaron ; B 85 -15 849 629 ;
+C -1 ; WX 600 ; N Umacron ; B 125 -18 702 698 ;
+C -1 ; WX 600 ; N uring ; B 101 -15 572 627 ;
+C -1 ; WX 600 ; N threebaseior ; B 213 240 501 622 ;
+C -1 ; WX 600 ; N Ograve ; B 94 -18 625 805 ;
+C -1 ; WX 600 ; N Agrave ; B 3 0 607 805 ;
+C -1 ; WX 600 ; N Abreve ; B 3 0 607 732 ;
+C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ;
+C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ;
+C -1 ; WX 600 ; N Tcaron ; B 108 0 665 802 ;
+C -1 ; WX 600 ; N partialdiff ; B 45 -38 546 710 ;
+C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 620 ;
+C -1 ; WX 600 ; N Nacute ; B 7 -13 712 805 ;
+C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 787 ;
+C -1 ; WX 600 ; N adieresis ; B 76 -15 575 620 ;
+C -1 ; WX 600 ; N edieresis ; B 106 -15 598 620 ;
+C -1 ; WX 600 ; N cacute ; B 106 -15 612 672 ;
+C -1 ; WX 600 ; N nacute ; B 26 0 602 672 ;
+C -1 ; WX 600 ; N umacron ; B 101 -15 600 565 ;
+C -1 ; WX 600 ; N Ncaron ; B 7 -13 712 802 ;
+C -1 ; WX 600 ; N Iacute ; B 96 0 640 805 ;
+C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ;
+C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ;
+C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N Gbreve ; B 83 -18 645 732 ;
+C -1 ; WX 600 ; N Idotaccent ; B 96 0 623 753 ;
+C -1 ; WX 600 ; N summation ; B 15 -10 670 706 ;
+C -1 ; WX 600 ; N Egrave ; B 53 0 660 805 ;
+C -1 ; WX 600 ; N racute ; B 60 0 636 672 ;
+C -1 ; WX 600 ; N omacron ; B 102 -15 600 565 ;
+C -1 ; WX 600 ; N Zacute ; B 86 0 670 805 ;
+C -1 ; WX 600 ; N Zcaron ; B 86 0 642 802 ;
+C -1 ; WX 600 ; N greaterequal ; B 98 0 594 710 ;
+C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ;
+C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ;
+C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 515 629 ;
+C -1 ; WX 600 ; N tcaron ; B 167 -15 587 717 ;
+C -1 ; WX 600 ; N eogonek ; B 106 -172 598 441 ;
+C -1 ; WX 600 ; N Uogonek ; B 124 -172 702 562 ;
+C -1 ; WX 600 ; N Aacute ; B 3 0 660 805 ;
+C -1 ; WX 600 ; N Adieresis ; B 3 0 607 753 ;
+C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ;
+C -1 ; WX 600 ; N zacute ; B 99 0 612 672 ;
+C -1 ; WX 600 ; N iogonek ; B 95 -172 515 657 ;
+C -1 ; WX 600 ; N Oacute ; B 94 -18 640 805 ;
+C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ;
+C -1 ; WX 600 ; N amacron ; B 76 -15 600 565 ;
+C -1 ; WX 600 ; N sacute ; B 78 -15 612 672 ;
+C -1 ; WX 600 ; N idieresis ; B 95 0 545 620 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 787 ;
+C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 805 ;
+C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ;
+C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ;
+C -1 ; WX 600 ; N twobaseior ; B 230 249 535 622 ;
+C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 753 ;
+C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ;
+C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ;
+C -1 ; WX 600 ; N ohungarumlaut ; B 102 -15 723 672 ;
+C -1 ; WX 600 ; N Eogonek ; B 53 -172 660 562 ;
+C -1 ; WX 600 ; N dcroat ; B 85 -15 704 629 ;
+C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ;
+C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ;
+C -1 ; WX 600 ; N lcaron ; B 95 0 667 629 ;
+C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 671 562 ;
+C -1 ; WX 600 ; N Lacute ; B 47 0 607 805 ;
+C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ;
+C -1 ; WX 600 ; N edotaccent ; B 106 -15 598 620 ;
+C -1 ; WX 600 ; N Igrave ; B 96 0 623 805 ;
+C -1 ; WX 600 ; N Imacron ; B 96 0 628 698 ;
+C -1 ; WX 600 ; N Lcaron ; B 47 0 632 562 ;
+C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ;
+C -1 ; WX 600 ; N lessequal ; B 98 0 645 710 ;
+C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ;
+C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ;
+C -1 ; WX 600 ; N Uhungarumlaut ; B 125 -18 761 805 ;
+C -1 ; WX 600 ; N Eacute ; B 53 0 670 805 ;
+C -1 ; WX 600 ; N emacron ; B 106 -15 600 565 ;
+C -1 ; WX 600 ; N gbreve ; B 61 -157 657 609 ;
+C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ;
+C -1 ; WX 600 ; N Scaron ; B 76 -20 672 802 ;
+C -1 ; WX 600 ; N Scommaaccent ; B 76 -250 650 580 ;
+C -1 ; WX 600 ; N Ohungarumlaut ; B 94 -18 751 805 ;
+C -1 ; WX 600 ; N degree ; B 214 269 576 622 ;
+C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ;
+C -1 ; WX 600 ; N Ccaron ; B 93 -18 672 802 ;
+C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ;
+C -1 ; WX 600 ; N radical ; B 85 -15 765 792 ;
+C -1 ; WX 600 ; N Dcaron ; B 43 0 645 802 ;
+C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 636 441 ;
+C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 729 ;
+C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ;
+C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 598 562 ;
+C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 607 562 ;
+C -1 ; WX 600 ; N Atilde ; B 3 0 655 729 ;
+C -1 ; WX 600 ; N Aogonek ; B 3 -172 607 562 ;
+C -1 ; WX 600 ; N Aring ; B 3 0 607 750 ;
+C -1 ; WX 600 ; N Otilde ; B 94 -18 655 729 ;
+C -1 ; WX 600 ; N zdotaccent ; B 99 0 593 620 ;
+C -1 ; WX 600 ; N Ecaron ; B 53 0 660 802 ;
+C -1 ; WX 600 ; N Iogonek ; B 96 -172 623 562 ;
+C -1 ; WX 600 ; N kcommaaccent ; B 58 -250 633 629 ;
+C -1 ; WX 600 ; N minus ; B 129 232 580 283 ;
+C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 787 ;
+C -1 ; WX 600 ; N ncaron ; B 26 0 614 669 ;
+C -1 ; WX 600 ; N tcommaaccent ; B 165 -250 561 561 ;
+C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ;
+C -1 ; WX 600 ; N odieresis ; B 102 -15 588 620 ;
+C -1 ; WX 600 ; N udieresis ; B 101 -15 575 620 ;
+C -1 ; WX 600 ; N notequal ; B 43 -16 621 529 ;
+C -1 ; WX 600 ; N gcommaaccent ; B 61 -157 657 708 ;
+C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ;
+C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ;
+C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 585 441 ;
+C -1 ; WX 600 ; N onebaseior ; B 231 249 491 622 ;
+C -1 ; WX 600 ; N imacron ; B 95 0 543 565 ;
+C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Courier.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Courier.afm
new file mode 100644
index 0000000..1d23d2e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Courier.afm
@@ -0,0 +1,342 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 17:27:09 1997
+Comment UniqueID 43050
+Comment VMusage 39754 50779
+FontName Courier
+FullName Courier
+FamilyName Courier
+Weight Medium
+ItalicAngle 0
+IsFixedPitch true
+CharacterSet ExtendedRoman
+FontBBox -23 -250 715 805
+UnderlinePosition -100
+UnderlineThickness 50
+Version 003.000
+Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 426
+Ascender 629
+Descender -157
+StdHW 51
+StdVW 51
+StartCharMetrics 315
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ;
+C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ;
+C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ;
+C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ;
+C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ;
+C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ;
+C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ;
+C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ;
+C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ;
+C 43 ; WX 600 ; N plus ; B 80 44 520 470 ;
+C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ;
+C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ;
+C 46 ; WX 600 ; N period ; B 229 -15 371 109 ;
+C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ;
+C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ;
+C 49 ; WX 600 ; N one ; B 96 0 505 622 ;
+C 50 ; WX 600 ; N two ; B 70 0 471 622 ;
+C 51 ; WX 600 ; N three ; B 75 -15 466 622 ;
+C 52 ; WX 600 ; N four ; B 78 0 500 622 ;
+C 53 ; WX 600 ; N five ; B 92 -15 497 607 ;
+C 54 ; WX 600 ; N six ; B 111 -15 497 622 ;
+C 55 ; WX 600 ; N seven ; B 82 0 483 607 ;
+C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ;
+C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ;
+C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ;
+C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ;
+C 60 ; WX 600 ; N less ; B 41 42 519 472 ;
+C 61 ; WX 600 ; N equal ; B 80 138 520 376 ;
+C 62 ; WX 600 ; N greater ; B 66 42 544 472 ;
+C 63 ; WX 600 ; N question ; B 129 -15 492 572 ;
+C 64 ; WX 600 ; N at ; B 77 -15 533 622 ;
+C 65 ; WX 600 ; N A ; B 3 0 597 562 ;
+C 66 ; WX 600 ; N B ; B 43 0 559 562 ;
+C 67 ; WX 600 ; N C ; B 41 -18 540 580 ;
+C 68 ; WX 600 ; N D ; B 43 0 574 562 ;
+C 69 ; WX 600 ; N E ; B 53 0 550 562 ;
+C 70 ; WX 600 ; N F ; B 53 0 545 562 ;
+C 71 ; WX 600 ; N G ; B 31 -18 575 580 ;
+C 72 ; WX 600 ; N H ; B 32 0 568 562 ;
+C 73 ; WX 600 ; N I ; B 96 0 504 562 ;
+C 74 ; WX 600 ; N J ; B 34 -18 566 562 ;
+C 75 ; WX 600 ; N K ; B 38 0 582 562 ;
+C 76 ; WX 600 ; N L ; B 47 0 554 562 ;
+C 77 ; WX 600 ; N M ; B 4 0 596 562 ;
+C 78 ; WX 600 ; N N ; B 7 -13 593 562 ;
+C 79 ; WX 600 ; N O ; B 43 -18 557 580 ;
+C 80 ; WX 600 ; N P ; B 79 0 558 562 ;
+C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ;
+C 82 ; WX 600 ; N R ; B 38 0 588 562 ;
+C 83 ; WX 600 ; N S ; B 72 -20 529 580 ;
+C 84 ; WX 600 ; N T ; B 38 0 563 562 ;
+C 85 ; WX 600 ; N U ; B 17 -18 583 562 ;
+C 86 ; WX 600 ; N V ; B -4 -13 604 562 ;
+C 87 ; WX 600 ; N W ; B -3 -13 603 562 ;
+C 88 ; WX 600 ; N X ; B 23 0 577 562 ;
+C 89 ; WX 600 ; N Y ; B 24 0 576 562 ;
+C 90 ; WX 600 ; N Z ; B 86 0 514 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ;
+C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ;
+C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ;
+C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ;
+C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ;
+C 97 ; WX 600 ; N a ; B 53 -15 559 441 ;
+C 98 ; WX 600 ; N b ; B 14 -15 575 629 ;
+C 99 ; WX 600 ; N c ; B 66 -15 529 441 ;
+C 100 ; WX 600 ; N d ; B 45 -15 591 629 ;
+C 101 ; WX 600 ; N e ; B 66 -15 548 441 ;
+C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 45 -157 566 441 ;
+C 104 ; WX 600 ; N h ; B 18 0 582 629 ;
+C 105 ; WX 600 ; N i ; B 95 0 505 657 ;
+C 106 ; WX 600 ; N j ; B 82 -157 410 657 ;
+C 107 ; WX 600 ; N k ; B 43 0 580 629 ;
+C 108 ; WX 600 ; N l ; B 95 0 505 629 ;
+C 109 ; WX 600 ; N m ; B -5 0 605 441 ;
+C 110 ; WX 600 ; N n ; B 26 0 575 441 ;
+C 111 ; WX 600 ; N o ; B 62 -15 538 441 ;
+C 112 ; WX 600 ; N p ; B 9 -157 555 441 ;
+C 113 ; WX 600 ; N q ; B 45 -157 591 441 ;
+C 114 ; WX 600 ; N r ; B 60 0 559 441 ;
+C 115 ; WX 600 ; N s ; B 80 -15 513 441 ;
+C 116 ; WX 600 ; N t ; B 87 -15 530 561 ;
+C 117 ; WX 600 ; N u ; B 21 -15 562 426 ;
+C 118 ; WX 600 ; N v ; B 10 -10 590 426 ;
+C 119 ; WX 600 ; N w ; B -4 -10 604 426 ;
+C 120 ; WX 600 ; N x ; B 20 0 580 426 ;
+C 121 ; WX 600 ; N y ; B 7 -157 592 426 ;
+C 122 ; WX 600 ; N z ; B 99 0 502 426 ;
+C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ;
+C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ;
+C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ;
+C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ;
+C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ;
+C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ;
+C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ;
+C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ;
+C 165 ; WX 600 ; N yen ; B 26 0 574 562 ;
+C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ;
+C 167 ; WX 600 ; N section ; B 113 -78 488 580 ;
+C 168 ; WX 600 ; N currency ; B 73 58 527 506 ;
+C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ;
+C 174 ; WX 600 ; N fi ; B 3 0 597 629 ;
+C 175 ; WX 600 ; N fl ; B 3 0 597 629 ;
+C 177 ; WX 600 ; N endash ; B 75 231 525 285 ;
+C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ;
+C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ;
+C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ;
+C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ;
+C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ;
+C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ;
+C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ;
+C 193 ; WX 600 ; N grave ; B 151 497 378 672 ;
+C 194 ; WX 600 ; N acute ; B 242 497 469 672 ;
+C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ;
+C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ;
+C 197 ; WX 600 ; N macron ; B 120 525 480 565 ;
+C 198 ; WX 600 ; N breve ; B 153 501 447 609 ;
+C 199 ; WX 600 ; N dotaccent ; B 249 537 352 640 ;
+C 200 ; WX 600 ; N dieresis ; B 148 537 453 640 ;
+C 202 ; WX 600 ; N ring ; B 218 463 382 627 ;
+C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ;
+C 206 ; WX 600 ; N ogonek ; B 211 -172 407 4 ;
+C 207 ; WX 600 ; N caron ; B 124 492 476 669 ;
+C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ;
+C 225 ; WX 600 ; N AE ; B 3 0 550 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ;
+C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ;
+C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ;
+C 234 ; WX 600 ; N OE ; B 7 0 567 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ;
+C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ;
+C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ;
+C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ;
+C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ;
+C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ;
+C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ;
+C -1 ; WX 600 ; N Idieresis ; B 96 0 504 753 ;
+C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ;
+C -1 ; WX 600 ; N abreve ; B 53 -15 559 609 ;
+C -1 ; WX 600 ; N uhungarumlaut ; B 21 -15 580 672 ;
+C -1 ; WX 600 ; N ecaron ; B 66 -15 548 669 ;
+C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 753 ;
+C -1 ; WX 600 ; N divide ; B 87 48 513 467 ;
+C -1 ; WX 600 ; N Yacute ; B 24 0 576 805 ;
+C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 787 ;
+C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 787 ;
+C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ;
+C -1 ; WX 600 ; N scommaaccent ; B 80 -250 513 441 ;
+C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ;
+C -1 ; WX 600 ; N Uring ; B 17 -18 583 760 ;
+C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 753 ;
+C -1 ; WX 600 ; N aogonek ; B 53 -172 587 441 ;
+C -1 ; WX 600 ; N Uacute ; B 17 -18 583 805 ;
+C -1 ; WX 600 ; N uogonek ; B 21 -172 590 426 ;
+C -1 ; WX 600 ; N Edieresis ; B 53 0 550 753 ;
+C -1 ; WX 600 ; N Dcroat ; B 30 0 574 562 ;
+C -1 ; WX 600 ; N commaaccent ; B 198 -250 335 -58 ;
+C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N Emacron ; B 53 0 550 698 ;
+C -1 ; WX 600 ; N ccaron ; B 66 -15 529 669 ;
+C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ;
+C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 593 562 ;
+C -1 ; WX 600 ; N lacute ; B 95 0 505 805 ;
+C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ;
+C -1 ; WX 600 ; N Tcommaaccent ; B 38 -250 563 562 ;
+C -1 ; WX 600 ; N Cacute ; B 41 -18 540 805 ;
+C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ;
+C -1 ; WX 600 ; N Edotaccent ; B 53 0 550 753 ;
+C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ;
+C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ;
+C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ;
+C -1 ; WX 600 ; N lozenge ; B 18 0 443 706 ;
+C -1 ; WX 600 ; N Rcaron ; B 38 0 588 802 ;
+C -1 ; WX 600 ; N Gcommaaccent ; B 31 -250 575 580 ;
+C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ;
+C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ;
+C -1 ; WX 600 ; N Amacron ; B 3 0 597 698 ;
+C -1 ; WX 600 ; N rcaron ; B 60 0 559 669 ;
+C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ;
+C -1 ; WX 600 ; N Zdotaccent ; B 86 0 514 753 ;
+C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ;
+C -1 ; WX 600 ; N Omacron ; B 43 -18 557 698 ;
+C -1 ; WX 600 ; N Racute ; B 38 0 588 805 ;
+C -1 ; WX 600 ; N Sacute ; B 72 -20 529 805 ;
+C -1 ; WX 600 ; N dcaron ; B 45 -15 715 629 ;
+C -1 ; WX 600 ; N Umacron ; B 17 -18 583 698 ;
+C -1 ; WX 600 ; N uring ; B 21 -15 562 627 ;
+C -1 ; WX 600 ; N threebaseior ; B 155 240 406 622 ;
+C -1 ; WX 600 ; N Ograve ; B 43 -18 557 805 ;
+C -1 ; WX 600 ; N Agrave ; B 3 0 597 805 ;
+C -1 ; WX 600 ; N Abreve ; B 3 0 597 732 ;
+C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ;
+C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ;
+C -1 ; WX 600 ; N Tcaron ; B 38 0 563 802 ;
+C -1 ; WX 600 ; N partialdiff ; B 17 -38 459 710 ;
+C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 620 ;
+C -1 ; WX 600 ; N Nacute ; B 7 -13 593 805 ;
+C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 787 ;
+C -1 ; WX 600 ; N adieresis ; B 53 -15 559 620 ;
+C -1 ; WX 600 ; N edieresis ; B 66 -15 548 620 ;
+C -1 ; WX 600 ; N cacute ; B 66 -15 529 672 ;
+C -1 ; WX 600 ; N nacute ; B 26 0 575 672 ;
+C -1 ; WX 600 ; N umacron ; B 21 -15 562 565 ;
+C -1 ; WX 600 ; N Ncaron ; B 7 -13 593 802 ;
+C -1 ; WX 600 ; N Iacute ; B 96 0 504 805 ;
+C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ;
+C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ;
+C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N Gbreve ; B 31 -18 575 732 ;
+C -1 ; WX 600 ; N Idotaccent ; B 96 0 504 753 ;
+C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ;
+C -1 ; WX 600 ; N Egrave ; B 53 0 550 805 ;
+C -1 ; WX 600 ; N racute ; B 60 0 559 672 ;
+C -1 ; WX 600 ; N omacron ; B 62 -15 538 565 ;
+C -1 ; WX 600 ; N Zacute ; B 86 0 514 805 ;
+C -1 ; WX 600 ; N Zcaron ; B 86 0 514 802 ;
+C -1 ; WX 600 ; N greaterequal ; B 98 0 502 710 ;
+C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ;
+C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ;
+C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 505 629 ;
+C -1 ; WX 600 ; N tcaron ; B 87 -15 530 717 ;
+C -1 ; WX 600 ; N eogonek ; B 66 -172 548 441 ;
+C -1 ; WX 600 ; N Uogonek ; B 17 -172 583 562 ;
+C -1 ; WX 600 ; N Aacute ; B 3 0 597 805 ;
+C -1 ; WX 600 ; N Adieresis ; B 3 0 597 753 ;
+C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ;
+C -1 ; WX 600 ; N zacute ; B 99 0 502 672 ;
+C -1 ; WX 600 ; N iogonek ; B 95 -172 505 657 ;
+C -1 ; WX 600 ; N Oacute ; B 43 -18 557 805 ;
+C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ;
+C -1 ; WX 600 ; N amacron ; B 53 -15 559 565 ;
+C -1 ; WX 600 ; N sacute ; B 80 -15 513 672 ;
+C -1 ; WX 600 ; N idieresis ; B 95 0 505 620 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 787 ;
+C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 805 ;
+C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ;
+C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ;
+C -1 ; WX 600 ; N twobaseior ; B 177 249 424 622 ;
+C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 753 ;
+C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ;
+C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ;
+C -1 ; WX 600 ; N ohungarumlaut ; B 62 -15 580 672 ;
+C -1 ; WX 600 ; N Eogonek ; B 53 -172 561 562 ;
+C -1 ; WX 600 ; N dcroat ; B 45 -15 591 629 ;
+C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ;
+C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ;
+C -1 ; WX 600 ; N lcaron ; B 95 0 533 629 ;
+C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 582 562 ;
+C -1 ; WX 600 ; N Lacute ; B 47 0 554 805 ;
+C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ;
+C -1 ; WX 600 ; N edotaccent ; B 66 -15 548 620 ;
+C -1 ; WX 600 ; N Igrave ; B 96 0 504 805 ;
+C -1 ; WX 600 ; N Imacron ; B 96 0 504 698 ;
+C -1 ; WX 600 ; N Lcaron ; B 47 0 554 562 ;
+C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ;
+C -1 ; WX 600 ; N lessequal ; B 98 0 502 710 ;
+C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ;
+C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ;
+C -1 ; WX 600 ; N Uhungarumlaut ; B 17 -18 590 805 ;
+C -1 ; WX 600 ; N Eacute ; B 53 0 550 805 ;
+C -1 ; WX 600 ; N emacron ; B 66 -15 548 565 ;
+C -1 ; WX 600 ; N gbreve ; B 45 -157 566 609 ;
+C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ;
+C -1 ; WX 600 ; N Scaron ; B 72 -20 529 802 ;
+C -1 ; WX 600 ; N Scommaaccent ; B 72 -250 529 580 ;
+C -1 ; WX 600 ; N Ohungarumlaut ; B 43 -18 580 805 ;
+C -1 ; WX 600 ; N degree ; B 123 269 477 622 ;
+C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ;
+C -1 ; WX 600 ; N Ccaron ; B 41 -18 540 802 ;
+C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ;
+C -1 ; WX 600 ; N radical ; B 3 -15 597 792 ;
+C -1 ; WX 600 ; N Dcaron ; B 43 0 574 802 ;
+C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 559 441 ;
+C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 729 ;
+C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ;
+C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 588 562 ;
+C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 554 562 ;
+C -1 ; WX 600 ; N Atilde ; B 3 0 597 729 ;
+C -1 ; WX 600 ; N Aogonek ; B 3 -172 608 562 ;
+C -1 ; WX 600 ; N Aring ; B 3 0 597 750 ;
+C -1 ; WX 600 ; N Otilde ; B 43 -18 557 729 ;
+C -1 ; WX 600 ; N zdotaccent ; B 99 0 502 620 ;
+C -1 ; WX 600 ; N Ecaron ; B 53 0 550 802 ;
+C -1 ; WX 600 ; N Iogonek ; B 96 -172 504 562 ;
+C -1 ; WX 600 ; N kcommaaccent ; B 43 -250 580 629 ;
+C -1 ; WX 600 ; N minus ; B 80 232 520 283 ;
+C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 787 ;
+C -1 ; WX 600 ; N ncaron ; B 26 0 575 669 ;
+C -1 ; WX 600 ; N tcommaaccent ; B 87 -250 530 561 ;
+C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ;
+C -1 ; WX 600 ; N odieresis ; B 62 -15 538 620 ;
+C -1 ; WX 600 ; N udieresis ; B 21 -15 562 620 ;
+C -1 ; WX 600 ; N notequal ; B 15 -16 540 529 ;
+C -1 ; WX 600 ; N gcommaaccent ; B 45 -157 566 708 ;
+C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ;
+C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ;
+C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 575 441 ;
+C -1 ; WX 600 ; N onebaseior ; B 172 249 428 622 ;
+C -1 ; WX 600 ; N imacron ; B 95 0 505 565 ;
+C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-Bold.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-Bold.afm
new file mode 100644
index 0000000..276cc8f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-Bold.afm
@@ -0,0 +1,2827 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 12:43:52 1997
+Comment UniqueID 43052
+Comment VMusage 37169 48194
+FontName Helvetica-Bold
+FullName Helvetica Bold
+FamilyName Helvetica
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+CharacterSet ExtendedRoman
+FontBBox -170 -228 1003 962
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 532
+Ascender 718
+Descender -207
+StdHW 118
+StdVW 140
+StartCharMetrics 315
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ;
+C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ;
+C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ;
+C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ;
+C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ;
+C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ;
+C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ;
+C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ;
+C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ;
+C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ;
+C 43 ; WX 584 ; N plus ; B 40 0 544 506 ;
+C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ;
+C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ;
+C 46 ; WX 278 ; N period ; B 64 0 214 146 ;
+C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ;
+C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ;
+C 49 ; WX 556 ; N one ; B 69 0 378 710 ;
+C 50 ; WX 556 ; N two ; B 26 0 511 710 ;
+C 51 ; WX 556 ; N three ; B 27 -19 516 710 ;
+C 52 ; WX 556 ; N four ; B 27 0 526 710 ;
+C 53 ; WX 556 ; N five ; B 27 -19 516 698 ;
+C 54 ; WX 556 ; N six ; B 31 -19 520 710 ;
+C 55 ; WX 556 ; N seven ; B 25 0 528 698 ;
+C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ;
+C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ;
+C 58 ; WX 333 ; N colon ; B 92 0 242 512 ;
+C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ;
+C 60 ; WX 584 ; N less ; B 38 -8 546 514 ;
+C 61 ; WX 584 ; N equal ; B 40 87 544 419 ;
+C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ;
+C 63 ; WX 611 ; N question ; B 60 0 556 727 ;
+C 64 ; WX 975 ; N at ; B 118 -19 856 737 ;
+C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
+C 66 ; WX 722 ; N B ; B 76 0 669 718 ;
+C 67 ; WX 722 ; N C ; B 44 -19 684 737 ;
+C 68 ; WX 722 ; N D ; B 76 0 685 718 ;
+C 69 ; WX 667 ; N E ; B 76 0 621 718 ;
+C 70 ; WX 611 ; N F ; B 76 0 587 718 ;
+C 71 ; WX 778 ; N G ; B 44 -19 713 737 ;
+C 72 ; WX 722 ; N H ; B 71 0 651 718 ;
+C 73 ; WX 278 ; N I ; B 64 0 214 718 ;
+C 74 ; WX 556 ; N J ; B 22 -18 484 718 ;
+C 75 ; WX 722 ; N K ; B 87 0 722 718 ;
+C 76 ; WX 611 ; N L ; B 76 0 583 718 ;
+C 77 ; WX 833 ; N M ; B 69 0 765 718 ;
+C 78 ; WX 722 ; N N ; B 69 0 654 718 ;
+C 79 ; WX 778 ; N O ; B 44 -19 734 737 ;
+C 80 ; WX 667 ; N P ; B 76 0 627 718 ;
+C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ;
+C 82 ; WX 722 ; N R ; B 76 0 677 718 ;
+C 83 ; WX 667 ; N S ; B 39 -19 629 737 ;
+C 84 ; WX 611 ; N T ; B 14 0 598 718 ;
+C 85 ; WX 722 ; N U ; B 72 -19 651 718 ;
+C 86 ; WX 667 ; N V ; B 19 0 648 718 ;
+C 87 ; WX 944 ; N W ; B 16 0 929 718 ;
+C 88 ; WX 667 ; N X ; B 14 0 653 718 ;
+C 89 ; WX 667 ; N Y ; B 15 0 653 718 ;
+C 90 ; WX 611 ; N Z ; B 25 0 586 718 ;
+C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ;
+C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ;
+C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ;
+C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ;
+C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ;
+C 97 ; WX 556 ; N a ; B 29 -14 527 546 ;
+C 98 ; WX 611 ; N b ; B 61 -14 578 718 ;
+C 99 ; WX 556 ; N c ; B 34 -14 524 546 ;
+C 100 ; WX 611 ; N d ; B 34 -14 551 718 ;
+C 101 ; WX 556 ; N e ; B 23 -14 528 546 ;
+C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 40 -217 553 546 ;
+C 104 ; WX 611 ; N h ; B 65 0 546 718 ;
+C 105 ; WX 278 ; N i ; B 69 0 209 725 ;
+C 106 ; WX 278 ; N j ; B 3 -214 209 725 ;
+C 107 ; WX 556 ; N k ; B 69 0 562 718 ;
+C 108 ; WX 278 ; N l ; B 69 0 209 718 ;
+C 109 ; WX 889 ; N m ; B 64 0 826 546 ;
+C 110 ; WX 611 ; N n ; B 65 0 546 546 ;
+C 111 ; WX 611 ; N o ; B 34 -14 578 546 ;
+C 112 ; WX 611 ; N p ; B 62 -207 578 546 ;
+C 113 ; WX 611 ; N q ; B 34 -207 552 546 ;
+C 114 ; WX 389 ; N r ; B 64 0 373 546 ;
+C 115 ; WX 556 ; N s ; B 30 -14 519 546 ;
+C 116 ; WX 333 ; N t ; B 10 -6 309 676 ;
+C 117 ; WX 611 ; N u ; B 66 -14 545 532 ;
+C 118 ; WX 556 ; N v ; B 13 0 543 532 ;
+C 119 ; WX 778 ; N w ; B 10 0 769 532 ;
+C 120 ; WX 556 ; N x ; B 15 0 541 532 ;
+C 121 ; WX 556 ; N y ; B 10 -214 539 532 ;
+C 122 ; WX 500 ; N z ; B 20 0 480 532 ;
+C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ;
+C 124 ; WX 280 ; N bar ; B 84 -225 196 775 ;
+C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ;
+C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ;
+C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ;
+C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ;
+C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ;
+C 165 ; WX 556 ; N yen ; B -9 0 565 698 ;
+C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ;
+C 167 ; WX 556 ; N section ; B 34 -184 522 727 ;
+C 168 ; WX 556 ; N currency ; B -3 76 559 636 ;
+C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ;
+C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ;
+C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ;
+C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ;
+C 174 ; WX 611 ; N fi ; B 10 0 542 727 ;
+C 175 ; WX 611 ; N fl ; B 10 0 542 727 ;
+C 177 ; WX 556 ; N endash ; B 0 227 556 333 ;
+C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ;
+C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ;
+C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ;
+C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ;
+C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ;
+C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ;
+C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ;
+C 193 ; WX 333 ; N grave ; B -23 604 225 750 ;
+C 194 ; WX 333 ; N acute ; B 108 604 356 750 ;
+C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ;
+C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ;
+C 197 ; WX 333 ; N macron ; B -6 604 339 678 ;
+C 198 ; WX 333 ; N breve ; B -2 604 335 750 ;
+C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ;
+C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ;
+C 202 ; WX 333 ; N ring ; B 59 568 275 776 ;
+C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ;
+C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ;
+C 207 ; WX 333 ; N caron ; B -10 604 343 750 ;
+C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ;
+C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 22 401 347 737 ;
+C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ;
+C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ;
+C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 6 401 360 737 ;
+C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ;
+C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ;
+C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ;
+C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ;
+C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ;
+C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ;
+C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ;
+C -1 ; WX 556 ; N abreve ; B 29 -14 527 750 ;
+C -1 ; WX 611 ; N uhungarumlaut ; B 66 -14 625 750 ;
+C -1 ; WX 556 ; N ecaron ; B 23 -14 528 750 ;
+C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ;
+C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ;
+C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ;
+C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ;
+C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ;
+C -1 ; WX 556 ; N scommaaccent ; B 30 -228 519 546 ;
+C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ;
+C -1 ; WX 722 ; N Uring ; B 72 -19 651 962 ;
+C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ;
+C -1 ; WX 556 ; N aogonek ; B 29 -224 545 546 ;
+C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ;
+C -1 ; WX 611 ; N uogonek ; B 66 -228 545 532 ;
+C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ;
+C -1 ; WX 722 ; N Dcroat ; B -5 0 685 718 ;
+C -1 ; WX 250 ; N commaaccent ; B 64 -228 199 -50 ;
+C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ;
+C -1 ; WX 667 ; N Emacron ; B 76 0 621 864 ;
+C -1 ; WX 556 ; N ccaron ; B 34 -14 524 750 ;
+C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ;
+C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 654 718 ;
+C -1 ; WX 278 ; N lacute ; B 69 0 329 936 ;
+C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ;
+C -1 ; WX 611 ; N Tcommaaccent ; B 14 -228 598 718 ;
+C -1 ; WX 722 ; N Cacute ; B 44 -19 684 936 ;
+C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ;
+C -1 ; WX 667 ; N Edotaccent ; B 76 0 621 915 ;
+C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ;
+C -1 ; WX 556 ; N scedilla ; B 30 -228 519 546 ;
+C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ;
+C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ;
+C -1 ; WX 722 ; N Rcaron ; B 76 0 677 936 ;
+C -1 ; WX 778 ; N Gcommaaccent ; B 44 -228 713 737 ;
+C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ;
+C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ;
+C -1 ; WX 722 ; N Amacron ; B 20 0 702 864 ;
+C -1 ; WX 389 ; N rcaron ; B 18 0 373 750 ;
+C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ;
+C -1 ; WX 611 ; N Zdotaccent ; B 25 0 586 915 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ;
+C -1 ; WX 778 ; N Omacron ; B 44 -19 734 864 ;
+C -1 ; WX 722 ; N Racute ; B 76 0 677 936 ;
+C -1 ; WX 667 ; N Sacute ; B 39 -19 629 936 ;
+C -1 ; WX 743 ; N dcaron ; B 34 -14 750 718 ;
+C -1 ; WX 722 ; N Umacron ; B 72 -19 651 864 ;
+C -1 ; WX 611 ; N uring ; B 66 -14 545 776 ;
+C -1 ; WX 333 ; N threebaseior ; B 8 271 326 710 ;
+C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ;
+C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
+C -1 ; WX 722 ; N Abreve ; B 20 0 702 936 ;
+C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ;
+C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ;
+C -1 ; WX 611 ; N Tcaron ; B 14 0 598 936 ;
+C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ;
+C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ;
+C -1 ; WX 722 ; N Nacute ; B 69 0 654 936 ;
+C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ;
+C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ;
+C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ;
+C -1 ; WX 556 ; N cacute ; B 34 -14 524 750 ;
+C -1 ; WX 611 ; N nacute ; B 65 0 546 750 ;
+C -1 ; WX 611 ; N umacron ; B 66 -14 545 678 ;
+C -1 ; WX 722 ; N Ncaron ; B 69 0 654 936 ;
+C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ;
+C -1 ; WX 280 ; N brokenbar ; B 84 -150 196 700 ;
+C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ;
+C -1 ; WX 778 ; N Gbreve ; B 44 -19 713 936 ;
+C -1 ; WX 278 ; N Idotaccent ; B 64 0 214 915 ;
+C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ;
+C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ;
+C -1 ; WX 389 ; N racute ; B 64 0 384 750 ;
+C -1 ; WX 611 ; N omacron ; B 34 -14 578 678 ;
+C -1 ; WX 611 ; N Zacute ; B 25 0 586 936 ;
+C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ;
+C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ;
+C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ;
+C -1 ; WX 278 ; N lcommaaccent ; B 69 -228 213 718 ;
+C -1 ; WX 389 ; N tcaron ; B 10 -6 421 878 ;
+C -1 ; WX 556 ; N eogonek ; B 23 -228 528 546 ;
+C -1 ; WX 722 ; N Uogonek ; B 72 -228 651 718 ;
+C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ;
+C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ;
+C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ;
+C -1 ; WX 500 ; N zacute ; B 20 0 480 750 ;
+C -1 ; WX 278 ; N iogonek ; B 16 -224 249 725 ;
+C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ;
+C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ;
+C -1 ; WX 556 ; N amacron ; B 29 -14 527 678 ;
+C -1 ; WX 556 ; N sacute ; B 30 -14 519 750 ;
+C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ;
+C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ;
+C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ;
+C -1 ; WX 333 ; N twobaseior ; B 9 283 324 710 ;
+C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ;
+C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ;
+C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ;
+C -1 ; WX 611 ; N ohungarumlaut ; B 34 -14 625 750 ;
+C -1 ; WX 667 ; N Eogonek ; B 76 -224 639 718 ;
+C -1 ; WX 611 ; N dcroat ; B 34 -14 650 718 ;
+C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ;
+C -1 ; WX 667 ; N Scedilla ; B 39 -228 629 737 ;
+C -1 ; WX 400 ; N lcaron ; B 69 0 408 718 ;
+C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 722 718 ;
+C -1 ; WX 611 ; N Lacute ; B 76 0 583 936 ;
+C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ;
+C -1 ; WX 556 ; N edotaccent ; B 23 -14 528 729 ;
+C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ;
+C -1 ; WX 278 ; N Imacron ; B -33 0 312 864 ;
+C -1 ; WX 611 ; N Lcaron ; B 76 0 583 718 ;
+C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ;
+C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ;
+C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ;
+C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ;
+C -1 ; WX 722 ; N Uhungarumlaut ; B 72 -19 681 936 ;
+C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ;
+C -1 ; WX 556 ; N emacron ; B 23 -14 528 678 ;
+C -1 ; WX 611 ; N gbreve ; B 40 -217 553 750 ;
+C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ;
+C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ;
+C -1 ; WX 667 ; N Scommaaccent ; B 39 -228 629 737 ;
+C -1 ; WX 778 ; N Ohungarumlaut ; B 44 -19 734 936 ;
+C -1 ; WX 400 ; N degree ; B 57 426 343 712 ;
+C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ;
+C -1 ; WX 722 ; N Ccaron ; B 44 -19 684 936 ;
+C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ;
+C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ;
+C -1 ; WX 722 ; N Dcaron ; B 76 0 685 936 ;
+C -1 ; WX 389 ; N rcommaaccent ; B 64 -228 373 546 ;
+C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ;
+C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ;
+C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 677 718 ;
+C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 583 718 ;
+C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ;
+C -1 ; WX 722 ; N Aogonek ; B 20 -224 742 718 ;
+C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
+C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ;
+C -1 ; WX 500 ; N zdotaccent ; B 20 0 480 729 ;
+C -1 ; WX 667 ; N Ecaron ; B 76 0 621 936 ;
+C -1 ; WX 278 ; N Iogonek ; B -11 -228 222 718 ;
+C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 562 718 ;
+C -1 ; WX 584 ; N minus ; B 40 197 544 309 ;
+C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ;
+C -1 ; WX 611 ; N ncaron ; B 65 0 546 750 ;
+C -1 ; WX 333 ; N tcommaaccent ; B 10 -228 309 676 ;
+C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ;
+C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ;
+C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ;
+C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ;
+C -1 ; WX 611 ; N gcommaaccent ; B 40 -217 553 850 ;
+C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ;
+C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ;
+C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 546 546 ;
+C -1 ; WX 333 ; N onebaseior ; B 26 283 237 710 ;
+C -1 ; WX 278 ; N imacron ; B -8 0 285 678 ;
+C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 2481
+KPX A C -40
+KPX A Cacute -40
+KPX A Ccaron -40
+KPX A Ccedilla -40
+KPX A G -50
+KPX A Gbreve -50
+KPX A Gcommaaccent -50
+KPX A O -40
+KPX A Oacute -40
+KPX A Ocircumflex -40
+KPX A Odieresis -40
+KPX A Ograve -40
+KPX A Ohungarumlaut -40
+KPX A Omacron -40
+KPX A Oslash -40
+KPX A Otilde -40
+KPX A Q -40
+KPX A T -90
+KPX A Tcaron -90
+KPX A Tcommaaccent -90
+KPX A U -50
+KPX A Uacute -50
+KPX A Ucircumflex -50
+KPX A Udieresis -50
+KPX A Ugrave -50
+KPX A Uhungarumlaut -50
+KPX A Umacron -50
+KPX A Uogonek -50
+KPX A Uring -50
+KPX A V -80
+KPX A W -60
+KPX A Y -110
+KPX A Yacute -110
+KPX A Ydieresis -110
+KPX A u -30
+KPX A uacute -30
+KPX A ucircumflex -30
+KPX A udieresis -30
+KPX A ugrave -30
+KPX A uhungarumlaut -30
+KPX A umacron -30
+KPX A uogonek -30
+KPX A uring -30
+KPX A v -40
+KPX A w -30
+KPX A y -30
+KPX A yacute -30
+KPX A ydieresis -30
+KPX Aacute C -40
+KPX Aacute Cacute -40
+KPX Aacute Ccaron -40
+KPX Aacute Ccedilla -40
+KPX Aacute G -50
+KPX Aacute Gbreve -50
+KPX Aacute Gcommaaccent -50
+KPX Aacute O -40
+KPX Aacute Oacute -40
+KPX Aacute Ocircumflex -40
+KPX Aacute Odieresis -40
+KPX Aacute Ograve -40
+KPX Aacute Ohungarumlaut -40
+KPX Aacute Omacron -40
+KPX Aacute Oslash -40
+KPX Aacute Otilde -40
+KPX Aacute Q -40
+KPX Aacute T -90
+KPX Aacute Tcaron -90
+KPX Aacute Tcommaaccent -90
+KPX Aacute U -50
+KPX Aacute Uacute -50
+KPX Aacute Ucircumflex -50
+KPX Aacute Udieresis -50
+KPX Aacute Ugrave -50
+KPX Aacute Uhungarumlaut -50
+KPX Aacute Umacron -50
+KPX Aacute Uogonek -50
+KPX Aacute Uring -50
+KPX Aacute V -80
+KPX Aacute W -60
+KPX Aacute Y -110
+KPX Aacute Yacute -110
+KPX Aacute Ydieresis -110
+KPX Aacute u -30
+KPX Aacute uacute -30
+KPX Aacute ucircumflex -30
+KPX Aacute udieresis -30
+KPX Aacute ugrave -30
+KPX Aacute uhungarumlaut -30
+KPX Aacute umacron -30
+KPX Aacute uogonek -30
+KPX Aacute uring -30
+KPX Aacute v -40
+KPX Aacute w -30
+KPX Aacute y -30
+KPX Aacute yacute -30
+KPX Aacute ydieresis -30
+KPX Abreve C -40
+KPX Abreve Cacute -40
+KPX Abreve Ccaron -40
+KPX Abreve Ccedilla -40
+KPX Abreve G -50
+KPX Abreve Gbreve -50
+KPX Abreve Gcommaaccent -50
+KPX Abreve O -40
+KPX Abreve Oacute -40
+KPX Abreve Ocircumflex -40
+KPX Abreve Odieresis -40
+KPX Abreve Ograve -40
+KPX Abreve Ohungarumlaut -40
+KPX Abreve Omacron -40
+KPX Abreve Oslash -40
+KPX Abreve Otilde -40
+KPX Abreve Q -40
+KPX Abreve T -90
+KPX Abreve Tcaron -90
+KPX Abreve Tcommaaccent -90
+KPX Abreve U -50
+KPX Abreve Uacute -50
+KPX Abreve Ucircumflex -50
+KPX Abreve Udieresis -50
+KPX Abreve Ugrave -50
+KPX Abreve Uhungarumlaut -50
+KPX Abreve Umacron -50
+KPX Abreve Uogonek -50
+KPX Abreve Uring -50
+KPX Abreve V -80
+KPX Abreve W -60
+KPX Abreve Y -110
+KPX Abreve Yacute -110
+KPX Abreve Ydieresis -110
+KPX Abreve u -30
+KPX Abreve uacute -30
+KPX Abreve ucircumflex -30
+KPX Abreve udieresis -30
+KPX Abreve ugrave -30
+KPX Abreve uhungarumlaut -30
+KPX Abreve umacron -30
+KPX Abreve uogonek -30
+KPX Abreve uring -30
+KPX Abreve v -40
+KPX Abreve w -30
+KPX Abreve y -30
+KPX Abreve yacute -30
+KPX Abreve ydieresis -30
+KPX Acircumflex C -40
+KPX Acircumflex Cacute -40
+KPX Acircumflex Ccaron -40
+KPX Acircumflex Ccedilla -40
+KPX Acircumflex G -50
+KPX Acircumflex Gbreve -50
+KPX Acircumflex Gcommaaccent -50
+KPX Acircumflex O -40
+KPX Acircumflex Oacute -40
+KPX Acircumflex Ocircumflex -40
+KPX Acircumflex Odieresis -40
+KPX Acircumflex Ograve -40
+KPX Acircumflex Ohungarumlaut -40
+KPX Acircumflex Omacron -40
+KPX Acircumflex Oslash -40
+KPX Acircumflex Otilde -40
+KPX Acircumflex Q -40
+KPX Acircumflex T -90
+KPX Acircumflex Tcaron -90
+KPX Acircumflex Tcommaaccent -90
+KPX Acircumflex U -50
+KPX Acircumflex Uacute -50
+KPX Acircumflex Ucircumflex -50
+KPX Acircumflex Udieresis -50
+KPX Acircumflex Ugrave -50
+KPX Acircumflex Uhungarumlaut -50
+KPX Acircumflex Umacron -50
+KPX Acircumflex Uogonek -50
+KPX Acircumflex Uring -50
+KPX Acircumflex V -80
+KPX Acircumflex W -60
+KPX Acircumflex Y -110
+KPX Acircumflex Yacute -110
+KPX Acircumflex Ydieresis -110
+KPX Acircumflex u -30
+KPX Acircumflex uacute -30
+KPX Acircumflex ucircumflex -30
+KPX Acircumflex udieresis -30
+KPX Acircumflex ugrave -30
+KPX Acircumflex uhungarumlaut -30
+KPX Acircumflex umacron -30
+KPX Acircumflex uogonek -30
+KPX Acircumflex uring -30
+KPX Acircumflex v -40
+KPX Acircumflex w -30
+KPX Acircumflex y -30
+KPX Acircumflex yacute -30
+KPX Acircumflex ydieresis -30
+KPX Adieresis C -40
+KPX Adieresis Cacute -40
+KPX Adieresis Ccaron -40
+KPX Adieresis Ccedilla -40
+KPX Adieresis G -50
+KPX Adieresis Gbreve -50
+KPX Adieresis Gcommaaccent -50
+KPX Adieresis O -40
+KPX Adieresis Oacute -40
+KPX Adieresis Ocircumflex -40
+KPX Adieresis Odieresis -40
+KPX Adieresis Ograve -40
+KPX Adieresis Ohungarumlaut -40
+KPX Adieresis Omacron -40
+KPX Adieresis Oslash -40
+KPX Adieresis Otilde -40
+KPX Adieresis Q -40
+KPX Adieresis T -90
+KPX Adieresis Tcaron -90
+KPX Adieresis Tcommaaccent -90
+KPX Adieresis U -50
+KPX Adieresis Uacute -50
+KPX Adieresis Ucircumflex -50
+KPX Adieresis Udieresis -50
+KPX Adieresis Ugrave -50
+KPX Adieresis Uhungarumlaut -50
+KPX Adieresis Umacron -50
+KPX Adieresis Uogonek -50
+KPX Adieresis Uring -50
+KPX Adieresis V -80
+KPX Adieresis W -60
+KPX Adieresis Y -110
+KPX Adieresis Yacute -110
+KPX Adieresis Ydieresis -110
+KPX Adieresis u -30
+KPX Adieresis uacute -30
+KPX Adieresis ucircumflex -30
+KPX Adieresis udieresis -30
+KPX Adieresis ugrave -30
+KPX Adieresis uhungarumlaut -30
+KPX Adieresis umacron -30
+KPX Adieresis uogonek -30
+KPX Adieresis uring -30
+KPX Adieresis v -40
+KPX Adieresis w -30
+KPX Adieresis y -30
+KPX Adieresis yacute -30
+KPX Adieresis ydieresis -30
+KPX Agrave C -40
+KPX Agrave Cacute -40
+KPX Agrave Ccaron -40
+KPX Agrave Ccedilla -40
+KPX Agrave G -50
+KPX Agrave Gbreve -50
+KPX Agrave Gcommaaccent -50
+KPX Agrave O -40
+KPX Agrave Oacute -40
+KPX Agrave Ocircumflex -40
+KPX Agrave Odieresis -40
+KPX Agrave Ograve -40
+KPX Agrave Ohungarumlaut -40
+KPX Agrave Omacron -40
+KPX Agrave Oslash -40
+KPX Agrave Otilde -40
+KPX Agrave Q -40
+KPX Agrave T -90
+KPX Agrave Tcaron -90
+KPX Agrave Tcommaaccent -90
+KPX Agrave U -50
+KPX Agrave Uacute -50
+KPX Agrave Ucircumflex -50
+KPX Agrave Udieresis -50
+KPX Agrave Ugrave -50
+KPX Agrave Uhungarumlaut -50
+KPX Agrave Umacron -50
+KPX Agrave Uogonek -50
+KPX Agrave Uring -50
+KPX Agrave V -80
+KPX Agrave W -60
+KPX Agrave Y -110
+KPX Agrave Yacute -110
+KPX Agrave Ydieresis -110
+KPX Agrave u -30
+KPX Agrave uacute -30
+KPX Agrave ucircumflex -30
+KPX Agrave udieresis -30
+KPX Agrave ugrave -30
+KPX Agrave uhungarumlaut -30
+KPX Agrave umacron -30
+KPX Agrave uogonek -30
+KPX Agrave uring -30
+KPX Agrave v -40
+KPX Agrave w -30
+KPX Agrave y -30
+KPX Agrave yacute -30
+KPX Agrave ydieresis -30
+KPX Amacron C -40
+KPX Amacron Cacute -40
+KPX Amacron Ccaron -40
+KPX Amacron Ccedilla -40
+KPX Amacron G -50
+KPX Amacron Gbreve -50
+KPX Amacron Gcommaaccent -50
+KPX Amacron O -40
+KPX Amacron Oacute -40
+KPX Amacron Ocircumflex -40
+KPX Amacron Odieresis -40
+KPX Amacron Ograve -40
+KPX Amacron Ohungarumlaut -40
+KPX Amacron Omacron -40
+KPX Amacron Oslash -40
+KPX Amacron Otilde -40
+KPX Amacron Q -40
+KPX Amacron T -90
+KPX Amacron Tcaron -90
+KPX Amacron Tcommaaccent -90
+KPX Amacron U -50
+KPX Amacron Uacute -50
+KPX Amacron Ucircumflex -50
+KPX Amacron Udieresis -50
+KPX Amacron Ugrave -50
+KPX Amacron Uhungarumlaut -50
+KPX Amacron Umacron -50
+KPX Amacron Uogonek -50
+KPX Amacron Uring -50
+KPX Amacron V -80
+KPX Amacron W -60
+KPX Amacron Y -110
+KPX Amacron Yacute -110
+KPX Amacron Ydieresis -110
+KPX Amacron u -30
+KPX Amacron uacute -30
+KPX Amacron ucircumflex -30
+KPX Amacron udieresis -30
+KPX Amacron ugrave -30
+KPX Amacron uhungarumlaut -30
+KPX Amacron umacron -30
+KPX Amacron uogonek -30
+KPX Amacron uring -30
+KPX Amacron v -40
+KPX Amacron w -30
+KPX Amacron y -30
+KPX Amacron yacute -30
+KPX Amacron ydieresis -30
+KPX Aogonek C -40
+KPX Aogonek Cacute -40
+KPX Aogonek Ccaron -40
+KPX Aogonek Ccedilla -40
+KPX Aogonek G -50
+KPX Aogonek Gbreve -50
+KPX Aogonek Gcommaaccent -50
+KPX Aogonek O -40
+KPX Aogonek Oacute -40
+KPX Aogonek Ocircumflex -40
+KPX Aogonek Odieresis -40
+KPX Aogonek Ograve -40
+KPX Aogonek Ohungarumlaut -40
+KPX Aogonek Omacron -40
+KPX Aogonek Oslash -40
+KPX Aogonek Otilde -40
+KPX Aogonek Q -40
+KPX Aogonek T -90
+KPX Aogonek Tcaron -90
+KPX Aogonek Tcommaaccent -90
+KPX Aogonek U -50
+KPX Aogonek Uacute -50
+KPX Aogonek Ucircumflex -50
+KPX Aogonek Udieresis -50
+KPX Aogonek Ugrave -50
+KPX Aogonek Uhungarumlaut -50
+KPX Aogonek Umacron -50
+KPX Aogonek Uogonek -50
+KPX Aogonek Uring -50
+KPX Aogonek V -80
+KPX Aogonek W -60
+KPX Aogonek Y -110
+KPX Aogonek Yacute -110
+KPX Aogonek Ydieresis -110
+KPX Aogonek u -30
+KPX Aogonek uacute -30
+KPX Aogonek ucircumflex -30
+KPX Aogonek udieresis -30
+KPX Aogonek ugrave -30
+KPX Aogonek uhungarumlaut -30
+KPX Aogonek umacron -30
+KPX Aogonek uogonek -30
+KPX Aogonek uring -30
+KPX Aogonek v -40
+KPX Aogonek w -30
+KPX Aogonek y -30
+KPX Aogonek yacute -30
+KPX Aogonek ydieresis -30
+KPX Aring C -40
+KPX Aring Cacute -40
+KPX Aring Ccaron -40
+KPX Aring Ccedilla -40
+KPX Aring G -50
+KPX Aring Gbreve -50
+KPX Aring Gcommaaccent -50
+KPX Aring O -40
+KPX Aring Oacute -40
+KPX Aring Ocircumflex -40
+KPX Aring Odieresis -40
+KPX Aring Ograve -40
+KPX Aring Ohungarumlaut -40
+KPX Aring Omacron -40
+KPX Aring Oslash -40
+KPX Aring Otilde -40
+KPX Aring Q -40
+KPX Aring T -90
+KPX Aring Tcaron -90
+KPX Aring Tcommaaccent -90
+KPX Aring U -50
+KPX Aring Uacute -50
+KPX Aring Ucircumflex -50
+KPX Aring Udieresis -50
+KPX Aring Ugrave -50
+KPX Aring Uhungarumlaut -50
+KPX Aring Umacron -50
+KPX Aring Uogonek -50
+KPX Aring Uring -50
+KPX Aring V -80
+KPX Aring W -60
+KPX Aring Y -110
+KPX Aring Yacute -110
+KPX Aring Ydieresis -110
+KPX Aring u -30
+KPX Aring uacute -30
+KPX Aring ucircumflex -30
+KPX Aring udieresis -30
+KPX Aring ugrave -30
+KPX Aring uhungarumlaut -30
+KPX Aring umacron -30
+KPX Aring uogonek -30
+KPX Aring uring -30
+KPX Aring v -40
+KPX Aring w -30
+KPX Aring y -30
+KPX Aring yacute -30
+KPX Aring ydieresis -30
+KPX Atilde C -40
+KPX Atilde Cacute -40
+KPX Atilde Ccaron -40
+KPX Atilde Ccedilla -40
+KPX Atilde G -50
+KPX Atilde Gbreve -50
+KPX Atilde Gcommaaccent -50
+KPX Atilde O -40
+KPX Atilde Oacute -40
+KPX Atilde Ocircumflex -40
+KPX Atilde Odieresis -40
+KPX Atilde Ograve -40
+KPX Atilde Ohungarumlaut -40
+KPX Atilde Omacron -40
+KPX Atilde Oslash -40
+KPX Atilde Otilde -40
+KPX Atilde Q -40
+KPX Atilde T -90
+KPX Atilde Tcaron -90
+KPX Atilde Tcommaaccent -90
+KPX Atilde U -50
+KPX Atilde Uacute -50
+KPX Atilde Ucircumflex -50
+KPX Atilde Udieresis -50
+KPX Atilde Ugrave -50
+KPX Atilde Uhungarumlaut -50
+KPX Atilde Umacron -50
+KPX Atilde Uogonek -50
+KPX Atilde Uring -50
+KPX Atilde V -80
+KPX Atilde W -60
+KPX Atilde Y -110
+KPX Atilde Yacute -110
+KPX Atilde Ydieresis -110
+KPX Atilde u -30
+KPX Atilde uacute -30
+KPX Atilde ucircumflex -30
+KPX Atilde udieresis -30
+KPX Atilde ugrave -30
+KPX Atilde uhungarumlaut -30
+KPX Atilde umacron -30
+KPX Atilde uogonek -30
+KPX Atilde uring -30
+KPX Atilde v -40
+KPX Atilde w -30
+KPX Atilde y -30
+KPX Atilde yacute -30
+KPX Atilde ydieresis -30
+KPX B A -30
+KPX B Aacute -30
+KPX B Abreve -30
+KPX B Acircumflex -30
+KPX B Adieresis -30
+KPX B Agrave -30
+KPX B Amacron -30
+KPX B Aogonek -30
+KPX B Aring -30
+KPX B Atilde -30
+KPX B U -10
+KPX B Uacute -10
+KPX B Ucircumflex -10
+KPX B Udieresis -10
+KPX B Ugrave -10
+KPX B Uhungarumlaut -10
+KPX B Umacron -10
+KPX B Uogonek -10
+KPX B Uring -10
+KPX D A -40
+KPX D Aacute -40
+KPX D Abreve -40
+KPX D Acircumflex -40
+KPX D Adieresis -40
+KPX D Agrave -40
+KPX D Amacron -40
+KPX D Aogonek -40
+KPX D Aring -40
+KPX D Atilde -40
+KPX D V -40
+KPX D W -40
+KPX D Y -70
+KPX D Yacute -70
+KPX D Ydieresis -70
+KPX D comma -30
+KPX D period -30
+KPX Dcaron A -40
+KPX Dcaron Aacute -40
+KPX Dcaron Abreve -40
+KPX Dcaron Acircumflex -40
+KPX Dcaron Adieresis -40
+KPX Dcaron Agrave -40
+KPX Dcaron Amacron -40
+KPX Dcaron Aogonek -40
+KPX Dcaron Aring -40
+KPX Dcaron Atilde -40
+KPX Dcaron V -40
+KPX Dcaron W -40
+KPX Dcaron Y -70
+KPX Dcaron Yacute -70
+KPX Dcaron Ydieresis -70
+KPX Dcaron comma -30
+KPX Dcaron period -30
+KPX Dcroat A -40
+KPX Dcroat Aacute -40
+KPX Dcroat Abreve -40
+KPX Dcroat Acircumflex -40
+KPX Dcroat Adieresis -40
+KPX Dcroat Agrave -40
+KPX Dcroat Amacron -40
+KPX Dcroat Aogonek -40
+KPX Dcroat Aring -40
+KPX Dcroat Atilde -40
+KPX Dcroat V -40
+KPX Dcroat W -40
+KPX Dcroat Y -70
+KPX Dcroat Yacute -70
+KPX Dcroat Ydieresis -70
+KPX Dcroat comma -30
+KPX Dcroat period -30
+KPX F A -80
+KPX F Aacute -80
+KPX F Abreve -80
+KPX F Acircumflex -80
+KPX F Adieresis -80
+KPX F Agrave -80
+KPX F Amacron -80
+KPX F Aogonek -80
+KPX F Aring -80
+KPX F Atilde -80
+KPX F a -20
+KPX F aacute -20
+KPX F abreve -20
+KPX F acircumflex -20
+KPX F adieresis -20
+KPX F agrave -20
+KPX F amacron -20
+KPX F aogonek -20
+KPX F aring -20
+KPX F atilde -20
+KPX F comma -100
+KPX F period -100
+KPX J A -20
+KPX J Aacute -20
+KPX J Abreve -20
+KPX J Acircumflex -20
+KPX J Adieresis -20
+KPX J Agrave -20
+KPX J Amacron -20
+KPX J Aogonek -20
+KPX J Aring -20
+KPX J Atilde -20
+KPX J comma -20
+KPX J period -20
+KPX J u -20
+KPX J uacute -20
+KPX J ucircumflex -20
+KPX J udieresis -20
+KPX J ugrave -20
+KPX J uhungarumlaut -20
+KPX J umacron -20
+KPX J uogonek -20
+KPX J uring -20
+KPX K O -30
+KPX K Oacute -30
+KPX K Ocircumflex -30
+KPX K Odieresis -30
+KPX K Ograve -30
+KPX K Ohungarumlaut -30
+KPX K Omacron -30
+KPX K Oslash -30
+KPX K Otilde -30
+KPX K e -15
+KPX K eacute -15
+KPX K ecaron -15
+KPX K ecircumflex -15
+KPX K edieresis -15
+KPX K edotaccent -15
+KPX K egrave -15
+KPX K emacron -15
+KPX K eogonek -15
+KPX K o -35
+KPX K oacute -35
+KPX K ocircumflex -35
+KPX K odieresis -35
+KPX K ograve -35
+KPX K ohungarumlaut -35
+KPX K omacron -35
+KPX K oslash -35
+KPX K otilde -35
+KPX K u -30
+KPX K uacute -30
+KPX K ucircumflex -30
+KPX K udieresis -30
+KPX K ugrave -30
+KPX K uhungarumlaut -30
+KPX K umacron -30
+KPX K uogonek -30
+KPX K uring -30
+KPX K y -40
+KPX K yacute -40
+KPX K ydieresis -40
+KPX Kcommaaccent O -30
+KPX Kcommaaccent Oacute -30
+KPX Kcommaaccent Ocircumflex -30
+KPX Kcommaaccent Odieresis -30
+KPX Kcommaaccent Ograve -30
+KPX Kcommaaccent Ohungarumlaut -30
+KPX Kcommaaccent Omacron -30
+KPX Kcommaaccent Oslash -30
+KPX Kcommaaccent Otilde -30
+KPX Kcommaaccent e -15
+KPX Kcommaaccent eacute -15
+KPX Kcommaaccent ecaron -15
+KPX Kcommaaccent ecircumflex -15
+KPX Kcommaaccent edieresis -15
+KPX Kcommaaccent edotaccent -15
+KPX Kcommaaccent egrave -15
+KPX Kcommaaccent emacron -15
+KPX Kcommaaccent eogonek -15
+KPX Kcommaaccent o -35
+KPX Kcommaaccent oacute -35
+KPX Kcommaaccent ocircumflex -35
+KPX Kcommaaccent odieresis -35
+KPX Kcommaaccent ograve -35
+KPX Kcommaaccent ohungarumlaut -35
+KPX Kcommaaccent omacron -35
+KPX Kcommaaccent oslash -35
+KPX Kcommaaccent otilde -35
+KPX Kcommaaccent u -30
+KPX Kcommaaccent uacute -30
+KPX Kcommaaccent ucircumflex -30
+KPX Kcommaaccent udieresis -30
+KPX Kcommaaccent ugrave -30
+KPX Kcommaaccent uhungarumlaut -30
+KPX Kcommaaccent umacron -30
+KPX Kcommaaccent uogonek -30
+KPX Kcommaaccent uring -30
+KPX Kcommaaccent y -40
+KPX Kcommaaccent yacute -40
+KPX Kcommaaccent ydieresis -40
+KPX L T -90
+KPX L Tcaron -90
+KPX L Tcommaaccent -90
+KPX L V -110
+KPX L W -80
+KPX L Y -120
+KPX L Yacute -120
+KPX L Ydieresis -120
+KPX L quotedblright -140
+KPX L quoteright -140
+KPX L y -30
+KPX L yacute -30
+KPX L ydieresis -30
+KPX Lacute T -90
+KPX Lacute Tcaron -90
+KPX Lacute Tcommaaccent -90
+KPX Lacute V -110
+KPX Lacute W -80
+KPX Lacute Y -120
+KPX Lacute Yacute -120
+KPX Lacute Ydieresis -120
+KPX Lacute quotedblright -140
+KPX Lacute quoteright -140
+KPX Lacute y -30
+KPX Lacute yacute -30
+KPX Lacute ydieresis -30
+KPX Lcommaaccent T -90
+KPX Lcommaaccent Tcaron -90
+KPX Lcommaaccent Tcommaaccent -90
+KPX Lcommaaccent V -110
+KPX Lcommaaccent W -80
+KPX Lcommaaccent Y -120
+KPX Lcommaaccent Yacute -120
+KPX Lcommaaccent Ydieresis -120
+KPX Lcommaaccent quotedblright -140
+KPX Lcommaaccent quoteright -140
+KPX Lcommaaccent y -30
+KPX Lcommaaccent yacute -30
+KPX Lcommaaccent ydieresis -30
+KPX Lslash T -90
+KPX Lslash Tcaron -90
+KPX Lslash Tcommaaccent -90
+KPX Lslash V -110
+KPX Lslash W -80
+KPX Lslash Y -120
+KPX Lslash Yacute -120
+KPX Lslash Ydieresis -120
+KPX Lslash quotedblright -140
+KPX Lslash quoteright -140
+KPX Lslash y -30
+KPX Lslash yacute -30
+KPX Lslash ydieresis -30
+KPX O A -50
+KPX O Aacute -50
+KPX O Abreve -50
+KPX O Acircumflex -50
+KPX O Adieresis -50
+KPX O Agrave -50
+KPX O Amacron -50
+KPX O Aogonek -50
+KPX O Aring -50
+KPX O Atilde -50
+KPX O T -40
+KPX O Tcaron -40
+KPX O Tcommaaccent -40
+KPX O V -50
+KPX O W -50
+KPX O X -50
+KPX O Y -70
+KPX O Yacute -70
+KPX O Ydieresis -70
+KPX O comma -40
+KPX O period -40
+KPX Oacute A -50
+KPX Oacute Aacute -50
+KPX Oacute Abreve -50
+KPX Oacute Acircumflex -50
+KPX Oacute Adieresis -50
+KPX Oacute Agrave -50
+KPX Oacute Amacron -50
+KPX Oacute Aogonek -50
+KPX Oacute Aring -50
+KPX Oacute Atilde -50
+KPX Oacute T -40
+KPX Oacute Tcaron -40
+KPX Oacute Tcommaaccent -40
+KPX Oacute V -50
+KPX Oacute W -50
+KPX Oacute X -50
+KPX Oacute Y -70
+KPX Oacute Yacute -70
+KPX Oacute Ydieresis -70
+KPX Oacute comma -40
+KPX Oacute period -40
+KPX Ocircumflex A -50
+KPX Ocircumflex Aacute -50
+KPX Ocircumflex Abreve -50
+KPX Ocircumflex Acircumflex -50
+KPX Ocircumflex Adieresis -50
+KPX Ocircumflex Agrave -50
+KPX Ocircumflex Amacron -50
+KPX Ocircumflex Aogonek -50
+KPX Ocircumflex Aring -50
+KPX Ocircumflex Atilde -50
+KPX Ocircumflex T -40
+KPX Ocircumflex Tcaron -40
+KPX Ocircumflex Tcommaaccent -40
+KPX Ocircumflex V -50
+KPX Ocircumflex W -50
+KPX Ocircumflex X -50
+KPX Ocircumflex Y -70
+KPX Ocircumflex Yacute -70
+KPX Ocircumflex Ydieresis -70
+KPX Ocircumflex comma -40
+KPX Ocircumflex period -40
+KPX Odieresis A -50
+KPX Odieresis Aacute -50
+KPX Odieresis Abreve -50
+KPX Odieresis Acircumflex -50
+KPX Odieresis Adieresis -50
+KPX Odieresis Agrave -50
+KPX Odieresis Amacron -50
+KPX Odieresis Aogonek -50
+KPX Odieresis Aring -50
+KPX Odieresis Atilde -50
+KPX Odieresis T -40
+KPX Odieresis Tcaron -40
+KPX Odieresis Tcommaaccent -40
+KPX Odieresis V -50
+KPX Odieresis W -50
+KPX Odieresis X -50
+KPX Odieresis Y -70
+KPX Odieresis Yacute -70
+KPX Odieresis Ydieresis -70
+KPX Odieresis comma -40
+KPX Odieresis period -40
+KPX Ograve A -50
+KPX Ograve Aacute -50
+KPX Ograve Abreve -50
+KPX Ograve Acircumflex -50
+KPX Ograve Adieresis -50
+KPX Ograve Agrave -50
+KPX Ograve Amacron -50
+KPX Ograve Aogonek -50
+KPX Ograve Aring -50
+KPX Ograve Atilde -50
+KPX Ograve T -40
+KPX Ograve Tcaron -40
+KPX Ograve Tcommaaccent -40
+KPX Ograve V -50
+KPX Ograve W -50
+KPX Ograve X -50
+KPX Ograve Y -70
+KPX Ograve Yacute -70
+KPX Ograve Ydieresis -70
+KPX Ograve comma -40
+KPX Ograve period -40
+KPX Ohungarumlaut A -50
+KPX Ohungarumlaut Aacute -50
+KPX Ohungarumlaut Abreve -50
+KPX Ohungarumlaut Acircumflex -50
+KPX Ohungarumlaut Adieresis -50
+KPX Ohungarumlaut Agrave -50
+KPX Ohungarumlaut Amacron -50
+KPX Ohungarumlaut Aogonek -50
+KPX Ohungarumlaut Aring -50
+KPX Ohungarumlaut Atilde -50
+KPX Ohungarumlaut T -40
+KPX Ohungarumlaut Tcaron -40
+KPX Ohungarumlaut Tcommaaccent -40
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut W -50
+KPX Ohungarumlaut X -50
+KPX Ohungarumlaut Y -70
+KPX Ohungarumlaut Yacute -70
+KPX Ohungarumlaut Ydieresis -70
+KPX Ohungarumlaut comma -40
+KPX Ohungarumlaut period -40
+KPX Omacron A -50
+KPX Omacron Aacute -50
+KPX Omacron Abreve -50
+KPX Omacron Acircumflex -50
+KPX Omacron Adieresis -50
+KPX Omacron Agrave -50
+KPX Omacron Amacron -50
+KPX Omacron Aogonek -50
+KPX Omacron Aring -50
+KPX Omacron Atilde -50
+KPX Omacron T -40
+KPX Omacron Tcaron -40
+KPX Omacron Tcommaaccent -40
+KPX Omacron V -50
+KPX Omacron W -50
+KPX Omacron X -50
+KPX Omacron Y -70
+KPX Omacron Yacute -70
+KPX Omacron Ydieresis -70
+KPX Omacron comma -40
+KPX Omacron period -40
+KPX Oslash A -50
+KPX Oslash Aacute -50
+KPX Oslash Abreve -50
+KPX Oslash Acircumflex -50
+KPX Oslash Adieresis -50
+KPX Oslash Agrave -50
+KPX Oslash Amacron -50
+KPX Oslash Aogonek -50
+KPX Oslash Aring -50
+KPX Oslash Atilde -50
+KPX Oslash T -40
+KPX Oslash Tcaron -40
+KPX Oslash Tcommaaccent -40
+KPX Oslash V -50
+KPX Oslash W -50
+KPX Oslash X -50
+KPX Oslash Y -70
+KPX Oslash Yacute -70
+KPX Oslash Ydieresis -70
+KPX Oslash comma -40
+KPX Oslash period -40
+KPX Otilde A -50
+KPX Otilde Aacute -50
+KPX Otilde Abreve -50
+KPX Otilde Acircumflex -50
+KPX Otilde Adieresis -50
+KPX Otilde Agrave -50
+KPX Otilde Amacron -50
+KPX Otilde Aogonek -50
+KPX Otilde Aring -50
+KPX Otilde Atilde -50
+KPX Otilde T -40
+KPX Otilde Tcaron -40
+KPX Otilde Tcommaaccent -40
+KPX Otilde V -50
+KPX Otilde W -50
+KPX Otilde X -50
+KPX Otilde Y -70
+KPX Otilde Yacute -70
+KPX Otilde Ydieresis -70
+KPX Otilde comma -40
+KPX Otilde period -40
+KPX P A -100
+KPX P Aacute -100
+KPX P Abreve -100
+KPX P Acircumflex -100
+KPX P Adieresis -100
+KPX P Agrave -100
+KPX P Amacron -100
+KPX P Aogonek -100
+KPX P Aring -100
+KPX P Atilde -100
+KPX P a -30
+KPX P aacute -30
+KPX P abreve -30
+KPX P acircumflex -30
+KPX P adieresis -30
+KPX P agrave -30
+KPX P amacron -30
+KPX P aogonek -30
+KPX P aring -30
+KPX P atilde -30
+KPX P comma -120
+KPX P e -30
+KPX P eacute -30
+KPX P ecaron -30
+KPX P ecircumflex -30
+KPX P edieresis -30
+KPX P edotaccent -30
+KPX P egrave -30
+KPX P emacron -30
+KPX P eogonek -30
+KPX P o -40
+KPX P oacute -40
+KPX P ocircumflex -40
+KPX P odieresis -40
+KPX P ograve -40
+KPX P ohungarumlaut -40
+KPX P omacron -40
+KPX P oslash -40
+KPX P otilde -40
+KPX P period -120
+KPX Q U -10
+KPX Q Uacute -10
+KPX Q Ucircumflex -10
+KPX Q Udieresis -10
+KPX Q Ugrave -10
+KPX Q Uhungarumlaut -10
+KPX Q Umacron -10
+KPX Q Uogonek -10
+KPX Q Uring -10
+KPX Q comma 20
+KPX Q period 20
+KPX R O -20
+KPX R Oacute -20
+KPX R Ocircumflex -20
+KPX R Odieresis -20
+KPX R Ograve -20
+KPX R Ohungarumlaut -20
+KPX R Omacron -20
+KPX R Oslash -20
+KPX R Otilde -20
+KPX R T -20
+KPX R Tcaron -20
+KPX R Tcommaaccent -20
+KPX R U -20
+KPX R Uacute -20
+KPX R Ucircumflex -20
+KPX R Udieresis -20
+KPX R Ugrave -20
+KPX R Uhungarumlaut -20
+KPX R Umacron -20
+KPX R Uogonek -20
+KPX R Uring -20
+KPX R V -50
+KPX R W -40
+KPX R Y -50
+KPX R Yacute -50
+KPX R Ydieresis -50
+KPX Racute O -20
+KPX Racute Oacute -20
+KPX Racute Ocircumflex -20
+KPX Racute Odieresis -20
+KPX Racute Ograve -20
+KPX Racute Ohungarumlaut -20
+KPX Racute Omacron -20
+KPX Racute Oslash -20
+KPX Racute Otilde -20
+KPX Racute T -20
+KPX Racute Tcaron -20
+KPX Racute Tcommaaccent -20
+KPX Racute U -20
+KPX Racute Uacute -20
+KPX Racute Ucircumflex -20
+KPX Racute Udieresis -20
+KPX Racute Ugrave -20
+KPX Racute Uhungarumlaut -20
+KPX Racute Umacron -20
+KPX Racute Uogonek -20
+KPX Racute Uring -20
+KPX Racute V -50
+KPX Racute W -40
+KPX Racute Y -50
+KPX Racute Yacute -50
+KPX Racute Ydieresis -50
+KPX Rcaron O -20
+KPX Rcaron Oacute -20
+KPX Rcaron Ocircumflex -20
+KPX Rcaron Odieresis -20
+KPX Rcaron Ograve -20
+KPX Rcaron Ohungarumlaut -20
+KPX Rcaron Omacron -20
+KPX Rcaron Oslash -20
+KPX Rcaron Otilde -20
+KPX Rcaron T -20
+KPX Rcaron Tcaron -20
+KPX Rcaron Tcommaaccent -20
+KPX Rcaron U -20
+KPX Rcaron Uacute -20
+KPX Rcaron Ucircumflex -20
+KPX Rcaron Udieresis -20
+KPX Rcaron Ugrave -20
+KPX Rcaron Uhungarumlaut -20
+KPX Rcaron Umacron -20
+KPX Rcaron Uogonek -20
+KPX Rcaron Uring -20
+KPX Rcaron V -50
+KPX Rcaron W -40
+KPX Rcaron Y -50
+KPX Rcaron Yacute -50
+KPX Rcaron Ydieresis -50
+KPX Rcommaaccent O -20
+KPX Rcommaaccent Oacute -20
+KPX Rcommaaccent Ocircumflex -20
+KPX Rcommaaccent Odieresis -20
+KPX Rcommaaccent Ograve -20
+KPX Rcommaaccent Ohungarumlaut -20
+KPX Rcommaaccent Omacron -20
+KPX Rcommaaccent Oslash -20
+KPX Rcommaaccent Otilde -20
+KPX Rcommaaccent T -20
+KPX Rcommaaccent Tcaron -20
+KPX Rcommaaccent Tcommaaccent -20
+KPX Rcommaaccent U -20
+KPX Rcommaaccent Uacute -20
+KPX Rcommaaccent Ucircumflex -20
+KPX Rcommaaccent Udieresis -20
+KPX Rcommaaccent Ugrave -20
+KPX Rcommaaccent Uhungarumlaut -20
+KPX Rcommaaccent Umacron -20
+KPX Rcommaaccent Uogonek -20
+KPX Rcommaaccent Uring -20
+KPX Rcommaaccent V -50
+KPX Rcommaaccent W -40
+KPX Rcommaaccent Y -50
+KPX Rcommaaccent Yacute -50
+KPX Rcommaaccent Ydieresis -50
+KPX T A -90
+KPX T Aacute -90
+KPX T Abreve -90
+KPX T Acircumflex -90
+KPX T Adieresis -90
+KPX T Agrave -90
+KPX T Amacron -90
+KPX T Aogonek -90
+KPX T Aring -90
+KPX T Atilde -90
+KPX T O -40
+KPX T Oacute -40
+KPX T Ocircumflex -40
+KPX T Odieresis -40
+KPX T Ograve -40
+KPX T Ohungarumlaut -40
+KPX T Omacron -40
+KPX T Oslash -40
+KPX T Otilde -40
+KPX T a -80
+KPX T aacute -80
+KPX T abreve -80
+KPX T acircumflex -80
+KPX T adieresis -80
+KPX T agrave -80
+KPX T amacron -80
+KPX T aogonek -80
+KPX T aring -80
+KPX T atilde -80
+KPX T colon -40
+KPX T comma -80
+KPX T e -60
+KPX T eacute -60
+KPX T ecaron -60
+KPX T ecircumflex -60
+KPX T edieresis -60
+KPX T edotaccent -60
+KPX T egrave -60
+KPX T emacron -60
+KPX T eogonek -60
+KPX T hyphen -120
+KPX T o -80
+KPX T oacute -80
+KPX T ocircumflex -80
+KPX T odieresis -80
+KPX T ograve -80
+KPX T ohungarumlaut -80
+KPX T omacron -80
+KPX T oslash -80
+KPX T otilde -80
+KPX T period -80
+KPX T r -80
+KPX T racute -80
+KPX T rcommaaccent -80
+KPX T semicolon -40
+KPX T u -90
+KPX T uacute -90
+KPX T ucircumflex -90
+KPX T udieresis -90
+KPX T ugrave -90
+KPX T uhungarumlaut -90
+KPX T umacron -90
+KPX T uogonek -90
+KPX T uring -90
+KPX T w -60
+KPX T y -60
+KPX T yacute -60
+KPX T ydieresis -60
+KPX Tcaron A -90
+KPX Tcaron Aacute -90
+KPX Tcaron Abreve -90
+KPX Tcaron Acircumflex -90
+KPX Tcaron Adieresis -90
+KPX Tcaron Agrave -90
+KPX Tcaron Amacron -90
+KPX Tcaron Aogonek -90
+KPX Tcaron Aring -90
+KPX Tcaron Atilde -90
+KPX Tcaron O -40
+KPX Tcaron Oacute -40
+KPX Tcaron Ocircumflex -40
+KPX Tcaron Odieresis -40
+KPX Tcaron Ograve -40
+KPX Tcaron Ohungarumlaut -40
+KPX Tcaron Omacron -40
+KPX Tcaron Oslash -40
+KPX Tcaron Otilde -40
+KPX Tcaron a -80
+KPX Tcaron aacute -80
+KPX Tcaron abreve -80
+KPX Tcaron acircumflex -80
+KPX Tcaron adieresis -80
+KPX Tcaron agrave -80
+KPX Tcaron amacron -80
+KPX Tcaron aogonek -80
+KPX Tcaron aring -80
+KPX Tcaron atilde -80
+KPX Tcaron colon -40
+KPX Tcaron comma -80
+KPX Tcaron e -60
+KPX Tcaron eacute -60
+KPX Tcaron ecaron -60
+KPX Tcaron ecircumflex -60
+KPX Tcaron edieresis -60
+KPX Tcaron edotaccent -60
+KPX Tcaron egrave -60
+KPX Tcaron emacron -60
+KPX Tcaron eogonek -60
+KPX Tcaron hyphen -120
+KPX Tcaron o -80
+KPX Tcaron oacute -80
+KPX Tcaron ocircumflex -80
+KPX Tcaron odieresis -80
+KPX Tcaron ograve -80
+KPX Tcaron ohungarumlaut -80
+KPX Tcaron omacron -80
+KPX Tcaron oslash -80
+KPX Tcaron otilde -80
+KPX Tcaron period -80
+KPX Tcaron r -80
+KPX Tcaron racute -80
+KPX Tcaron rcommaaccent -80
+KPX Tcaron semicolon -40
+KPX Tcaron u -90
+KPX Tcaron uacute -90
+KPX Tcaron ucircumflex -90
+KPX Tcaron udieresis -90
+KPX Tcaron ugrave -90
+KPX Tcaron uhungarumlaut -90
+KPX Tcaron umacron -90
+KPX Tcaron uogonek -90
+KPX Tcaron uring -90
+KPX Tcaron w -60
+KPX Tcaron y -60
+KPX Tcaron yacute -60
+KPX Tcaron ydieresis -60
+KPX Tcommaaccent A -90
+KPX Tcommaaccent Aacute -90
+KPX Tcommaaccent Abreve -90
+KPX Tcommaaccent Acircumflex -90
+KPX Tcommaaccent Adieresis -90
+KPX Tcommaaccent Agrave -90
+KPX Tcommaaccent Amacron -90
+KPX Tcommaaccent Aogonek -90
+KPX Tcommaaccent Aring -90
+KPX Tcommaaccent Atilde -90
+KPX Tcommaaccent O -40
+KPX Tcommaaccent Oacute -40
+KPX Tcommaaccent Ocircumflex -40
+KPX Tcommaaccent Odieresis -40
+KPX Tcommaaccent Ograve -40
+KPX Tcommaaccent Ohungarumlaut -40
+KPX Tcommaaccent Omacron -40
+KPX Tcommaaccent Oslash -40
+KPX Tcommaaccent Otilde -40
+KPX Tcommaaccent a -80
+KPX Tcommaaccent aacute -80
+KPX Tcommaaccent abreve -80
+KPX Tcommaaccent acircumflex -80
+KPX Tcommaaccent adieresis -80
+KPX Tcommaaccent agrave -80
+KPX Tcommaaccent amacron -80
+KPX Tcommaaccent aogonek -80
+KPX Tcommaaccent aring -80
+KPX Tcommaaccent atilde -80
+KPX Tcommaaccent colon -40
+KPX Tcommaaccent comma -80
+KPX Tcommaaccent e -60
+KPX Tcommaaccent eacute -60
+KPX Tcommaaccent ecaron -60
+KPX Tcommaaccent ecircumflex -60
+KPX Tcommaaccent edieresis -60
+KPX Tcommaaccent edotaccent -60
+KPX Tcommaaccent egrave -60
+KPX Tcommaaccent emacron -60
+KPX Tcommaaccent eogonek -60
+KPX Tcommaaccent hyphen -120
+KPX Tcommaaccent o -80
+KPX Tcommaaccent oacute -80
+KPX Tcommaaccent ocircumflex -80
+KPX Tcommaaccent odieresis -80
+KPX Tcommaaccent ograve -80
+KPX Tcommaaccent ohungarumlaut -80
+KPX Tcommaaccent omacron -80
+KPX Tcommaaccent oslash -80
+KPX Tcommaaccent otilde -80
+KPX Tcommaaccent period -80
+KPX Tcommaaccent r -80
+KPX Tcommaaccent racute -80
+KPX Tcommaaccent rcommaaccent -80
+KPX Tcommaaccent semicolon -40
+KPX Tcommaaccent u -90
+KPX Tcommaaccent uacute -90
+KPX Tcommaaccent ucircumflex -90
+KPX Tcommaaccent udieresis -90
+KPX Tcommaaccent ugrave -90
+KPX Tcommaaccent uhungarumlaut -90
+KPX Tcommaaccent umacron -90
+KPX Tcommaaccent uogonek -90
+KPX Tcommaaccent uring -90
+KPX Tcommaaccent w -60
+KPX Tcommaaccent y -60
+KPX Tcommaaccent yacute -60
+KPX Tcommaaccent ydieresis -60
+KPX U A -50
+KPX U Aacute -50
+KPX U Abreve -50
+KPX U Acircumflex -50
+KPX U Adieresis -50
+KPX U Agrave -50
+KPX U Amacron -50
+KPX U Aogonek -50
+KPX U Aring -50
+KPX U Atilde -50
+KPX U comma -30
+KPX U period -30
+KPX Uacute A -50
+KPX Uacute Aacute -50
+KPX Uacute Abreve -50
+KPX Uacute Acircumflex -50
+KPX Uacute Adieresis -50
+KPX Uacute Agrave -50
+KPX Uacute Amacron -50
+KPX Uacute Aogonek -50
+KPX Uacute Aring -50
+KPX Uacute Atilde -50
+KPX Uacute comma -30
+KPX Uacute period -30
+KPX Ucircumflex A -50
+KPX Ucircumflex Aacute -50
+KPX Ucircumflex Abreve -50
+KPX Ucircumflex Acircumflex -50
+KPX Ucircumflex Adieresis -50
+KPX Ucircumflex Agrave -50
+KPX Ucircumflex Amacron -50
+KPX Ucircumflex Aogonek -50
+KPX Ucircumflex Aring -50
+KPX Ucircumflex Atilde -50
+KPX Ucircumflex comma -30
+KPX Ucircumflex period -30
+KPX Udieresis A -50
+KPX Udieresis Aacute -50
+KPX Udieresis Abreve -50
+KPX Udieresis Acircumflex -50
+KPX Udieresis Adieresis -50
+KPX Udieresis Agrave -50
+KPX Udieresis Amacron -50
+KPX Udieresis Aogonek -50
+KPX Udieresis Aring -50
+KPX Udieresis Atilde -50
+KPX Udieresis comma -30
+KPX Udieresis period -30
+KPX Ugrave A -50
+KPX Ugrave Aacute -50
+KPX Ugrave Abreve -50
+KPX Ugrave Acircumflex -50
+KPX Ugrave Adieresis -50
+KPX Ugrave Agrave -50
+KPX Ugrave Amacron -50
+KPX Ugrave Aogonek -50
+KPX Ugrave Aring -50
+KPX Ugrave Atilde -50
+KPX Ugrave comma -30
+KPX Ugrave period -30
+KPX Uhungarumlaut A -50
+KPX Uhungarumlaut Aacute -50
+KPX Uhungarumlaut Abreve -50
+KPX Uhungarumlaut Acircumflex -50
+KPX Uhungarumlaut Adieresis -50
+KPX Uhungarumlaut Agrave -50
+KPX Uhungarumlaut Amacron -50
+KPX Uhungarumlaut Aogonek -50
+KPX Uhungarumlaut Aring -50
+KPX Uhungarumlaut Atilde -50
+KPX Uhungarumlaut comma -30
+KPX Uhungarumlaut period -30
+KPX Umacron A -50
+KPX Umacron Aacute -50
+KPX Umacron Abreve -50
+KPX Umacron Acircumflex -50
+KPX Umacron Adieresis -50
+KPX Umacron Agrave -50
+KPX Umacron Amacron -50
+KPX Umacron Aogonek -50
+KPX Umacron Aring -50
+KPX Umacron Atilde -50
+KPX Umacron comma -30
+KPX Umacron period -30
+KPX Uogonek A -50
+KPX Uogonek Aacute -50
+KPX Uogonek Abreve -50
+KPX Uogonek Acircumflex -50
+KPX Uogonek Adieresis -50
+KPX Uogonek Agrave -50
+KPX Uogonek Amacron -50
+KPX Uogonek Aogonek -50
+KPX Uogonek Aring -50
+KPX Uogonek Atilde -50
+KPX Uogonek comma -30
+KPX Uogonek period -30
+KPX Uring A -50
+KPX Uring Aacute -50
+KPX Uring Abreve -50
+KPX Uring Acircumflex -50
+KPX Uring Adieresis -50
+KPX Uring Agrave -50
+KPX Uring Amacron -50
+KPX Uring Aogonek -50
+KPX Uring Aring -50
+KPX Uring Atilde -50
+KPX Uring comma -30
+KPX Uring period -30
+KPX V A -80
+KPX V Aacute -80
+KPX V Abreve -80
+KPX V Acircumflex -80
+KPX V Adieresis -80
+KPX V Agrave -80
+KPX V Amacron -80
+KPX V Aogonek -80
+KPX V Aring -80
+KPX V Atilde -80
+KPX V G -50
+KPX V Gbreve -50
+KPX V Gcommaaccent -50
+KPX V O -50
+KPX V Oacute -50
+KPX V Ocircumflex -50
+KPX V Odieresis -50
+KPX V Ograve -50
+KPX V Ohungarumlaut -50
+KPX V Omacron -50
+KPX V Oslash -50
+KPX V Otilde -50
+KPX V a -60
+KPX V aacute -60
+KPX V abreve -60
+KPX V acircumflex -60
+KPX V adieresis -60
+KPX V agrave -60
+KPX V amacron -60
+KPX V aogonek -60
+KPX V aring -60
+KPX V atilde -60
+KPX V colon -40
+KPX V comma -120
+KPX V e -50
+KPX V eacute -50
+KPX V ecaron -50
+KPX V ecircumflex -50
+KPX V edieresis -50
+KPX V edotaccent -50
+KPX V egrave -50
+KPX V emacron -50
+KPX V eogonek -50
+KPX V hyphen -80
+KPX V o -90
+KPX V oacute -90
+KPX V ocircumflex -90
+KPX V odieresis -90
+KPX V ograve -90
+KPX V ohungarumlaut -90
+KPX V omacron -90
+KPX V oslash -90
+KPX V otilde -90
+KPX V period -120
+KPX V semicolon -40
+KPX V u -60
+KPX V uacute -60
+KPX V ucircumflex -60
+KPX V udieresis -60
+KPX V ugrave -60
+KPX V uhungarumlaut -60
+KPX V umacron -60
+KPX V uogonek -60
+KPX V uring -60
+KPX W A -60
+KPX W Aacute -60
+KPX W Abreve -60
+KPX W Acircumflex -60
+KPX W Adieresis -60
+KPX W Agrave -60
+KPX W Amacron -60
+KPX W Aogonek -60
+KPX W Aring -60
+KPX W Atilde -60
+KPX W O -20
+KPX W Oacute -20
+KPX W Ocircumflex -20
+KPX W Odieresis -20
+KPX W Ograve -20
+KPX W Ohungarumlaut -20
+KPX W Omacron -20
+KPX W Oslash -20
+KPX W Otilde -20
+KPX W a -40
+KPX W aacute -40
+KPX W abreve -40
+KPX W acircumflex -40
+KPX W adieresis -40
+KPX W agrave -40
+KPX W amacron -40
+KPX W aogonek -40
+KPX W aring -40
+KPX W atilde -40
+KPX W colon -10
+KPX W comma -80
+KPX W e -35
+KPX W eacute -35
+KPX W ecaron -35
+KPX W ecircumflex -35
+KPX W edieresis -35
+KPX W edotaccent -35
+KPX W egrave -35
+KPX W emacron -35
+KPX W eogonek -35
+KPX W hyphen -40
+KPX W o -60
+KPX W oacute -60
+KPX W ocircumflex -60
+KPX W odieresis -60
+KPX W ograve -60
+KPX W ohungarumlaut -60
+KPX W omacron -60
+KPX W oslash -60
+KPX W otilde -60
+KPX W period -80
+KPX W semicolon -10
+KPX W u -45
+KPX W uacute -45
+KPX W ucircumflex -45
+KPX W udieresis -45
+KPX W ugrave -45
+KPX W uhungarumlaut -45
+KPX W umacron -45
+KPX W uogonek -45
+KPX W uring -45
+KPX W y -20
+KPX W yacute -20
+KPX W ydieresis -20
+KPX Y A -110
+KPX Y Aacute -110
+KPX Y Abreve -110
+KPX Y Acircumflex -110
+KPX Y Adieresis -110
+KPX Y Agrave -110
+KPX Y Amacron -110
+KPX Y Aogonek -110
+KPX Y Aring -110
+KPX Y Atilde -110
+KPX Y O -70
+KPX Y Oacute -70
+KPX Y Ocircumflex -70
+KPX Y Odieresis -70
+KPX Y Ograve -70
+KPX Y Ohungarumlaut -70
+KPX Y Omacron -70
+KPX Y Oslash -70
+KPX Y Otilde -70
+KPX Y a -90
+KPX Y aacute -90
+KPX Y abreve -90
+KPX Y acircumflex -90
+KPX Y adieresis -90
+KPX Y agrave -90
+KPX Y amacron -90
+KPX Y aogonek -90
+KPX Y aring -90
+KPX Y atilde -90
+KPX Y colon -50
+KPX Y comma -100
+KPX Y e -80
+KPX Y eacute -80
+KPX Y ecaron -80
+KPX Y ecircumflex -80
+KPX Y edieresis -80
+KPX Y edotaccent -80
+KPX Y egrave -80
+KPX Y emacron -80
+KPX Y eogonek -80
+KPX Y o -100
+KPX Y oacute -100
+KPX Y ocircumflex -100
+KPX Y odieresis -100
+KPX Y ograve -100
+KPX Y ohungarumlaut -100
+KPX Y omacron -100
+KPX Y oslash -100
+KPX Y otilde -100
+KPX Y period -100
+KPX Y semicolon -50
+KPX Y u -100
+KPX Y uacute -100
+KPX Y ucircumflex -100
+KPX Y udieresis -100
+KPX Y ugrave -100
+KPX Y uhungarumlaut -100
+KPX Y umacron -100
+KPX Y uogonek -100
+KPX Y uring -100
+KPX Yacute A -110
+KPX Yacute Aacute -110
+KPX Yacute Abreve -110
+KPX Yacute Acircumflex -110
+KPX Yacute Adieresis -110
+KPX Yacute Agrave -110
+KPX Yacute Amacron -110
+KPX Yacute Aogonek -110
+KPX Yacute Aring -110
+KPX Yacute Atilde -110
+KPX Yacute O -70
+KPX Yacute Oacute -70
+KPX Yacute Ocircumflex -70
+KPX Yacute Odieresis -70
+KPX Yacute Ograve -70
+KPX Yacute Ohungarumlaut -70
+KPX Yacute Omacron -70
+KPX Yacute Oslash -70
+KPX Yacute Otilde -70
+KPX Yacute a -90
+KPX Yacute aacute -90
+KPX Yacute abreve -90
+KPX Yacute acircumflex -90
+KPX Yacute adieresis -90
+KPX Yacute agrave -90
+KPX Yacute amacron -90
+KPX Yacute aogonek -90
+KPX Yacute aring -90
+KPX Yacute atilde -90
+KPX Yacute colon -50
+KPX Yacute comma -100
+KPX Yacute e -80
+KPX Yacute eacute -80
+KPX Yacute ecaron -80
+KPX Yacute ecircumflex -80
+KPX Yacute edieresis -80
+KPX Yacute edotaccent -80
+KPX Yacute egrave -80
+KPX Yacute emacron -80
+KPX Yacute eogonek -80
+KPX Yacute o -100
+KPX Yacute oacute -100
+KPX Yacute ocircumflex -100
+KPX Yacute odieresis -100
+KPX Yacute ograve -100
+KPX Yacute ohungarumlaut -100
+KPX Yacute omacron -100
+KPX Yacute oslash -100
+KPX Yacute otilde -100
+KPX Yacute period -100
+KPX Yacute semicolon -50
+KPX Yacute u -100
+KPX Yacute uacute -100
+KPX Yacute ucircumflex -100
+KPX Yacute udieresis -100
+KPX Yacute ugrave -100
+KPX Yacute uhungarumlaut -100
+KPX Yacute umacron -100
+KPX Yacute uogonek -100
+KPX Yacute uring -100
+KPX Ydieresis A -110
+KPX Ydieresis Aacute -110
+KPX Ydieresis Abreve -110
+KPX Ydieresis Acircumflex -110
+KPX Ydieresis Adieresis -110
+KPX Ydieresis Agrave -110
+KPX Ydieresis Amacron -110
+KPX Ydieresis Aogonek -110
+KPX Ydieresis Aring -110
+KPX Ydieresis Atilde -110
+KPX Ydieresis O -70
+KPX Ydieresis Oacute -70
+KPX Ydieresis Ocircumflex -70
+KPX Ydieresis Odieresis -70
+KPX Ydieresis Ograve -70
+KPX Ydieresis Ohungarumlaut -70
+KPX Ydieresis Omacron -70
+KPX Ydieresis Oslash -70
+KPX Ydieresis Otilde -70
+KPX Ydieresis a -90
+KPX Ydieresis aacute -90
+KPX Ydieresis abreve -90
+KPX Ydieresis acircumflex -90
+KPX Ydieresis adieresis -90
+KPX Ydieresis agrave -90
+KPX Ydieresis amacron -90
+KPX Ydieresis aogonek -90
+KPX Ydieresis aring -90
+KPX Ydieresis atilde -90
+KPX Ydieresis colon -50
+KPX Ydieresis comma -100
+KPX Ydieresis e -80
+KPX Ydieresis eacute -80
+KPX Ydieresis ecaron -80
+KPX Ydieresis ecircumflex -80
+KPX Ydieresis edieresis -80
+KPX Ydieresis edotaccent -80
+KPX Ydieresis egrave -80
+KPX Ydieresis emacron -80
+KPX Ydieresis eogonek -80
+KPX Ydieresis o -100
+KPX Ydieresis oacute -100
+KPX Ydieresis ocircumflex -100
+KPX Ydieresis odieresis -100
+KPX Ydieresis ograve -100
+KPX Ydieresis ohungarumlaut -100
+KPX Ydieresis omacron -100
+KPX Ydieresis oslash -100
+KPX Ydieresis otilde -100
+KPX Ydieresis period -100
+KPX Ydieresis semicolon -50
+KPX Ydieresis u -100
+KPX Ydieresis uacute -100
+KPX Ydieresis ucircumflex -100
+KPX Ydieresis udieresis -100
+KPX Ydieresis ugrave -100
+KPX Ydieresis uhungarumlaut -100
+KPX Ydieresis umacron -100
+KPX Ydieresis uogonek -100
+KPX Ydieresis uring -100
+KPX a g -10
+KPX a gbreve -10
+KPX a gcommaaccent -10
+KPX a v -15
+KPX a w -15
+KPX a y -20
+KPX a yacute -20
+KPX a ydieresis -20
+KPX aacute g -10
+KPX aacute gbreve -10
+KPX aacute gcommaaccent -10
+KPX aacute v -15
+KPX aacute w -15
+KPX aacute y -20
+KPX aacute yacute -20
+KPX aacute ydieresis -20
+KPX abreve g -10
+KPX abreve gbreve -10
+KPX abreve gcommaaccent -10
+KPX abreve v -15
+KPX abreve w -15
+KPX abreve y -20
+KPX abreve yacute -20
+KPX abreve ydieresis -20
+KPX acircumflex g -10
+KPX acircumflex gbreve -10
+KPX acircumflex gcommaaccent -10
+KPX acircumflex v -15
+KPX acircumflex w -15
+KPX acircumflex y -20
+KPX acircumflex yacute -20
+KPX acircumflex ydieresis -20
+KPX adieresis g -10
+KPX adieresis gbreve -10
+KPX adieresis gcommaaccent -10
+KPX adieresis v -15
+KPX adieresis w -15
+KPX adieresis y -20
+KPX adieresis yacute -20
+KPX adieresis ydieresis -20
+KPX agrave g -10
+KPX agrave gbreve -10
+KPX agrave gcommaaccent -10
+KPX agrave v -15
+KPX agrave w -15
+KPX agrave y -20
+KPX agrave yacute -20
+KPX agrave ydieresis -20
+KPX amacron g -10
+KPX amacron gbreve -10
+KPX amacron gcommaaccent -10
+KPX amacron v -15
+KPX amacron w -15
+KPX amacron y -20
+KPX amacron yacute -20
+KPX amacron ydieresis -20
+KPX aogonek g -10
+KPX aogonek gbreve -10
+KPX aogonek gcommaaccent -10
+KPX aogonek v -15
+KPX aogonek w -15
+KPX aogonek y -20
+KPX aogonek yacute -20
+KPX aogonek ydieresis -20
+KPX aring g -10
+KPX aring gbreve -10
+KPX aring gcommaaccent -10
+KPX aring v -15
+KPX aring w -15
+KPX aring y -20
+KPX aring yacute -20
+KPX aring ydieresis -20
+KPX atilde g -10
+KPX atilde gbreve -10
+KPX atilde gcommaaccent -10
+KPX atilde v -15
+KPX atilde w -15
+KPX atilde y -20
+KPX atilde yacute -20
+KPX atilde ydieresis -20
+KPX b l -10
+KPX b lacute -10
+KPX b lcommaaccent -10
+KPX b lslash -10
+KPX b u -20
+KPX b uacute -20
+KPX b ucircumflex -20
+KPX b udieresis -20
+KPX b ugrave -20
+KPX b uhungarumlaut -20
+KPX b umacron -20
+KPX b uogonek -20
+KPX b uring -20
+KPX b v -20
+KPX b y -20
+KPX b yacute -20
+KPX b ydieresis -20
+KPX c h -10
+KPX c k -20
+KPX c kcommaaccent -20
+KPX c l -20
+KPX c lacute -20
+KPX c lcommaaccent -20
+KPX c lslash -20
+KPX c y -10
+KPX c yacute -10
+KPX c ydieresis -10
+KPX cacute h -10
+KPX cacute k -20
+KPX cacute kcommaaccent -20
+KPX cacute l -20
+KPX cacute lacute -20
+KPX cacute lcommaaccent -20
+KPX cacute lslash -20
+KPX cacute y -10
+KPX cacute yacute -10
+KPX cacute ydieresis -10
+KPX ccaron h -10
+KPX ccaron k -20
+KPX ccaron kcommaaccent -20
+KPX ccaron l -20
+KPX ccaron lacute -20
+KPX ccaron lcommaaccent -20
+KPX ccaron lslash -20
+KPX ccaron y -10
+KPX ccaron yacute -10
+KPX ccaron ydieresis -10
+KPX ccedilla h -10
+KPX ccedilla k -20
+KPX ccedilla kcommaaccent -20
+KPX ccedilla l -20
+KPX ccedilla lacute -20
+KPX ccedilla lcommaaccent -20
+KPX ccedilla lslash -20
+KPX ccedilla y -10
+KPX ccedilla yacute -10
+KPX ccedilla ydieresis -10
+KPX colon space -40
+KPX comma quotedblright -120
+KPX comma quoteright -120
+KPX comma space -40
+KPX d d -10
+KPX d dcroat -10
+KPX d v -15
+KPX d w -15
+KPX d y -15
+KPX d yacute -15
+KPX d ydieresis -15
+KPX dcroat d -10
+KPX dcroat dcroat -10
+KPX dcroat v -15
+KPX dcroat w -15
+KPX dcroat y -15
+KPX dcroat yacute -15
+KPX dcroat ydieresis -15
+KPX e comma 10
+KPX e period 20
+KPX e v -15
+KPX e w -15
+KPX e x -15
+KPX e y -15
+KPX e yacute -15
+KPX e ydieresis -15
+KPX eacute comma 10
+KPX eacute period 20
+KPX eacute v -15
+KPX eacute w -15
+KPX eacute x -15
+KPX eacute y -15
+KPX eacute yacute -15
+KPX eacute ydieresis -15
+KPX ecaron comma 10
+KPX ecaron period 20
+KPX ecaron v -15
+KPX ecaron w -15
+KPX ecaron x -15
+KPX ecaron y -15
+KPX ecaron yacute -15
+KPX ecaron ydieresis -15
+KPX ecircumflex comma 10
+KPX ecircumflex period 20
+KPX ecircumflex v -15
+KPX ecircumflex w -15
+KPX ecircumflex x -15
+KPX ecircumflex y -15
+KPX ecircumflex yacute -15
+KPX ecircumflex ydieresis -15
+KPX edieresis comma 10
+KPX edieresis period 20
+KPX edieresis v -15
+KPX edieresis w -15
+KPX edieresis x -15
+KPX edieresis y -15
+KPX edieresis yacute -15
+KPX edieresis ydieresis -15
+KPX edotaccent comma 10
+KPX edotaccent period 20
+KPX edotaccent v -15
+KPX edotaccent w -15
+KPX edotaccent x -15
+KPX edotaccent y -15
+KPX edotaccent yacute -15
+KPX edotaccent ydieresis -15
+KPX egrave comma 10
+KPX egrave period 20
+KPX egrave v -15
+KPX egrave w -15
+KPX egrave x -15
+KPX egrave y -15
+KPX egrave yacute -15
+KPX egrave ydieresis -15
+KPX emacron comma 10
+KPX emacron period 20
+KPX emacron v -15
+KPX emacron w -15
+KPX emacron x -15
+KPX emacron y -15
+KPX emacron yacute -15
+KPX emacron ydieresis -15
+KPX eogonek comma 10
+KPX eogonek period 20
+KPX eogonek v -15
+KPX eogonek w -15
+KPX eogonek x -15
+KPX eogonek y -15
+KPX eogonek yacute -15
+KPX eogonek ydieresis -15
+KPX f comma -10
+KPX f e -10
+KPX f eacute -10
+KPX f ecaron -10
+KPX f ecircumflex -10
+KPX f edieresis -10
+KPX f edotaccent -10
+KPX f egrave -10
+KPX f emacron -10
+KPX f eogonek -10
+KPX f o -20
+KPX f oacute -20
+KPX f ocircumflex -20
+KPX f odieresis -20
+KPX f ograve -20
+KPX f ohungarumlaut -20
+KPX f omacron -20
+KPX f oslash -20
+KPX f otilde -20
+KPX f period -10
+KPX f quotedblright 30
+KPX f quoteright 30
+KPX g e 10
+KPX g eacute 10
+KPX g ecaron 10
+KPX g ecircumflex 10
+KPX g edieresis 10
+KPX g edotaccent 10
+KPX g egrave 10
+KPX g emacron 10
+KPX g eogonek 10
+KPX g g -10
+KPX g gbreve -10
+KPX g gcommaaccent -10
+KPX gbreve e 10
+KPX gbreve eacute 10
+KPX gbreve ecaron 10
+KPX gbreve ecircumflex 10
+KPX gbreve edieresis 10
+KPX gbreve edotaccent 10
+KPX gbreve egrave 10
+KPX gbreve emacron 10
+KPX gbreve eogonek 10
+KPX gbreve g -10
+KPX gbreve gbreve -10
+KPX gbreve gcommaaccent -10
+KPX gcommaaccent e 10
+KPX gcommaaccent eacute 10
+KPX gcommaaccent ecaron 10
+KPX gcommaaccent ecircumflex 10
+KPX gcommaaccent edieresis 10
+KPX gcommaaccent edotaccent 10
+KPX gcommaaccent egrave 10
+KPX gcommaaccent emacron 10
+KPX gcommaaccent eogonek 10
+KPX gcommaaccent g -10
+KPX gcommaaccent gbreve -10
+KPX gcommaaccent gcommaaccent -10
+KPX h y -20
+KPX h yacute -20
+KPX h ydieresis -20
+KPX k o -15
+KPX k oacute -15
+KPX k ocircumflex -15
+KPX k odieresis -15
+KPX k ograve -15
+KPX k ohungarumlaut -15
+KPX k omacron -15
+KPX k oslash -15
+KPX k otilde -15
+KPX kcommaaccent o -15
+KPX kcommaaccent oacute -15
+KPX kcommaaccent ocircumflex -15
+KPX kcommaaccent odieresis -15
+KPX kcommaaccent ograve -15
+KPX kcommaaccent ohungarumlaut -15
+KPX kcommaaccent omacron -15
+KPX kcommaaccent oslash -15
+KPX kcommaaccent otilde -15
+KPX l w -15
+KPX l y -15
+KPX l yacute -15
+KPX l ydieresis -15
+KPX lacute w -15
+KPX lacute y -15
+KPX lacute yacute -15
+KPX lacute ydieresis -15
+KPX lcommaaccent w -15
+KPX lcommaaccent y -15
+KPX lcommaaccent yacute -15
+KPX lcommaaccent ydieresis -15
+KPX lslash w -15
+KPX lslash y -15
+KPX lslash yacute -15
+KPX lslash ydieresis -15
+KPX m u -20
+KPX m uacute -20
+KPX m ucircumflex -20
+KPX m udieresis -20
+KPX m ugrave -20
+KPX m uhungarumlaut -20
+KPX m umacron -20
+KPX m uogonek -20
+KPX m uring -20
+KPX m y -30
+KPX m yacute -30
+KPX m ydieresis -30
+KPX n u -10
+KPX n uacute -10
+KPX n ucircumflex -10
+KPX n udieresis -10
+KPX n ugrave -10
+KPX n uhungarumlaut -10
+KPX n umacron -10
+KPX n uogonek -10
+KPX n uring -10
+KPX n v -40
+KPX n y -20
+KPX n yacute -20
+KPX n ydieresis -20
+KPX nacute u -10
+KPX nacute uacute -10
+KPX nacute ucircumflex -10
+KPX nacute udieresis -10
+KPX nacute ugrave -10
+KPX nacute uhungarumlaut -10
+KPX nacute umacron -10
+KPX nacute uogonek -10
+KPX nacute uring -10
+KPX nacute v -40
+KPX nacute y -20
+KPX nacute yacute -20
+KPX nacute ydieresis -20
+KPX ncaron u -10
+KPX ncaron uacute -10
+KPX ncaron ucircumflex -10
+KPX ncaron udieresis -10
+KPX ncaron ugrave -10
+KPX ncaron uhungarumlaut -10
+KPX ncaron umacron -10
+KPX ncaron uogonek -10
+KPX ncaron uring -10
+KPX ncaron v -40
+KPX ncaron y -20
+KPX ncaron yacute -20
+KPX ncaron ydieresis -20
+KPX ncommaaccent u -10
+KPX ncommaaccent uacute -10
+KPX ncommaaccent ucircumflex -10
+KPX ncommaaccent udieresis -10
+KPX ncommaaccent ugrave -10
+KPX ncommaaccent uhungarumlaut -10
+KPX ncommaaccent umacron -10
+KPX ncommaaccent uogonek -10
+KPX ncommaaccent uring -10
+KPX ncommaaccent v -40
+KPX ncommaaccent y -20
+KPX ncommaaccent yacute -20
+KPX ncommaaccent ydieresis -20
+KPX ntilde u -10
+KPX ntilde uacute -10
+KPX ntilde ucircumflex -10
+KPX ntilde udieresis -10
+KPX ntilde ugrave -10
+KPX ntilde uhungarumlaut -10
+KPX ntilde umacron -10
+KPX ntilde uogonek -10
+KPX ntilde uring -10
+KPX ntilde v -40
+KPX ntilde y -20
+KPX ntilde yacute -20
+KPX ntilde ydieresis -20
+KPX o v -20
+KPX o w -15
+KPX o x -30
+KPX o y -20
+KPX o yacute -20
+KPX o ydieresis -20
+KPX oacute v -20
+KPX oacute w -15
+KPX oacute x -30
+KPX oacute y -20
+KPX oacute yacute -20
+KPX oacute ydieresis -20
+KPX ocircumflex v -20
+KPX ocircumflex w -15
+KPX ocircumflex x -30
+KPX ocircumflex y -20
+KPX ocircumflex yacute -20
+KPX ocircumflex ydieresis -20
+KPX odieresis v -20
+KPX odieresis w -15
+KPX odieresis x -30
+KPX odieresis y -20
+KPX odieresis yacute -20
+KPX odieresis ydieresis -20
+KPX ograve v -20
+KPX ograve w -15
+KPX ograve x -30
+KPX ograve y -20
+KPX ograve yacute -20
+KPX ograve ydieresis -20
+KPX ohungarumlaut v -20
+KPX ohungarumlaut w -15
+KPX ohungarumlaut x -30
+KPX ohungarumlaut y -20
+KPX ohungarumlaut yacute -20
+KPX ohungarumlaut ydieresis -20
+KPX omacron v -20
+KPX omacron w -15
+KPX omacron x -30
+KPX omacron y -20
+KPX omacron yacute -20
+KPX omacron ydieresis -20
+KPX oslash v -20
+KPX oslash w -15
+KPX oslash x -30
+KPX oslash y -20
+KPX oslash yacute -20
+KPX oslash ydieresis -20
+KPX otilde v -20
+KPX otilde w -15
+KPX otilde x -30
+KPX otilde y -20
+KPX otilde yacute -20
+KPX otilde ydieresis -20
+KPX p y -15
+KPX p yacute -15
+KPX p ydieresis -15
+KPX period quotedblright -120
+KPX period quoteright -120
+KPX period space -40
+KPX quotedblright space -80
+KPX quoteleft quoteleft -46
+KPX quoteright d -80
+KPX quoteright dcroat -80
+KPX quoteright l -20
+KPX quoteright lacute -20
+KPX quoteright lcommaaccent -20
+KPX quoteright lslash -20
+KPX quoteright quoteright -46
+KPX quoteright r -40
+KPX quoteright racute -40
+KPX quoteright rcaron -40
+KPX quoteright rcommaaccent -40
+KPX quoteright s -60
+KPX quoteright sacute -60
+KPX quoteright scaron -60
+KPX quoteright scedilla -60
+KPX quoteright scommaaccent -60
+KPX quoteright space -80
+KPX quoteright v -20
+KPX r c -20
+KPX r cacute -20
+KPX r ccaron -20
+KPX r ccedilla -20
+KPX r comma -60
+KPX r d -20
+KPX r dcroat -20
+KPX r g -15
+KPX r gbreve -15
+KPX r gcommaaccent -15
+KPX r hyphen -20
+KPX r o -20
+KPX r oacute -20
+KPX r ocircumflex -20
+KPX r odieresis -20
+KPX r ograve -20
+KPX r ohungarumlaut -20
+KPX r omacron -20
+KPX r oslash -20
+KPX r otilde -20
+KPX r period -60
+KPX r q -20
+KPX r s -15
+KPX r sacute -15
+KPX r scaron -15
+KPX r scedilla -15
+KPX r scommaaccent -15
+KPX r t 20
+KPX r tcommaaccent 20
+KPX r v 10
+KPX r y 10
+KPX r yacute 10
+KPX r ydieresis 10
+KPX racute c -20
+KPX racute cacute -20
+KPX racute ccaron -20
+KPX racute ccedilla -20
+KPX racute comma -60
+KPX racute d -20
+KPX racute dcroat -20
+KPX racute g -15
+KPX racute gbreve -15
+KPX racute gcommaaccent -15
+KPX racute hyphen -20
+KPX racute o -20
+KPX racute oacute -20
+KPX racute ocircumflex -20
+KPX racute odieresis -20
+KPX racute ograve -20
+KPX racute ohungarumlaut -20
+KPX racute omacron -20
+KPX racute oslash -20
+KPX racute otilde -20
+KPX racute period -60
+KPX racute q -20
+KPX racute s -15
+KPX racute sacute -15
+KPX racute scaron -15
+KPX racute scedilla -15
+KPX racute scommaaccent -15
+KPX racute t 20
+KPX racute tcommaaccent 20
+KPX racute v 10
+KPX racute y 10
+KPX racute yacute 10
+KPX racute ydieresis 10
+KPX rcaron c -20
+KPX rcaron cacute -20
+KPX rcaron ccaron -20
+KPX rcaron ccedilla -20
+KPX rcaron comma -60
+KPX rcaron d -20
+KPX rcaron dcroat -20
+KPX rcaron g -15
+KPX rcaron gbreve -15
+KPX rcaron gcommaaccent -15
+KPX rcaron hyphen -20
+KPX rcaron o -20
+KPX rcaron oacute -20
+KPX rcaron ocircumflex -20
+KPX rcaron odieresis -20
+KPX rcaron ograve -20
+KPX rcaron ohungarumlaut -20
+KPX rcaron omacron -20
+KPX rcaron oslash -20
+KPX rcaron otilde -20
+KPX rcaron period -60
+KPX rcaron q -20
+KPX rcaron s -15
+KPX rcaron sacute -15
+KPX rcaron scaron -15
+KPX rcaron scedilla -15
+KPX rcaron scommaaccent -15
+KPX rcaron t 20
+KPX rcaron tcommaaccent 20
+KPX rcaron v 10
+KPX rcaron y 10
+KPX rcaron yacute 10
+KPX rcaron ydieresis 10
+KPX rcommaaccent c -20
+KPX rcommaaccent cacute -20
+KPX rcommaaccent ccaron -20
+KPX rcommaaccent ccedilla -20
+KPX rcommaaccent comma -60
+KPX rcommaaccent d -20
+KPX rcommaaccent dcroat -20
+KPX rcommaaccent g -15
+KPX rcommaaccent gbreve -15
+KPX rcommaaccent gcommaaccent -15
+KPX rcommaaccent hyphen -20
+KPX rcommaaccent o -20
+KPX rcommaaccent oacute -20
+KPX rcommaaccent ocircumflex -20
+KPX rcommaaccent odieresis -20
+KPX rcommaaccent ograve -20
+KPX rcommaaccent ohungarumlaut -20
+KPX rcommaaccent omacron -20
+KPX rcommaaccent oslash -20
+KPX rcommaaccent otilde -20
+KPX rcommaaccent period -60
+KPX rcommaaccent q -20
+KPX rcommaaccent s -15
+KPX rcommaaccent sacute -15
+KPX rcommaaccent scaron -15
+KPX rcommaaccent scedilla -15
+KPX rcommaaccent scommaaccent -15
+KPX rcommaaccent t 20
+KPX rcommaaccent tcommaaccent 20
+KPX rcommaaccent v 10
+KPX rcommaaccent y 10
+KPX rcommaaccent yacute 10
+KPX rcommaaccent ydieresis 10
+KPX s w -15
+KPX sacute w -15
+KPX scaron w -15
+KPX scedilla w -15
+KPX scommaaccent w -15
+KPX semicolon space -40
+KPX space T -100
+KPX space Tcaron -100
+KPX space Tcommaaccent -100
+KPX space V -80
+KPX space W -80
+KPX space Y -120
+KPX space Yacute -120
+KPX space Ydieresis -120
+KPX space quotedblleft -80
+KPX space quoteleft -60
+KPX v a -20
+KPX v aacute -20
+KPX v abreve -20
+KPX v acircumflex -20
+KPX v adieresis -20
+KPX v agrave -20
+KPX v amacron -20
+KPX v aogonek -20
+KPX v aring -20
+KPX v atilde -20
+KPX v comma -80
+KPX v o -30
+KPX v oacute -30
+KPX v ocircumflex -30
+KPX v odieresis -30
+KPX v ograve -30
+KPX v ohungarumlaut -30
+KPX v omacron -30
+KPX v oslash -30
+KPX v otilde -30
+KPX v period -80
+KPX w comma -40
+KPX w o -20
+KPX w oacute -20
+KPX w ocircumflex -20
+KPX w odieresis -20
+KPX w ograve -20
+KPX w ohungarumlaut -20
+KPX w omacron -20
+KPX w oslash -20
+KPX w otilde -20
+KPX w period -40
+KPX x e -10
+KPX x eacute -10
+KPX x ecaron -10
+KPX x ecircumflex -10
+KPX x edieresis -10
+KPX x edotaccent -10
+KPX x egrave -10
+KPX x emacron -10
+KPX x eogonek -10
+KPX y a -30
+KPX y aacute -30
+KPX y abreve -30
+KPX y acircumflex -30
+KPX y adieresis -30
+KPX y agrave -30
+KPX y amacron -30
+KPX y aogonek -30
+KPX y aring -30
+KPX y atilde -30
+KPX y comma -80
+KPX y e -10
+KPX y eacute -10
+KPX y ecaron -10
+KPX y ecircumflex -10
+KPX y edieresis -10
+KPX y edotaccent -10
+KPX y egrave -10
+KPX y emacron -10
+KPX y eogonek -10
+KPX y o -25
+KPX y oacute -25
+KPX y ocircumflex -25
+KPX y odieresis -25
+KPX y ograve -25
+KPX y ohungarumlaut -25
+KPX y omacron -25
+KPX y oslash -25
+KPX y otilde -25
+KPX y period -80
+KPX yacute a -30
+KPX yacute aacute -30
+KPX yacute abreve -30
+KPX yacute acircumflex -30
+KPX yacute adieresis -30
+KPX yacute agrave -30
+KPX yacute amacron -30
+KPX yacute aogonek -30
+KPX yacute aring -30
+KPX yacute atilde -30
+KPX yacute comma -80
+KPX yacute e -10
+KPX yacute eacute -10
+KPX yacute ecaron -10
+KPX yacute ecircumflex -10
+KPX yacute edieresis -10
+KPX yacute edotaccent -10
+KPX yacute egrave -10
+KPX yacute emacron -10
+KPX yacute eogonek -10
+KPX yacute o -25
+KPX yacute oacute -25
+KPX yacute ocircumflex -25
+KPX yacute odieresis -25
+KPX yacute ograve -25
+KPX yacute ohungarumlaut -25
+KPX yacute omacron -25
+KPX yacute oslash -25
+KPX yacute otilde -25
+KPX yacute period -80
+KPX ydieresis a -30
+KPX ydieresis aacute -30
+KPX ydieresis abreve -30
+KPX ydieresis acircumflex -30
+KPX ydieresis adieresis -30
+KPX ydieresis agrave -30
+KPX ydieresis amacron -30
+KPX ydieresis aogonek -30
+KPX ydieresis aring -30
+KPX ydieresis atilde -30
+KPX ydieresis comma -80
+KPX ydieresis e -10
+KPX ydieresis eacute -10
+KPX ydieresis ecaron -10
+KPX ydieresis ecircumflex -10
+KPX ydieresis edieresis -10
+KPX ydieresis edotaccent -10
+KPX ydieresis egrave -10
+KPX ydieresis emacron -10
+KPX ydieresis eogonek -10
+KPX ydieresis o -25
+KPX ydieresis oacute -25
+KPX ydieresis ocircumflex -25
+KPX ydieresis odieresis -25
+KPX ydieresis ograve -25
+KPX ydieresis ohungarumlaut -25
+KPX ydieresis omacron -25
+KPX ydieresis oslash -25
+KPX ydieresis otilde -25
+KPX ydieresis period -80
+KPX z e 10
+KPX z eacute 10
+KPX z ecaron 10
+KPX z ecircumflex 10
+KPX z edieresis 10
+KPX z edotaccent 10
+KPX z egrave 10
+KPX z emacron 10
+KPX z eogonek 10
+KPX zacute e 10
+KPX zacute eacute 10
+KPX zacute ecaron 10
+KPX zacute ecircumflex 10
+KPX zacute edieresis 10
+KPX zacute edotaccent 10
+KPX zacute egrave 10
+KPX zacute emacron 10
+KPX zacute eogonek 10
+KPX zcaron e 10
+KPX zcaron eacute 10
+KPX zcaron ecaron 10
+KPX zcaron ecircumflex 10
+KPX zcaron edieresis 10
+KPX zcaron edotaccent 10
+KPX zcaron egrave 10
+KPX zcaron emacron 10
+KPX zcaron eogonek 10
+KPX zdotaccent e 10
+KPX zdotaccent eacute 10
+KPX zdotaccent ecaron 10
+KPX zdotaccent ecircumflex 10
+KPX zdotaccent edieresis 10
+KPX zdotaccent edotaccent 10
+KPX zdotaccent egrave 10
+KPX zdotaccent emacron 10
+KPX zdotaccent eogonek 10
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-BoldOblique.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-BoldOblique.afm
new file mode 100644
index 0000000..0bb1bfb
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-BoldOblique.afm
@@ -0,0 +1,2827 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 12:45:12 1997
+Comment UniqueID 43053
+Comment VMusage 14482 68586
+FontName Helvetica-BoldOblique
+FullName Helvetica Bold Oblique
+FamilyName Helvetica
+Weight Bold
+ItalicAngle -12
+IsFixedPitch false
+CharacterSet ExtendedRoman
+FontBBox -174 -228 1114 962
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 532
+Ascender 718
+Descender -207
+StdHW 118
+StdVW 140
+StartCharMetrics 315
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ;
+C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ;
+C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ;
+C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ;
+C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ;
+C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ;
+C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ;
+C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ;
+C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ;
+C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ;
+C 43 ; WX 584 ; N plus ; B 82 0 610 506 ;
+C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ;
+C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ;
+C 46 ; WX 278 ; N period ; B 64 0 245 146 ;
+C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ;
+C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ;
+C 49 ; WX 556 ; N one ; B 173 0 529 710 ;
+C 50 ; WX 556 ; N two ; B 26 0 619 710 ;
+C 51 ; WX 556 ; N three ; B 65 -19 608 710 ;
+C 52 ; WX 556 ; N four ; B 60 0 598 710 ;
+C 53 ; WX 556 ; N five ; B 64 -19 636 698 ;
+C 54 ; WX 556 ; N six ; B 85 -19 619 710 ;
+C 55 ; WX 556 ; N seven ; B 125 0 676 698 ;
+C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ;
+C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ;
+C 58 ; WX 333 ; N colon ; B 92 0 351 512 ;
+C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ;
+C 60 ; WX 584 ; N less ; B 82 -8 655 514 ;
+C 61 ; WX 584 ; N equal ; B 58 87 633 419 ;
+C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ;
+C 63 ; WX 611 ; N question ; B 165 0 671 727 ;
+C 64 ; WX 975 ; N at ; B 186 -19 954 737 ;
+C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
+C 66 ; WX 722 ; N B ; B 76 0 764 718 ;
+C 67 ; WX 722 ; N C ; B 107 -19 789 737 ;
+C 68 ; WX 722 ; N D ; B 76 0 777 718 ;
+C 69 ; WX 667 ; N E ; B 76 0 757 718 ;
+C 70 ; WX 611 ; N F ; B 76 0 740 718 ;
+C 71 ; WX 778 ; N G ; B 108 -19 817 737 ;
+C 72 ; WX 722 ; N H ; B 71 0 804 718 ;
+C 73 ; WX 278 ; N I ; B 64 0 367 718 ;
+C 74 ; WX 556 ; N J ; B 60 -18 637 718 ;
+C 75 ; WX 722 ; N K ; B 87 0 858 718 ;
+C 76 ; WX 611 ; N L ; B 76 0 611 718 ;
+C 77 ; WX 833 ; N M ; B 69 0 918 718 ;
+C 78 ; WX 722 ; N N ; B 69 0 807 718 ;
+C 79 ; WX 778 ; N O ; B 107 -19 823 737 ;
+C 80 ; WX 667 ; N P ; B 76 0 738 718 ;
+C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ;
+C 82 ; WX 722 ; N R ; B 76 0 778 718 ;
+C 83 ; WX 667 ; N S ; B 81 -19 718 737 ;
+C 84 ; WX 611 ; N T ; B 140 0 751 718 ;
+C 85 ; WX 722 ; N U ; B 116 -19 804 718 ;
+C 86 ; WX 667 ; N V ; B 172 0 801 718 ;
+C 87 ; WX 944 ; N W ; B 169 0 1082 718 ;
+C 88 ; WX 667 ; N X ; B 14 0 791 718 ;
+C 89 ; WX 667 ; N Y ; B 168 0 806 718 ;
+C 90 ; WX 611 ; N Z ; B 25 0 737 718 ;
+C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ;
+C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ;
+C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ;
+C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ;
+C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ;
+C 97 ; WX 556 ; N a ; B 55 -14 583 546 ;
+C 98 ; WX 611 ; N b ; B 61 -14 645 718 ;
+C 99 ; WX 556 ; N c ; B 79 -14 599 546 ;
+C 100 ; WX 611 ; N d ; B 82 -14 704 718 ;
+C 101 ; WX 556 ; N e ; B 70 -14 593 546 ;
+C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 38 -217 666 546 ;
+C 104 ; WX 611 ; N h ; B 65 0 629 718 ;
+C 105 ; WX 278 ; N i ; B 69 0 363 725 ;
+C 106 ; WX 278 ; N j ; B -42 -214 363 725 ;
+C 107 ; WX 556 ; N k ; B 69 0 670 718 ;
+C 108 ; WX 278 ; N l ; B 69 0 362 718 ;
+C 109 ; WX 889 ; N m ; B 64 0 909 546 ;
+C 110 ; WX 611 ; N n ; B 65 0 629 546 ;
+C 111 ; WX 611 ; N o ; B 82 -14 643 546 ;
+C 112 ; WX 611 ; N p ; B 18 -207 645 546 ;
+C 113 ; WX 611 ; N q ; B 80 -207 665 546 ;
+C 114 ; WX 389 ; N r ; B 64 0 489 546 ;
+C 115 ; WX 556 ; N s ; B 63 -14 584 546 ;
+C 116 ; WX 333 ; N t ; B 100 -6 422 676 ;
+C 117 ; WX 611 ; N u ; B 98 -14 658 532 ;
+C 118 ; WX 556 ; N v ; B 126 0 656 532 ;
+C 119 ; WX 778 ; N w ; B 123 0 882 532 ;
+C 120 ; WX 556 ; N x ; B 15 0 648 532 ;
+C 121 ; WX 556 ; N y ; B 42 -214 652 532 ;
+C 122 ; WX 500 ; N z ; B 20 0 583 532 ;
+C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ;
+C 124 ; WX 280 ; N bar ; B 36 -225 361 775 ;
+C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ;
+C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ;
+C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ;
+C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ;
+C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ;
+C 165 ; WX 556 ; N yen ; B 60 0 713 698 ;
+C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ;
+C 167 ; WX 556 ; N section ; B 61 -184 598 727 ;
+C 168 ; WX 556 ; N currency ; B 27 76 680 636 ;
+C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ;
+C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ;
+C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ;
+C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ;
+C 174 ; WX 611 ; N fi ; B 87 0 696 727 ;
+C 175 ; WX 611 ; N fl ; B 87 0 695 727 ;
+C 177 ; WX 556 ; N endash ; B 48 227 627 333 ;
+C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ;
+C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ;
+C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ;
+C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ;
+C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ;
+C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ;
+C 193 ; WX 333 ; N grave ; B 136 604 353 750 ;
+C 194 ; WX 333 ; N acute ; B 236 604 515 750 ;
+C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ;
+C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ;
+C 197 ; WX 333 ; N macron ; B 122 604 483 678 ;
+C 198 ; WX 333 ; N breve ; B 156 604 494 750 ;
+C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ;
+C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ;
+C 202 ; WX 333 ; N ring ; B 200 568 420 776 ;
+C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ;
+C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ;
+C 207 ; WX 333 ; N caron ; B 149 604 502 750 ;
+C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ;
+C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 125 401 465 737 ;
+C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ;
+C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ;
+C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 123 401 485 737 ;
+C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ;
+C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ;
+C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ;
+C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ;
+C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ;
+C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ;
+C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ;
+C -1 ; WX 556 ; N abreve ; B 55 -14 606 750 ;
+C -1 ; WX 611 ; N uhungarumlaut ; B 98 -14 784 750 ;
+C -1 ; WX 556 ; N ecaron ; B 70 -14 614 750 ;
+C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ;
+C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ;
+C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ;
+C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ;
+C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ;
+C -1 ; WX 556 ; N scommaaccent ; B 63 -228 584 546 ;
+C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ;
+C -1 ; WX 722 ; N Uring ; B 116 -19 804 962 ;
+C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ;
+C -1 ; WX 556 ; N aogonek ; B 55 -224 583 546 ;
+C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ;
+C -1 ; WX 611 ; N uogonek ; B 98 -228 658 532 ;
+C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ;
+C -1 ; WX 722 ; N Dcroat ; B 62 0 777 718 ;
+C -1 ; WX 250 ; N commaaccent ; B 16 -228 188 -50 ;
+C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ;
+C -1 ; WX 667 ; N Emacron ; B 76 0 757 864 ;
+C -1 ; WX 556 ; N ccaron ; B 79 -14 614 750 ;
+C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ;
+C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 807 718 ;
+C -1 ; WX 278 ; N lacute ; B 69 0 528 936 ;
+C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ;
+C -1 ; WX 611 ; N Tcommaaccent ; B 140 -228 751 718 ;
+C -1 ; WX 722 ; N Cacute ; B 107 -19 789 936 ;
+C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ;
+C -1 ; WX 667 ; N Edotaccent ; B 76 0 757 915 ;
+C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ;
+C -1 ; WX 556 ; N scedilla ; B 63 -228 584 546 ;
+C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ;
+C -1 ; WX 494 ; N lozenge ; B 90 0 564 745 ;
+C -1 ; WX 722 ; N Rcaron ; B 76 0 778 936 ;
+C -1 ; WX 778 ; N Gcommaaccent ; B 108 -228 817 737 ;
+C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ;
+C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ;
+C -1 ; WX 722 ; N Amacron ; B 20 0 718 864 ;
+C -1 ; WX 389 ; N rcaron ; B 64 0 530 750 ;
+C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ;
+C -1 ; WX 611 ; N Zdotaccent ; B 25 0 737 915 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ;
+C -1 ; WX 778 ; N Omacron ; B 107 -19 823 864 ;
+C -1 ; WX 722 ; N Racute ; B 76 0 778 936 ;
+C -1 ; WX 667 ; N Sacute ; B 81 -19 722 936 ;
+C -1 ; WX 743 ; N dcaron ; B 82 -14 903 718 ;
+C -1 ; WX 722 ; N Umacron ; B 116 -19 804 864 ;
+C -1 ; WX 611 ; N uring ; B 98 -14 658 776 ;
+C -1 ; WX 333 ; N threebaseior ; B 91 271 441 710 ;
+C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ;
+C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
+C -1 ; WX 722 ; N Abreve ; B 20 0 729 936 ;
+C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ;
+C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ;
+C -1 ; WX 611 ; N Tcaron ; B 140 0 751 936 ;
+C -1 ; WX 494 ; N partialdiff ; B 43 -21 585 750 ;
+C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ;
+C -1 ; WX 722 ; N Nacute ; B 69 0 807 936 ;
+C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ;
+C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ;
+C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ;
+C -1 ; WX 556 ; N cacute ; B 79 -14 627 750 ;
+C -1 ; WX 611 ; N nacute ; B 65 0 654 750 ;
+C -1 ; WX 611 ; N umacron ; B 98 -14 658 678 ;
+C -1 ; WX 722 ; N Ncaron ; B 69 0 807 936 ;
+C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ;
+C -1 ; WX 280 ; N brokenbar ; B 52 -150 345 700 ;
+C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ;
+C -1 ; WX 778 ; N Gbreve ; B 108 -19 817 936 ;
+C -1 ; WX 278 ; N Idotaccent ; B 64 0 397 915 ;
+C -1 ; WX 600 ; N summation ; B 14 -10 670 706 ;
+C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ;
+C -1 ; WX 389 ; N racute ; B 64 0 543 750 ;
+C -1 ; WX 611 ; N omacron ; B 82 -14 643 678 ;
+C -1 ; WX 611 ; N Zacute ; B 25 0 737 936 ;
+C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ;
+C -1 ; WX 549 ; N greaterequal ; B 26 0 629 704 ;
+C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ;
+C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ;
+C -1 ; WX 278 ; N lcommaaccent ; B 30 -228 362 718 ;
+C -1 ; WX 389 ; N tcaron ; B 100 -6 608 878 ;
+C -1 ; WX 556 ; N eogonek ; B 70 -228 593 546 ;
+C -1 ; WX 722 ; N Uogonek ; B 116 -228 804 718 ;
+C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ;
+C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ;
+C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ;
+C -1 ; WX 500 ; N zacute ; B 20 0 599 750 ;
+C -1 ; WX 278 ; N iogonek ; B -14 -224 363 725 ;
+C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ;
+C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ;
+C -1 ; WX 556 ; N amacron ; B 55 -14 595 678 ;
+C -1 ; WX 556 ; N sacute ; B 63 -14 627 750 ;
+C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ;
+C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ;
+C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ;
+C -1 ; WX 333 ; N twobaseior ; B 69 283 449 710 ;
+C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ;
+C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ;
+C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ;
+C -1 ; WX 611 ; N ohungarumlaut ; B 82 -14 784 750 ;
+C -1 ; WX 667 ; N Eogonek ; B 76 -224 757 718 ;
+C -1 ; WX 611 ; N dcroat ; B 82 -14 789 718 ;
+C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ;
+C -1 ; WX 667 ; N Scedilla ; B 81 -228 718 737 ;
+C -1 ; WX 400 ; N lcaron ; B 69 0 561 718 ;
+C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 858 718 ;
+C -1 ; WX 611 ; N Lacute ; B 76 0 611 936 ;
+C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ;
+C -1 ; WX 556 ; N edotaccent ; B 70 -14 593 729 ;
+C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ;
+C -1 ; WX 278 ; N Imacron ; B 64 0 496 864 ;
+C -1 ; WX 611 ; N Lcaron ; B 76 0 643 718 ;
+C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ;
+C -1 ; WX 549 ; N lessequal ; B 29 0 676 704 ;
+C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ;
+C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ;
+C -1 ; WX 722 ; N Uhungarumlaut ; B 116 -19 880 936 ;
+C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ;
+C -1 ; WX 556 ; N emacron ; B 70 -14 595 678 ;
+C -1 ; WX 611 ; N gbreve ; B 38 -217 666 750 ;
+C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ;
+C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ;
+C -1 ; WX 667 ; N Scommaaccent ; B 81 -228 718 737 ;
+C -1 ; WX 778 ; N Ohungarumlaut ; B 107 -19 908 936 ;
+C -1 ; WX 400 ; N degree ; B 175 426 467 712 ;
+C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ;
+C -1 ; WX 722 ; N Ccaron ; B 107 -19 789 936 ;
+C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ;
+C -1 ; WX 549 ; N radical ; B 112 -46 689 850 ;
+C -1 ; WX 722 ; N Dcaron ; B 76 0 777 936 ;
+C -1 ; WX 389 ; N rcommaaccent ; B 26 -228 489 546 ;
+C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ;
+C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ;
+C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 778 718 ;
+C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 611 718 ;
+C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ;
+C -1 ; WX 722 ; N Aogonek ; B 20 -224 702 718 ;
+C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
+C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ;
+C -1 ; WX 500 ; N zdotaccent ; B 20 0 583 729 ;
+C -1 ; WX 667 ; N Ecaron ; B 76 0 757 936 ;
+C -1 ; WX 278 ; N Iogonek ; B -41 -228 367 718 ;
+C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 670 718 ;
+C -1 ; WX 584 ; N minus ; B 82 197 610 309 ;
+C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ;
+C -1 ; WX 611 ; N ncaron ; B 65 0 641 750 ;
+C -1 ; WX 333 ; N tcommaaccent ; B 58 -228 422 676 ;
+C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ;
+C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ;
+C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ;
+C -1 ; WX 549 ; N notequal ; B 32 -49 630 570 ;
+C -1 ; WX 611 ; N gcommaaccent ; B 38 -217 666 850 ;
+C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ;
+C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ;
+C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 629 546 ;
+C -1 ; WX 333 ; N onebaseior ; B 148 283 388 710 ;
+C -1 ; WX 278 ; N imacron ; B 69 0 429 678 ;
+C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 2481
+KPX A C -40
+KPX A Cacute -40
+KPX A Ccaron -40
+KPX A Ccedilla -40
+KPX A G -50
+KPX A Gbreve -50
+KPX A Gcommaaccent -50
+KPX A O -40
+KPX A Oacute -40
+KPX A Ocircumflex -40
+KPX A Odieresis -40
+KPX A Ograve -40
+KPX A Ohungarumlaut -40
+KPX A Omacron -40
+KPX A Oslash -40
+KPX A Otilde -40
+KPX A Q -40
+KPX A T -90
+KPX A Tcaron -90
+KPX A Tcommaaccent -90
+KPX A U -50
+KPX A Uacute -50
+KPX A Ucircumflex -50
+KPX A Udieresis -50
+KPX A Ugrave -50
+KPX A Uhungarumlaut -50
+KPX A Umacron -50
+KPX A Uogonek -50
+KPX A Uring -50
+KPX A V -80
+KPX A W -60
+KPX A Y -110
+KPX A Yacute -110
+KPX A Ydieresis -110
+KPX A u -30
+KPX A uacute -30
+KPX A ucircumflex -30
+KPX A udieresis -30
+KPX A ugrave -30
+KPX A uhungarumlaut -30
+KPX A umacron -30
+KPX A uogonek -30
+KPX A uring -30
+KPX A v -40
+KPX A w -30
+KPX A y -30
+KPX A yacute -30
+KPX A ydieresis -30
+KPX Aacute C -40
+KPX Aacute Cacute -40
+KPX Aacute Ccaron -40
+KPX Aacute Ccedilla -40
+KPX Aacute G -50
+KPX Aacute Gbreve -50
+KPX Aacute Gcommaaccent -50
+KPX Aacute O -40
+KPX Aacute Oacute -40
+KPX Aacute Ocircumflex -40
+KPX Aacute Odieresis -40
+KPX Aacute Ograve -40
+KPX Aacute Ohungarumlaut -40
+KPX Aacute Omacron -40
+KPX Aacute Oslash -40
+KPX Aacute Otilde -40
+KPX Aacute Q -40
+KPX Aacute T -90
+KPX Aacute Tcaron -90
+KPX Aacute Tcommaaccent -90
+KPX Aacute U -50
+KPX Aacute Uacute -50
+KPX Aacute Ucircumflex -50
+KPX Aacute Udieresis -50
+KPX Aacute Ugrave -50
+KPX Aacute Uhungarumlaut -50
+KPX Aacute Umacron -50
+KPX Aacute Uogonek -50
+KPX Aacute Uring -50
+KPX Aacute V -80
+KPX Aacute W -60
+KPX Aacute Y -110
+KPX Aacute Yacute -110
+KPX Aacute Ydieresis -110
+KPX Aacute u -30
+KPX Aacute uacute -30
+KPX Aacute ucircumflex -30
+KPX Aacute udieresis -30
+KPX Aacute ugrave -30
+KPX Aacute uhungarumlaut -30
+KPX Aacute umacron -30
+KPX Aacute uogonek -30
+KPX Aacute uring -30
+KPX Aacute v -40
+KPX Aacute w -30
+KPX Aacute y -30
+KPX Aacute yacute -30
+KPX Aacute ydieresis -30
+KPX Abreve C -40
+KPX Abreve Cacute -40
+KPX Abreve Ccaron -40
+KPX Abreve Ccedilla -40
+KPX Abreve G -50
+KPX Abreve Gbreve -50
+KPX Abreve Gcommaaccent -50
+KPX Abreve O -40
+KPX Abreve Oacute -40
+KPX Abreve Ocircumflex -40
+KPX Abreve Odieresis -40
+KPX Abreve Ograve -40
+KPX Abreve Ohungarumlaut -40
+KPX Abreve Omacron -40
+KPX Abreve Oslash -40
+KPX Abreve Otilde -40
+KPX Abreve Q -40
+KPX Abreve T -90
+KPX Abreve Tcaron -90
+KPX Abreve Tcommaaccent -90
+KPX Abreve U -50
+KPX Abreve Uacute -50
+KPX Abreve Ucircumflex -50
+KPX Abreve Udieresis -50
+KPX Abreve Ugrave -50
+KPX Abreve Uhungarumlaut -50
+KPX Abreve Umacron -50
+KPX Abreve Uogonek -50
+KPX Abreve Uring -50
+KPX Abreve V -80
+KPX Abreve W -60
+KPX Abreve Y -110
+KPX Abreve Yacute -110
+KPX Abreve Ydieresis -110
+KPX Abreve u -30
+KPX Abreve uacute -30
+KPX Abreve ucircumflex -30
+KPX Abreve udieresis -30
+KPX Abreve ugrave -30
+KPX Abreve uhungarumlaut -30
+KPX Abreve umacron -30
+KPX Abreve uogonek -30
+KPX Abreve uring -30
+KPX Abreve v -40
+KPX Abreve w -30
+KPX Abreve y -30
+KPX Abreve yacute -30
+KPX Abreve ydieresis -30
+KPX Acircumflex C -40
+KPX Acircumflex Cacute -40
+KPX Acircumflex Ccaron -40
+KPX Acircumflex Ccedilla -40
+KPX Acircumflex G -50
+KPX Acircumflex Gbreve -50
+KPX Acircumflex Gcommaaccent -50
+KPX Acircumflex O -40
+KPX Acircumflex Oacute -40
+KPX Acircumflex Ocircumflex -40
+KPX Acircumflex Odieresis -40
+KPX Acircumflex Ograve -40
+KPX Acircumflex Ohungarumlaut -40
+KPX Acircumflex Omacron -40
+KPX Acircumflex Oslash -40
+KPX Acircumflex Otilde -40
+KPX Acircumflex Q -40
+KPX Acircumflex T -90
+KPX Acircumflex Tcaron -90
+KPX Acircumflex Tcommaaccent -90
+KPX Acircumflex U -50
+KPX Acircumflex Uacute -50
+KPX Acircumflex Ucircumflex -50
+KPX Acircumflex Udieresis -50
+KPX Acircumflex Ugrave -50
+KPX Acircumflex Uhungarumlaut -50
+KPX Acircumflex Umacron -50
+KPX Acircumflex Uogonek -50
+KPX Acircumflex Uring -50
+KPX Acircumflex V -80
+KPX Acircumflex W -60
+KPX Acircumflex Y -110
+KPX Acircumflex Yacute -110
+KPX Acircumflex Ydieresis -110
+KPX Acircumflex u -30
+KPX Acircumflex uacute -30
+KPX Acircumflex ucircumflex -30
+KPX Acircumflex udieresis -30
+KPX Acircumflex ugrave -30
+KPX Acircumflex uhungarumlaut -30
+KPX Acircumflex umacron -30
+KPX Acircumflex uogonek -30
+KPX Acircumflex uring -30
+KPX Acircumflex v -40
+KPX Acircumflex w -30
+KPX Acircumflex y -30
+KPX Acircumflex yacute -30
+KPX Acircumflex ydieresis -30
+KPX Adieresis C -40
+KPX Adieresis Cacute -40
+KPX Adieresis Ccaron -40
+KPX Adieresis Ccedilla -40
+KPX Adieresis G -50
+KPX Adieresis Gbreve -50
+KPX Adieresis Gcommaaccent -50
+KPX Adieresis O -40
+KPX Adieresis Oacute -40
+KPX Adieresis Ocircumflex -40
+KPX Adieresis Odieresis -40
+KPX Adieresis Ograve -40
+KPX Adieresis Ohungarumlaut -40
+KPX Adieresis Omacron -40
+KPX Adieresis Oslash -40
+KPX Adieresis Otilde -40
+KPX Adieresis Q -40
+KPX Adieresis T -90
+KPX Adieresis Tcaron -90
+KPX Adieresis Tcommaaccent -90
+KPX Adieresis U -50
+KPX Adieresis Uacute -50
+KPX Adieresis Ucircumflex -50
+KPX Adieresis Udieresis -50
+KPX Adieresis Ugrave -50
+KPX Adieresis Uhungarumlaut -50
+KPX Adieresis Umacron -50
+KPX Adieresis Uogonek -50
+KPX Adieresis Uring -50
+KPX Adieresis V -80
+KPX Adieresis W -60
+KPX Adieresis Y -110
+KPX Adieresis Yacute -110
+KPX Adieresis Ydieresis -110
+KPX Adieresis u -30
+KPX Adieresis uacute -30
+KPX Adieresis ucircumflex -30
+KPX Adieresis udieresis -30
+KPX Adieresis ugrave -30
+KPX Adieresis uhungarumlaut -30
+KPX Adieresis umacron -30
+KPX Adieresis uogonek -30
+KPX Adieresis uring -30
+KPX Adieresis v -40
+KPX Adieresis w -30
+KPX Adieresis y -30
+KPX Adieresis yacute -30
+KPX Adieresis ydieresis -30
+KPX Agrave C -40
+KPX Agrave Cacute -40
+KPX Agrave Ccaron -40
+KPX Agrave Ccedilla -40
+KPX Agrave G -50
+KPX Agrave Gbreve -50
+KPX Agrave Gcommaaccent -50
+KPX Agrave O -40
+KPX Agrave Oacute -40
+KPX Agrave Ocircumflex -40
+KPX Agrave Odieresis -40
+KPX Agrave Ograve -40
+KPX Agrave Ohungarumlaut -40
+KPX Agrave Omacron -40
+KPX Agrave Oslash -40
+KPX Agrave Otilde -40
+KPX Agrave Q -40
+KPX Agrave T -90
+KPX Agrave Tcaron -90
+KPX Agrave Tcommaaccent -90
+KPX Agrave U -50
+KPX Agrave Uacute -50
+KPX Agrave Ucircumflex -50
+KPX Agrave Udieresis -50
+KPX Agrave Ugrave -50
+KPX Agrave Uhungarumlaut -50
+KPX Agrave Umacron -50
+KPX Agrave Uogonek -50
+KPX Agrave Uring -50
+KPX Agrave V -80
+KPX Agrave W -60
+KPX Agrave Y -110
+KPX Agrave Yacute -110
+KPX Agrave Ydieresis -110
+KPX Agrave u -30
+KPX Agrave uacute -30
+KPX Agrave ucircumflex -30
+KPX Agrave udieresis -30
+KPX Agrave ugrave -30
+KPX Agrave uhungarumlaut -30
+KPX Agrave umacron -30
+KPX Agrave uogonek -30
+KPX Agrave uring -30
+KPX Agrave v -40
+KPX Agrave w -30
+KPX Agrave y -30
+KPX Agrave yacute -30
+KPX Agrave ydieresis -30
+KPX Amacron C -40
+KPX Amacron Cacute -40
+KPX Amacron Ccaron -40
+KPX Amacron Ccedilla -40
+KPX Amacron G -50
+KPX Amacron Gbreve -50
+KPX Amacron Gcommaaccent -50
+KPX Amacron O -40
+KPX Amacron Oacute -40
+KPX Amacron Ocircumflex -40
+KPX Amacron Odieresis -40
+KPX Amacron Ograve -40
+KPX Amacron Ohungarumlaut -40
+KPX Amacron Omacron -40
+KPX Amacron Oslash -40
+KPX Amacron Otilde -40
+KPX Amacron Q -40
+KPX Amacron T -90
+KPX Amacron Tcaron -90
+KPX Amacron Tcommaaccent -90
+KPX Amacron U -50
+KPX Amacron Uacute -50
+KPX Amacron Ucircumflex -50
+KPX Amacron Udieresis -50
+KPX Amacron Ugrave -50
+KPX Amacron Uhungarumlaut -50
+KPX Amacron Umacron -50
+KPX Amacron Uogonek -50
+KPX Amacron Uring -50
+KPX Amacron V -80
+KPX Amacron W -60
+KPX Amacron Y -110
+KPX Amacron Yacute -110
+KPX Amacron Ydieresis -110
+KPX Amacron u -30
+KPX Amacron uacute -30
+KPX Amacron ucircumflex -30
+KPX Amacron udieresis -30
+KPX Amacron ugrave -30
+KPX Amacron uhungarumlaut -30
+KPX Amacron umacron -30
+KPX Amacron uogonek -30
+KPX Amacron uring -30
+KPX Amacron v -40
+KPX Amacron w -30
+KPX Amacron y -30
+KPX Amacron yacute -30
+KPX Amacron ydieresis -30
+KPX Aogonek C -40
+KPX Aogonek Cacute -40
+KPX Aogonek Ccaron -40
+KPX Aogonek Ccedilla -40
+KPX Aogonek G -50
+KPX Aogonek Gbreve -50
+KPX Aogonek Gcommaaccent -50
+KPX Aogonek O -40
+KPX Aogonek Oacute -40
+KPX Aogonek Ocircumflex -40
+KPX Aogonek Odieresis -40
+KPX Aogonek Ograve -40
+KPX Aogonek Ohungarumlaut -40
+KPX Aogonek Omacron -40
+KPX Aogonek Oslash -40
+KPX Aogonek Otilde -40
+KPX Aogonek Q -40
+KPX Aogonek T -90
+KPX Aogonek Tcaron -90
+KPX Aogonek Tcommaaccent -90
+KPX Aogonek U -50
+KPX Aogonek Uacute -50
+KPX Aogonek Ucircumflex -50
+KPX Aogonek Udieresis -50
+KPX Aogonek Ugrave -50
+KPX Aogonek Uhungarumlaut -50
+KPX Aogonek Umacron -50
+KPX Aogonek Uogonek -50
+KPX Aogonek Uring -50
+KPX Aogonek V -80
+KPX Aogonek W -60
+KPX Aogonek Y -110
+KPX Aogonek Yacute -110
+KPX Aogonek Ydieresis -110
+KPX Aogonek u -30
+KPX Aogonek uacute -30
+KPX Aogonek ucircumflex -30
+KPX Aogonek udieresis -30
+KPX Aogonek ugrave -30
+KPX Aogonek uhungarumlaut -30
+KPX Aogonek umacron -30
+KPX Aogonek uogonek -30
+KPX Aogonek uring -30
+KPX Aogonek v -40
+KPX Aogonek w -30
+KPX Aogonek y -30
+KPX Aogonek yacute -30
+KPX Aogonek ydieresis -30
+KPX Aring C -40
+KPX Aring Cacute -40
+KPX Aring Ccaron -40
+KPX Aring Ccedilla -40
+KPX Aring G -50
+KPX Aring Gbreve -50
+KPX Aring Gcommaaccent -50
+KPX Aring O -40
+KPX Aring Oacute -40
+KPX Aring Ocircumflex -40
+KPX Aring Odieresis -40
+KPX Aring Ograve -40
+KPX Aring Ohungarumlaut -40
+KPX Aring Omacron -40
+KPX Aring Oslash -40
+KPX Aring Otilde -40
+KPX Aring Q -40
+KPX Aring T -90
+KPX Aring Tcaron -90
+KPX Aring Tcommaaccent -90
+KPX Aring U -50
+KPX Aring Uacute -50
+KPX Aring Ucircumflex -50
+KPX Aring Udieresis -50
+KPX Aring Ugrave -50
+KPX Aring Uhungarumlaut -50
+KPX Aring Umacron -50
+KPX Aring Uogonek -50
+KPX Aring Uring -50
+KPX Aring V -80
+KPX Aring W -60
+KPX Aring Y -110
+KPX Aring Yacute -110
+KPX Aring Ydieresis -110
+KPX Aring u -30
+KPX Aring uacute -30
+KPX Aring ucircumflex -30
+KPX Aring udieresis -30
+KPX Aring ugrave -30
+KPX Aring uhungarumlaut -30
+KPX Aring umacron -30
+KPX Aring uogonek -30
+KPX Aring uring -30
+KPX Aring v -40
+KPX Aring w -30
+KPX Aring y -30
+KPX Aring yacute -30
+KPX Aring ydieresis -30
+KPX Atilde C -40
+KPX Atilde Cacute -40
+KPX Atilde Ccaron -40
+KPX Atilde Ccedilla -40
+KPX Atilde G -50
+KPX Atilde Gbreve -50
+KPX Atilde Gcommaaccent -50
+KPX Atilde O -40
+KPX Atilde Oacute -40
+KPX Atilde Ocircumflex -40
+KPX Atilde Odieresis -40
+KPX Atilde Ograve -40
+KPX Atilde Ohungarumlaut -40
+KPX Atilde Omacron -40
+KPX Atilde Oslash -40
+KPX Atilde Otilde -40
+KPX Atilde Q -40
+KPX Atilde T -90
+KPX Atilde Tcaron -90
+KPX Atilde Tcommaaccent -90
+KPX Atilde U -50
+KPX Atilde Uacute -50
+KPX Atilde Ucircumflex -50
+KPX Atilde Udieresis -50
+KPX Atilde Ugrave -50
+KPX Atilde Uhungarumlaut -50
+KPX Atilde Umacron -50
+KPX Atilde Uogonek -50
+KPX Atilde Uring -50
+KPX Atilde V -80
+KPX Atilde W -60
+KPX Atilde Y -110
+KPX Atilde Yacute -110
+KPX Atilde Ydieresis -110
+KPX Atilde u -30
+KPX Atilde uacute -30
+KPX Atilde ucircumflex -30
+KPX Atilde udieresis -30
+KPX Atilde ugrave -30
+KPX Atilde uhungarumlaut -30
+KPX Atilde umacron -30
+KPX Atilde uogonek -30
+KPX Atilde uring -30
+KPX Atilde v -40
+KPX Atilde w -30
+KPX Atilde y -30
+KPX Atilde yacute -30
+KPX Atilde ydieresis -30
+KPX B A -30
+KPX B Aacute -30
+KPX B Abreve -30
+KPX B Acircumflex -30
+KPX B Adieresis -30
+KPX B Agrave -30
+KPX B Amacron -30
+KPX B Aogonek -30
+KPX B Aring -30
+KPX B Atilde -30
+KPX B U -10
+KPX B Uacute -10
+KPX B Ucircumflex -10
+KPX B Udieresis -10
+KPX B Ugrave -10
+KPX B Uhungarumlaut -10
+KPX B Umacron -10
+KPX B Uogonek -10
+KPX B Uring -10
+KPX D A -40
+KPX D Aacute -40
+KPX D Abreve -40
+KPX D Acircumflex -40
+KPX D Adieresis -40
+KPX D Agrave -40
+KPX D Amacron -40
+KPX D Aogonek -40
+KPX D Aring -40
+KPX D Atilde -40
+KPX D V -40
+KPX D W -40
+KPX D Y -70
+KPX D Yacute -70
+KPX D Ydieresis -70
+KPX D comma -30
+KPX D period -30
+KPX Dcaron A -40
+KPX Dcaron Aacute -40
+KPX Dcaron Abreve -40
+KPX Dcaron Acircumflex -40
+KPX Dcaron Adieresis -40
+KPX Dcaron Agrave -40
+KPX Dcaron Amacron -40
+KPX Dcaron Aogonek -40
+KPX Dcaron Aring -40
+KPX Dcaron Atilde -40
+KPX Dcaron V -40
+KPX Dcaron W -40
+KPX Dcaron Y -70
+KPX Dcaron Yacute -70
+KPX Dcaron Ydieresis -70
+KPX Dcaron comma -30
+KPX Dcaron period -30
+KPX Dcroat A -40
+KPX Dcroat Aacute -40
+KPX Dcroat Abreve -40
+KPX Dcroat Acircumflex -40
+KPX Dcroat Adieresis -40
+KPX Dcroat Agrave -40
+KPX Dcroat Amacron -40
+KPX Dcroat Aogonek -40
+KPX Dcroat Aring -40
+KPX Dcroat Atilde -40
+KPX Dcroat V -40
+KPX Dcroat W -40
+KPX Dcroat Y -70
+KPX Dcroat Yacute -70
+KPX Dcroat Ydieresis -70
+KPX Dcroat comma -30
+KPX Dcroat period -30
+KPX F A -80
+KPX F Aacute -80
+KPX F Abreve -80
+KPX F Acircumflex -80
+KPX F Adieresis -80
+KPX F Agrave -80
+KPX F Amacron -80
+KPX F Aogonek -80
+KPX F Aring -80
+KPX F Atilde -80
+KPX F a -20
+KPX F aacute -20
+KPX F abreve -20
+KPX F acircumflex -20
+KPX F adieresis -20
+KPX F agrave -20
+KPX F amacron -20
+KPX F aogonek -20
+KPX F aring -20
+KPX F atilde -20
+KPX F comma -100
+KPX F period -100
+KPX J A -20
+KPX J Aacute -20
+KPX J Abreve -20
+KPX J Acircumflex -20
+KPX J Adieresis -20
+KPX J Agrave -20
+KPX J Amacron -20
+KPX J Aogonek -20
+KPX J Aring -20
+KPX J Atilde -20
+KPX J comma -20
+KPX J period -20
+KPX J u -20
+KPX J uacute -20
+KPX J ucircumflex -20
+KPX J udieresis -20
+KPX J ugrave -20
+KPX J uhungarumlaut -20
+KPX J umacron -20
+KPX J uogonek -20
+KPX J uring -20
+KPX K O -30
+KPX K Oacute -30
+KPX K Ocircumflex -30
+KPX K Odieresis -30
+KPX K Ograve -30
+KPX K Ohungarumlaut -30
+KPX K Omacron -30
+KPX K Oslash -30
+KPX K Otilde -30
+KPX K e -15
+KPX K eacute -15
+KPX K ecaron -15
+KPX K ecircumflex -15
+KPX K edieresis -15
+KPX K edotaccent -15
+KPX K egrave -15
+KPX K emacron -15
+KPX K eogonek -15
+KPX K o -35
+KPX K oacute -35
+KPX K ocircumflex -35
+KPX K odieresis -35
+KPX K ograve -35
+KPX K ohungarumlaut -35
+KPX K omacron -35
+KPX K oslash -35
+KPX K otilde -35
+KPX K u -30
+KPX K uacute -30
+KPX K ucircumflex -30
+KPX K udieresis -30
+KPX K ugrave -30
+KPX K uhungarumlaut -30
+KPX K umacron -30
+KPX K uogonek -30
+KPX K uring -30
+KPX K y -40
+KPX K yacute -40
+KPX K ydieresis -40
+KPX Kcommaaccent O -30
+KPX Kcommaaccent Oacute -30
+KPX Kcommaaccent Ocircumflex -30
+KPX Kcommaaccent Odieresis -30
+KPX Kcommaaccent Ograve -30
+KPX Kcommaaccent Ohungarumlaut -30
+KPX Kcommaaccent Omacron -30
+KPX Kcommaaccent Oslash -30
+KPX Kcommaaccent Otilde -30
+KPX Kcommaaccent e -15
+KPX Kcommaaccent eacute -15
+KPX Kcommaaccent ecaron -15
+KPX Kcommaaccent ecircumflex -15
+KPX Kcommaaccent edieresis -15
+KPX Kcommaaccent edotaccent -15
+KPX Kcommaaccent egrave -15
+KPX Kcommaaccent emacron -15
+KPX Kcommaaccent eogonek -15
+KPX Kcommaaccent o -35
+KPX Kcommaaccent oacute -35
+KPX Kcommaaccent ocircumflex -35
+KPX Kcommaaccent odieresis -35
+KPX Kcommaaccent ograve -35
+KPX Kcommaaccent ohungarumlaut -35
+KPX Kcommaaccent omacron -35
+KPX Kcommaaccent oslash -35
+KPX Kcommaaccent otilde -35
+KPX Kcommaaccent u -30
+KPX Kcommaaccent uacute -30
+KPX Kcommaaccent ucircumflex -30
+KPX Kcommaaccent udieresis -30
+KPX Kcommaaccent ugrave -30
+KPX Kcommaaccent uhungarumlaut -30
+KPX Kcommaaccent umacron -30
+KPX Kcommaaccent uogonek -30
+KPX Kcommaaccent uring -30
+KPX Kcommaaccent y -40
+KPX Kcommaaccent yacute -40
+KPX Kcommaaccent ydieresis -40
+KPX L T -90
+KPX L Tcaron -90
+KPX L Tcommaaccent -90
+KPX L V -110
+KPX L W -80
+KPX L Y -120
+KPX L Yacute -120
+KPX L Ydieresis -120
+KPX L quotedblright -140
+KPX L quoteright -140
+KPX L y -30
+KPX L yacute -30
+KPX L ydieresis -30
+KPX Lacute T -90
+KPX Lacute Tcaron -90
+KPX Lacute Tcommaaccent -90
+KPX Lacute V -110
+KPX Lacute W -80
+KPX Lacute Y -120
+KPX Lacute Yacute -120
+KPX Lacute Ydieresis -120
+KPX Lacute quotedblright -140
+KPX Lacute quoteright -140
+KPX Lacute y -30
+KPX Lacute yacute -30
+KPX Lacute ydieresis -30
+KPX Lcommaaccent T -90
+KPX Lcommaaccent Tcaron -90
+KPX Lcommaaccent Tcommaaccent -90
+KPX Lcommaaccent V -110
+KPX Lcommaaccent W -80
+KPX Lcommaaccent Y -120
+KPX Lcommaaccent Yacute -120
+KPX Lcommaaccent Ydieresis -120
+KPX Lcommaaccent quotedblright -140
+KPX Lcommaaccent quoteright -140
+KPX Lcommaaccent y -30
+KPX Lcommaaccent yacute -30
+KPX Lcommaaccent ydieresis -30
+KPX Lslash T -90
+KPX Lslash Tcaron -90
+KPX Lslash Tcommaaccent -90
+KPX Lslash V -110
+KPX Lslash W -80
+KPX Lslash Y -120
+KPX Lslash Yacute -120
+KPX Lslash Ydieresis -120
+KPX Lslash quotedblright -140
+KPX Lslash quoteright -140
+KPX Lslash y -30
+KPX Lslash yacute -30
+KPX Lslash ydieresis -30
+KPX O A -50
+KPX O Aacute -50
+KPX O Abreve -50
+KPX O Acircumflex -50
+KPX O Adieresis -50
+KPX O Agrave -50
+KPX O Amacron -50
+KPX O Aogonek -50
+KPX O Aring -50
+KPX O Atilde -50
+KPX O T -40
+KPX O Tcaron -40
+KPX O Tcommaaccent -40
+KPX O V -50
+KPX O W -50
+KPX O X -50
+KPX O Y -70
+KPX O Yacute -70
+KPX O Ydieresis -70
+KPX O comma -40
+KPX O period -40
+KPX Oacute A -50
+KPX Oacute Aacute -50
+KPX Oacute Abreve -50
+KPX Oacute Acircumflex -50
+KPX Oacute Adieresis -50
+KPX Oacute Agrave -50
+KPX Oacute Amacron -50
+KPX Oacute Aogonek -50
+KPX Oacute Aring -50
+KPX Oacute Atilde -50
+KPX Oacute T -40
+KPX Oacute Tcaron -40
+KPX Oacute Tcommaaccent -40
+KPX Oacute V -50
+KPX Oacute W -50
+KPX Oacute X -50
+KPX Oacute Y -70
+KPX Oacute Yacute -70
+KPX Oacute Ydieresis -70
+KPX Oacute comma -40
+KPX Oacute period -40
+KPX Ocircumflex A -50
+KPX Ocircumflex Aacute -50
+KPX Ocircumflex Abreve -50
+KPX Ocircumflex Acircumflex -50
+KPX Ocircumflex Adieresis -50
+KPX Ocircumflex Agrave -50
+KPX Ocircumflex Amacron -50
+KPX Ocircumflex Aogonek -50
+KPX Ocircumflex Aring -50
+KPX Ocircumflex Atilde -50
+KPX Ocircumflex T -40
+KPX Ocircumflex Tcaron -40
+KPX Ocircumflex Tcommaaccent -40
+KPX Ocircumflex V -50
+KPX Ocircumflex W -50
+KPX Ocircumflex X -50
+KPX Ocircumflex Y -70
+KPX Ocircumflex Yacute -70
+KPX Ocircumflex Ydieresis -70
+KPX Ocircumflex comma -40
+KPX Ocircumflex period -40
+KPX Odieresis A -50
+KPX Odieresis Aacute -50
+KPX Odieresis Abreve -50
+KPX Odieresis Acircumflex -50
+KPX Odieresis Adieresis -50
+KPX Odieresis Agrave -50
+KPX Odieresis Amacron -50
+KPX Odieresis Aogonek -50
+KPX Odieresis Aring -50
+KPX Odieresis Atilde -50
+KPX Odieresis T -40
+KPX Odieresis Tcaron -40
+KPX Odieresis Tcommaaccent -40
+KPX Odieresis V -50
+KPX Odieresis W -50
+KPX Odieresis X -50
+KPX Odieresis Y -70
+KPX Odieresis Yacute -70
+KPX Odieresis Ydieresis -70
+KPX Odieresis comma -40
+KPX Odieresis period -40
+KPX Ograve A -50
+KPX Ograve Aacute -50
+KPX Ograve Abreve -50
+KPX Ograve Acircumflex -50
+KPX Ograve Adieresis -50
+KPX Ograve Agrave -50
+KPX Ograve Amacron -50
+KPX Ograve Aogonek -50
+KPX Ograve Aring -50
+KPX Ograve Atilde -50
+KPX Ograve T -40
+KPX Ograve Tcaron -40
+KPX Ograve Tcommaaccent -40
+KPX Ograve V -50
+KPX Ograve W -50
+KPX Ograve X -50
+KPX Ograve Y -70
+KPX Ograve Yacute -70
+KPX Ograve Ydieresis -70
+KPX Ograve comma -40
+KPX Ograve period -40
+KPX Ohungarumlaut A -50
+KPX Ohungarumlaut Aacute -50
+KPX Ohungarumlaut Abreve -50
+KPX Ohungarumlaut Acircumflex -50
+KPX Ohungarumlaut Adieresis -50
+KPX Ohungarumlaut Agrave -50
+KPX Ohungarumlaut Amacron -50
+KPX Ohungarumlaut Aogonek -50
+KPX Ohungarumlaut Aring -50
+KPX Ohungarumlaut Atilde -50
+KPX Ohungarumlaut T -40
+KPX Ohungarumlaut Tcaron -40
+KPX Ohungarumlaut Tcommaaccent -40
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut W -50
+KPX Ohungarumlaut X -50
+KPX Ohungarumlaut Y -70
+KPX Ohungarumlaut Yacute -70
+KPX Ohungarumlaut Ydieresis -70
+KPX Ohungarumlaut comma -40
+KPX Ohungarumlaut period -40
+KPX Omacron A -50
+KPX Omacron Aacute -50
+KPX Omacron Abreve -50
+KPX Omacron Acircumflex -50
+KPX Omacron Adieresis -50
+KPX Omacron Agrave -50
+KPX Omacron Amacron -50
+KPX Omacron Aogonek -50
+KPX Omacron Aring -50
+KPX Omacron Atilde -50
+KPX Omacron T -40
+KPX Omacron Tcaron -40
+KPX Omacron Tcommaaccent -40
+KPX Omacron V -50
+KPX Omacron W -50
+KPX Omacron X -50
+KPX Omacron Y -70
+KPX Omacron Yacute -70
+KPX Omacron Ydieresis -70
+KPX Omacron comma -40
+KPX Omacron period -40
+KPX Oslash A -50
+KPX Oslash Aacute -50
+KPX Oslash Abreve -50
+KPX Oslash Acircumflex -50
+KPX Oslash Adieresis -50
+KPX Oslash Agrave -50
+KPX Oslash Amacron -50
+KPX Oslash Aogonek -50
+KPX Oslash Aring -50
+KPX Oslash Atilde -50
+KPX Oslash T -40
+KPX Oslash Tcaron -40
+KPX Oslash Tcommaaccent -40
+KPX Oslash V -50
+KPX Oslash W -50
+KPX Oslash X -50
+KPX Oslash Y -70
+KPX Oslash Yacute -70
+KPX Oslash Ydieresis -70
+KPX Oslash comma -40
+KPX Oslash period -40
+KPX Otilde A -50
+KPX Otilde Aacute -50
+KPX Otilde Abreve -50
+KPX Otilde Acircumflex -50
+KPX Otilde Adieresis -50
+KPX Otilde Agrave -50
+KPX Otilde Amacron -50
+KPX Otilde Aogonek -50
+KPX Otilde Aring -50
+KPX Otilde Atilde -50
+KPX Otilde T -40
+KPX Otilde Tcaron -40
+KPX Otilde Tcommaaccent -40
+KPX Otilde V -50
+KPX Otilde W -50
+KPX Otilde X -50
+KPX Otilde Y -70
+KPX Otilde Yacute -70
+KPX Otilde Ydieresis -70
+KPX Otilde comma -40
+KPX Otilde period -40
+KPX P A -100
+KPX P Aacute -100
+KPX P Abreve -100
+KPX P Acircumflex -100
+KPX P Adieresis -100
+KPX P Agrave -100
+KPX P Amacron -100
+KPX P Aogonek -100
+KPX P Aring -100
+KPX P Atilde -100
+KPX P a -30
+KPX P aacute -30
+KPX P abreve -30
+KPX P acircumflex -30
+KPX P adieresis -30
+KPX P agrave -30
+KPX P amacron -30
+KPX P aogonek -30
+KPX P aring -30
+KPX P atilde -30
+KPX P comma -120
+KPX P e -30
+KPX P eacute -30
+KPX P ecaron -30
+KPX P ecircumflex -30
+KPX P edieresis -30
+KPX P edotaccent -30
+KPX P egrave -30
+KPX P emacron -30
+KPX P eogonek -30
+KPX P o -40
+KPX P oacute -40
+KPX P ocircumflex -40
+KPX P odieresis -40
+KPX P ograve -40
+KPX P ohungarumlaut -40
+KPX P omacron -40
+KPX P oslash -40
+KPX P otilde -40
+KPX P period -120
+KPX Q U -10
+KPX Q Uacute -10
+KPX Q Ucircumflex -10
+KPX Q Udieresis -10
+KPX Q Ugrave -10
+KPX Q Uhungarumlaut -10
+KPX Q Umacron -10
+KPX Q Uogonek -10
+KPX Q Uring -10
+KPX Q comma 20
+KPX Q period 20
+KPX R O -20
+KPX R Oacute -20
+KPX R Ocircumflex -20
+KPX R Odieresis -20
+KPX R Ograve -20
+KPX R Ohungarumlaut -20
+KPX R Omacron -20
+KPX R Oslash -20
+KPX R Otilde -20
+KPX R T -20
+KPX R Tcaron -20
+KPX R Tcommaaccent -20
+KPX R U -20
+KPX R Uacute -20
+KPX R Ucircumflex -20
+KPX R Udieresis -20
+KPX R Ugrave -20
+KPX R Uhungarumlaut -20
+KPX R Umacron -20
+KPX R Uogonek -20
+KPX R Uring -20
+KPX R V -50
+KPX R W -40
+KPX R Y -50
+KPX R Yacute -50
+KPX R Ydieresis -50
+KPX Racute O -20
+KPX Racute Oacute -20
+KPX Racute Ocircumflex -20
+KPX Racute Odieresis -20
+KPX Racute Ograve -20
+KPX Racute Ohungarumlaut -20
+KPX Racute Omacron -20
+KPX Racute Oslash -20
+KPX Racute Otilde -20
+KPX Racute T -20
+KPX Racute Tcaron -20
+KPX Racute Tcommaaccent -20
+KPX Racute U -20
+KPX Racute Uacute -20
+KPX Racute Ucircumflex -20
+KPX Racute Udieresis -20
+KPX Racute Ugrave -20
+KPX Racute Uhungarumlaut -20
+KPX Racute Umacron -20
+KPX Racute Uogonek -20
+KPX Racute Uring -20
+KPX Racute V -50
+KPX Racute W -40
+KPX Racute Y -50
+KPX Racute Yacute -50
+KPX Racute Ydieresis -50
+KPX Rcaron O -20
+KPX Rcaron Oacute -20
+KPX Rcaron Ocircumflex -20
+KPX Rcaron Odieresis -20
+KPX Rcaron Ograve -20
+KPX Rcaron Ohungarumlaut -20
+KPX Rcaron Omacron -20
+KPX Rcaron Oslash -20
+KPX Rcaron Otilde -20
+KPX Rcaron T -20
+KPX Rcaron Tcaron -20
+KPX Rcaron Tcommaaccent -20
+KPX Rcaron U -20
+KPX Rcaron Uacute -20
+KPX Rcaron Ucircumflex -20
+KPX Rcaron Udieresis -20
+KPX Rcaron Ugrave -20
+KPX Rcaron Uhungarumlaut -20
+KPX Rcaron Umacron -20
+KPX Rcaron Uogonek -20
+KPX Rcaron Uring -20
+KPX Rcaron V -50
+KPX Rcaron W -40
+KPX Rcaron Y -50
+KPX Rcaron Yacute -50
+KPX Rcaron Ydieresis -50
+KPX Rcommaaccent O -20
+KPX Rcommaaccent Oacute -20
+KPX Rcommaaccent Ocircumflex -20
+KPX Rcommaaccent Odieresis -20
+KPX Rcommaaccent Ograve -20
+KPX Rcommaaccent Ohungarumlaut -20
+KPX Rcommaaccent Omacron -20
+KPX Rcommaaccent Oslash -20
+KPX Rcommaaccent Otilde -20
+KPX Rcommaaccent T -20
+KPX Rcommaaccent Tcaron -20
+KPX Rcommaaccent Tcommaaccent -20
+KPX Rcommaaccent U -20
+KPX Rcommaaccent Uacute -20
+KPX Rcommaaccent Ucircumflex -20
+KPX Rcommaaccent Udieresis -20
+KPX Rcommaaccent Ugrave -20
+KPX Rcommaaccent Uhungarumlaut -20
+KPX Rcommaaccent Umacron -20
+KPX Rcommaaccent Uogonek -20
+KPX Rcommaaccent Uring -20
+KPX Rcommaaccent V -50
+KPX Rcommaaccent W -40
+KPX Rcommaaccent Y -50
+KPX Rcommaaccent Yacute -50
+KPX Rcommaaccent Ydieresis -50
+KPX T A -90
+KPX T Aacute -90
+KPX T Abreve -90
+KPX T Acircumflex -90
+KPX T Adieresis -90
+KPX T Agrave -90
+KPX T Amacron -90
+KPX T Aogonek -90
+KPX T Aring -90
+KPX T Atilde -90
+KPX T O -40
+KPX T Oacute -40
+KPX T Ocircumflex -40
+KPX T Odieresis -40
+KPX T Ograve -40
+KPX T Ohungarumlaut -40
+KPX T Omacron -40
+KPX T Oslash -40
+KPX T Otilde -40
+KPX T a -80
+KPX T aacute -80
+KPX T abreve -80
+KPX T acircumflex -80
+KPX T adieresis -80
+KPX T agrave -80
+KPX T amacron -80
+KPX T aogonek -80
+KPX T aring -80
+KPX T atilde -80
+KPX T colon -40
+KPX T comma -80
+KPX T e -60
+KPX T eacute -60
+KPX T ecaron -60
+KPX T ecircumflex -60
+KPX T edieresis -60
+KPX T edotaccent -60
+KPX T egrave -60
+KPX T emacron -60
+KPX T eogonek -60
+KPX T hyphen -120
+KPX T o -80
+KPX T oacute -80
+KPX T ocircumflex -80
+KPX T odieresis -80
+KPX T ograve -80
+KPX T ohungarumlaut -80
+KPX T omacron -80
+KPX T oslash -80
+KPX T otilde -80
+KPX T period -80
+KPX T r -80
+KPX T racute -80
+KPX T rcommaaccent -80
+KPX T semicolon -40
+KPX T u -90
+KPX T uacute -90
+KPX T ucircumflex -90
+KPX T udieresis -90
+KPX T ugrave -90
+KPX T uhungarumlaut -90
+KPX T umacron -90
+KPX T uogonek -90
+KPX T uring -90
+KPX T w -60
+KPX T y -60
+KPX T yacute -60
+KPX T ydieresis -60
+KPX Tcaron A -90
+KPX Tcaron Aacute -90
+KPX Tcaron Abreve -90
+KPX Tcaron Acircumflex -90
+KPX Tcaron Adieresis -90
+KPX Tcaron Agrave -90
+KPX Tcaron Amacron -90
+KPX Tcaron Aogonek -90
+KPX Tcaron Aring -90
+KPX Tcaron Atilde -90
+KPX Tcaron O -40
+KPX Tcaron Oacute -40
+KPX Tcaron Ocircumflex -40
+KPX Tcaron Odieresis -40
+KPX Tcaron Ograve -40
+KPX Tcaron Ohungarumlaut -40
+KPX Tcaron Omacron -40
+KPX Tcaron Oslash -40
+KPX Tcaron Otilde -40
+KPX Tcaron a -80
+KPX Tcaron aacute -80
+KPX Tcaron abreve -80
+KPX Tcaron acircumflex -80
+KPX Tcaron adieresis -80
+KPX Tcaron agrave -80
+KPX Tcaron amacron -80
+KPX Tcaron aogonek -80
+KPX Tcaron aring -80
+KPX Tcaron atilde -80
+KPX Tcaron colon -40
+KPX Tcaron comma -80
+KPX Tcaron e -60
+KPX Tcaron eacute -60
+KPX Tcaron ecaron -60
+KPX Tcaron ecircumflex -60
+KPX Tcaron edieresis -60
+KPX Tcaron edotaccent -60
+KPX Tcaron egrave -60
+KPX Tcaron emacron -60
+KPX Tcaron eogonek -60
+KPX Tcaron hyphen -120
+KPX Tcaron o -80
+KPX Tcaron oacute -80
+KPX Tcaron ocircumflex -80
+KPX Tcaron odieresis -80
+KPX Tcaron ograve -80
+KPX Tcaron ohungarumlaut -80
+KPX Tcaron omacron -80
+KPX Tcaron oslash -80
+KPX Tcaron otilde -80
+KPX Tcaron period -80
+KPX Tcaron r -80
+KPX Tcaron racute -80
+KPX Tcaron rcommaaccent -80
+KPX Tcaron semicolon -40
+KPX Tcaron u -90
+KPX Tcaron uacute -90
+KPX Tcaron ucircumflex -90
+KPX Tcaron udieresis -90
+KPX Tcaron ugrave -90
+KPX Tcaron uhungarumlaut -90
+KPX Tcaron umacron -90
+KPX Tcaron uogonek -90
+KPX Tcaron uring -90
+KPX Tcaron w -60
+KPX Tcaron y -60
+KPX Tcaron yacute -60
+KPX Tcaron ydieresis -60
+KPX Tcommaaccent A -90
+KPX Tcommaaccent Aacute -90
+KPX Tcommaaccent Abreve -90
+KPX Tcommaaccent Acircumflex -90
+KPX Tcommaaccent Adieresis -90
+KPX Tcommaaccent Agrave -90
+KPX Tcommaaccent Amacron -90
+KPX Tcommaaccent Aogonek -90
+KPX Tcommaaccent Aring -90
+KPX Tcommaaccent Atilde -90
+KPX Tcommaaccent O -40
+KPX Tcommaaccent Oacute -40
+KPX Tcommaaccent Ocircumflex -40
+KPX Tcommaaccent Odieresis -40
+KPX Tcommaaccent Ograve -40
+KPX Tcommaaccent Ohungarumlaut -40
+KPX Tcommaaccent Omacron -40
+KPX Tcommaaccent Oslash -40
+KPX Tcommaaccent Otilde -40
+KPX Tcommaaccent a -80
+KPX Tcommaaccent aacute -80
+KPX Tcommaaccent abreve -80
+KPX Tcommaaccent acircumflex -80
+KPX Tcommaaccent adieresis -80
+KPX Tcommaaccent agrave -80
+KPX Tcommaaccent amacron -80
+KPX Tcommaaccent aogonek -80
+KPX Tcommaaccent aring -80
+KPX Tcommaaccent atilde -80
+KPX Tcommaaccent colon -40
+KPX Tcommaaccent comma -80
+KPX Tcommaaccent e -60
+KPX Tcommaaccent eacute -60
+KPX Tcommaaccent ecaron -60
+KPX Tcommaaccent ecircumflex -60
+KPX Tcommaaccent edieresis -60
+KPX Tcommaaccent edotaccent -60
+KPX Tcommaaccent egrave -60
+KPX Tcommaaccent emacron -60
+KPX Tcommaaccent eogonek -60
+KPX Tcommaaccent hyphen -120
+KPX Tcommaaccent o -80
+KPX Tcommaaccent oacute -80
+KPX Tcommaaccent ocircumflex -80
+KPX Tcommaaccent odieresis -80
+KPX Tcommaaccent ograve -80
+KPX Tcommaaccent ohungarumlaut -80
+KPX Tcommaaccent omacron -80
+KPX Tcommaaccent oslash -80
+KPX Tcommaaccent otilde -80
+KPX Tcommaaccent period -80
+KPX Tcommaaccent r -80
+KPX Tcommaaccent racute -80
+KPX Tcommaaccent rcommaaccent -80
+KPX Tcommaaccent semicolon -40
+KPX Tcommaaccent u -90
+KPX Tcommaaccent uacute -90
+KPX Tcommaaccent ucircumflex -90
+KPX Tcommaaccent udieresis -90
+KPX Tcommaaccent ugrave -90
+KPX Tcommaaccent uhungarumlaut -90
+KPX Tcommaaccent umacron -90
+KPX Tcommaaccent uogonek -90
+KPX Tcommaaccent uring -90
+KPX Tcommaaccent w -60
+KPX Tcommaaccent y -60
+KPX Tcommaaccent yacute -60
+KPX Tcommaaccent ydieresis -60
+KPX U A -50
+KPX U Aacute -50
+KPX U Abreve -50
+KPX U Acircumflex -50
+KPX U Adieresis -50
+KPX U Agrave -50
+KPX U Amacron -50
+KPX U Aogonek -50
+KPX U Aring -50
+KPX U Atilde -50
+KPX U comma -30
+KPX U period -30
+KPX Uacute A -50
+KPX Uacute Aacute -50
+KPX Uacute Abreve -50
+KPX Uacute Acircumflex -50
+KPX Uacute Adieresis -50
+KPX Uacute Agrave -50
+KPX Uacute Amacron -50
+KPX Uacute Aogonek -50
+KPX Uacute Aring -50
+KPX Uacute Atilde -50
+KPX Uacute comma -30
+KPX Uacute period -30
+KPX Ucircumflex A -50
+KPX Ucircumflex Aacute -50
+KPX Ucircumflex Abreve -50
+KPX Ucircumflex Acircumflex -50
+KPX Ucircumflex Adieresis -50
+KPX Ucircumflex Agrave -50
+KPX Ucircumflex Amacron -50
+KPX Ucircumflex Aogonek -50
+KPX Ucircumflex Aring -50
+KPX Ucircumflex Atilde -50
+KPX Ucircumflex comma -30
+KPX Ucircumflex period -30
+KPX Udieresis A -50
+KPX Udieresis Aacute -50
+KPX Udieresis Abreve -50
+KPX Udieresis Acircumflex -50
+KPX Udieresis Adieresis -50
+KPX Udieresis Agrave -50
+KPX Udieresis Amacron -50
+KPX Udieresis Aogonek -50
+KPX Udieresis Aring -50
+KPX Udieresis Atilde -50
+KPX Udieresis comma -30
+KPX Udieresis period -30
+KPX Ugrave A -50
+KPX Ugrave Aacute -50
+KPX Ugrave Abreve -50
+KPX Ugrave Acircumflex -50
+KPX Ugrave Adieresis -50
+KPX Ugrave Agrave -50
+KPX Ugrave Amacron -50
+KPX Ugrave Aogonek -50
+KPX Ugrave Aring -50
+KPX Ugrave Atilde -50
+KPX Ugrave comma -30
+KPX Ugrave period -30
+KPX Uhungarumlaut A -50
+KPX Uhungarumlaut Aacute -50
+KPX Uhungarumlaut Abreve -50
+KPX Uhungarumlaut Acircumflex -50
+KPX Uhungarumlaut Adieresis -50
+KPX Uhungarumlaut Agrave -50
+KPX Uhungarumlaut Amacron -50
+KPX Uhungarumlaut Aogonek -50
+KPX Uhungarumlaut Aring -50
+KPX Uhungarumlaut Atilde -50
+KPX Uhungarumlaut comma -30
+KPX Uhungarumlaut period -30
+KPX Umacron A -50
+KPX Umacron Aacute -50
+KPX Umacron Abreve -50
+KPX Umacron Acircumflex -50
+KPX Umacron Adieresis -50
+KPX Umacron Agrave -50
+KPX Umacron Amacron -50
+KPX Umacron Aogonek -50
+KPX Umacron Aring -50
+KPX Umacron Atilde -50
+KPX Umacron comma -30
+KPX Umacron period -30
+KPX Uogonek A -50
+KPX Uogonek Aacute -50
+KPX Uogonek Abreve -50
+KPX Uogonek Acircumflex -50
+KPX Uogonek Adieresis -50
+KPX Uogonek Agrave -50
+KPX Uogonek Amacron -50
+KPX Uogonek Aogonek -50
+KPX Uogonek Aring -50
+KPX Uogonek Atilde -50
+KPX Uogonek comma -30
+KPX Uogonek period -30
+KPX Uring A -50
+KPX Uring Aacute -50
+KPX Uring Abreve -50
+KPX Uring Acircumflex -50
+KPX Uring Adieresis -50
+KPX Uring Agrave -50
+KPX Uring Amacron -50
+KPX Uring Aogonek -50
+KPX Uring Aring -50
+KPX Uring Atilde -50
+KPX Uring comma -30
+KPX Uring period -30
+KPX V A -80
+KPX V Aacute -80
+KPX V Abreve -80
+KPX V Acircumflex -80
+KPX V Adieresis -80
+KPX V Agrave -80
+KPX V Amacron -80
+KPX V Aogonek -80
+KPX V Aring -80
+KPX V Atilde -80
+KPX V G -50
+KPX V Gbreve -50
+KPX V Gcommaaccent -50
+KPX V O -50
+KPX V Oacute -50
+KPX V Ocircumflex -50
+KPX V Odieresis -50
+KPX V Ograve -50
+KPX V Ohungarumlaut -50
+KPX V Omacron -50
+KPX V Oslash -50
+KPX V Otilde -50
+KPX V a -60
+KPX V aacute -60
+KPX V abreve -60
+KPX V acircumflex -60
+KPX V adieresis -60
+KPX V agrave -60
+KPX V amacron -60
+KPX V aogonek -60
+KPX V aring -60
+KPX V atilde -60
+KPX V colon -40
+KPX V comma -120
+KPX V e -50
+KPX V eacute -50
+KPX V ecaron -50
+KPX V ecircumflex -50
+KPX V edieresis -50
+KPX V edotaccent -50
+KPX V egrave -50
+KPX V emacron -50
+KPX V eogonek -50
+KPX V hyphen -80
+KPX V o -90
+KPX V oacute -90
+KPX V ocircumflex -90
+KPX V odieresis -90
+KPX V ograve -90
+KPX V ohungarumlaut -90
+KPX V omacron -90
+KPX V oslash -90
+KPX V otilde -90
+KPX V period -120
+KPX V semicolon -40
+KPX V u -60
+KPX V uacute -60
+KPX V ucircumflex -60
+KPX V udieresis -60
+KPX V ugrave -60
+KPX V uhungarumlaut -60
+KPX V umacron -60
+KPX V uogonek -60
+KPX V uring -60
+KPX W A -60
+KPX W Aacute -60
+KPX W Abreve -60
+KPX W Acircumflex -60
+KPX W Adieresis -60
+KPX W Agrave -60
+KPX W Amacron -60
+KPX W Aogonek -60
+KPX W Aring -60
+KPX W Atilde -60
+KPX W O -20
+KPX W Oacute -20
+KPX W Ocircumflex -20
+KPX W Odieresis -20
+KPX W Ograve -20
+KPX W Ohungarumlaut -20
+KPX W Omacron -20
+KPX W Oslash -20
+KPX W Otilde -20
+KPX W a -40
+KPX W aacute -40
+KPX W abreve -40
+KPX W acircumflex -40
+KPX W adieresis -40
+KPX W agrave -40
+KPX W amacron -40
+KPX W aogonek -40
+KPX W aring -40
+KPX W atilde -40
+KPX W colon -10
+KPX W comma -80
+KPX W e -35
+KPX W eacute -35
+KPX W ecaron -35
+KPX W ecircumflex -35
+KPX W edieresis -35
+KPX W edotaccent -35
+KPX W egrave -35
+KPX W emacron -35
+KPX W eogonek -35
+KPX W hyphen -40
+KPX W o -60
+KPX W oacute -60
+KPX W ocircumflex -60
+KPX W odieresis -60
+KPX W ograve -60
+KPX W ohungarumlaut -60
+KPX W omacron -60
+KPX W oslash -60
+KPX W otilde -60
+KPX W period -80
+KPX W semicolon -10
+KPX W u -45
+KPX W uacute -45
+KPX W ucircumflex -45
+KPX W udieresis -45
+KPX W ugrave -45
+KPX W uhungarumlaut -45
+KPX W umacron -45
+KPX W uogonek -45
+KPX W uring -45
+KPX W y -20
+KPX W yacute -20
+KPX W ydieresis -20
+KPX Y A -110
+KPX Y Aacute -110
+KPX Y Abreve -110
+KPX Y Acircumflex -110
+KPX Y Adieresis -110
+KPX Y Agrave -110
+KPX Y Amacron -110
+KPX Y Aogonek -110
+KPX Y Aring -110
+KPX Y Atilde -110
+KPX Y O -70
+KPX Y Oacute -70
+KPX Y Ocircumflex -70
+KPX Y Odieresis -70
+KPX Y Ograve -70
+KPX Y Ohungarumlaut -70
+KPX Y Omacron -70
+KPX Y Oslash -70
+KPX Y Otilde -70
+KPX Y a -90
+KPX Y aacute -90
+KPX Y abreve -90
+KPX Y acircumflex -90
+KPX Y adieresis -90
+KPX Y agrave -90
+KPX Y amacron -90
+KPX Y aogonek -90
+KPX Y aring -90
+KPX Y atilde -90
+KPX Y colon -50
+KPX Y comma -100
+KPX Y e -80
+KPX Y eacute -80
+KPX Y ecaron -80
+KPX Y ecircumflex -80
+KPX Y edieresis -80
+KPX Y edotaccent -80
+KPX Y egrave -80
+KPX Y emacron -80
+KPX Y eogonek -80
+KPX Y o -100
+KPX Y oacute -100
+KPX Y ocircumflex -100
+KPX Y odieresis -100
+KPX Y ograve -100
+KPX Y ohungarumlaut -100
+KPX Y omacron -100
+KPX Y oslash -100
+KPX Y otilde -100
+KPX Y period -100
+KPX Y semicolon -50
+KPX Y u -100
+KPX Y uacute -100
+KPX Y ucircumflex -100
+KPX Y udieresis -100
+KPX Y ugrave -100
+KPX Y uhungarumlaut -100
+KPX Y umacron -100
+KPX Y uogonek -100
+KPX Y uring -100
+KPX Yacute A -110
+KPX Yacute Aacute -110
+KPX Yacute Abreve -110
+KPX Yacute Acircumflex -110
+KPX Yacute Adieresis -110
+KPX Yacute Agrave -110
+KPX Yacute Amacron -110
+KPX Yacute Aogonek -110
+KPX Yacute Aring -110
+KPX Yacute Atilde -110
+KPX Yacute O -70
+KPX Yacute Oacute -70
+KPX Yacute Ocircumflex -70
+KPX Yacute Odieresis -70
+KPX Yacute Ograve -70
+KPX Yacute Ohungarumlaut -70
+KPX Yacute Omacron -70
+KPX Yacute Oslash -70
+KPX Yacute Otilde -70
+KPX Yacute a -90
+KPX Yacute aacute -90
+KPX Yacute abreve -90
+KPX Yacute acircumflex -90
+KPX Yacute adieresis -90
+KPX Yacute agrave -90
+KPX Yacute amacron -90
+KPX Yacute aogonek -90
+KPX Yacute aring -90
+KPX Yacute atilde -90
+KPX Yacute colon -50
+KPX Yacute comma -100
+KPX Yacute e -80
+KPX Yacute eacute -80
+KPX Yacute ecaron -80
+KPX Yacute ecircumflex -80
+KPX Yacute edieresis -80
+KPX Yacute edotaccent -80
+KPX Yacute egrave -80
+KPX Yacute emacron -80
+KPX Yacute eogonek -80
+KPX Yacute o -100
+KPX Yacute oacute -100
+KPX Yacute ocircumflex -100
+KPX Yacute odieresis -100
+KPX Yacute ograve -100
+KPX Yacute ohungarumlaut -100
+KPX Yacute omacron -100
+KPX Yacute oslash -100
+KPX Yacute otilde -100
+KPX Yacute period -100
+KPX Yacute semicolon -50
+KPX Yacute u -100
+KPX Yacute uacute -100
+KPX Yacute ucircumflex -100
+KPX Yacute udieresis -100
+KPX Yacute ugrave -100
+KPX Yacute uhungarumlaut -100
+KPX Yacute umacron -100
+KPX Yacute uogonek -100
+KPX Yacute uring -100
+KPX Ydieresis A -110
+KPX Ydieresis Aacute -110
+KPX Ydieresis Abreve -110
+KPX Ydieresis Acircumflex -110
+KPX Ydieresis Adieresis -110
+KPX Ydieresis Agrave -110
+KPX Ydieresis Amacron -110
+KPX Ydieresis Aogonek -110
+KPX Ydieresis Aring -110
+KPX Ydieresis Atilde -110
+KPX Ydieresis O -70
+KPX Ydieresis Oacute -70
+KPX Ydieresis Ocircumflex -70
+KPX Ydieresis Odieresis -70
+KPX Ydieresis Ograve -70
+KPX Ydieresis Ohungarumlaut -70
+KPX Ydieresis Omacron -70
+KPX Ydieresis Oslash -70
+KPX Ydieresis Otilde -70
+KPX Ydieresis a -90
+KPX Ydieresis aacute -90
+KPX Ydieresis abreve -90
+KPX Ydieresis acircumflex -90
+KPX Ydieresis adieresis -90
+KPX Ydieresis agrave -90
+KPX Ydieresis amacron -90
+KPX Ydieresis aogonek -90
+KPX Ydieresis aring -90
+KPX Ydieresis atilde -90
+KPX Ydieresis colon -50
+KPX Ydieresis comma -100
+KPX Ydieresis e -80
+KPX Ydieresis eacute -80
+KPX Ydieresis ecaron -80
+KPX Ydieresis ecircumflex -80
+KPX Ydieresis edieresis -80
+KPX Ydieresis edotaccent -80
+KPX Ydieresis egrave -80
+KPX Ydieresis emacron -80
+KPX Ydieresis eogonek -80
+KPX Ydieresis o -100
+KPX Ydieresis oacute -100
+KPX Ydieresis ocircumflex -100
+KPX Ydieresis odieresis -100
+KPX Ydieresis ograve -100
+KPX Ydieresis ohungarumlaut -100
+KPX Ydieresis omacron -100
+KPX Ydieresis oslash -100
+KPX Ydieresis otilde -100
+KPX Ydieresis period -100
+KPX Ydieresis semicolon -50
+KPX Ydieresis u -100
+KPX Ydieresis uacute -100
+KPX Ydieresis ucircumflex -100
+KPX Ydieresis udieresis -100
+KPX Ydieresis ugrave -100
+KPX Ydieresis uhungarumlaut -100
+KPX Ydieresis umacron -100
+KPX Ydieresis uogonek -100
+KPX Ydieresis uring -100
+KPX a g -10
+KPX a gbreve -10
+KPX a gcommaaccent -10
+KPX a v -15
+KPX a w -15
+KPX a y -20
+KPX a yacute -20
+KPX a ydieresis -20
+KPX aacute g -10
+KPX aacute gbreve -10
+KPX aacute gcommaaccent -10
+KPX aacute v -15
+KPX aacute w -15
+KPX aacute y -20
+KPX aacute yacute -20
+KPX aacute ydieresis -20
+KPX abreve g -10
+KPX abreve gbreve -10
+KPX abreve gcommaaccent -10
+KPX abreve v -15
+KPX abreve w -15
+KPX abreve y -20
+KPX abreve yacute -20
+KPX abreve ydieresis -20
+KPX acircumflex g -10
+KPX acircumflex gbreve -10
+KPX acircumflex gcommaaccent -10
+KPX acircumflex v -15
+KPX acircumflex w -15
+KPX acircumflex y -20
+KPX acircumflex yacute -20
+KPX acircumflex ydieresis -20
+KPX adieresis g -10
+KPX adieresis gbreve -10
+KPX adieresis gcommaaccent -10
+KPX adieresis v -15
+KPX adieresis w -15
+KPX adieresis y -20
+KPX adieresis yacute -20
+KPX adieresis ydieresis -20
+KPX agrave g -10
+KPX agrave gbreve -10
+KPX agrave gcommaaccent -10
+KPX agrave v -15
+KPX agrave w -15
+KPX agrave y -20
+KPX agrave yacute -20
+KPX agrave ydieresis -20
+KPX amacron g -10
+KPX amacron gbreve -10
+KPX amacron gcommaaccent -10
+KPX amacron v -15
+KPX amacron w -15
+KPX amacron y -20
+KPX amacron yacute -20
+KPX amacron ydieresis -20
+KPX aogonek g -10
+KPX aogonek gbreve -10
+KPX aogonek gcommaaccent -10
+KPX aogonek v -15
+KPX aogonek w -15
+KPX aogonek y -20
+KPX aogonek yacute -20
+KPX aogonek ydieresis -20
+KPX aring g -10
+KPX aring gbreve -10
+KPX aring gcommaaccent -10
+KPX aring v -15
+KPX aring w -15
+KPX aring y -20
+KPX aring yacute -20
+KPX aring ydieresis -20
+KPX atilde g -10
+KPX atilde gbreve -10
+KPX atilde gcommaaccent -10
+KPX atilde v -15
+KPX atilde w -15
+KPX atilde y -20
+KPX atilde yacute -20
+KPX atilde ydieresis -20
+KPX b l -10
+KPX b lacute -10
+KPX b lcommaaccent -10
+KPX b lslash -10
+KPX b u -20
+KPX b uacute -20
+KPX b ucircumflex -20
+KPX b udieresis -20
+KPX b ugrave -20
+KPX b uhungarumlaut -20
+KPX b umacron -20
+KPX b uogonek -20
+KPX b uring -20
+KPX b v -20
+KPX b y -20
+KPX b yacute -20
+KPX b ydieresis -20
+KPX c h -10
+KPX c k -20
+KPX c kcommaaccent -20
+KPX c l -20
+KPX c lacute -20
+KPX c lcommaaccent -20
+KPX c lslash -20
+KPX c y -10
+KPX c yacute -10
+KPX c ydieresis -10
+KPX cacute h -10
+KPX cacute k -20
+KPX cacute kcommaaccent -20
+KPX cacute l -20
+KPX cacute lacute -20
+KPX cacute lcommaaccent -20
+KPX cacute lslash -20
+KPX cacute y -10
+KPX cacute yacute -10
+KPX cacute ydieresis -10
+KPX ccaron h -10
+KPX ccaron k -20
+KPX ccaron kcommaaccent -20
+KPX ccaron l -20
+KPX ccaron lacute -20
+KPX ccaron lcommaaccent -20
+KPX ccaron lslash -20
+KPX ccaron y -10
+KPX ccaron yacute -10
+KPX ccaron ydieresis -10
+KPX ccedilla h -10
+KPX ccedilla k -20
+KPX ccedilla kcommaaccent -20
+KPX ccedilla l -20
+KPX ccedilla lacute -20
+KPX ccedilla lcommaaccent -20
+KPX ccedilla lslash -20
+KPX ccedilla y -10
+KPX ccedilla yacute -10
+KPX ccedilla ydieresis -10
+KPX colon space -40
+KPX comma quotedblright -120
+KPX comma quoteright -120
+KPX comma space -40
+KPX d d -10
+KPX d dcroat -10
+KPX d v -15
+KPX d w -15
+KPX d y -15
+KPX d yacute -15
+KPX d ydieresis -15
+KPX dcroat d -10
+KPX dcroat dcroat -10
+KPX dcroat v -15
+KPX dcroat w -15
+KPX dcroat y -15
+KPX dcroat yacute -15
+KPX dcroat ydieresis -15
+KPX e comma 10
+KPX e period 20
+KPX e v -15
+KPX e w -15
+KPX e x -15
+KPX e y -15
+KPX e yacute -15
+KPX e ydieresis -15
+KPX eacute comma 10
+KPX eacute period 20
+KPX eacute v -15
+KPX eacute w -15
+KPX eacute x -15
+KPX eacute y -15
+KPX eacute yacute -15
+KPX eacute ydieresis -15
+KPX ecaron comma 10
+KPX ecaron period 20
+KPX ecaron v -15
+KPX ecaron w -15
+KPX ecaron x -15
+KPX ecaron y -15
+KPX ecaron yacute -15
+KPX ecaron ydieresis -15
+KPX ecircumflex comma 10
+KPX ecircumflex period 20
+KPX ecircumflex v -15
+KPX ecircumflex w -15
+KPX ecircumflex x -15
+KPX ecircumflex y -15
+KPX ecircumflex yacute -15
+KPX ecircumflex ydieresis -15
+KPX edieresis comma 10
+KPX edieresis period 20
+KPX edieresis v -15
+KPX edieresis w -15
+KPX edieresis x -15
+KPX edieresis y -15
+KPX edieresis yacute -15
+KPX edieresis ydieresis -15
+KPX edotaccent comma 10
+KPX edotaccent period 20
+KPX edotaccent v -15
+KPX edotaccent w -15
+KPX edotaccent x -15
+KPX edotaccent y -15
+KPX edotaccent yacute -15
+KPX edotaccent ydieresis -15
+KPX egrave comma 10
+KPX egrave period 20
+KPX egrave v -15
+KPX egrave w -15
+KPX egrave x -15
+KPX egrave y -15
+KPX egrave yacute -15
+KPX egrave ydieresis -15
+KPX emacron comma 10
+KPX emacron period 20
+KPX emacron v -15
+KPX emacron w -15
+KPX emacron x -15
+KPX emacron y -15
+KPX emacron yacute -15
+KPX emacron ydieresis -15
+KPX eogonek comma 10
+KPX eogonek period 20
+KPX eogonek v -15
+KPX eogonek w -15
+KPX eogonek x -15
+KPX eogonek y -15
+KPX eogonek yacute -15
+KPX eogonek ydieresis -15
+KPX f comma -10
+KPX f e -10
+KPX f eacute -10
+KPX f ecaron -10
+KPX f ecircumflex -10
+KPX f edieresis -10
+KPX f edotaccent -10
+KPX f egrave -10
+KPX f emacron -10
+KPX f eogonek -10
+KPX f o -20
+KPX f oacute -20
+KPX f ocircumflex -20
+KPX f odieresis -20
+KPX f ograve -20
+KPX f ohungarumlaut -20
+KPX f omacron -20
+KPX f oslash -20
+KPX f otilde -20
+KPX f period -10
+KPX f quotedblright 30
+KPX f quoteright 30
+KPX g e 10
+KPX g eacute 10
+KPX g ecaron 10
+KPX g ecircumflex 10
+KPX g edieresis 10
+KPX g edotaccent 10
+KPX g egrave 10
+KPX g emacron 10
+KPX g eogonek 10
+KPX g g -10
+KPX g gbreve -10
+KPX g gcommaaccent -10
+KPX gbreve e 10
+KPX gbreve eacute 10
+KPX gbreve ecaron 10
+KPX gbreve ecircumflex 10
+KPX gbreve edieresis 10
+KPX gbreve edotaccent 10
+KPX gbreve egrave 10
+KPX gbreve emacron 10
+KPX gbreve eogonek 10
+KPX gbreve g -10
+KPX gbreve gbreve -10
+KPX gbreve gcommaaccent -10
+KPX gcommaaccent e 10
+KPX gcommaaccent eacute 10
+KPX gcommaaccent ecaron 10
+KPX gcommaaccent ecircumflex 10
+KPX gcommaaccent edieresis 10
+KPX gcommaaccent edotaccent 10
+KPX gcommaaccent egrave 10
+KPX gcommaaccent emacron 10
+KPX gcommaaccent eogonek 10
+KPX gcommaaccent g -10
+KPX gcommaaccent gbreve -10
+KPX gcommaaccent gcommaaccent -10
+KPX h y -20
+KPX h yacute -20
+KPX h ydieresis -20
+KPX k o -15
+KPX k oacute -15
+KPX k ocircumflex -15
+KPX k odieresis -15
+KPX k ograve -15
+KPX k ohungarumlaut -15
+KPX k omacron -15
+KPX k oslash -15
+KPX k otilde -15
+KPX kcommaaccent o -15
+KPX kcommaaccent oacute -15
+KPX kcommaaccent ocircumflex -15
+KPX kcommaaccent odieresis -15
+KPX kcommaaccent ograve -15
+KPX kcommaaccent ohungarumlaut -15
+KPX kcommaaccent omacron -15
+KPX kcommaaccent oslash -15
+KPX kcommaaccent otilde -15
+KPX l w -15
+KPX l y -15
+KPX l yacute -15
+KPX l ydieresis -15
+KPX lacute w -15
+KPX lacute y -15
+KPX lacute yacute -15
+KPX lacute ydieresis -15
+KPX lcommaaccent w -15
+KPX lcommaaccent y -15
+KPX lcommaaccent yacute -15
+KPX lcommaaccent ydieresis -15
+KPX lslash w -15
+KPX lslash y -15
+KPX lslash yacute -15
+KPX lslash ydieresis -15
+KPX m u -20
+KPX m uacute -20
+KPX m ucircumflex -20
+KPX m udieresis -20
+KPX m ugrave -20
+KPX m uhungarumlaut -20
+KPX m umacron -20
+KPX m uogonek -20
+KPX m uring -20
+KPX m y -30
+KPX m yacute -30
+KPX m ydieresis -30
+KPX n u -10
+KPX n uacute -10
+KPX n ucircumflex -10
+KPX n udieresis -10
+KPX n ugrave -10
+KPX n uhungarumlaut -10
+KPX n umacron -10
+KPX n uogonek -10
+KPX n uring -10
+KPX n v -40
+KPX n y -20
+KPX n yacute -20
+KPX n ydieresis -20
+KPX nacute u -10
+KPX nacute uacute -10
+KPX nacute ucircumflex -10
+KPX nacute udieresis -10
+KPX nacute ugrave -10
+KPX nacute uhungarumlaut -10
+KPX nacute umacron -10
+KPX nacute uogonek -10
+KPX nacute uring -10
+KPX nacute v -40
+KPX nacute y -20
+KPX nacute yacute -20
+KPX nacute ydieresis -20
+KPX ncaron u -10
+KPX ncaron uacute -10
+KPX ncaron ucircumflex -10
+KPX ncaron udieresis -10
+KPX ncaron ugrave -10
+KPX ncaron uhungarumlaut -10
+KPX ncaron umacron -10
+KPX ncaron uogonek -10
+KPX ncaron uring -10
+KPX ncaron v -40
+KPX ncaron y -20
+KPX ncaron yacute -20
+KPX ncaron ydieresis -20
+KPX ncommaaccent u -10
+KPX ncommaaccent uacute -10
+KPX ncommaaccent ucircumflex -10
+KPX ncommaaccent udieresis -10
+KPX ncommaaccent ugrave -10
+KPX ncommaaccent uhungarumlaut -10
+KPX ncommaaccent umacron -10
+KPX ncommaaccent uogonek -10
+KPX ncommaaccent uring -10
+KPX ncommaaccent v -40
+KPX ncommaaccent y -20
+KPX ncommaaccent yacute -20
+KPX ncommaaccent ydieresis -20
+KPX ntilde u -10
+KPX ntilde uacute -10
+KPX ntilde ucircumflex -10
+KPX ntilde udieresis -10
+KPX ntilde ugrave -10
+KPX ntilde uhungarumlaut -10
+KPX ntilde umacron -10
+KPX ntilde uogonek -10
+KPX ntilde uring -10
+KPX ntilde v -40
+KPX ntilde y -20
+KPX ntilde yacute -20
+KPX ntilde ydieresis -20
+KPX o v -20
+KPX o w -15
+KPX o x -30
+KPX o y -20
+KPX o yacute -20
+KPX o ydieresis -20
+KPX oacute v -20
+KPX oacute w -15
+KPX oacute x -30
+KPX oacute y -20
+KPX oacute yacute -20
+KPX oacute ydieresis -20
+KPX ocircumflex v -20
+KPX ocircumflex w -15
+KPX ocircumflex x -30
+KPX ocircumflex y -20
+KPX ocircumflex yacute -20
+KPX ocircumflex ydieresis -20
+KPX odieresis v -20
+KPX odieresis w -15
+KPX odieresis x -30
+KPX odieresis y -20
+KPX odieresis yacute -20
+KPX odieresis ydieresis -20
+KPX ograve v -20
+KPX ograve w -15
+KPX ograve x -30
+KPX ograve y -20
+KPX ograve yacute -20
+KPX ograve ydieresis -20
+KPX ohungarumlaut v -20
+KPX ohungarumlaut w -15
+KPX ohungarumlaut x -30
+KPX ohungarumlaut y -20
+KPX ohungarumlaut yacute -20
+KPX ohungarumlaut ydieresis -20
+KPX omacron v -20
+KPX omacron w -15
+KPX omacron x -30
+KPX omacron y -20
+KPX omacron yacute -20
+KPX omacron ydieresis -20
+KPX oslash v -20
+KPX oslash w -15
+KPX oslash x -30
+KPX oslash y -20
+KPX oslash yacute -20
+KPX oslash ydieresis -20
+KPX otilde v -20
+KPX otilde w -15
+KPX otilde x -30
+KPX otilde y -20
+KPX otilde yacute -20
+KPX otilde ydieresis -20
+KPX p y -15
+KPX p yacute -15
+KPX p ydieresis -15
+KPX period quotedblright -120
+KPX period quoteright -120
+KPX period space -40
+KPX quotedblright space -80
+KPX quoteleft quoteleft -46
+KPX quoteright d -80
+KPX quoteright dcroat -80
+KPX quoteright l -20
+KPX quoteright lacute -20
+KPX quoteright lcommaaccent -20
+KPX quoteright lslash -20
+KPX quoteright quoteright -46
+KPX quoteright r -40
+KPX quoteright racute -40
+KPX quoteright rcaron -40
+KPX quoteright rcommaaccent -40
+KPX quoteright s -60
+KPX quoteright sacute -60
+KPX quoteright scaron -60
+KPX quoteright scedilla -60
+KPX quoteright scommaaccent -60
+KPX quoteright space -80
+KPX quoteright v -20
+KPX r c -20
+KPX r cacute -20
+KPX r ccaron -20
+KPX r ccedilla -20
+KPX r comma -60
+KPX r d -20
+KPX r dcroat -20
+KPX r g -15
+KPX r gbreve -15
+KPX r gcommaaccent -15
+KPX r hyphen -20
+KPX r o -20
+KPX r oacute -20
+KPX r ocircumflex -20
+KPX r odieresis -20
+KPX r ograve -20
+KPX r ohungarumlaut -20
+KPX r omacron -20
+KPX r oslash -20
+KPX r otilde -20
+KPX r period -60
+KPX r q -20
+KPX r s -15
+KPX r sacute -15
+KPX r scaron -15
+KPX r scedilla -15
+KPX r scommaaccent -15
+KPX r t 20
+KPX r tcommaaccent 20
+KPX r v 10
+KPX r y 10
+KPX r yacute 10
+KPX r ydieresis 10
+KPX racute c -20
+KPX racute cacute -20
+KPX racute ccaron -20
+KPX racute ccedilla -20
+KPX racute comma -60
+KPX racute d -20
+KPX racute dcroat -20
+KPX racute g -15
+KPX racute gbreve -15
+KPX racute gcommaaccent -15
+KPX racute hyphen -20
+KPX racute o -20
+KPX racute oacute -20
+KPX racute ocircumflex -20
+KPX racute odieresis -20
+KPX racute ograve -20
+KPX racute ohungarumlaut -20
+KPX racute omacron -20
+KPX racute oslash -20
+KPX racute otilde -20
+KPX racute period -60
+KPX racute q -20
+KPX racute s -15
+KPX racute sacute -15
+KPX racute scaron -15
+KPX racute scedilla -15
+KPX racute scommaaccent -15
+KPX racute t 20
+KPX racute tcommaaccent 20
+KPX racute v 10
+KPX racute y 10
+KPX racute yacute 10
+KPX racute ydieresis 10
+KPX rcaron c -20
+KPX rcaron cacute -20
+KPX rcaron ccaron -20
+KPX rcaron ccedilla -20
+KPX rcaron comma -60
+KPX rcaron d -20
+KPX rcaron dcroat -20
+KPX rcaron g -15
+KPX rcaron gbreve -15
+KPX rcaron gcommaaccent -15
+KPX rcaron hyphen -20
+KPX rcaron o -20
+KPX rcaron oacute -20
+KPX rcaron ocircumflex -20
+KPX rcaron odieresis -20
+KPX rcaron ograve -20
+KPX rcaron ohungarumlaut -20
+KPX rcaron omacron -20
+KPX rcaron oslash -20
+KPX rcaron otilde -20
+KPX rcaron period -60
+KPX rcaron q -20
+KPX rcaron s -15
+KPX rcaron sacute -15
+KPX rcaron scaron -15
+KPX rcaron scedilla -15
+KPX rcaron scommaaccent -15
+KPX rcaron t 20
+KPX rcaron tcommaaccent 20
+KPX rcaron v 10
+KPX rcaron y 10
+KPX rcaron yacute 10
+KPX rcaron ydieresis 10
+KPX rcommaaccent c -20
+KPX rcommaaccent cacute -20
+KPX rcommaaccent ccaron -20
+KPX rcommaaccent ccedilla -20
+KPX rcommaaccent comma -60
+KPX rcommaaccent d -20
+KPX rcommaaccent dcroat -20
+KPX rcommaaccent g -15
+KPX rcommaaccent gbreve -15
+KPX rcommaaccent gcommaaccent -15
+KPX rcommaaccent hyphen -20
+KPX rcommaaccent o -20
+KPX rcommaaccent oacute -20
+KPX rcommaaccent ocircumflex -20
+KPX rcommaaccent odieresis -20
+KPX rcommaaccent ograve -20
+KPX rcommaaccent ohungarumlaut -20
+KPX rcommaaccent omacron -20
+KPX rcommaaccent oslash -20
+KPX rcommaaccent otilde -20
+KPX rcommaaccent period -60
+KPX rcommaaccent q -20
+KPX rcommaaccent s -15
+KPX rcommaaccent sacute -15
+KPX rcommaaccent scaron -15
+KPX rcommaaccent scedilla -15
+KPX rcommaaccent scommaaccent -15
+KPX rcommaaccent t 20
+KPX rcommaaccent tcommaaccent 20
+KPX rcommaaccent v 10
+KPX rcommaaccent y 10
+KPX rcommaaccent yacute 10
+KPX rcommaaccent ydieresis 10
+KPX s w -15
+KPX sacute w -15
+KPX scaron w -15
+KPX scedilla w -15
+KPX scommaaccent w -15
+KPX semicolon space -40
+KPX space T -100
+KPX space Tcaron -100
+KPX space Tcommaaccent -100
+KPX space V -80
+KPX space W -80
+KPX space Y -120
+KPX space Yacute -120
+KPX space Ydieresis -120
+KPX space quotedblleft -80
+KPX space quoteleft -60
+KPX v a -20
+KPX v aacute -20
+KPX v abreve -20
+KPX v acircumflex -20
+KPX v adieresis -20
+KPX v agrave -20
+KPX v amacron -20
+KPX v aogonek -20
+KPX v aring -20
+KPX v atilde -20
+KPX v comma -80
+KPX v o -30
+KPX v oacute -30
+KPX v ocircumflex -30
+KPX v odieresis -30
+KPX v ograve -30
+KPX v ohungarumlaut -30
+KPX v omacron -30
+KPX v oslash -30
+KPX v otilde -30
+KPX v period -80
+KPX w comma -40
+KPX w o -20
+KPX w oacute -20
+KPX w ocircumflex -20
+KPX w odieresis -20
+KPX w ograve -20
+KPX w ohungarumlaut -20
+KPX w omacron -20
+KPX w oslash -20
+KPX w otilde -20
+KPX w period -40
+KPX x e -10
+KPX x eacute -10
+KPX x ecaron -10
+KPX x ecircumflex -10
+KPX x edieresis -10
+KPX x edotaccent -10
+KPX x egrave -10
+KPX x emacron -10
+KPX x eogonek -10
+KPX y a -30
+KPX y aacute -30
+KPX y abreve -30
+KPX y acircumflex -30
+KPX y adieresis -30
+KPX y agrave -30
+KPX y amacron -30
+KPX y aogonek -30
+KPX y aring -30
+KPX y atilde -30
+KPX y comma -80
+KPX y e -10
+KPX y eacute -10
+KPX y ecaron -10
+KPX y ecircumflex -10
+KPX y edieresis -10
+KPX y edotaccent -10
+KPX y egrave -10
+KPX y emacron -10
+KPX y eogonek -10
+KPX y o -25
+KPX y oacute -25
+KPX y ocircumflex -25
+KPX y odieresis -25
+KPX y ograve -25
+KPX y ohungarumlaut -25
+KPX y omacron -25
+KPX y oslash -25
+KPX y otilde -25
+KPX y period -80
+KPX yacute a -30
+KPX yacute aacute -30
+KPX yacute abreve -30
+KPX yacute acircumflex -30
+KPX yacute adieresis -30
+KPX yacute agrave -30
+KPX yacute amacron -30
+KPX yacute aogonek -30
+KPX yacute aring -30
+KPX yacute atilde -30
+KPX yacute comma -80
+KPX yacute e -10
+KPX yacute eacute -10
+KPX yacute ecaron -10
+KPX yacute ecircumflex -10
+KPX yacute edieresis -10
+KPX yacute edotaccent -10
+KPX yacute egrave -10
+KPX yacute emacron -10
+KPX yacute eogonek -10
+KPX yacute o -25
+KPX yacute oacute -25
+KPX yacute ocircumflex -25
+KPX yacute odieresis -25
+KPX yacute ograve -25
+KPX yacute ohungarumlaut -25
+KPX yacute omacron -25
+KPX yacute oslash -25
+KPX yacute otilde -25
+KPX yacute period -80
+KPX ydieresis a -30
+KPX ydieresis aacute -30
+KPX ydieresis abreve -30
+KPX ydieresis acircumflex -30
+KPX ydieresis adieresis -30
+KPX ydieresis agrave -30
+KPX ydieresis amacron -30
+KPX ydieresis aogonek -30
+KPX ydieresis aring -30
+KPX ydieresis atilde -30
+KPX ydieresis comma -80
+KPX ydieresis e -10
+KPX ydieresis eacute -10
+KPX ydieresis ecaron -10
+KPX ydieresis ecircumflex -10
+KPX ydieresis edieresis -10
+KPX ydieresis edotaccent -10
+KPX ydieresis egrave -10
+KPX ydieresis emacron -10
+KPX ydieresis eogonek -10
+KPX ydieresis o -25
+KPX ydieresis oacute -25
+KPX ydieresis ocircumflex -25
+KPX ydieresis odieresis -25
+KPX ydieresis ograve -25
+KPX ydieresis ohungarumlaut -25
+KPX ydieresis omacron -25
+KPX ydieresis oslash -25
+KPX ydieresis otilde -25
+KPX ydieresis period -80
+KPX z e 10
+KPX z eacute 10
+KPX z ecaron 10
+KPX z ecircumflex 10
+KPX z edieresis 10
+KPX z edotaccent 10
+KPX z egrave 10
+KPX z emacron 10
+KPX z eogonek 10
+KPX zacute e 10
+KPX zacute eacute 10
+KPX zacute ecaron 10
+KPX zacute ecircumflex 10
+KPX zacute edieresis 10
+KPX zacute edotaccent 10
+KPX zacute egrave 10
+KPX zacute emacron 10
+KPX zacute eogonek 10
+KPX zcaron e 10
+KPX zcaron eacute 10
+KPX zcaron ecaron 10
+KPX zcaron ecircumflex 10
+KPX zcaron edieresis 10
+KPX zcaron edotaccent 10
+KPX zcaron egrave 10
+KPX zcaron emacron 10
+KPX zcaron eogonek 10
+KPX zdotaccent e 10
+KPX zdotaccent eacute 10
+KPX zdotaccent ecaron 10
+KPX zdotaccent ecircumflex 10
+KPX zdotaccent edieresis 10
+KPX zdotaccent edotaccent 10
+KPX zdotaccent egrave 10
+KPX zdotaccent emacron 10
+KPX zdotaccent eogonek 10
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-Oblique.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-Oblique.afm
new file mode 100644
index 0000000..a1494fb
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica-Oblique.afm
@@ -0,0 +1,3051 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 12:44:31 1997
+Comment UniqueID 43055
+Comment VMusage 14960 69346
+FontName Helvetica-Oblique
+FullName Helvetica Oblique
+FamilyName Helvetica
+Weight Medium
+ItalicAngle -12
+IsFixedPitch false
+CharacterSet ExtendedRoman
+FontBBox -170 -225 1116 931
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 523
+Ascender 718
+Descender -207
+StdHW 76
+StdVW 88
+StartCharMetrics 315
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ;
+C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ;
+C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ;
+C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ;
+C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ;
+C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ;
+C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ;
+C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ;
+C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ;
+C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ;
+C 43 ; WX 584 ; N plus ; B 85 0 606 505 ;
+C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ;
+C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ;
+C 46 ; WX 278 ; N period ; B 87 0 214 106 ;
+C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ;
+C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ;
+C 49 ; WX 556 ; N one ; B 207 0 508 703 ;
+C 50 ; WX 556 ; N two ; B 26 0 617 703 ;
+C 51 ; WX 556 ; N three ; B 75 -19 610 703 ;
+C 52 ; WX 556 ; N four ; B 61 0 576 703 ;
+C 53 ; WX 556 ; N five ; B 68 -19 621 688 ;
+C 54 ; WX 556 ; N six ; B 91 -19 615 703 ;
+C 55 ; WX 556 ; N seven ; B 137 0 669 688 ;
+C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ;
+C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ;
+C 58 ; WX 278 ; N colon ; B 87 0 301 516 ;
+C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ;
+C 60 ; WX 584 ; N less ; B 94 11 641 495 ;
+C 61 ; WX 584 ; N equal ; B 63 115 628 390 ;
+C 62 ; WX 584 ; N greater ; B 50 11 597 495 ;
+C 63 ; WX 556 ; N question ; B 161 0 610 727 ;
+C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ;
+C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
+C 66 ; WX 667 ; N B ; B 74 0 712 718 ;
+C 67 ; WX 722 ; N C ; B 108 -19 782 737 ;
+C 68 ; WX 722 ; N D ; B 81 0 764 718 ;
+C 69 ; WX 667 ; N E ; B 86 0 762 718 ;
+C 70 ; WX 611 ; N F ; B 86 0 736 718 ;
+C 71 ; WX 778 ; N G ; B 111 -19 799 737 ;
+C 72 ; WX 722 ; N H ; B 77 0 799 718 ;
+C 73 ; WX 278 ; N I ; B 91 0 341 718 ;
+C 74 ; WX 500 ; N J ; B 47 -19 581 718 ;
+C 75 ; WX 667 ; N K ; B 76 0 808 718 ;
+C 76 ; WX 556 ; N L ; B 76 0 555 718 ;
+C 77 ; WX 833 ; N M ; B 73 0 914 718 ;
+C 78 ; WX 722 ; N N ; B 76 0 799 718 ;
+C 79 ; WX 778 ; N O ; B 105 -19 826 737 ;
+C 80 ; WX 667 ; N P ; B 86 0 737 718 ;
+C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ;
+C 82 ; WX 722 ; N R ; B 88 0 773 718 ;
+C 83 ; WX 667 ; N S ; B 90 -19 713 737 ;
+C 84 ; WX 611 ; N T ; B 148 0 750 718 ;
+C 85 ; WX 722 ; N U ; B 123 -19 797 718 ;
+C 86 ; WX 667 ; N V ; B 173 0 800 718 ;
+C 87 ; WX 944 ; N W ; B 169 0 1081 718 ;
+C 88 ; WX 667 ; N X ; B 19 0 790 718 ;
+C 89 ; WX 667 ; N Y ; B 167 0 806 718 ;
+C 90 ; WX 611 ; N Z ; B 23 0 741 718 ;
+C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ;
+C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ;
+C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ;
+C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ;
+C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
+C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ;
+C 97 ; WX 556 ; N a ; B 61 -15 559 538 ;
+C 98 ; WX 556 ; N b ; B 58 -15 584 718 ;
+C 99 ; WX 500 ; N c ; B 74 -15 553 538 ;
+C 100 ; WX 556 ; N d ; B 84 -15 652 718 ;
+C 101 ; WX 556 ; N e ; B 84 -15 578 538 ;
+C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 42 -220 610 538 ;
+C 104 ; WX 556 ; N h ; B 65 0 573 718 ;
+C 105 ; WX 222 ; N i ; B 67 0 308 718 ;
+C 106 ; WX 222 ; N j ; B -60 -210 308 718 ;
+C 107 ; WX 500 ; N k ; B 67 0 600 718 ;
+C 108 ; WX 222 ; N l ; B 67 0 308 718 ;
+C 109 ; WX 833 ; N m ; B 65 0 852 538 ;
+C 110 ; WX 556 ; N n ; B 65 0 573 538 ;
+C 111 ; WX 556 ; N o ; B 83 -14 585 538 ;
+C 112 ; WX 556 ; N p ; B 14 -207 584 538 ;
+C 113 ; WX 556 ; N q ; B 84 -207 605 538 ;
+C 114 ; WX 333 ; N r ; B 77 0 446 538 ;
+C 115 ; WX 500 ; N s ; B 63 -15 529 538 ;
+C 116 ; WX 278 ; N t ; B 102 -7 368 669 ;
+C 117 ; WX 556 ; N u ; B 94 -15 600 523 ;
+C 118 ; WX 500 ; N v ; B 119 0 603 523 ;
+C 119 ; WX 722 ; N w ; B 125 0 820 523 ;
+C 120 ; WX 500 ; N x ; B 11 0 594 523 ;
+C 121 ; WX 500 ; N y ; B 15 -214 600 523 ;
+C 122 ; WX 500 ; N z ; B 31 0 571 523 ;
+C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ;
+C 124 ; WX 260 ; N bar ; B 46 -225 332 775 ;
+C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ;
+C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ;
+C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ;
+C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ;
+C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ;
+C 165 ; WX 556 ; N yen ; B 81 0 699 688 ;
+C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ;
+C 167 ; WX 556 ; N section ; B 76 -191 584 737 ;
+C 168 ; WX 556 ; N currency ; B 60 99 646 603 ;
+C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ;
+C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ;
+C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ;
+C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ;
+C 174 ; WX 500 ; N fi ; B 86 0 587 728 ;
+C 175 ; WX 500 ; N fl ; B 86 0 585 728 ;
+C 177 ; WX 556 ; N endash ; B 51 240 623 313 ;
+C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ;
+C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ;
+C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ;
+C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ;
+C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ;
+C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ;
+C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ;
+C 193 ; WX 333 ; N grave ; B 170 593 337 734 ;
+C 194 ; WX 333 ; N acute ; B 248 593 475 734 ;
+C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ;
+C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ;
+C 197 ; WX 333 ; N macron ; B 143 627 468 684 ;
+C 198 ; WX 333 ; N breve ; B 167 595 476 731 ;
+C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ;
+C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ;
+C 202 ; WX 333 ; N ring ; B 214 572 402 756 ;
+C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ;
+C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ;
+C 207 ; WX 333 ; N caron ; B 177 593 468 734 ;
+C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ;
+C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 127 405 449 737 ;
+C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ;
+C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ;
+C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 141 405 468 737 ;
+C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ;
+C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ;
+C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ;
+C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ;
+C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ;
+C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ;
+C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ;
+C -1 ; WX 556 ; N abreve ; B 61 -15 578 731 ;
+C -1 ; WX 556 ; N uhungarumlaut ; B 94 -15 677 734 ;
+C -1 ; WX 556 ; N ecaron ; B 84 -15 580 734 ;
+C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ;
+C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ;
+C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ;
+C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
+C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ;
+C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ;
+C -1 ; WX 500 ; N scommaaccent ; B 63 -225 529 538 ;
+C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ;
+C -1 ; WX 722 ; N Uring ; B 123 -19 797 931 ;
+C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ;
+C -1 ; WX 556 ; N aogonek ; B 61 -220 559 538 ;
+C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ;
+C -1 ; WX 556 ; N uogonek ; B 94 -225 600 523 ;
+C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ;
+C -1 ; WX 722 ; N Dcroat ; B 69 0 764 718 ;
+C -1 ; WX 250 ; N commaaccent ; B 39 -225 172 -40 ;
+C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ;
+C -1 ; WX 667 ; N Emacron ; B 86 0 762 879 ;
+C -1 ; WX 500 ; N ccaron ; B 74 -15 553 734 ;
+C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ;
+C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 799 718 ;
+C -1 ; WX 222 ; N lacute ; B 67 0 461 929 ;
+C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ;
+C -1 ; WX 611 ; N Tcommaaccent ; B 148 -225 750 718 ;
+C -1 ; WX 722 ; N Cacute ; B 108 -19 782 929 ;
+C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ;
+C -1 ; WX 667 ; N Edotaccent ; B 86 0 762 901 ;
+C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ;
+C -1 ; WX 500 ; N scedilla ; B 63 -225 529 538 ;
+C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ;
+C -1 ; WX 471 ; N lozenge ; B 88 0 540 728 ;
+C -1 ; WX 722 ; N Rcaron ; B 88 0 773 929 ;
+C -1 ; WX 778 ; N Gcommaaccent ; B 111 -225 799 737 ;
+C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ;
+C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ;
+C -1 ; WX 667 ; N Amacron ; B 14 0 677 879 ;
+C -1 ; WX 333 ; N rcaron ; B 77 0 508 734 ;
+C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ;
+C -1 ; WX 611 ; N Zdotaccent ; B 23 0 741 901 ;
+C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ;
+C -1 ; WX 778 ; N Omacron ; B 105 -19 826 879 ;
+C -1 ; WX 722 ; N Racute ; B 88 0 773 929 ;
+C -1 ; WX 667 ; N Sacute ; B 90 -19 713 929 ;
+C -1 ; WX 643 ; N dcaron ; B 84 -15 808 718 ;
+C -1 ; WX 722 ; N Umacron ; B 123 -19 797 879 ;
+C -1 ; WX 556 ; N uring ; B 94 -15 600 756 ;
+C -1 ; WX 333 ; N threebaseior ; B 90 270 436 703 ;
+C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ;
+C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
+C -1 ; WX 667 ; N Abreve ; B 14 0 685 926 ;
+C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ;
+C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ;
+C -1 ; WX 611 ; N Tcaron ; B 148 0 750 929 ;
+C -1 ; WX 476 ; N partialdiff ; B 41 -38 550 714 ;
+C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ;
+C -1 ; WX 722 ; N Nacute ; B 76 0 799 929 ;
+C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ;
+C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ;
+C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ;
+C -1 ; WX 500 ; N cacute ; B 74 -15 559 734 ;
+C -1 ; WX 556 ; N nacute ; B 65 0 587 734 ;
+C -1 ; WX 556 ; N umacron ; B 94 -15 600 684 ;
+C -1 ; WX 722 ; N Ncaron ; B 76 0 799 929 ;
+C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ;
+C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ;
+C -1 ; WX 260 ; N brokenbar ; B 62 -150 316 700 ;
+C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ;
+C -1 ; WX 778 ; N Gbreve ; B 111 -19 799 926 ;
+C -1 ; WX 278 ; N Idotaccent ; B 91 0 377 901 ;
+C -1 ; WX 600 ; N summation ; B 15 -10 671 706 ;
+C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ;
+C -1 ; WX 333 ; N racute ; B 77 0 475 734 ;
+C -1 ; WX 556 ; N omacron ; B 83 -14 585 684 ;
+C -1 ; WX 611 ; N Zacute ; B 23 0 741 929 ;
+C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ;
+C -1 ; WX 549 ; N greaterequal ; B 26 0 620 674 ;
+C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ;
+C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ;
+C -1 ; WX 222 ; N lcommaaccent ; B 25 -225 308 718 ;
+C -1 ; WX 317 ; N tcaron ; B 102 -7 501 808 ;
+C -1 ; WX 556 ; N eogonek ; B 84 -225 578 538 ;
+C -1 ; WX 722 ; N Uogonek ; B 123 -225 797 718 ;
+C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ;
+C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
+C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ;
+C -1 ; WX 500 ; N zacute ; B 31 0 571 734 ;
+C -1 ; WX 222 ; N iogonek ; B -61 -225 308 718 ;
+C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ;
+C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ;
+C -1 ; WX 556 ; N amacron ; B 61 -15 580 684 ;
+C -1 ; WX 500 ; N sacute ; B 63 -15 559 734 ;
+C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ;
+C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ;
+C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ;
+C -1 ; WX 333 ; N twobaseior ; B 64 281 449 703 ;
+C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ;
+C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ;
+C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ;
+C -1 ; WX 556 ; N ohungarumlaut ; B 83 -14 677 734 ;
+C -1 ; WX 667 ; N Eogonek ; B 86 -220 762 718 ;
+C -1 ; WX 556 ; N dcroat ; B 84 -15 689 718 ;
+C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ;
+C -1 ; WX 667 ; N Scedilla ; B 90 -225 713 737 ;
+C -1 ; WX 299 ; N lcaron ; B 67 0 464 718 ;
+C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 808 718 ;
+C -1 ; WX 556 ; N Lacute ; B 76 0 555 929 ;
+C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ;
+C -1 ; WX 556 ; N edotaccent ; B 84 -15 578 706 ;
+C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ;
+C -1 ; WX 278 ; N Imacron ; B 91 0 483 879 ;
+C -1 ; WX 556 ; N Lcaron ; B 76 0 570 718 ;
+C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ;
+C -1 ; WX 549 ; N lessequal ; B 26 0 666 674 ;
+C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ;
+C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ;
+C -1 ; WX 722 ; N Uhungarumlaut ; B 123 -19 801 929 ;
+C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ;
+C -1 ; WX 556 ; N emacron ; B 84 -15 580 684 ;
+C -1 ; WX 556 ; N gbreve ; B 42 -220 610 731 ;
+C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ;
+C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ;
+C -1 ; WX 667 ; N Scommaaccent ; B 90 -225 713 737 ;
+C -1 ; WX 778 ; N Ohungarumlaut ; B 105 -19 829 929 ;
+C -1 ; WX 400 ; N degree ; B 169 411 468 703 ;
+C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ;
+C -1 ; WX 722 ; N Ccaron ; B 108 -19 782 929 ;
+C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ;
+C -1 ; WX 453 ; N radical ; B 79 -80 617 762 ;
+C -1 ; WX 722 ; N Dcaron ; B 81 0 764 929 ;
+C -1 ; WX 333 ; N rcommaaccent ; B 30 -225 446 538 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ;
+C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ;
+C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 773 718 ;
+C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 555 718 ;
+C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ;
+C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ;
+C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
+C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ;
+C -1 ; WX 500 ; N zdotaccent ; B 31 0 571 706 ;
+C -1 ; WX 667 ; N Ecaron ; B 86 0 762 929 ;
+C -1 ; WX 278 ; N Iogonek ; B -33 -225 341 718 ;
+C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 600 718 ;
+C -1 ; WX 584 ; N minus ; B 85 216 606 289 ;
+C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ;
+C -1 ; WX 556 ; N ncaron ; B 65 0 580 734 ;
+C -1 ; WX 278 ; N tcommaaccent ; B 63 -225 368 669 ;
+C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ;
+C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ;
+C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ;
+C -1 ; WX 549 ; N notequal ; B 34 -35 623 551 ;
+C -1 ; WX 556 ; N gcommaaccent ; B 42 -220 610 822 ;
+C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ;
+C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 573 538 ;
+C -1 ; WX 333 ; N onebaseior ; B 166 281 371 703 ;
+C -1 ; WX 278 ; N imacron ; B 95 0 417 684 ;
+C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 2705
+KPX A C -30
+KPX A Cacute -30
+KPX A Ccaron -30
+KPX A Ccedilla -30
+KPX A G -30
+KPX A Gbreve -30
+KPX A Gcommaaccent -30
+KPX A O -30
+KPX A Oacute -30
+KPX A Ocircumflex -30
+KPX A Odieresis -30
+KPX A Ograve -30
+KPX A Ohungarumlaut -30
+KPX A Omacron -30
+KPX A Oslash -30
+KPX A Otilde -30
+KPX A Q -30
+KPX A T -120
+KPX A Tcaron -120
+KPX A Tcommaaccent -120
+KPX A U -50
+KPX A Uacute -50
+KPX A Ucircumflex -50
+KPX A Udieresis -50
+KPX A Ugrave -50
+KPX A Uhungarumlaut -50
+KPX A Umacron -50
+KPX A Uogonek -50
+KPX A Uring -50
+KPX A V -70
+KPX A W -50
+KPX A Y -100
+KPX A Yacute -100
+KPX A Ydieresis -100
+KPX A u -30
+KPX A uacute -30
+KPX A ucircumflex -30
+KPX A udieresis -30
+KPX A ugrave -30
+KPX A uhungarumlaut -30
+KPX A umacron -30
+KPX A uogonek -30
+KPX A uring -30
+KPX A v -40
+KPX A w -40
+KPX A y -40
+KPX A yacute -40
+KPX A ydieresis -40
+KPX Aacute C -30
+KPX Aacute Cacute -30
+KPX Aacute Ccaron -30
+KPX Aacute Ccedilla -30
+KPX Aacute G -30
+KPX Aacute Gbreve -30
+KPX Aacute Gcommaaccent -30
+KPX Aacute O -30
+KPX Aacute Oacute -30
+KPX Aacute Ocircumflex -30
+KPX Aacute Odieresis -30
+KPX Aacute Ograve -30
+KPX Aacute Ohungarumlaut -30
+KPX Aacute Omacron -30
+KPX Aacute Oslash -30
+KPX Aacute Otilde -30
+KPX Aacute Q -30
+KPX Aacute T -120
+KPX Aacute Tcaron -120
+KPX Aacute Tcommaaccent -120
+KPX Aacute U -50
+KPX Aacute Uacute -50
+KPX Aacute Ucircumflex -50
+KPX Aacute Udieresis -50
+KPX Aacute Ugrave -50
+KPX Aacute Uhungarumlaut -50
+KPX Aacute Umacron -50
+KPX Aacute Uogonek -50
+KPX Aacute Uring -50
+KPX Aacute V -70
+KPX Aacute W -50
+KPX Aacute Y -100
+KPX Aacute Yacute -100
+KPX Aacute Ydieresis -100
+KPX Aacute u -30
+KPX Aacute uacute -30
+KPX Aacute ucircumflex -30
+KPX Aacute udieresis -30
+KPX Aacute ugrave -30
+KPX Aacute uhungarumlaut -30
+KPX Aacute umacron -30
+KPX Aacute uogonek -30
+KPX Aacute uring -30
+KPX Aacute v -40
+KPX Aacute w -40
+KPX Aacute y -40
+KPX Aacute yacute -40
+KPX Aacute ydieresis -40
+KPX Abreve C -30
+KPX Abreve Cacute -30
+KPX Abreve Ccaron -30
+KPX Abreve Ccedilla -30
+KPX Abreve G -30
+KPX Abreve Gbreve -30
+KPX Abreve Gcommaaccent -30
+KPX Abreve O -30
+KPX Abreve Oacute -30
+KPX Abreve Ocircumflex -30
+KPX Abreve Odieresis -30
+KPX Abreve Ograve -30
+KPX Abreve Ohungarumlaut -30
+KPX Abreve Omacron -30
+KPX Abreve Oslash -30
+KPX Abreve Otilde -30
+KPX Abreve Q -30
+KPX Abreve T -120
+KPX Abreve Tcaron -120
+KPX Abreve Tcommaaccent -120
+KPX Abreve U -50
+KPX Abreve Uacute -50
+KPX Abreve Ucircumflex -50
+KPX Abreve Udieresis -50
+KPX Abreve Ugrave -50
+KPX Abreve Uhungarumlaut -50
+KPX Abreve Umacron -50
+KPX Abreve Uogonek -50
+KPX Abreve Uring -50
+KPX Abreve V -70
+KPX Abreve W -50
+KPX Abreve Y -100
+KPX Abreve Yacute -100
+KPX Abreve Ydieresis -100
+KPX Abreve u -30
+KPX Abreve uacute -30
+KPX Abreve ucircumflex -30
+KPX Abreve udieresis -30
+KPX Abreve ugrave -30
+KPX Abreve uhungarumlaut -30
+KPX Abreve umacron -30
+KPX Abreve uogonek -30
+KPX Abreve uring -30
+KPX Abreve v -40
+KPX Abreve w -40
+KPX Abreve y -40
+KPX Abreve yacute -40
+KPX Abreve ydieresis -40
+KPX Acircumflex C -30
+KPX Acircumflex Cacute -30
+KPX Acircumflex Ccaron -30
+KPX Acircumflex Ccedilla -30
+KPX Acircumflex G -30
+KPX Acircumflex Gbreve -30
+KPX Acircumflex Gcommaaccent -30
+KPX Acircumflex O -30
+KPX Acircumflex Oacute -30
+KPX Acircumflex Ocircumflex -30
+KPX Acircumflex Odieresis -30
+KPX Acircumflex Ograve -30
+KPX Acircumflex Ohungarumlaut -30
+KPX Acircumflex Omacron -30
+KPX Acircumflex Oslash -30
+KPX Acircumflex Otilde -30
+KPX Acircumflex Q -30
+KPX Acircumflex T -120
+KPX Acircumflex Tcaron -120
+KPX Acircumflex Tcommaaccent -120
+KPX Acircumflex U -50
+KPX Acircumflex Uacute -50
+KPX Acircumflex Ucircumflex -50
+KPX Acircumflex Udieresis -50
+KPX Acircumflex Ugrave -50
+KPX Acircumflex Uhungarumlaut -50
+KPX Acircumflex Umacron -50
+KPX Acircumflex Uogonek -50
+KPX Acircumflex Uring -50
+KPX Acircumflex V -70
+KPX Acircumflex W -50
+KPX Acircumflex Y -100
+KPX Acircumflex Yacute -100
+KPX Acircumflex Ydieresis -100
+KPX Acircumflex u -30
+KPX Acircumflex uacute -30
+KPX Acircumflex ucircumflex -30
+KPX Acircumflex udieresis -30
+KPX Acircumflex ugrave -30
+KPX Acircumflex uhungarumlaut -30
+KPX Acircumflex umacron -30
+KPX Acircumflex uogonek -30
+KPX Acircumflex uring -30
+KPX Acircumflex v -40
+KPX Acircumflex w -40
+KPX Acircumflex y -40
+KPX Acircumflex yacute -40
+KPX Acircumflex ydieresis -40
+KPX Adieresis C -30
+KPX Adieresis Cacute -30
+KPX Adieresis Ccaron -30
+KPX Adieresis Ccedilla -30
+KPX Adieresis G -30
+KPX Adieresis Gbreve -30
+KPX Adieresis Gcommaaccent -30
+KPX Adieresis O -30
+KPX Adieresis Oacute -30
+KPX Adieresis Ocircumflex -30
+KPX Adieresis Odieresis -30
+KPX Adieresis Ograve -30
+KPX Adieresis Ohungarumlaut -30
+KPX Adieresis Omacron -30
+KPX Adieresis Oslash -30
+KPX Adieresis Otilde -30
+KPX Adieresis Q -30
+KPX Adieresis T -120
+KPX Adieresis Tcaron -120
+KPX Adieresis Tcommaaccent -120
+KPX Adieresis U -50
+KPX Adieresis Uacute -50
+KPX Adieresis Ucircumflex -50
+KPX Adieresis Udieresis -50
+KPX Adieresis Ugrave -50
+KPX Adieresis Uhungarumlaut -50
+KPX Adieresis Umacron -50
+KPX Adieresis Uogonek -50
+KPX Adieresis Uring -50
+KPX Adieresis V -70
+KPX Adieresis W -50
+KPX Adieresis Y -100
+KPX Adieresis Yacute -100
+KPX Adieresis Ydieresis -100
+KPX Adieresis u -30
+KPX Adieresis uacute -30
+KPX Adieresis ucircumflex -30
+KPX Adieresis udieresis -30
+KPX Adieresis ugrave -30
+KPX Adieresis uhungarumlaut -30
+KPX Adieresis umacron -30
+KPX Adieresis uogonek -30
+KPX Adieresis uring -30
+KPX Adieresis v -40
+KPX Adieresis w -40
+KPX Adieresis y -40
+KPX Adieresis yacute -40
+KPX Adieresis ydieresis -40
+KPX Agrave C -30
+KPX Agrave Cacute -30
+KPX Agrave Ccaron -30
+KPX Agrave Ccedilla -30
+KPX Agrave G -30
+KPX Agrave Gbreve -30
+KPX Agrave Gcommaaccent -30
+KPX Agrave O -30
+KPX Agrave Oacute -30
+KPX Agrave Ocircumflex -30
+KPX Agrave Odieresis -30
+KPX Agrave Ograve -30
+KPX Agrave Ohungarumlaut -30
+KPX Agrave Omacron -30
+KPX Agrave Oslash -30
+KPX Agrave Otilde -30
+KPX Agrave Q -30
+KPX Agrave T -120
+KPX Agrave Tcaron -120
+KPX Agrave Tcommaaccent -120
+KPX Agrave U -50
+KPX Agrave Uacute -50
+KPX Agrave Ucircumflex -50
+KPX Agrave Udieresis -50
+KPX Agrave Ugrave -50
+KPX Agrave Uhungarumlaut -50
+KPX Agrave Umacron -50
+KPX Agrave Uogonek -50
+KPX Agrave Uring -50
+KPX Agrave V -70
+KPX Agrave W -50
+KPX Agrave Y -100
+KPX Agrave Yacute -100
+KPX Agrave Ydieresis -100
+KPX Agrave u -30
+KPX Agrave uacute -30
+KPX Agrave ucircumflex -30
+KPX Agrave udieresis -30
+KPX Agrave ugrave -30
+KPX Agrave uhungarumlaut -30
+KPX Agrave umacron -30
+KPX Agrave uogonek -30
+KPX Agrave uring -30
+KPX Agrave v -40
+KPX Agrave w -40
+KPX Agrave y -40
+KPX Agrave yacute -40
+KPX Agrave ydieresis -40
+KPX Amacron C -30
+KPX Amacron Cacute -30
+KPX Amacron Ccaron -30
+KPX Amacron Ccedilla -30
+KPX Amacron G -30
+KPX Amacron Gbreve -30
+KPX Amacron Gcommaaccent -30
+KPX Amacron O -30
+KPX Amacron Oacute -30
+KPX Amacron Ocircumflex -30
+KPX Amacron Odieresis -30
+KPX Amacron Ograve -30
+KPX Amacron Ohungarumlaut -30
+KPX Amacron Omacron -30
+KPX Amacron Oslash -30
+KPX Amacron Otilde -30
+KPX Amacron Q -30
+KPX Amacron T -120
+KPX Amacron Tcaron -120
+KPX Amacron Tcommaaccent -120
+KPX Amacron U -50
+KPX Amacron Uacute -50
+KPX Amacron Ucircumflex -50
+KPX Amacron Udieresis -50
+KPX Amacron Ugrave -50
+KPX Amacron Uhungarumlaut -50
+KPX Amacron Umacron -50
+KPX Amacron Uogonek -50
+KPX Amacron Uring -50
+KPX Amacron V -70
+KPX Amacron W -50
+KPX Amacron Y -100
+KPX Amacron Yacute -100
+KPX Amacron Ydieresis -100
+KPX Amacron u -30
+KPX Amacron uacute -30
+KPX Amacron ucircumflex -30
+KPX Amacron udieresis -30
+KPX Amacron ugrave -30
+KPX Amacron uhungarumlaut -30
+KPX Amacron umacron -30
+KPX Amacron uogonek -30
+KPX Amacron uring -30
+KPX Amacron v -40
+KPX Amacron w -40
+KPX Amacron y -40
+KPX Amacron yacute -40
+KPX Amacron ydieresis -40
+KPX Aogonek C -30
+KPX Aogonek Cacute -30
+KPX Aogonek Ccaron -30
+KPX Aogonek Ccedilla -30
+KPX Aogonek G -30
+KPX Aogonek Gbreve -30
+KPX Aogonek Gcommaaccent -30
+KPX Aogonek O -30
+KPX Aogonek Oacute -30
+KPX Aogonek Ocircumflex -30
+KPX Aogonek Odieresis -30
+KPX Aogonek Ograve -30
+KPX Aogonek Ohungarumlaut -30
+KPX Aogonek Omacron -30
+KPX Aogonek Oslash -30
+KPX Aogonek Otilde -30
+KPX Aogonek Q -30
+KPX Aogonek T -120
+KPX Aogonek Tcaron -120
+KPX Aogonek Tcommaaccent -120
+KPX Aogonek U -50
+KPX Aogonek Uacute -50
+KPX Aogonek Ucircumflex -50
+KPX Aogonek Udieresis -50
+KPX Aogonek Ugrave -50
+KPX Aogonek Uhungarumlaut -50
+KPX Aogonek Umacron -50
+KPX Aogonek Uogonek -50
+KPX Aogonek Uring -50
+KPX Aogonek V -70
+KPX Aogonek W -50
+KPX Aogonek Y -100
+KPX Aogonek Yacute -100
+KPX Aogonek Ydieresis -100
+KPX Aogonek u -30
+KPX Aogonek uacute -30
+KPX Aogonek ucircumflex -30
+KPX Aogonek udieresis -30
+KPX Aogonek ugrave -30
+KPX Aogonek uhungarumlaut -30
+KPX Aogonek umacron -30
+KPX Aogonek uogonek -30
+KPX Aogonek uring -30
+KPX Aogonek v -40
+KPX Aogonek w -40
+KPX Aogonek y -40
+KPX Aogonek yacute -40
+KPX Aogonek ydieresis -40
+KPX Aring C -30
+KPX Aring Cacute -30
+KPX Aring Ccaron -30
+KPX Aring Ccedilla -30
+KPX Aring G -30
+KPX Aring Gbreve -30
+KPX Aring Gcommaaccent -30
+KPX Aring O -30
+KPX Aring Oacute -30
+KPX Aring Ocircumflex -30
+KPX Aring Odieresis -30
+KPX Aring Ograve -30
+KPX Aring Ohungarumlaut -30
+KPX Aring Omacron -30
+KPX Aring Oslash -30
+KPX Aring Otilde -30
+KPX Aring Q -30
+KPX Aring T -120
+KPX Aring Tcaron -120
+KPX Aring Tcommaaccent -120
+KPX Aring U -50
+KPX Aring Uacute -50
+KPX Aring Ucircumflex -50
+KPX Aring Udieresis -50
+KPX Aring Ugrave -50
+KPX Aring Uhungarumlaut -50
+KPX Aring Umacron -50
+KPX Aring Uogonek -50
+KPX Aring Uring -50
+KPX Aring V -70
+KPX Aring W -50
+KPX Aring Y -100
+KPX Aring Yacute -100
+KPX Aring Ydieresis -100
+KPX Aring u -30
+KPX Aring uacute -30
+KPX Aring ucircumflex -30
+KPX Aring udieresis -30
+KPX Aring ugrave -30
+KPX Aring uhungarumlaut -30
+KPX Aring umacron -30
+KPX Aring uogonek -30
+KPX Aring uring -30
+KPX Aring v -40
+KPX Aring w -40
+KPX Aring y -40
+KPX Aring yacute -40
+KPX Aring ydieresis -40
+KPX Atilde C -30
+KPX Atilde Cacute -30
+KPX Atilde Ccaron -30
+KPX Atilde Ccedilla -30
+KPX Atilde G -30
+KPX Atilde Gbreve -30
+KPX Atilde Gcommaaccent -30
+KPX Atilde O -30
+KPX Atilde Oacute -30
+KPX Atilde Ocircumflex -30
+KPX Atilde Odieresis -30
+KPX Atilde Ograve -30
+KPX Atilde Ohungarumlaut -30
+KPX Atilde Omacron -30
+KPX Atilde Oslash -30
+KPX Atilde Otilde -30
+KPX Atilde Q -30
+KPX Atilde T -120
+KPX Atilde Tcaron -120
+KPX Atilde Tcommaaccent -120
+KPX Atilde U -50
+KPX Atilde Uacute -50
+KPX Atilde Ucircumflex -50
+KPX Atilde Udieresis -50
+KPX Atilde Ugrave -50
+KPX Atilde Uhungarumlaut -50
+KPX Atilde Umacron -50
+KPX Atilde Uogonek -50
+KPX Atilde Uring -50
+KPX Atilde V -70
+KPX Atilde W -50
+KPX Atilde Y -100
+KPX Atilde Yacute -100
+KPX Atilde Ydieresis -100
+KPX Atilde u -30
+KPX Atilde uacute -30
+KPX Atilde ucircumflex -30
+KPX Atilde udieresis -30
+KPX Atilde ugrave -30
+KPX Atilde uhungarumlaut -30
+KPX Atilde umacron -30
+KPX Atilde uogonek -30
+KPX Atilde uring -30
+KPX Atilde v -40
+KPX Atilde w -40
+KPX Atilde y -40
+KPX Atilde yacute -40
+KPX Atilde ydieresis -40
+KPX B U -10
+KPX B Uacute -10
+KPX B Ucircumflex -10
+KPX B Udieresis -10
+KPX B Ugrave -10
+KPX B Uhungarumlaut -10
+KPX B Umacron -10
+KPX B Uogonek -10
+KPX B Uring -10
+KPX B comma -20
+KPX B period -20
+KPX C comma -30
+KPX C period -30
+KPX Cacute comma -30
+KPX Cacute period -30
+KPX Ccaron comma -30
+KPX Ccaron period -30
+KPX Ccedilla comma -30
+KPX Ccedilla period -30
+KPX D A -40
+KPX D Aacute -40
+KPX D Abreve -40
+KPX D Acircumflex -40
+KPX D Adieresis -40
+KPX D Agrave -40
+KPX D Amacron -40
+KPX D Aogonek -40
+KPX D Aring -40
+KPX D Atilde -40
+KPX D V -70
+KPX D W -40
+KPX D Y -90
+KPX D Yacute -90
+KPX D Ydieresis -90
+KPX D comma -70
+KPX D period -70
+KPX Dcaron A -40
+KPX Dcaron Aacute -40
+KPX Dcaron Abreve -40
+KPX Dcaron Acircumflex -40
+KPX Dcaron Adieresis -40
+KPX Dcaron Agrave -40
+KPX Dcaron Amacron -40
+KPX Dcaron Aogonek -40
+KPX Dcaron Aring -40
+KPX Dcaron Atilde -40
+KPX Dcaron V -70
+KPX Dcaron W -40
+KPX Dcaron Y -90
+KPX Dcaron Yacute -90
+KPX Dcaron Ydieresis -90
+KPX Dcaron comma -70
+KPX Dcaron period -70
+KPX Dcroat A -40
+KPX Dcroat Aacute -40
+KPX Dcroat Abreve -40
+KPX Dcroat Acircumflex -40
+KPX Dcroat Adieresis -40
+KPX Dcroat Agrave -40
+KPX Dcroat Amacron -40
+KPX Dcroat Aogonek -40
+KPX Dcroat Aring -40
+KPX Dcroat Atilde -40
+KPX Dcroat V -70
+KPX Dcroat W -40
+KPX Dcroat Y -90
+KPX Dcroat Yacute -90
+KPX Dcroat Ydieresis -90
+KPX Dcroat comma -70
+KPX Dcroat period -70
+KPX F A -80
+KPX F Aacute -80
+KPX F Abreve -80
+KPX F Acircumflex -80
+KPX F Adieresis -80
+KPX F Agrave -80
+KPX F Amacron -80
+KPX F Aogonek -80
+KPX F Aring -80
+KPX F Atilde -80
+KPX F a -50
+KPX F aacute -50
+KPX F abreve -50
+KPX F acircumflex -50
+KPX F adieresis -50
+KPX F agrave -50
+KPX F amacron -50
+KPX F aogonek -50
+KPX F aring -50
+KPX F atilde -50
+KPX F comma -150
+KPX F e -30
+KPX F eacute -30
+KPX F ecaron -30
+KPX F ecircumflex -30
+KPX F edieresis -30
+KPX F edotaccent -30
+KPX F egrave -30
+KPX F emacron -30
+KPX F eogonek -30
+KPX F o -30
+KPX F oacute -30
+KPX F ocircumflex -30
+KPX F odieresis -30
+KPX F ograve -30
+KPX F ohungarumlaut -30
+KPX F omacron -30
+KPX F oslash -30
+KPX F otilde -30
+KPX F period -150
+KPX F r -45
+KPX F racute -45
+KPX F rcaron -45
+KPX F rcommaaccent -45
+KPX J A -20
+KPX J Aacute -20
+KPX J Abreve -20
+KPX J Acircumflex -20
+KPX J Adieresis -20
+KPX J Agrave -20
+KPX J Amacron -20
+KPX J Aogonek -20
+KPX J Aring -20
+KPX J Atilde -20
+KPX J a -20
+KPX J aacute -20
+KPX J abreve -20
+KPX J acircumflex -20
+KPX J adieresis -20
+KPX J agrave -20
+KPX J amacron -20
+KPX J aogonek -20
+KPX J aring -20
+KPX J atilde -20
+KPX J comma -30
+KPX J period -30
+KPX J u -20
+KPX J uacute -20
+KPX J ucircumflex -20
+KPX J udieresis -20
+KPX J ugrave -20
+KPX J uhungarumlaut -20
+KPX J umacron -20
+KPX J uogonek -20
+KPX J uring -20
+KPX K O -50
+KPX K Oacute -50
+KPX K Ocircumflex -50
+KPX K Odieresis -50
+KPX K Ograve -50
+KPX K Ohungarumlaut -50
+KPX K Omacron -50
+KPX K Oslash -50
+KPX K Otilde -50
+KPX K e -40
+KPX K eacute -40
+KPX K ecaron -40
+KPX K ecircumflex -40
+KPX K edieresis -40
+KPX K edotaccent -40
+KPX K egrave -40
+KPX K emacron -40
+KPX K eogonek -40
+KPX K o -40
+KPX K oacute -40
+KPX K ocircumflex -40
+KPX K odieresis -40
+KPX K ograve -40
+KPX K ohungarumlaut -40
+KPX K omacron -40
+KPX K oslash -40
+KPX K otilde -40
+KPX K u -30
+KPX K uacute -30
+KPX K ucircumflex -30
+KPX K udieresis -30
+KPX K ugrave -30
+KPX K uhungarumlaut -30
+KPX K umacron -30
+KPX K uogonek -30
+KPX K uring -30
+KPX K y -50
+KPX K yacute -50
+KPX K ydieresis -50
+KPX Kcommaaccent O -50
+KPX Kcommaaccent Oacute -50
+KPX Kcommaaccent Ocircumflex -50
+KPX Kcommaaccent Odieresis -50
+KPX Kcommaaccent Ograve -50
+KPX Kcommaaccent Ohungarumlaut -50
+KPX Kcommaaccent Omacron -50
+KPX Kcommaaccent Oslash -50
+KPX Kcommaaccent Otilde -50
+KPX Kcommaaccent e -40
+KPX Kcommaaccent eacute -40
+KPX Kcommaaccent ecaron -40
+KPX Kcommaaccent ecircumflex -40
+KPX Kcommaaccent edieresis -40
+KPX Kcommaaccent edotaccent -40
+KPX Kcommaaccent egrave -40
+KPX Kcommaaccent emacron -40
+KPX Kcommaaccent eogonek -40
+KPX Kcommaaccent o -40
+KPX Kcommaaccent oacute -40
+KPX Kcommaaccent ocircumflex -40
+KPX Kcommaaccent odieresis -40
+KPX Kcommaaccent ograve -40
+KPX Kcommaaccent ohungarumlaut -40
+KPX Kcommaaccent omacron -40
+KPX Kcommaaccent oslash -40
+KPX Kcommaaccent otilde -40
+KPX Kcommaaccent u -30
+KPX Kcommaaccent uacute -30
+KPX Kcommaaccent ucircumflex -30
+KPX Kcommaaccent udieresis -30
+KPX Kcommaaccent ugrave -30
+KPX Kcommaaccent uhungarumlaut -30
+KPX Kcommaaccent umacron -30
+KPX Kcommaaccent uogonek -30
+KPX Kcommaaccent uring -30
+KPX Kcommaaccent y -50
+KPX Kcommaaccent yacute -50
+KPX Kcommaaccent ydieresis -50
+KPX L T -110
+KPX L Tcaron -110
+KPX L Tcommaaccent -110
+KPX L V -110
+KPX L W -70
+KPX L Y -140
+KPX L Yacute -140
+KPX L Ydieresis -140
+KPX L quotedblright -140
+KPX L quoteright -160
+KPX L y -30
+KPX L yacute -30
+KPX L ydieresis -30
+KPX Lacute T -110
+KPX Lacute Tcaron -110
+KPX Lacute Tcommaaccent -110
+KPX Lacute V -110
+KPX Lacute W -70
+KPX Lacute Y -140
+KPX Lacute Yacute -140
+KPX Lacute Ydieresis -140
+KPX Lacute quotedblright -140
+KPX Lacute quoteright -160
+KPX Lacute y -30
+KPX Lacute yacute -30
+KPX Lacute ydieresis -30
+KPX Lcaron T -110
+KPX Lcaron Tcaron -110
+KPX Lcaron Tcommaaccent -110
+KPX Lcaron V -110
+KPX Lcaron W -70
+KPX Lcaron Y -140
+KPX Lcaron Yacute -140
+KPX Lcaron Ydieresis -140
+KPX Lcaron quotedblright -140
+KPX Lcaron quoteright -160
+KPX Lcaron y -30
+KPX Lcaron yacute -30
+KPX Lcaron ydieresis -30
+KPX Lcommaaccent T -110
+KPX Lcommaaccent Tcaron -110
+KPX Lcommaaccent Tcommaaccent -110
+KPX Lcommaaccent V -110
+KPX Lcommaaccent W -70
+KPX Lcommaaccent Y -140
+KPX Lcommaaccent Yacute -140
+KPX Lcommaaccent Ydieresis -140
+KPX Lcommaaccent quotedblright -140
+KPX Lcommaaccent quoteright -160
+KPX Lcommaaccent y -30
+KPX Lcommaaccent yacute -30
+KPX Lcommaaccent ydieresis -30
+KPX Lslash T -110
+KPX Lslash Tcaron -110
+KPX Lslash Tcommaaccent -110
+KPX Lslash V -110
+KPX Lslash W -70
+KPX Lslash Y -140
+KPX Lslash Yacute -140
+KPX Lslash Ydieresis -140
+KPX Lslash quotedblright -140
+KPX Lslash quoteright -160
+KPX Lslash y -30
+KPX Lslash yacute -30
+KPX Lslash ydieresis -30
+KPX O A -20
+KPX O Aacute -20
+KPX O Abreve -20
+KPX O Acircumflex -20
+KPX O Adieresis -20
+KPX O Agrave -20
+KPX O Amacron -20
+KPX O Aogonek -20
+KPX O Aring -20
+KPX O Atilde -20
+KPX O T -40
+KPX O Tcaron -40
+KPX O Tcommaaccent -40
+KPX O V -50
+KPX O W -30
+KPX O X -60
+KPX O Y -70
+KPX O Yacute -70
+KPX O Ydieresis -70
+KPX O comma -40
+KPX O period -40
+KPX Oacute A -20
+KPX Oacute Aacute -20
+KPX Oacute Abreve -20
+KPX Oacute Acircumflex -20
+KPX Oacute Adieresis -20
+KPX Oacute Agrave -20
+KPX Oacute Amacron -20
+KPX Oacute Aogonek -20
+KPX Oacute Aring -20
+KPX Oacute Atilde -20
+KPX Oacute T -40
+KPX Oacute Tcaron -40
+KPX Oacute Tcommaaccent -40
+KPX Oacute V -50
+KPX Oacute W -30
+KPX Oacute X -60
+KPX Oacute Y -70
+KPX Oacute Yacute -70
+KPX Oacute Ydieresis -70
+KPX Oacute comma -40
+KPX Oacute period -40
+KPX Ocircumflex A -20
+KPX Ocircumflex Aacute -20
+KPX Ocircumflex Abreve -20
+KPX Ocircumflex Acircumflex -20
+KPX Ocircumflex Adieresis -20
+KPX Ocircumflex Agrave -20
+KPX Ocircumflex Amacron -20
+KPX Ocircumflex Aogonek -20
+KPX Ocircumflex Aring -20
+KPX Ocircumflex Atilde -20
+KPX Ocircumflex T -40
+KPX Ocircumflex Tcaron -40
+KPX Ocircumflex Tcommaaccent -40
+KPX Ocircumflex V -50
+KPX Ocircumflex W -30
+KPX Ocircumflex X -60
+KPX Ocircumflex Y -70
+KPX Ocircumflex Yacute -70
+KPX Ocircumflex Ydieresis -70
+KPX Ocircumflex comma -40
+KPX Ocircumflex period -40
+KPX Odieresis A -20
+KPX Odieresis Aacute -20
+KPX Odieresis Abreve -20
+KPX Odieresis Acircumflex -20
+KPX Odieresis Adieresis -20
+KPX Odieresis Agrave -20
+KPX Odieresis Amacron -20
+KPX Odieresis Aogonek -20
+KPX Odieresis Aring -20
+KPX Odieresis Atilde -20
+KPX Odieresis T -40
+KPX Odieresis Tcaron -40
+KPX Odieresis Tcommaaccent -40
+KPX Odieresis V -50
+KPX Odieresis W -30
+KPX Odieresis X -60
+KPX Odieresis Y -70
+KPX Odieresis Yacute -70
+KPX Odieresis Ydieresis -70
+KPX Odieresis comma -40
+KPX Odieresis period -40
+KPX Ograve A -20
+KPX Ograve Aacute -20
+KPX Ograve Abreve -20
+KPX Ograve Acircumflex -20
+KPX Ograve Adieresis -20
+KPX Ograve Agrave -20
+KPX Ograve Amacron -20
+KPX Ograve Aogonek -20
+KPX Ograve Aring -20
+KPX Ograve Atilde -20
+KPX Ograve T -40
+KPX Ograve Tcaron -40
+KPX Ograve Tcommaaccent -40
+KPX Ograve V -50
+KPX Ograve W -30
+KPX Ograve X -60
+KPX Ograve Y -70
+KPX Ograve Yacute -70
+KPX Ograve Ydieresis -70
+KPX Ograve comma -40
+KPX Ograve period -40
+KPX Ohungarumlaut A -20
+KPX Ohungarumlaut Aacute -20
+KPX Ohungarumlaut Abreve -20
+KPX Ohungarumlaut Acircumflex -20
+KPX Ohungarumlaut Adieresis -20
+KPX Ohungarumlaut Agrave -20
+KPX Ohungarumlaut Amacron -20
+KPX Ohungarumlaut Aogonek -20
+KPX Ohungarumlaut Aring -20
+KPX Ohungarumlaut Atilde -20
+KPX Ohungarumlaut T -40
+KPX Ohungarumlaut Tcaron -40
+KPX Ohungarumlaut Tcommaaccent -40
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut W -30
+KPX Ohungarumlaut X -60
+KPX Ohungarumlaut Y -70
+KPX Ohungarumlaut Yacute -70
+KPX Ohungarumlaut Ydieresis -70
+KPX Ohungarumlaut comma -40
+KPX Ohungarumlaut period -40
+KPX Omacron A -20
+KPX Omacron Aacute -20
+KPX Omacron Abreve -20
+KPX Omacron Acircumflex -20
+KPX Omacron Adieresis -20
+KPX Omacron Agrave -20
+KPX Omacron Amacron -20
+KPX Omacron Aogonek -20
+KPX Omacron Aring -20
+KPX Omacron Atilde -20
+KPX Omacron T -40
+KPX Omacron Tcaron -40
+KPX Omacron Tcommaaccent -40
+KPX Omacron V -50
+KPX Omacron W -30
+KPX Omacron X -60
+KPX Omacron Y -70
+KPX Omacron Yacute -70
+KPX Omacron Ydieresis -70
+KPX Omacron comma -40
+KPX Omacron period -40
+KPX Oslash A -20
+KPX Oslash Aacute -20
+KPX Oslash Abreve -20
+KPX Oslash Acircumflex -20
+KPX Oslash Adieresis -20
+KPX Oslash Agrave -20
+KPX Oslash Amacron -20
+KPX Oslash Aogonek -20
+KPX Oslash Aring -20
+KPX Oslash Atilde -20
+KPX Oslash T -40
+KPX Oslash Tcaron -40
+KPX Oslash Tcommaaccent -40
+KPX Oslash V -50
+KPX Oslash W -30
+KPX Oslash X -60
+KPX Oslash Y -70
+KPX Oslash Yacute -70
+KPX Oslash Ydieresis -70
+KPX Oslash comma -40
+KPX Oslash period -40
+KPX Otilde A -20
+KPX Otilde Aacute -20
+KPX Otilde Abreve -20
+KPX Otilde Acircumflex -20
+KPX Otilde Adieresis -20
+KPX Otilde Agrave -20
+KPX Otilde Amacron -20
+KPX Otilde Aogonek -20
+KPX Otilde Aring -20
+KPX Otilde Atilde -20
+KPX Otilde T -40
+KPX Otilde Tcaron -40
+KPX Otilde Tcommaaccent -40
+KPX Otilde V -50
+KPX Otilde W -30
+KPX Otilde X -60
+KPX Otilde Y -70
+KPX Otilde Yacute -70
+KPX Otilde Ydieresis -70
+KPX Otilde comma -40
+KPX Otilde period -40
+KPX P A -120
+KPX P Aacute -120
+KPX P Abreve -120
+KPX P Acircumflex -120
+KPX P Adieresis -120
+KPX P Agrave -120
+KPX P Amacron -120
+KPX P Aogonek -120
+KPX P Aring -120
+KPX P Atilde -120
+KPX P a -40
+KPX P aacute -40
+KPX P abreve -40
+KPX P acircumflex -40
+KPX P adieresis -40
+KPX P agrave -40
+KPX P amacron -40
+KPX P aogonek -40
+KPX P aring -40
+KPX P atilde -40
+KPX P comma -180
+KPX P e -50
+KPX P eacute -50
+KPX P ecaron -50
+KPX P ecircumflex -50
+KPX P edieresis -50
+KPX P edotaccent -50
+KPX P egrave -50
+KPX P emacron -50
+KPX P eogonek -50
+KPX P o -50
+KPX P oacute -50
+KPX P ocircumflex -50
+KPX P odieresis -50
+KPX P ograve -50
+KPX P ohungarumlaut -50
+KPX P omacron -50
+KPX P oslash -50
+KPX P otilde -50
+KPX P period -180
+KPX Q U -10
+KPX Q Uacute -10
+KPX Q Ucircumflex -10
+KPX Q Udieresis -10
+KPX Q Ugrave -10
+KPX Q Uhungarumlaut -10
+KPX Q Umacron -10
+KPX Q Uogonek -10
+KPX Q Uring -10
+KPX R O -20
+KPX R Oacute -20
+KPX R Ocircumflex -20
+KPX R Odieresis -20
+KPX R Ograve -20
+KPX R Ohungarumlaut -20
+KPX R Omacron -20
+KPX R Oslash -20
+KPX R Otilde -20
+KPX R T -30
+KPX R Tcaron -30
+KPX R Tcommaaccent -30
+KPX R U -40
+KPX R Uacute -40
+KPX R Ucircumflex -40
+KPX R Udieresis -40
+KPX R Ugrave -40
+KPX R Uhungarumlaut -40
+KPX R Umacron -40
+KPX R Uogonek -40
+KPX R Uring -40
+KPX R V -50
+KPX R W -30
+KPX R Y -50
+KPX R Yacute -50
+KPX R Ydieresis -50
+KPX Racute O -20
+KPX Racute Oacute -20
+KPX Racute Ocircumflex -20
+KPX Racute Odieresis -20
+KPX Racute Ograve -20
+KPX Racute Ohungarumlaut -20
+KPX Racute Omacron -20
+KPX Racute Oslash -20
+KPX Racute Otilde -20
+KPX Racute T -30
+KPX Racute Tcaron -30
+KPX Racute Tcommaaccent -30
+KPX Racute U -40
+KPX Racute Uacute -40
+KPX Racute Ucircumflex -40
+KPX Racute Udieresis -40
+KPX Racute Ugrave -40
+KPX Racute Uhungarumlaut -40
+KPX Racute Umacron -40
+KPX Racute Uogonek -40
+KPX Racute Uring -40
+KPX Racute V -50
+KPX Racute W -30
+KPX Racute Y -50
+KPX Racute Yacute -50
+KPX Racute Ydieresis -50
+KPX Rcaron O -20
+KPX Rcaron Oacute -20
+KPX Rcaron Ocircumflex -20
+KPX Rcaron Odieresis -20
+KPX Rcaron Ograve -20
+KPX Rcaron Ohungarumlaut -20
+KPX Rcaron Omacron -20
+KPX Rcaron Oslash -20
+KPX Rcaron Otilde -20
+KPX Rcaron T -30
+KPX Rcaron Tcaron -30
+KPX Rcaron Tcommaaccent -30
+KPX Rcaron U -40
+KPX Rcaron Uacute -40
+KPX Rcaron Ucircumflex -40
+KPX Rcaron Udieresis -40
+KPX Rcaron Ugrave -40
+KPX Rcaron Uhungarumlaut -40
+KPX Rcaron Umacron -40
+KPX Rcaron Uogonek -40
+KPX Rcaron Uring -40
+KPX Rcaron V -50
+KPX Rcaron W -30
+KPX Rcaron Y -50
+KPX Rcaron Yacute -50
+KPX Rcaron Ydieresis -50
+KPX Rcommaaccent O -20
+KPX Rcommaaccent Oacute -20
+KPX Rcommaaccent Ocircumflex -20
+KPX Rcommaaccent Odieresis -20
+KPX Rcommaaccent Ograve -20
+KPX Rcommaaccent Ohungarumlaut -20
+KPX Rcommaaccent Omacron -20
+KPX Rcommaaccent Oslash -20
+KPX Rcommaaccent Otilde -20
+KPX Rcommaaccent T -30
+KPX Rcommaaccent Tcaron -30
+KPX Rcommaaccent Tcommaaccent -30
+KPX Rcommaaccent U -40
+KPX Rcommaaccent Uacute -40
+KPX Rcommaaccent Ucircumflex -40
+KPX Rcommaaccent Udieresis -40
+KPX Rcommaaccent Ugrave -40
+KPX Rcommaaccent Uhungarumlaut -40
+KPX Rcommaaccent Umacron -40
+KPX Rcommaaccent Uogonek -40
+KPX Rcommaaccent Uring -40
+KPX Rcommaaccent V -50
+KPX Rcommaaccent W -30
+KPX Rcommaaccent Y -50
+KPX Rcommaaccent Yacute -50
+KPX Rcommaaccent Ydieresis -50
+KPX S comma -20
+KPX S period -20
+KPX Sacute comma -20
+KPX Sacute period -20
+KPX Scaron comma -20
+KPX Scaron period -20
+KPX Scedilla comma -20
+KPX Scedilla period -20
+KPX Scommaaccent comma -20
+KPX Scommaaccent period -20
+KPX T A -120
+KPX T Aacute -120
+KPX T Abreve -120
+KPX T Acircumflex -120
+KPX T Adieresis -120
+KPX T Agrave -120
+KPX T Amacron -120
+KPX T Aogonek -120
+KPX T Aring -120
+KPX T Atilde -120
+KPX T O -40
+KPX T Oacute -40
+KPX T Ocircumflex -40
+KPX T Odieresis -40
+KPX T Ograve -40
+KPX T Ohungarumlaut -40
+KPX T Omacron -40
+KPX T Oslash -40
+KPX T Otilde -40
+KPX T a -120
+KPX T aacute -120
+KPX T abreve -60
+KPX T acircumflex -120
+KPX T adieresis -120
+KPX T agrave -120
+KPX T amacron -60
+KPX T aogonek -120
+KPX T aring -120
+KPX T atilde -60
+KPX T colon -20
+KPX T comma -120
+KPX T e -120
+KPX T eacute -120
+KPX T ecaron -120
+KPX T ecircumflex -120
+KPX T edieresis -120
+KPX T edotaccent -120
+KPX T egrave -60
+KPX T emacron -60
+KPX T eogonek -120
+KPX T hyphen -140
+KPX T o -120
+KPX T oacute -120
+KPX T ocircumflex -120
+KPX T odieresis -120
+KPX T ograve -120
+KPX T ohungarumlaut -120
+KPX T omacron -60
+KPX T oslash -120
+KPX T otilde -60
+KPX T period -120
+KPX T r -120
+KPX T racute -120
+KPX T rcaron -120
+KPX T rcommaaccent -120
+KPX T semicolon -20
+KPX T u -120
+KPX T uacute -120
+KPX T ucircumflex -120
+KPX T udieresis -120
+KPX T ugrave -120
+KPX T uhungarumlaut -120
+KPX T umacron -60
+KPX T uogonek -120
+KPX T uring -120
+KPX T w -120
+KPX T y -120
+KPX T yacute -120
+KPX T ydieresis -60
+KPX Tcaron A -120
+KPX Tcaron Aacute -120
+KPX Tcaron Abreve -120
+KPX Tcaron Acircumflex -120
+KPX Tcaron Adieresis -120
+KPX Tcaron Agrave -120
+KPX Tcaron Amacron -120
+KPX Tcaron Aogonek -120
+KPX Tcaron Aring -120
+KPX Tcaron Atilde -120
+KPX Tcaron O -40
+KPX Tcaron Oacute -40
+KPX Tcaron Ocircumflex -40
+KPX Tcaron Odieresis -40
+KPX Tcaron Ograve -40
+KPX Tcaron Ohungarumlaut -40
+KPX Tcaron Omacron -40
+KPX Tcaron Oslash -40
+KPX Tcaron Otilde -40
+KPX Tcaron a -120
+KPX Tcaron aacute -120
+KPX Tcaron abreve -60
+KPX Tcaron acircumflex -120
+KPX Tcaron adieresis -120
+KPX Tcaron agrave -120
+KPX Tcaron amacron -60
+KPX Tcaron aogonek -120
+KPX Tcaron aring -120
+KPX Tcaron atilde -60
+KPX Tcaron colon -20
+KPX Tcaron comma -120
+KPX Tcaron e -120
+KPX Tcaron eacute -120
+KPX Tcaron ecaron -120
+KPX Tcaron ecircumflex -120
+KPX Tcaron edieresis -120
+KPX Tcaron edotaccent -120
+KPX Tcaron egrave -60
+KPX Tcaron emacron -60
+KPX Tcaron eogonek -120
+KPX Tcaron hyphen -140
+KPX Tcaron o -120
+KPX Tcaron oacute -120
+KPX Tcaron ocircumflex -120
+KPX Tcaron odieresis -120
+KPX Tcaron ograve -120
+KPX Tcaron ohungarumlaut -120
+KPX Tcaron omacron -60
+KPX Tcaron oslash -120
+KPX Tcaron otilde -60
+KPX Tcaron period -120
+KPX Tcaron r -120
+KPX Tcaron racute -120
+KPX Tcaron rcaron -120
+KPX Tcaron rcommaaccent -120
+KPX Tcaron semicolon -20
+KPX Tcaron u -120
+KPX Tcaron uacute -120
+KPX Tcaron ucircumflex -120
+KPX Tcaron udieresis -120
+KPX Tcaron ugrave -120
+KPX Tcaron uhungarumlaut -120
+KPX Tcaron umacron -60
+KPX Tcaron uogonek -120
+KPX Tcaron uring -120
+KPX Tcaron w -120
+KPX Tcaron y -120
+KPX Tcaron yacute -120
+KPX Tcaron ydieresis -60
+KPX Tcommaaccent A -120
+KPX Tcommaaccent Aacute -120
+KPX Tcommaaccent Abreve -120
+KPX Tcommaaccent Acircumflex -120
+KPX Tcommaaccent Adieresis -120
+KPX Tcommaaccent Agrave -120
+KPX Tcommaaccent Amacron -120
+KPX Tcommaaccent Aogonek -120
+KPX Tcommaaccent Aring -120
+KPX Tcommaaccent Atilde -120
+KPX Tcommaaccent O -40
+KPX Tcommaaccent Oacute -40
+KPX Tcommaaccent Ocircumflex -40
+KPX Tcommaaccent Odieresis -40
+KPX Tcommaaccent Ograve -40
+KPX Tcommaaccent Ohungarumlaut -40
+KPX Tcommaaccent Omacron -40
+KPX Tcommaaccent Oslash -40
+KPX Tcommaaccent Otilde -40
+KPX Tcommaaccent a -120
+KPX Tcommaaccent aacute -120
+KPX Tcommaaccent abreve -60
+KPX Tcommaaccent acircumflex -120
+KPX Tcommaaccent adieresis -120
+KPX Tcommaaccent agrave -120
+KPX Tcommaaccent amacron -60
+KPX Tcommaaccent aogonek -120
+KPX Tcommaaccent aring -120
+KPX Tcommaaccent atilde -60
+KPX Tcommaaccent colon -20
+KPX Tcommaaccent comma -120
+KPX Tcommaaccent e -120
+KPX Tcommaaccent eacute -120
+KPX Tcommaaccent ecaron -120
+KPX Tcommaaccent ecircumflex -120
+KPX Tcommaaccent edieresis -120
+KPX Tcommaaccent edotaccent -120
+KPX Tcommaaccent egrave -60
+KPX Tcommaaccent emacron -60
+KPX Tcommaaccent eogonek -120
+KPX Tcommaaccent hyphen -140
+KPX Tcommaaccent o -120
+KPX Tcommaaccent oacute -120
+KPX Tcommaaccent ocircumflex -120
+KPX Tcommaaccent odieresis -120
+KPX Tcommaaccent ograve -120
+KPX Tcommaaccent ohungarumlaut -120
+KPX Tcommaaccent omacron -60
+KPX Tcommaaccent oslash -120
+KPX Tcommaaccent otilde -60
+KPX Tcommaaccent period -120
+KPX Tcommaaccent r -120
+KPX Tcommaaccent racute -120
+KPX Tcommaaccent rcaron -120
+KPX Tcommaaccent rcommaaccent -120
+KPX Tcommaaccent semicolon -20
+KPX Tcommaaccent u -120
+KPX Tcommaaccent uacute -120
+KPX Tcommaaccent ucircumflex -120
+KPX Tcommaaccent udieresis -120
+KPX Tcommaaccent ugrave -120
+KPX Tcommaaccent uhungarumlaut -120
+KPX Tcommaaccent umacron -60
+KPX Tcommaaccent uogonek -120
+KPX Tcommaaccent uring -120
+KPX Tcommaaccent w -120
+KPX Tcommaaccent y -120
+KPX Tcommaaccent yacute -120
+KPX Tcommaaccent ydieresis -60
+KPX U A -40
+KPX U Aacute -40
+KPX U Abreve -40
+KPX U Acircumflex -40
+KPX U Adieresis -40
+KPX U Agrave -40
+KPX U Amacron -40
+KPX U Aogonek -40
+KPX U Aring -40
+KPX U Atilde -40
+KPX U comma -40
+KPX U period -40
+KPX Uacute A -40
+KPX Uacute Aacute -40
+KPX Uacute Abreve -40
+KPX Uacute Acircumflex -40
+KPX Uacute Adieresis -40
+KPX Uacute Agrave -40
+KPX Uacute Amacron -40
+KPX Uacute Aogonek -40
+KPX Uacute Aring -40
+KPX Uacute Atilde -40
+KPX Uacute comma -40
+KPX Uacute period -40
+KPX Ucircumflex A -40
+KPX Ucircumflex Aacute -40
+KPX Ucircumflex Abreve -40
+KPX Ucircumflex Acircumflex -40
+KPX Ucircumflex Adieresis -40
+KPX Ucircumflex Agrave -40
+KPX Ucircumflex Amacron -40
+KPX Ucircumflex Aogonek -40
+KPX Ucircumflex Aring -40
+KPX Ucircumflex Atilde -40
+KPX Ucircumflex comma -40
+KPX Ucircumflex period -40
+KPX Udieresis A -40
+KPX Udieresis Aacute -40
+KPX Udieresis Abreve -40
+KPX Udieresis Acircumflex -40
+KPX Udieresis Adieresis -40
+KPX Udieresis Agrave -40
+KPX Udieresis Amacron -40
+KPX Udieresis Aogonek -40
+KPX Udieresis Aring -40
+KPX Udieresis Atilde -40
+KPX Udieresis comma -40
+KPX Udieresis period -40
+KPX Ugrave A -40
+KPX Ugrave Aacute -40
+KPX Ugrave Abreve -40
+KPX Ugrave Acircumflex -40
+KPX Ugrave Adieresis -40
+KPX Ugrave Agrave -40
+KPX Ugrave Amacron -40
+KPX Ugrave Aogonek -40
+KPX Ugrave Aring -40
+KPX Ugrave Atilde -40
+KPX Ugrave comma -40
+KPX Ugrave period -40
+KPX Uhungarumlaut A -40
+KPX Uhungarumlaut Aacute -40
+KPX Uhungarumlaut Abreve -40
+KPX Uhungarumlaut Acircumflex -40
+KPX Uhungarumlaut Adieresis -40
+KPX Uhungarumlaut Agrave -40
+KPX Uhungarumlaut Amacron -40
+KPX Uhungarumlaut Aogonek -40
+KPX Uhungarumlaut Aring -40
+KPX Uhungarumlaut Atilde -40
+KPX Uhungarumlaut comma -40
+KPX Uhungarumlaut period -40
+KPX Umacron A -40
+KPX Umacron Aacute -40
+KPX Umacron Abreve -40
+KPX Umacron Acircumflex -40
+KPX Umacron Adieresis -40
+KPX Umacron Agrave -40
+KPX Umacron Amacron -40
+KPX Umacron Aogonek -40
+KPX Umacron Aring -40
+KPX Umacron Atilde -40
+KPX Umacron comma -40
+KPX Umacron period -40
+KPX Uogonek A -40
+KPX Uogonek Aacute -40
+KPX Uogonek Abreve -40
+KPX Uogonek Acircumflex -40
+KPX Uogonek Adieresis -40
+KPX Uogonek Agrave -40
+KPX Uogonek Amacron -40
+KPX Uogonek Aogonek -40
+KPX Uogonek Aring -40
+KPX Uogonek Atilde -40
+KPX Uogonek comma -40
+KPX Uogonek period -40
+KPX Uring A -40
+KPX Uring Aacute -40
+KPX Uring Abreve -40
+KPX Uring Acircumflex -40
+KPX Uring Adieresis -40
+KPX Uring Agrave -40
+KPX Uring Amacron -40
+KPX Uring Aogonek -40
+KPX Uring Aring -40
+KPX Uring Atilde -40
+KPX Uring comma -40
+KPX Uring period -40
+KPX V A -80
+KPX V Aacute -80
+KPX V Abreve -80
+KPX V Acircumflex -80
+KPX V Adieresis -80
+KPX V Agrave -80
+KPX V Amacron -80
+KPX V Aogonek -80
+KPX V Aring -80
+KPX V Atilde -80
+KPX V G -40
+KPX V Gbreve -40
+KPX V Gcommaaccent -40
+KPX V O -40
+KPX V Oacute -40
+KPX V Ocircumflex -40
+KPX V Odieresis -40
+KPX V Ograve -40
+KPX V Ohungarumlaut -40
+KPX V Omacron -40
+KPX V Oslash -40
+KPX V Otilde -40
+KPX V a -70
+KPX V aacute -70
+KPX V abreve -70
+KPX V acircumflex -70
+KPX V adieresis -70
+KPX V agrave -70
+KPX V amacron -70
+KPX V aogonek -70
+KPX V aring -70
+KPX V atilde -70
+KPX V colon -40
+KPX V comma -125
+KPX V e -80
+KPX V eacute -80
+KPX V ecaron -80
+KPX V ecircumflex -80
+KPX V edieresis -80
+KPX V edotaccent -80
+KPX V egrave -80
+KPX V emacron -80
+KPX V eogonek -80
+KPX V hyphen -80
+KPX V o -80
+KPX V oacute -80
+KPX V ocircumflex -80
+KPX V odieresis -80
+KPX V ograve -80
+KPX V ohungarumlaut -80
+KPX V omacron -80
+KPX V oslash -80
+KPX V otilde -80
+KPX V period -125
+KPX V semicolon -40
+KPX V u -70
+KPX V uacute -70
+KPX V ucircumflex -70
+KPX V udieresis -70
+KPX V ugrave -70
+KPX V uhungarumlaut -70
+KPX V umacron -70
+KPX V uogonek -70
+KPX V uring -70
+KPX W A -50
+KPX W Aacute -50
+KPX W Abreve -50
+KPX W Acircumflex -50
+KPX W Adieresis -50
+KPX W Agrave -50
+KPX W Amacron -50
+KPX W Aogonek -50
+KPX W Aring -50
+KPX W Atilde -50
+KPX W O -20
+KPX W Oacute -20
+KPX W Ocircumflex -20
+KPX W Odieresis -20
+KPX W Ograve -20
+KPX W Ohungarumlaut -20
+KPX W Omacron -20
+KPX W Oslash -20
+KPX W Otilde -20
+KPX W a -40
+KPX W aacute -40
+KPX W abreve -40
+KPX W acircumflex -40
+KPX W adieresis -40
+KPX W agrave -40
+KPX W amacron -40
+KPX W aogonek -40
+KPX W aring -40
+KPX W atilde -40
+KPX W comma -80
+KPX W e -30
+KPX W eacute -30
+KPX W ecaron -30
+KPX W ecircumflex -30
+KPX W edieresis -30
+KPX W edotaccent -30
+KPX W egrave -30
+KPX W emacron -30
+KPX W eogonek -30
+KPX W hyphen -40
+KPX W o -30
+KPX W oacute -30
+KPX W ocircumflex -30
+KPX W odieresis -30
+KPX W ograve -30
+KPX W ohungarumlaut -30
+KPX W omacron -30
+KPX W oslash -30
+KPX W otilde -30
+KPX W period -80
+KPX W u -30
+KPX W uacute -30
+KPX W ucircumflex -30
+KPX W udieresis -30
+KPX W ugrave -30
+KPX W uhungarumlaut -30
+KPX W umacron -30
+KPX W uogonek -30
+KPX W uring -30
+KPX W y -20
+KPX W yacute -20
+KPX W ydieresis -20
+KPX Y A -110
+KPX Y Aacute -110
+KPX Y Abreve -110
+KPX Y Acircumflex -110
+KPX Y Adieresis -110
+KPX Y Agrave -110
+KPX Y Amacron -110
+KPX Y Aogonek -110
+KPX Y Aring -110
+KPX Y Atilde -110
+KPX Y O -85
+KPX Y Oacute -85
+KPX Y Ocircumflex -85
+KPX Y Odieresis -85
+KPX Y Ograve -85
+KPX Y Ohungarumlaut -85
+KPX Y Omacron -85
+KPX Y Oslash -85
+KPX Y Otilde -85
+KPX Y a -140
+KPX Y aacute -140
+KPX Y abreve -70
+KPX Y acircumflex -140
+KPX Y adieresis -140
+KPX Y agrave -140
+KPX Y amacron -70
+KPX Y aogonek -140
+KPX Y aring -140
+KPX Y atilde -140
+KPX Y colon -60
+KPX Y comma -140
+KPX Y e -140
+KPX Y eacute -140
+KPX Y ecaron -140
+KPX Y ecircumflex -140
+KPX Y edieresis -140
+KPX Y edotaccent -140
+KPX Y egrave -140
+KPX Y emacron -70
+KPX Y eogonek -140
+KPX Y hyphen -140
+KPX Y i -20
+KPX Y iacute -20
+KPX Y iogonek -20
+KPX Y o -140
+KPX Y oacute -140
+KPX Y ocircumflex -140
+KPX Y odieresis -140
+KPX Y ograve -140
+KPX Y ohungarumlaut -140
+KPX Y omacron -140
+KPX Y oslash -140
+KPX Y otilde -140
+KPX Y period -140
+KPX Y semicolon -60
+KPX Y u -110
+KPX Y uacute -110
+KPX Y ucircumflex -110
+KPX Y udieresis -110
+KPX Y ugrave -110
+KPX Y uhungarumlaut -110
+KPX Y umacron -110
+KPX Y uogonek -110
+KPX Y uring -110
+KPX Yacute A -110
+KPX Yacute Aacute -110
+KPX Yacute Abreve -110
+KPX Yacute Acircumflex -110
+KPX Yacute Adieresis -110
+KPX Yacute Agrave -110
+KPX Yacute Amacron -110
+KPX Yacute Aogonek -110
+KPX Yacute Aring -110
+KPX Yacute Atilde -110
+KPX Yacute O -85
+KPX Yacute Oacute -85
+KPX Yacute Ocircumflex -85
+KPX Yacute Odieresis -85
+KPX Yacute Ograve -85
+KPX Yacute Ohungarumlaut -85
+KPX Yacute Omacron -85
+KPX Yacute Oslash -85
+KPX Yacute Otilde -85
+KPX Yacute a -140
+KPX Yacute aacute -140
+KPX Yacute abreve -70
+KPX Yacute acircumflex -140
+KPX Yacute adieresis -140
+KPX Yacute agrave -140
+KPX Yacute amacron -70
+KPX Yacute aogonek -140
+KPX Yacute aring -140
+KPX Yacute atilde -70
+KPX Yacute colon -60
+KPX Yacute comma -140
+KPX Yacute e -140
+KPX Yacute eacute -140
+KPX Yacute ecaron -140
+KPX Yacute ecircumflex -140
+KPX Yacute edieresis -140
+KPX Yacute edotaccent -140
+KPX Yacute egrave -140
+KPX Yacute emacron -70
+KPX Yacute eogonek -140
+KPX Yacute hyphen -140
+KPX Yacute i -20
+KPX Yacute iacute -20
+KPX Yacute iogonek -20
+KPX Yacute o -140
+KPX Yacute oacute -140
+KPX Yacute ocircumflex -140
+KPX Yacute odieresis -140
+KPX Yacute ograve -140
+KPX Yacute ohungarumlaut -140
+KPX Yacute omacron -70
+KPX Yacute oslash -140
+KPX Yacute otilde -140
+KPX Yacute period -140
+KPX Yacute semicolon -60
+KPX Yacute u -110
+KPX Yacute uacute -110
+KPX Yacute ucircumflex -110
+KPX Yacute udieresis -110
+KPX Yacute ugrave -110
+KPX Yacute uhungarumlaut -110
+KPX Yacute umacron -110
+KPX Yacute uogonek -110
+KPX Yacute uring -110
+KPX Ydieresis A -110
+KPX Ydieresis Aacute -110
+KPX Ydieresis Abreve -110
+KPX Ydieresis Acircumflex -110
+KPX Ydieresis Adieresis -110
+KPX Ydieresis Agrave -110
+KPX Ydieresis Amacron -110
+KPX Ydieresis Aogonek -110
+KPX Ydieresis Aring -110
+KPX Ydieresis Atilde -110
+KPX Ydieresis O -85
+KPX Ydieresis Oacute -85
+KPX Ydieresis Ocircumflex -85
+KPX Ydieresis Odieresis -85
+KPX Ydieresis Ograve -85
+KPX Ydieresis Ohungarumlaut -85
+KPX Ydieresis Omacron -85
+KPX Ydieresis Oslash -85
+KPX Ydieresis Otilde -85
+KPX Ydieresis a -140
+KPX Ydieresis aacute -140
+KPX Ydieresis abreve -70
+KPX Ydieresis acircumflex -140
+KPX Ydieresis adieresis -140
+KPX Ydieresis agrave -140
+KPX Ydieresis amacron -70
+KPX Ydieresis aogonek -140
+KPX Ydieresis aring -140
+KPX Ydieresis atilde -70
+KPX Ydieresis colon -60
+KPX Ydieresis comma -140
+KPX Ydieresis e -140
+KPX Ydieresis eacute -140
+KPX Ydieresis ecaron -140
+KPX Ydieresis ecircumflex -140
+KPX Ydieresis edieresis -140
+KPX Ydieresis edotaccent -140
+KPX Ydieresis egrave -140
+KPX Ydieresis emacron -70
+KPX Ydieresis eogonek -140
+KPX Ydieresis hyphen -140
+KPX Ydieresis i -20
+KPX Ydieresis iacute -20
+KPX Ydieresis iogonek -20
+KPX Ydieresis o -140
+KPX Ydieresis oacute -140
+KPX Ydieresis ocircumflex -140
+KPX Ydieresis odieresis -140
+KPX Ydieresis ograve -140
+KPX Ydieresis ohungarumlaut -140
+KPX Ydieresis omacron -140
+KPX Ydieresis oslash -140
+KPX Ydieresis otilde -140
+KPX Ydieresis period -140
+KPX Ydieresis semicolon -60
+KPX Ydieresis u -110
+KPX Ydieresis uacute -110
+KPX Ydieresis ucircumflex -110
+KPX Ydieresis udieresis -110
+KPX Ydieresis ugrave -110
+KPX Ydieresis uhungarumlaut -110
+KPX Ydieresis umacron -110
+KPX Ydieresis uogonek -110
+KPX Ydieresis uring -110
+KPX a v -20
+KPX a w -20
+KPX a y -30
+KPX a yacute -30
+KPX a ydieresis -30
+KPX aacute v -20
+KPX aacute w -20
+KPX aacute y -30
+KPX aacute yacute -30
+KPX aacute ydieresis -30
+KPX abreve v -20
+KPX abreve w -20
+KPX abreve y -30
+KPX abreve yacute -30
+KPX abreve ydieresis -30
+KPX acircumflex v -20
+KPX acircumflex w -20
+KPX acircumflex y -30
+KPX acircumflex yacute -30
+KPX acircumflex ydieresis -30
+KPX adieresis v -20
+KPX adieresis w -20
+KPX adieresis y -30
+KPX adieresis yacute -30
+KPX adieresis ydieresis -30
+KPX agrave v -20
+KPX agrave w -20
+KPX agrave y -30
+KPX agrave yacute -30
+KPX agrave ydieresis -30
+KPX amacron v -20
+KPX amacron w -20
+KPX amacron y -30
+KPX amacron yacute -30
+KPX amacron ydieresis -30
+KPX aogonek v -20
+KPX aogonek w -20
+KPX aogonek y -30
+KPX aogonek yacute -30
+KPX aogonek ydieresis -30
+KPX aring v -20
+KPX aring w -20
+KPX aring y -30
+KPX aring yacute -30
+KPX aring ydieresis -30
+KPX atilde v -20
+KPX atilde w -20
+KPX atilde y -30
+KPX atilde yacute -30
+KPX atilde ydieresis -30
+KPX b b -10
+KPX b comma -40
+KPX b l -20
+KPX b lacute -20
+KPX b lcommaaccent -20
+KPX b lslash -20
+KPX b period -40
+KPX b u -20
+KPX b uacute -20
+KPX b ucircumflex -20
+KPX b udieresis -20
+KPX b ugrave -20
+KPX b uhungarumlaut -20
+KPX b umacron -20
+KPX b uogonek -20
+KPX b uring -20
+KPX b v -20
+KPX b y -20
+KPX b yacute -20
+KPX b ydieresis -20
+KPX c comma -15
+KPX c k -20
+KPX c kcommaaccent -20
+KPX cacute comma -15
+KPX cacute k -20
+KPX cacute kcommaaccent -20
+KPX ccaron comma -15
+KPX ccaron k -20
+KPX ccaron kcommaaccent -20
+KPX ccedilla comma -15
+KPX ccedilla k -20
+KPX ccedilla kcommaaccent -20
+KPX colon space -50
+KPX comma quotedblright -100
+KPX comma quoteright -100
+KPX e comma -15
+KPX e period -15
+KPX e v -30
+KPX e w -20
+KPX e x -30
+KPX e y -20
+KPX e yacute -20
+KPX e ydieresis -20
+KPX eacute comma -15
+KPX eacute period -15
+KPX eacute v -30
+KPX eacute w -20
+KPX eacute x -30
+KPX eacute y -20
+KPX eacute yacute -20
+KPX eacute ydieresis -20
+KPX ecaron comma -15
+KPX ecaron period -15
+KPX ecaron v -30
+KPX ecaron w -20
+KPX ecaron x -30
+KPX ecaron y -20
+KPX ecaron yacute -20
+KPX ecaron ydieresis -20
+KPX ecircumflex comma -15
+KPX ecircumflex period -15
+KPX ecircumflex v -30
+KPX ecircumflex w -20
+KPX ecircumflex x -30
+KPX ecircumflex y -20
+KPX ecircumflex yacute -20
+KPX ecircumflex ydieresis -20
+KPX edieresis comma -15
+KPX edieresis period -15
+KPX edieresis v -30
+KPX edieresis w -20
+KPX edieresis x -30
+KPX edieresis y -20
+KPX edieresis yacute -20
+KPX edieresis ydieresis -20
+KPX edotaccent comma -15
+KPX edotaccent period -15
+KPX edotaccent v -30
+KPX edotaccent w -20
+KPX edotaccent x -30
+KPX edotaccent y -20
+KPX edotaccent yacute -20
+KPX edotaccent ydieresis -20
+KPX egrave comma -15
+KPX egrave period -15
+KPX egrave v -30
+KPX egrave w -20
+KPX egrave x -30
+KPX egrave y -20
+KPX egrave yacute -20
+KPX egrave ydieresis -20
+KPX emacron comma -15
+KPX emacron period -15
+KPX emacron v -30
+KPX emacron w -20
+KPX emacron x -30
+KPX emacron y -20
+KPX emacron yacute -20
+KPX emacron ydieresis -20
+KPX eogonek comma -15
+KPX eogonek period -15
+KPX eogonek v -30
+KPX eogonek w -20
+KPX eogonek x -30
+KPX eogonek y -20
+KPX eogonek yacute -20
+KPX eogonek ydieresis -20
+KPX f a -30
+KPX f aacute -30
+KPX f abreve -30
+KPX f acircumflex -30
+KPX f adieresis -30
+KPX f agrave -30
+KPX f amacron -30
+KPX f aogonek -30
+KPX f aring -30
+KPX f atilde -30
+KPX f comma -30
+KPX f dotlessi -28
+KPX f e -30
+KPX f eacute -30
+KPX f ecaron -30
+KPX f ecircumflex -30
+KPX f edieresis -30
+KPX f edotaccent -30
+KPX f egrave -30
+KPX f emacron -30
+KPX f eogonek -30
+KPX f o -30
+KPX f oacute -30
+KPX f ocircumflex -30
+KPX f odieresis -30
+KPX f ograve -30
+KPX f ohungarumlaut -30
+KPX f omacron -30
+KPX f oslash -30
+KPX f otilde -30
+KPX f period -30
+KPX f quotedblright 60
+KPX f quoteright 50
+KPX g r -10
+KPX g racute -10
+KPX g rcaron -10
+KPX g rcommaaccent -10
+KPX gbreve r -10
+KPX gbreve racute -10
+KPX gbreve rcaron -10
+KPX gbreve rcommaaccent -10
+KPX gcommaaccent r -10
+KPX gcommaaccent racute -10
+KPX gcommaaccent rcaron -10
+KPX gcommaaccent rcommaaccent -10
+KPX h y -30
+KPX h yacute -30
+KPX h ydieresis -30
+KPX k e -20
+KPX k eacute -20
+KPX k ecaron -20
+KPX k ecircumflex -20
+KPX k edieresis -20
+KPX k edotaccent -20
+KPX k egrave -20
+KPX k emacron -20
+KPX k eogonek -20
+KPX k o -20
+KPX k oacute -20
+KPX k ocircumflex -20
+KPX k odieresis -20
+KPX k ograve -20
+KPX k ohungarumlaut -20
+KPX k omacron -20
+KPX k oslash -20
+KPX k otilde -20
+KPX kcommaaccent e -20
+KPX kcommaaccent eacute -20
+KPX kcommaaccent ecaron -20
+KPX kcommaaccent ecircumflex -20
+KPX kcommaaccent edieresis -20
+KPX kcommaaccent edotaccent -20
+KPX kcommaaccent egrave -20
+KPX kcommaaccent emacron -20
+KPX kcommaaccent eogonek -20
+KPX kcommaaccent o -20
+KPX kcommaaccent oacute -20
+KPX kcommaaccent ocircumflex -20
+KPX kcommaaccent odieresis -20
+KPX kcommaaccent ograve -20
+KPX kcommaaccent ohungarumlaut -20
+KPX kcommaaccent omacron -20
+KPX kcommaaccent oslash -20
+KPX kcommaaccent otilde -20
+KPX m u -10
+KPX m uacute -10
+KPX m ucircumflex -10
+KPX m udieresis -10
+KPX m ugrave -10
+KPX m uhungarumlaut -10
+KPX m umacron -10
+KPX m uogonek -10
+KPX m uring -10
+KPX m y -15
+KPX m yacute -15
+KPX m ydieresis -15
+KPX n u -10
+KPX n uacute -10
+KPX n ucircumflex -10
+KPX n udieresis -10
+KPX n ugrave -10
+KPX n uhungarumlaut -10
+KPX n umacron -10
+KPX n uogonek -10
+KPX n uring -10
+KPX n v -20
+KPX n y -15
+KPX n yacute -15
+KPX n ydieresis -15
+KPX nacute u -10
+KPX nacute uacute -10
+KPX nacute ucircumflex -10
+KPX nacute udieresis -10
+KPX nacute ugrave -10
+KPX nacute uhungarumlaut -10
+KPX nacute umacron -10
+KPX nacute uogonek -10
+KPX nacute uring -10
+KPX nacute v -20
+KPX nacute y -15
+KPX nacute yacute -15
+KPX nacute ydieresis -15
+KPX ncaron u -10
+KPX ncaron uacute -10
+KPX ncaron ucircumflex -10
+KPX ncaron udieresis -10
+KPX ncaron ugrave -10
+KPX ncaron uhungarumlaut -10
+KPX ncaron umacron -10
+KPX ncaron uogonek -10
+KPX ncaron uring -10
+KPX ncaron v -20
+KPX ncaron y -15
+KPX ncaron yacute -15
+KPX ncaron ydieresis -15
+KPX ncommaaccent u -10
+KPX ncommaaccent uacute -10
+KPX ncommaaccent ucircumflex -10
+KPX ncommaaccent udieresis -10
+KPX ncommaaccent ugrave -10
+KPX ncommaaccent uhungarumlaut -10
+KPX ncommaaccent umacron -10
+KPX ncommaaccent uogonek -10
+KPX ncommaaccent uring -10
+KPX ncommaaccent v -20
+KPX ncommaaccent y -15
+KPX ncommaaccent yacute -15
+KPX ncommaaccent ydieresis -15
+KPX ntilde u -10
+KPX ntilde uacute -10
+KPX ntilde ucircumflex -10
+KPX ntilde udieresis -10
+KPX ntilde ugrave -10
+KPX ntilde uhungarumlaut -10
+KPX ntilde umacron -10
+KPX ntilde uogonek -10
+KPX ntilde uring -10
+KPX ntilde v -20
+KPX ntilde y -15
+KPX ntilde yacute -15
+KPX ntilde ydieresis -15
+KPX o comma -40
+KPX o period -40
+KPX o v -15
+KPX o w -15
+KPX o x -30
+KPX o y -30
+KPX o yacute -30
+KPX o ydieresis -30
+KPX oacute comma -40
+KPX oacute period -40
+KPX oacute v -15
+KPX oacute w -15
+KPX oacute x -30
+KPX oacute y -30
+KPX oacute yacute -30
+KPX oacute ydieresis -30
+KPX ocircumflex comma -40
+KPX ocircumflex period -40
+KPX ocircumflex v -15
+KPX ocircumflex w -15
+KPX ocircumflex x -30
+KPX ocircumflex y -30
+KPX ocircumflex yacute -30
+KPX ocircumflex ydieresis -30
+KPX odieresis comma -40
+KPX odieresis period -40
+KPX odieresis v -15
+KPX odieresis w -15
+KPX odieresis x -30
+KPX odieresis y -30
+KPX odieresis yacute -30
+KPX odieresis ydieresis -30
+KPX ograve comma -40
+KPX ograve period -40
+KPX ograve v -15
+KPX ograve w -15
+KPX ograve x -30
+KPX ograve y -30
+KPX ograve yacute -30
+KPX ograve ydieresis -30
+KPX ohungarumlaut comma -40
+KPX ohungarumlaut period -40
+KPX ohungarumlaut v -15
+KPX ohungarumlaut w -15
+KPX ohungarumlaut x -30
+KPX ohungarumlaut y -30
+KPX ohungarumlaut yacute -30
+KPX ohungarumlaut ydieresis -30
+KPX omacron comma -40
+KPX omacron period -40
+KPX omacron v -15
+KPX omacron w -15
+KPX omacron x -30
+KPX omacron y -30
+KPX omacron yacute -30
+KPX omacron ydieresis -30
+KPX oslash a -55
+KPX oslash aacute -55
+KPX oslash abreve -55
+KPX oslash acircumflex -55
+KPX oslash adieresis -55
+KPX oslash agrave -55
+KPX oslash amacron -55
+KPX oslash aogonek -55
+KPX oslash aring -55
+KPX oslash atilde -55
+KPX oslash b -55
+KPX oslash c -55
+KPX oslash cacute -55
+KPX oslash ccaron -55
+KPX oslash ccedilla -55
+KPX oslash comma -95
+KPX oslash d -55
+KPX oslash dcroat -55
+KPX oslash e -55
+KPX oslash eacute -55
+KPX oslash ecaron -55
+KPX oslash ecircumflex -55
+KPX oslash edieresis -55
+KPX oslash edotaccent -55
+KPX oslash egrave -55
+KPX oslash emacron -55
+KPX oslash eogonek -55
+KPX oslash f -55
+KPX oslash g -55
+KPX oslash gbreve -55
+KPX oslash gcommaaccent -55
+KPX oslash h -55
+KPX oslash i -55
+KPX oslash iacute -55
+KPX oslash icircumflex -55
+KPX oslash idieresis -55
+KPX oslash igrave -55
+KPX oslash imacron -55
+KPX oslash iogonek -55
+KPX oslash j -55
+KPX oslash k -55
+KPX oslash kcommaaccent -55
+KPX oslash l -55
+KPX oslash lacute -55
+KPX oslash lcommaaccent -55
+KPX oslash lslash -55
+KPX oslash m -55
+KPX oslash n -55
+KPX oslash nacute -55
+KPX oslash ncaron -55
+KPX oslash ncommaaccent -55
+KPX oslash ntilde -55
+KPX oslash o -55
+KPX oslash oacute -55
+KPX oslash ocircumflex -55
+KPX oslash odieresis -55
+KPX oslash ograve -55
+KPX oslash ohungarumlaut -55
+KPX oslash omacron -55
+KPX oslash oslash -55
+KPX oslash otilde -55
+KPX oslash p -55
+KPX oslash period -95
+KPX oslash q -55
+KPX oslash r -55
+KPX oslash racute -55
+KPX oslash rcaron -55
+KPX oslash rcommaaccent -55
+KPX oslash s -55
+KPX oslash sacute -55
+KPX oslash scaron -55
+KPX oslash scedilla -55
+KPX oslash scommaaccent -55
+KPX oslash t -55
+KPX oslash tcommaaccent -55
+KPX oslash u -55
+KPX oslash uacute -55
+KPX oslash ucircumflex -55
+KPX oslash udieresis -55
+KPX oslash ugrave -55
+KPX oslash uhungarumlaut -55
+KPX oslash umacron -55
+KPX oslash uogonek -55
+KPX oslash uring -55
+KPX oslash v -70
+KPX oslash w -70
+KPX oslash x -85
+KPX oslash y -70
+KPX oslash yacute -70
+KPX oslash ydieresis -70
+KPX oslash z -55
+KPX oslash zacute -55
+KPX oslash zcaron -55
+KPX oslash zdotaccent -55
+KPX otilde comma -40
+KPX otilde period -40
+KPX otilde v -15
+KPX otilde w -15
+KPX otilde x -30
+KPX otilde y -30
+KPX otilde yacute -30
+KPX otilde ydieresis -30
+KPX p comma -35
+KPX p period -35
+KPX p y -30
+KPX p yacute -30
+KPX p ydieresis -30
+KPX period quotedblright -100
+KPX period quoteright -100
+KPX period space -60
+KPX quotedblright space -40
+KPX quoteleft quoteleft -57
+KPX quoteright d -50
+KPX quoteright dcroat -50
+KPX quoteright quoteright -57
+KPX quoteright r -50
+KPX quoteright racute -50
+KPX quoteright rcaron -50
+KPX quoteright rcommaaccent -50
+KPX quoteright s -50
+KPX quoteright sacute -50
+KPX quoteright scaron -50
+KPX quoteright scedilla -50
+KPX quoteright scommaaccent -50
+KPX quoteright space -70
+KPX r a -10
+KPX r aacute -10
+KPX r abreve -10
+KPX r acircumflex -10
+KPX r adieresis -10
+KPX r agrave -10
+KPX r amacron -10
+KPX r aogonek -10
+KPX r aring -10
+KPX r atilde -10
+KPX r colon 30
+KPX r comma -50
+KPX r i 15
+KPX r iacute 15
+KPX r icircumflex 15
+KPX r idieresis 15
+KPX r igrave 15
+KPX r imacron 15
+KPX r iogonek 15
+KPX r k 15
+KPX r kcommaaccent 15
+KPX r l 15
+KPX r lacute 15
+KPX r lcommaaccent 15
+KPX r lslash 15
+KPX r m 25
+KPX r n 25
+KPX r nacute 25
+KPX r ncaron 25
+KPX r ncommaaccent 25
+KPX r ntilde 25
+KPX r p 30
+KPX r period -50
+KPX r semicolon 30
+KPX r t 40
+KPX r tcommaaccent 40
+KPX r u 15
+KPX r uacute 15
+KPX r ucircumflex 15
+KPX r udieresis 15
+KPX r ugrave 15
+KPX r uhungarumlaut 15
+KPX r umacron 15
+KPX r uogonek 15
+KPX r uring 15
+KPX r v 30
+KPX r y 30
+KPX r yacute 30
+KPX r ydieresis 30
+KPX racute a -10
+KPX racute aacute -10
+KPX racute abreve -10
+KPX racute acircumflex -10
+KPX racute adieresis -10
+KPX racute agrave -10
+KPX racute amacron -10
+KPX racute aogonek -10
+KPX racute aring -10
+KPX racute atilde -10
+KPX racute colon 30
+KPX racute comma -50
+KPX racute i 15
+KPX racute iacute 15
+KPX racute icircumflex 15
+KPX racute idieresis 15
+KPX racute igrave 15
+KPX racute imacron 15
+KPX racute iogonek 15
+KPX racute k 15
+KPX racute kcommaaccent 15
+KPX racute l 15
+KPX racute lacute 15
+KPX racute lcommaaccent 15
+KPX racute lslash 15
+KPX racute m 25
+KPX racute n 25
+KPX racute nacute 25
+KPX racute ncaron 25
+KPX racute ncommaaccent 25
+KPX racute ntilde 25
+KPX racute p 30
+KPX racute period -50
+KPX racute semicolon 30
+KPX racute t 40
+KPX racute tcommaaccent 40
+KPX racute u 15
+KPX racute uacute 15
+KPX racute ucircumflex 15
+KPX racute udieresis 15
+KPX racute ugrave 15
+KPX racute uhungarumlaut 15
+KPX racute umacron 15
+KPX racute uogonek 15
+KPX racute uring 15
+KPX racute v 30
+KPX racute y 30
+KPX racute yacute 30
+KPX racute ydieresis 30
+KPX rcaron a -10
+KPX rcaron aacute -10
+KPX rcaron abreve -10
+KPX rcaron acircumflex -10
+KPX rcaron adieresis -10
+KPX rcaron agrave -10
+KPX rcaron amacron -10
+KPX rcaron aogonek -10
+KPX rcaron aring -10
+KPX rcaron atilde -10
+KPX rcaron colon 30
+KPX rcaron comma -50
+KPX rcaron i 15
+KPX rcaron iacute 15
+KPX rcaron icircumflex 15
+KPX rcaron idieresis 15
+KPX rcaron igrave 15
+KPX rcaron imacron 15
+KPX rcaron iogonek 15
+KPX rcaron k 15
+KPX rcaron kcommaaccent 15
+KPX rcaron l 15
+KPX rcaron lacute 15
+KPX rcaron lcommaaccent 15
+KPX rcaron lslash 15
+KPX rcaron m 25
+KPX rcaron n 25
+KPX rcaron nacute 25
+KPX rcaron ncaron 25
+KPX rcaron ncommaaccent 25
+KPX rcaron ntilde 25
+KPX rcaron p 30
+KPX rcaron period -50
+KPX rcaron semicolon 30
+KPX rcaron t 40
+KPX rcaron tcommaaccent 40
+KPX rcaron u 15
+KPX rcaron uacute 15
+KPX rcaron ucircumflex 15
+KPX rcaron udieresis 15
+KPX rcaron ugrave 15
+KPX rcaron uhungarumlaut 15
+KPX rcaron umacron 15
+KPX rcaron uogonek 15
+KPX rcaron uring 15
+KPX rcaron v 30
+KPX rcaron y 30
+KPX rcaron yacute 30
+KPX rcaron ydieresis 30
+KPX rcommaaccent a -10
+KPX rcommaaccent aacute -10
+KPX rcommaaccent abreve -10
+KPX rcommaaccent acircumflex -10
+KPX rcommaaccent adieresis -10
+KPX rcommaaccent agrave -10
+KPX rcommaaccent amacron -10
+KPX rcommaaccent aogonek -10
+KPX rcommaaccent aring -10
+KPX rcommaaccent atilde -10
+KPX rcommaaccent colon 30
+KPX rcommaaccent comma -50
+KPX rcommaaccent i 15
+KPX rcommaaccent iacute 15
+KPX rcommaaccent icircumflex 15
+KPX rcommaaccent idieresis 15
+KPX rcommaaccent igrave 15
+KPX rcommaaccent imacron 15
+KPX rcommaaccent iogonek 15
+KPX rcommaaccent k 15
+KPX rcommaaccent kcommaaccent 15
+KPX rcommaaccent l 15
+KPX rcommaaccent lacute 15
+KPX rcommaaccent lcommaaccent 15
+KPX rcommaaccent lslash 15
+KPX rcommaaccent m 25
+KPX rcommaaccent n 25
+KPX rcommaaccent nacute 25
+KPX rcommaaccent ncaron 25
+KPX rcommaaccent ncommaaccent 25
+KPX rcommaaccent ntilde 25
+KPX rcommaaccent p 30
+KPX rcommaaccent period -50
+KPX rcommaaccent semicolon 30
+KPX rcommaaccent t 40
+KPX rcommaaccent tcommaaccent 40
+KPX rcommaaccent u 15
+KPX rcommaaccent uacute 15
+KPX rcommaaccent ucircumflex 15
+KPX rcommaaccent udieresis 15
+KPX rcommaaccent ugrave 15
+KPX rcommaaccent uhungarumlaut 15
+KPX rcommaaccent umacron 15
+KPX rcommaaccent uogonek 15
+KPX rcommaaccent uring 15
+KPX rcommaaccent v 30
+KPX rcommaaccent y 30
+KPX rcommaaccent yacute 30
+KPX rcommaaccent ydieresis 30
+KPX s comma -15
+KPX s period -15
+KPX s w -30
+KPX sacute comma -15
+KPX sacute period -15
+KPX sacute w -30
+KPX scaron comma -15
+KPX scaron period -15
+KPX scaron w -30
+KPX scedilla comma -15
+KPX scedilla period -15
+KPX scedilla w -30
+KPX scommaaccent comma -15
+KPX scommaaccent period -15
+KPX scommaaccent w -30
+KPX semicolon space -50
+KPX space T -50
+KPX space Tcaron -50
+KPX space Tcommaaccent -50
+KPX space V -50
+KPX space W -40
+KPX space Y -90
+KPX space Yacute -90
+KPX space Ydieresis -90
+KPX space quotedblleft -30
+KPX space quoteleft -60
+KPX v a -25
+KPX v aacute -25
+KPX v abreve -25
+KPX v acircumflex -25
+KPX v adieresis -25
+KPX v agrave -25
+KPX v amacron -25
+KPX v aogonek -25
+KPX v aring -25
+KPX v atilde -25
+KPX v comma -80
+KPX v e -25
+KPX v eacute -25
+KPX v ecaron -25
+KPX v ecircumflex -25
+KPX v edieresis -25
+KPX v edotaccent -25
+KPX v egrave -25
+KPX v emacron -25
+KPX v eogonek -25
+KPX v o -25
+KPX v oacute -25
+KPX v ocircumflex -25
+KPX v odieresis -25
+KPX v ograve -25
+KPX v ohungarumlaut -25
+KPX v omacron -25
+KPX v oslash -25
+KPX v otilde -25
+KPX v period -80
+KPX w a -15
+KPX w aacute -15
+KPX w abreve -15
+KPX w acircumflex -15
+KPX w adieresis -15
+KPX w agrave -15
+KPX w amacron -15
+KPX w aogonek -15
+KPX w aring -15
+KPX w atilde -15
+KPX w comma -60
+KPX w e -10
+KPX w eacute -10
+KPX w ecaron -10
+KPX w ecircumflex -10
+KPX w edieresis -10
+KPX w edotaccent -10
+KPX w egrave -10
+KPX w emacron -10
+KPX w eogonek -10
+KPX w o -10
+KPX w oacute -10
+KPX w ocircumflex -10
+KPX w odieresis -10
+KPX w ograve -10
+KPX w ohungarumlaut -10
+KPX w omacron -10
+KPX w oslash -10
+KPX w otilde -10
+KPX w period -60
+KPX x e -30
+KPX x eacute -30
+KPX x ecaron -30
+KPX x ecircumflex -30
+KPX x edieresis -30
+KPX x edotaccent -30
+KPX x egrave -30
+KPX x emacron -30
+KPX x eogonek -30
+KPX y a -20
+KPX y aacute -20
+KPX y abreve -20
+KPX y acircumflex -20
+KPX y adieresis -20
+KPX y agrave -20
+KPX y amacron -20
+KPX y aogonek -20
+KPX y aring -20
+KPX y atilde -20
+KPX y comma -100
+KPX y e -20
+KPX y eacute -20
+KPX y ecaron -20
+KPX y ecircumflex -20
+KPX y edieresis -20
+KPX y edotaccent -20
+KPX y egrave -20
+KPX y emacron -20
+KPX y eogonek -20
+KPX y o -20
+KPX y oacute -20
+KPX y ocircumflex -20
+KPX y odieresis -20
+KPX y ograve -20
+KPX y ohungarumlaut -20
+KPX y omacron -20
+KPX y oslash -20
+KPX y otilde -20
+KPX y period -100
+KPX yacute a -20
+KPX yacute aacute -20
+KPX yacute abreve -20
+KPX yacute acircumflex -20
+KPX yacute adieresis -20
+KPX yacute agrave -20
+KPX yacute amacron -20
+KPX yacute aogonek -20
+KPX yacute aring -20
+KPX yacute atilde -20
+KPX yacute comma -100
+KPX yacute e -20
+KPX yacute eacute -20
+KPX yacute ecaron -20
+KPX yacute ecircumflex -20
+KPX yacute edieresis -20
+KPX yacute edotaccent -20
+KPX yacute egrave -20
+KPX yacute emacron -20
+KPX yacute eogonek -20
+KPX yacute o -20
+KPX yacute oacute -20
+KPX yacute ocircumflex -20
+KPX yacute odieresis -20
+KPX yacute ograve -20
+KPX yacute ohungarumlaut -20
+KPX yacute omacron -20
+KPX yacute oslash -20
+KPX yacute otilde -20
+KPX yacute period -100
+KPX ydieresis a -20
+KPX ydieresis aacute -20
+KPX ydieresis abreve -20
+KPX ydieresis acircumflex -20
+KPX ydieresis adieresis -20
+KPX ydieresis agrave -20
+KPX ydieresis amacron -20
+KPX ydieresis aogonek -20
+KPX ydieresis aring -20
+KPX ydieresis atilde -20
+KPX ydieresis comma -100
+KPX ydieresis e -20
+KPX ydieresis eacute -20
+KPX ydieresis ecaron -20
+KPX ydieresis ecircumflex -20
+KPX ydieresis edieresis -20
+KPX ydieresis edotaccent -20
+KPX ydieresis egrave -20
+KPX ydieresis emacron -20
+KPX ydieresis eogonek -20
+KPX ydieresis o -20
+KPX ydieresis oacute -20
+KPX ydieresis ocircumflex -20
+KPX ydieresis odieresis -20
+KPX ydieresis ograve -20
+KPX ydieresis ohungarumlaut -20
+KPX ydieresis omacron -20
+KPX ydieresis oslash -20
+KPX ydieresis otilde -20
+KPX ydieresis period -100
+KPX z e -15
+KPX z eacute -15
+KPX z ecaron -15
+KPX z ecircumflex -15
+KPX z edieresis -15
+KPX z edotaccent -15
+KPX z egrave -15
+KPX z emacron -15
+KPX z eogonek -15
+KPX z o -15
+KPX z oacute -15
+KPX z ocircumflex -15
+KPX z odieresis -15
+KPX z ograve -15
+KPX z ohungarumlaut -15
+KPX z omacron -15
+KPX z oslash -15
+KPX z otilde -15
+KPX zacute e -15
+KPX zacute eacute -15
+KPX zacute ecaron -15
+KPX zacute ecircumflex -15
+KPX zacute edieresis -15
+KPX zacute edotaccent -15
+KPX zacute egrave -15
+KPX zacute emacron -15
+KPX zacute eogonek -15
+KPX zacute o -15
+KPX zacute oacute -15
+KPX zacute ocircumflex -15
+KPX zacute odieresis -15
+KPX zacute ograve -15
+KPX zacute ohungarumlaut -15
+KPX zacute omacron -15
+KPX zacute oslash -15
+KPX zacute otilde -15
+KPX zcaron e -15
+KPX zcaron eacute -15
+KPX zcaron ecaron -15
+KPX zcaron ecircumflex -15
+KPX zcaron edieresis -15
+KPX zcaron edotaccent -15
+KPX zcaron egrave -15
+KPX zcaron emacron -15
+KPX zcaron eogonek -15
+KPX zcaron o -15
+KPX zcaron oacute -15
+KPX zcaron ocircumflex -15
+KPX zcaron odieresis -15
+KPX zcaron ograve -15
+KPX zcaron ohungarumlaut -15
+KPX zcaron omacron -15
+KPX zcaron oslash -15
+KPX zcaron otilde -15
+KPX zdotaccent e -15
+KPX zdotaccent eacute -15
+KPX zdotaccent ecaron -15
+KPX zdotaccent ecircumflex -15
+KPX zdotaccent edieresis -15
+KPX zdotaccent edotaccent -15
+KPX zdotaccent egrave -15
+KPX zdotaccent emacron -15
+KPX zdotaccent eogonek -15
+KPX zdotaccent o -15
+KPX zdotaccent oacute -15
+KPX zdotaccent ocircumflex -15
+KPX zdotaccent odieresis -15
+KPX zdotaccent ograve -15
+KPX zdotaccent ohungarumlaut -15
+KPX zdotaccent omacron -15
+KPX zdotaccent oslash -15
+KPX zdotaccent otilde -15
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica.afm
new file mode 100644
index 0000000..10746a5
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Helvetica.afm
@@ -0,0 +1,3051 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 12:38:23 1997
+Comment UniqueID 43054
+Comment VMusage 37069 48094
+FontName Helvetica
+FullName Helvetica
+FamilyName Helvetica
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+CharacterSet ExtendedRoman
+FontBBox -166 -225 1000 931
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 523
+Ascender 718
+Descender -207
+StdHW 76
+StdVW 88
+StartCharMetrics 315
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ;
+C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ;
+C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ;
+C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ;
+C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ;
+C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ;
+C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ;
+C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ;
+C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ;
+C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ;
+C 43 ; WX 584 ; N plus ; B 39 0 545 505 ;
+C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ;
+C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ;
+C 46 ; WX 278 ; N period ; B 87 0 191 106 ;
+C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ;
+C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ;
+C 49 ; WX 556 ; N one ; B 101 0 359 703 ;
+C 50 ; WX 556 ; N two ; B 26 0 507 703 ;
+C 51 ; WX 556 ; N three ; B 34 -19 522 703 ;
+C 52 ; WX 556 ; N four ; B 25 0 523 703 ;
+C 53 ; WX 556 ; N five ; B 32 -19 514 688 ;
+C 54 ; WX 556 ; N six ; B 38 -19 518 703 ;
+C 55 ; WX 556 ; N seven ; B 37 0 523 688 ;
+C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ;
+C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ;
+C 58 ; WX 278 ; N colon ; B 87 0 191 516 ;
+C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ;
+C 60 ; WX 584 ; N less ; B 48 11 536 495 ;
+C 61 ; WX 584 ; N equal ; B 39 115 545 390 ;
+C 62 ; WX 584 ; N greater ; B 48 11 536 495 ;
+C 63 ; WX 556 ; N question ; B 56 0 492 727 ;
+C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ;
+C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
+C 66 ; WX 667 ; N B ; B 74 0 627 718 ;
+C 67 ; WX 722 ; N C ; B 44 -19 681 737 ;
+C 68 ; WX 722 ; N D ; B 81 0 674 718 ;
+C 69 ; WX 667 ; N E ; B 86 0 616 718 ;
+C 70 ; WX 611 ; N F ; B 86 0 583 718 ;
+C 71 ; WX 778 ; N G ; B 48 -19 704 737 ;
+C 72 ; WX 722 ; N H ; B 77 0 646 718 ;
+C 73 ; WX 278 ; N I ; B 91 0 188 718 ;
+C 74 ; WX 500 ; N J ; B 17 -19 428 718 ;
+C 75 ; WX 667 ; N K ; B 76 0 663 718 ;
+C 76 ; WX 556 ; N L ; B 76 0 537 718 ;
+C 77 ; WX 833 ; N M ; B 73 0 761 718 ;
+C 78 ; WX 722 ; N N ; B 76 0 646 718 ;
+C 79 ; WX 778 ; N O ; B 39 -19 739 737 ;
+C 80 ; WX 667 ; N P ; B 86 0 622 718 ;
+C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ;
+C 82 ; WX 722 ; N R ; B 88 0 684 718 ;
+C 83 ; WX 667 ; N S ; B 49 -19 620 737 ;
+C 84 ; WX 611 ; N T ; B 14 0 597 718 ;
+C 85 ; WX 722 ; N U ; B 79 -19 644 718 ;
+C 86 ; WX 667 ; N V ; B 20 0 647 718 ;
+C 87 ; WX 944 ; N W ; B 16 0 928 718 ;
+C 88 ; WX 667 ; N X ; B 19 0 648 718 ;
+C 89 ; WX 667 ; N Y ; B 14 0 653 718 ;
+C 90 ; WX 611 ; N Z ; B 23 0 588 718 ;
+C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ;
+C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ;
+C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ;
+C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ;
+C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
+C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ;
+C 97 ; WX 556 ; N a ; B 36 -15 530 538 ;
+C 98 ; WX 556 ; N b ; B 58 -15 517 718 ;
+C 99 ; WX 500 ; N c ; B 30 -15 477 538 ;
+C 100 ; WX 556 ; N d ; B 35 -15 499 718 ;
+C 101 ; WX 556 ; N e ; B 40 -15 516 538 ;
+C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 40 -220 499 538 ;
+C 104 ; WX 556 ; N h ; B 65 0 491 718 ;
+C 105 ; WX 222 ; N i ; B 67 0 155 718 ;
+C 106 ; WX 222 ; N j ; B -16 -210 155 718 ;
+C 107 ; WX 500 ; N k ; B 67 0 501 718 ;
+C 108 ; WX 222 ; N l ; B 67 0 155 718 ;
+C 109 ; WX 833 ; N m ; B 65 0 769 538 ;
+C 110 ; WX 556 ; N n ; B 65 0 491 538 ;
+C 111 ; WX 556 ; N o ; B 35 -14 521 538 ;
+C 112 ; WX 556 ; N p ; B 58 -207 517 538 ;
+C 113 ; WX 556 ; N q ; B 35 -207 494 538 ;
+C 114 ; WX 333 ; N r ; B 77 0 332 538 ;
+C 115 ; WX 500 ; N s ; B 32 -15 464 538 ;
+C 116 ; WX 278 ; N t ; B 14 -7 257 669 ;
+C 117 ; WX 556 ; N u ; B 68 -15 489 523 ;
+C 118 ; WX 500 ; N v ; B 8 0 492 523 ;
+C 119 ; WX 722 ; N w ; B 14 0 709 523 ;
+C 120 ; WX 500 ; N x ; B 11 0 490 523 ;
+C 121 ; WX 500 ; N y ; B 11 -214 489 523 ;
+C 122 ; WX 500 ; N z ; B 31 0 469 523 ;
+C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ;
+C 124 ; WX 260 ; N bar ; B 94 -225 167 775 ;
+C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ;
+C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ;
+C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ;
+C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ;
+C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ;
+C 165 ; WX 556 ; N yen ; B 3 0 553 688 ;
+C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ;
+C 167 ; WX 556 ; N section ; B 43 -191 512 737 ;
+C 168 ; WX 556 ; N currency ; B 28 99 528 603 ;
+C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ;
+C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ;
+C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ;
+C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ;
+C 174 ; WX 500 ; N fi ; B 14 0 434 728 ;
+C 175 ; WX 500 ; N fl ; B 14 0 432 728 ;
+C 177 ; WX 556 ; N endash ; B 0 240 556 313 ;
+C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ;
+C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ;
+C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ;
+C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ;
+C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ;
+C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ;
+C 193 ; WX 333 ; N grave ; B 14 593 211 734 ;
+C 194 ; WX 333 ; N acute ; B 122 593 319 734 ;
+C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ;
+C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ;
+C 197 ; WX 333 ; N macron ; B 10 627 323 684 ;
+C 198 ; WX 333 ; N breve ; B 13 595 321 731 ;
+C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ;
+C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ;
+C 202 ; WX 333 ; N ring ; B 75 572 259 756 ;
+C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ;
+C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ;
+C 207 ; WX 333 ; N caron ; B 21 593 312 734 ;
+C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ;
+C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 24 405 346 737 ;
+C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ;
+C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ;
+C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 25 405 341 737 ;
+C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ;
+C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ;
+C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ;
+C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ;
+C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ;
+C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ;
+C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ;
+C -1 ; WX 556 ; N abreve ; B 36 -15 530 731 ;
+C -1 ; WX 556 ; N uhungarumlaut ; B 68 -15 521 734 ;
+C -1 ; WX 556 ; N ecaron ; B 40 -15 516 734 ;
+C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ;
+C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ;
+C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ;
+C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
+C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ;
+C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ;
+C -1 ; WX 500 ; N scommaaccent ; B 32 -225 464 538 ;
+C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ;
+C -1 ; WX 722 ; N Uring ; B 79 -19 644 931 ;
+C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ;
+C -1 ; WX 556 ; N aogonek ; B 36 -220 547 538 ;
+C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ;
+C -1 ; WX 556 ; N uogonek ; B 68 -225 519 523 ;
+C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ;
+C -1 ; WX 722 ; N Dcroat ; B 0 0 674 718 ;
+C -1 ; WX 250 ; N commaaccent ; B 87 -225 181 -40 ;
+C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ;
+C -1 ; WX 667 ; N Emacron ; B 86 0 616 879 ;
+C -1 ; WX 500 ; N ccaron ; B 30 -15 477 734 ;
+C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ;
+C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 646 718 ;
+C -1 ; WX 222 ; N lacute ; B 67 0 264 929 ;
+C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ;
+C -1 ; WX 611 ; N Tcommaaccent ; B 14 -225 597 718 ;
+C -1 ; WX 722 ; N Cacute ; B 44 -19 681 929 ;
+C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ;
+C -1 ; WX 667 ; N Edotaccent ; B 86 0 616 901 ;
+C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ;
+C -1 ; WX 500 ; N scedilla ; B 32 -225 464 538 ;
+C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ;
+C -1 ; WX 471 ; N lozenge ; B 10 0 462 728 ;
+C -1 ; WX 722 ; N Rcaron ; B 88 0 684 929 ;
+C -1 ; WX 778 ; N Gcommaaccent ; B 48 -225 704 737 ;
+C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ;
+C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ;
+C -1 ; WX 667 ; N Amacron ; B 14 0 654 879 ;
+C -1 ; WX 333 ; N rcaron ; B 61 0 352 734 ;
+C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ;
+C -1 ; WX 611 ; N Zdotaccent ; B 23 0 588 901 ;
+C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ;
+C -1 ; WX 778 ; N Omacron ; B 39 -19 739 879 ;
+C -1 ; WX 722 ; N Racute ; B 88 0 684 929 ;
+C -1 ; WX 667 ; N Sacute ; B 49 -19 620 929 ;
+C -1 ; WX 643 ; N dcaron ; B 35 -15 655 718 ;
+C -1 ; WX 722 ; N Umacron ; B 79 -19 644 879 ;
+C -1 ; WX 556 ; N uring ; B 68 -15 489 756 ;
+C -1 ; WX 333 ; N threebaseior ; B 5 270 325 703 ;
+C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ;
+C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
+C -1 ; WX 667 ; N Abreve ; B 14 0 654 926 ;
+C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ;
+C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ;
+C -1 ; WX 611 ; N Tcaron ; B 14 0 597 929 ;
+C -1 ; WX 476 ; N partialdiff ; B 13 -38 463 714 ;
+C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ;
+C -1 ; WX 722 ; N Nacute ; B 76 0 646 929 ;
+C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ;
+C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ;
+C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ;
+C -1 ; WX 500 ; N cacute ; B 30 -15 477 734 ;
+C -1 ; WX 556 ; N nacute ; B 65 0 491 734 ;
+C -1 ; WX 556 ; N umacron ; B 68 -15 489 684 ;
+C -1 ; WX 722 ; N Ncaron ; B 76 0 646 929 ;
+C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ;
+C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ;
+C -1 ; WX 260 ; N brokenbar ; B 94 -150 167 700 ;
+C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ;
+C -1 ; WX 778 ; N Gbreve ; B 48 -19 704 926 ;
+C -1 ; WX 278 ; N Idotaccent ; B 91 0 188 901 ;
+C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ;
+C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ;
+C -1 ; WX 333 ; N racute ; B 77 0 332 734 ;
+C -1 ; WX 556 ; N omacron ; B 35 -14 521 684 ;
+C -1 ; WX 611 ; N Zacute ; B 23 0 588 929 ;
+C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ;
+C -1 ; WX 549 ; N greaterequal ; B 26 0 523 674 ;
+C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ;
+C -1 ; WX 222 ; N lcommaaccent ; B 67 -225 167 718 ;
+C -1 ; WX 317 ; N tcaron ; B 14 -7 329 808 ;
+C -1 ; WX 556 ; N eogonek ; B 40 -225 516 538 ;
+C -1 ; WX 722 ; N Uogonek ; B 79 -225 644 718 ;
+C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ;
+C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
+C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ;
+C -1 ; WX 500 ; N zacute ; B 31 0 469 734 ;
+C -1 ; WX 222 ; N iogonek ; B -31 -225 183 718 ;
+C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ;
+C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ;
+C -1 ; WX 556 ; N amacron ; B 36 -15 530 684 ;
+C -1 ; WX 500 ; N sacute ; B 32 -15 464 734 ;
+C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ;
+C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ;
+C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ;
+C -1 ; WX 333 ; N twobaseior ; B 4 281 323 703 ;
+C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ;
+C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ;
+C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ;
+C -1 ; WX 556 ; N ohungarumlaut ; B 35 -14 521 734 ;
+C -1 ; WX 667 ; N Eogonek ; B 86 -220 633 718 ;
+C -1 ; WX 556 ; N dcroat ; B 35 -15 550 718 ;
+C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ;
+C -1 ; WX 667 ; N Scedilla ; B 49 -225 620 737 ;
+C -1 ; WX 299 ; N lcaron ; B 67 0 311 718 ;
+C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 663 718 ;
+C -1 ; WX 556 ; N Lacute ; B 76 0 537 929 ;
+C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ;
+C -1 ; WX 556 ; N edotaccent ; B 40 -15 516 706 ;
+C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ;
+C -1 ; WX 278 ; N Imacron ; B -17 0 296 879 ;
+C -1 ; WX 556 ; N Lcaron ; B 76 0 537 718 ;
+C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ;
+C -1 ; WX 549 ; N lessequal ; B 26 0 523 674 ;
+C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ;
+C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ;
+C -1 ; WX 722 ; N Uhungarumlaut ; B 79 -19 644 929 ;
+C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ;
+C -1 ; WX 556 ; N emacron ; B 40 -15 516 684 ;
+C -1 ; WX 556 ; N gbreve ; B 40 -220 499 731 ;
+C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ;
+C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ;
+C -1 ; WX 667 ; N Scommaaccent ; B 49 -225 620 737 ;
+C -1 ; WX 778 ; N Ohungarumlaut ; B 39 -19 739 929 ;
+C -1 ; WX 400 ; N degree ; B 54 411 346 703 ;
+C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ;
+C -1 ; WX 722 ; N Ccaron ; B 44 -19 681 929 ;
+C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ;
+C -1 ; WX 453 ; N radical ; B -4 -80 458 762 ;
+C -1 ; WX 722 ; N Dcaron ; B 81 0 674 929 ;
+C -1 ; WX 333 ; N rcommaaccent ; B 77 -225 332 538 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ;
+C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ;
+C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 684 718 ;
+C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 537 718 ;
+C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ;
+C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ;
+C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
+C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ;
+C -1 ; WX 500 ; N zdotaccent ; B 31 0 469 706 ;
+C -1 ; WX 667 ; N Ecaron ; B 86 0 616 929 ;
+C -1 ; WX 278 ; N Iogonek ; B -3 -225 211 718 ;
+C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 501 718 ;
+C -1 ; WX 584 ; N minus ; B 39 216 545 289 ;
+C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ;
+C -1 ; WX 556 ; N ncaron ; B 65 0 491 734 ;
+C -1 ; WX 278 ; N tcommaaccent ; B 14 -225 257 669 ;
+C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ;
+C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ;
+C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ;
+C -1 ; WX 549 ; N notequal ; B 12 -35 537 551 ;
+C -1 ; WX 556 ; N gcommaaccent ; B 40 -220 499 822 ;
+C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ;
+C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 491 538 ;
+C -1 ; WX 333 ; N onebaseior ; B 43 281 222 703 ;
+C -1 ; WX 278 ; N imacron ; B 5 0 272 684 ;
+C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 2705
+KPX A C -30
+KPX A Cacute -30
+KPX A Ccaron -30
+KPX A Ccedilla -30
+KPX A G -30
+KPX A Gbreve -30
+KPX A Gcommaaccent -30
+KPX A O -30
+KPX A Oacute -30
+KPX A Ocircumflex -30
+KPX A Odieresis -30
+KPX A Ograve -30
+KPX A Ohungarumlaut -30
+KPX A Omacron -30
+KPX A Oslash -30
+KPX A Otilde -30
+KPX A Q -30
+KPX A T -120
+KPX A Tcaron -120
+KPX A Tcommaaccent -120
+KPX A U -50
+KPX A Uacute -50
+KPX A Ucircumflex -50
+KPX A Udieresis -50
+KPX A Ugrave -50
+KPX A Uhungarumlaut -50
+KPX A Umacron -50
+KPX A Uogonek -50
+KPX A Uring -50
+KPX A V -70
+KPX A W -50
+KPX A Y -100
+KPX A Yacute -100
+KPX A Ydieresis -100
+KPX A u -30
+KPX A uacute -30
+KPX A ucircumflex -30
+KPX A udieresis -30
+KPX A ugrave -30
+KPX A uhungarumlaut -30
+KPX A umacron -30
+KPX A uogonek -30
+KPX A uring -30
+KPX A v -40
+KPX A w -40
+KPX A y -40
+KPX A yacute -40
+KPX A ydieresis -40
+KPX Aacute C -30
+KPX Aacute Cacute -30
+KPX Aacute Ccaron -30
+KPX Aacute Ccedilla -30
+KPX Aacute G -30
+KPX Aacute Gbreve -30
+KPX Aacute Gcommaaccent -30
+KPX Aacute O -30
+KPX Aacute Oacute -30
+KPX Aacute Ocircumflex -30
+KPX Aacute Odieresis -30
+KPX Aacute Ograve -30
+KPX Aacute Ohungarumlaut -30
+KPX Aacute Omacron -30
+KPX Aacute Oslash -30
+KPX Aacute Otilde -30
+KPX Aacute Q -30
+KPX Aacute T -120
+KPX Aacute Tcaron -120
+KPX Aacute Tcommaaccent -120
+KPX Aacute U -50
+KPX Aacute Uacute -50
+KPX Aacute Ucircumflex -50
+KPX Aacute Udieresis -50
+KPX Aacute Ugrave -50
+KPX Aacute Uhungarumlaut -50
+KPX Aacute Umacron -50
+KPX Aacute Uogonek -50
+KPX Aacute Uring -50
+KPX Aacute V -70
+KPX Aacute W -50
+KPX Aacute Y -100
+KPX Aacute Yacute -100
+KPX Aacute Ydieresis -100
+KPX Aacute u -30
+KPX Aacute uacute -30
+KPX Aacute ucircumflex -30
+KPX Aacute udieresis -30
+KPX Aacute ugrave -30
+KPX Aacute uhungarumlaut -30
+KPX Aacute umacron -30
+KPX Aacute uogonek -30
+KPX Aacute uring -30
+KPX Aacute v -40
+KPX Aacute w -40
+KPX Aacute y -40
+KPX Aacute yacute -40
+KPX Aacute ydieresis -40
+KPX Abreve C -30
+KPX Abreve Cacute -30
+KPX Abreve Ccaron -30
+KPX Abreve Ccedilla -30
+KPX Abreve G -30
+KPX Abreve Gbreve -30
+KPX Abreve Gcommaaccent -30
+KPX Abreve O -30
+KPX Abreve Oacute -30
+KPX Abreve Ocircumflex -30
+KPX Abreve Odieresis -30
+KPX Abreve Ograve -30
+KPX Abreve Ohungarumlaut -30
+KPX Abreve Omacron -30
+KPX Abreve Oslash -30
+KPX Abreve Otilde -30
+KPX Abreve Q -30
+KPX Abreve T -120
+KPX Abreve Tcaron -120
+KPX Abreve Tcommaaccent -120
+KPX Abreve U -50
+KPX Abreve Uacute -50
+KPX Abreve Ucircumflex -50
+KPX Abreve Udieresis -50
+KPX Abreve Ugrave -50
+KPX Abreve Uhungarumlaut -50
+KPX Abreve Umacron -50
+KPX Abreve Uogonek -50
+KPX Abreve Uring -50
+KPX Abreve V -70
+KPX Abreve W -50
+KPX Abreve Y -100
+KPX Abreve Yacute -100
+KPX Abreve Ydieresis -100
+KPX Abreve u -30
+KPX Abreve uacute -30
+KPX Abreve ucircumflex -30
+KPX Abreve udieresis -30
+KPX Abreve ugrave -30
+KPX Abreve uhungarumlaut -30
+KPX Abreve umacron -30
+KPX Abreve uogonek -30
+KPX Abreve uring -30
+KPX Abreve v -40
+KPX Abreve w -40
+KPX Abreve y -40
+KPX Abreve yacute -40
+KPX Abreve ydieresis -40
+KPX Acircumflex C -30
+KPX Acircumflex Cacute -30
+KPX Acircumflex Ccaron -30
+KPX Acircumflex Ccedilla -30
+KPX Acircumflex G -30
+KPX Acircumflex Gbreve -30
+KPX Acircumflex Gcommaaccent -30
+KPX Acircumflex O -30
+KPX Acircumflex Oacute -30
+KPX Acircumflex Ocircumflex -30
+KPX Acircumflex Odieresis -30
+KPX Acircumflex Ograve -30
+KPX Acircumflex Ohungarumlaut -30
+KPX Acircumflex Omacron -30
+KPX Acircumflex Oslash -30
+KPX Acircumflex Otilde -30
+KPX Acircumflex Q -30
+KPX Acircumflex T -120
+KPX Acircumflex Tcaron -120
+KPX Acircumflex Tcommaaccent -120
+KPX Acircumflex U -50
+KPX Acircumflex Uacute -50
+KPX Acircumflex Ucircumflex -50
+KPX Acircumflex Udieresis -50
+KPX Acircumflex Ugrave -50
+KPX Acircumflex Uhungarumlaut -50
+KPX Acircumflex Umacron -50
+KPX Acircumflex Uogonek -50
+KPX Acircumflex Uring -50
+KPX Acircumflex V -70
+KPX Acircumflex W -50
+KPX Acircumflex Y -100
+KPX Acircumflex Yacute -100
+KPX Acircumflex Ydieresis -100
+KPX Acircumflex u -30
+KPX Acircumflex uacute -30
+KPX Acircumflex ucircumflex -30
+KPX Acircumflex udieresis -30
+KPX Acircumflex ugrave -30
+KPX Acircumflex uhungarumlaut -30
+KPX Acircumflex umacron -30
+KPX Acircumflex uogonek -30
+KPX Acircumflex uring -30
+KPX Acircumflex v -40
+KPX Acircumflex w -40
+KPX Acircumflex y -40
+KPX Acircumflex yacute -40
+KPX Acircumflex ydieresis -40
+KPX Adieresis C -30
+KPX Adieresis Cacute -30
+KPX Adieresis Ccaron -30
+KPX Adieresis Ccedilla -30
+KPX Adieresis G -30
+KPX Adieresis Gbreve -30
+KPX Adieresis Gcommaaccent -30
+KPX Adieresis O -30
+KPX Adieresis Oacute -30
+KPX Adieresis Ocircumflex -30
+KPX Adieresis Odieresis -30
+KPX Adieresis Ograve -30
+KPX Adieresis Ohungarumlaut -30
+KPX Adieresis Omacron -30
+KPX Adieresis Oslash -30
+KPX Adieresis Otilde -30
+KPX Adieresis Q -30
+KPX Adieresis T -120
+KPX Adieresis Tcaron -120
+KPX Adieresis Tcommaaccent -120
+KPX Adieresis U -50
+KPX Adieresis Uacute -50
+KPX Adieresis Ucircumflex -50
+KPX Adieresis Udieresis -50
+KPX Adieresis Ugrave -50
+KPX Adieresis Uhungarumlaut -50
+KPX Adieresis Umacron -50
+KPX Adieresis Uogonek -50
+KPX Adieresis Uring -50
+KPX Adieresis V -70
+KPX Adieresis W -50
+KPX Adieresis Y -100
+KPX Adieresis Yacute -100
+KPX Adieresis Ydieresis -100
+KPX Adieresis u -30
+KPX Adieresis uacute -30
+KPX Adieresis ucircumflex -30
+KPX Adieresis udieresis -30
+KPX Adieresis ugrave -30
+KPX Adieresis uhungarumlaut -30
+KPX Adieresis umacron -30
+KPX Adieresis uogonek -30
+KPX Adieresis uring -30
+KPX Adieresis v -40
+KPX Adieresis w -40
+KPX Adieresis y -40
+KPX Adieresis yacute -40
+KPX Adieresis ydieresis -40
+KPX Agrave C -30
+KPX Agrave Cacute -30
+KPX Agrave Ccaron -30
+KPX Agrave Ccedilla -30
+KPX Agrave G -30
+KPX Agrave Gbreve -30
+KPX Agrave Gcommaaccent -30
+KPX Agrave O -30
+KPX Agrave Oacute -30
+KPX Agrave Ocircumflex -30
+KPX Agrave Odieresis -30
+KPX Agrave Ograve -30
+KPX Agrave Ohungarumlaut -30
+KPX Agrave Omacron -30
+KPX Agrave Oslash -30
+KPX Agrave Otilde -30
+KPX Agrave Q -30
+KPX Agrave T -120
+KPX Agrave Tcaron -120
+KPX Agrave Tcommaaccent -120
+KPX Agrave U -50
+KPX Agrave Uacute -50
+KPX Agrave Ucircumflex -50
+KPX Agrave Udieresis -50
+KPX Agrave Ugrave -50
+KPX Agrave Uhungarumlaut -50
+KPX Agrave Umacron -50
+KPX Agrave Uogonek -50
+KPX Agrave Uring -50
+KPX Agrave V -70
+KPX Agrave W -50
+KPX Agrave Y -100
+KPX Agrave Yacute -100
+KPX Agrave Ydieresis -100
+KPX Agrave u -30
+KPX Agrave uacute -30
+KPX Agrave ucircumflex -30
+KPX Agrave udieresis -30
+KPX Agrave ugrave -30
+KPX Agrave uhungarumlaut -30
+KPX Agrave umacron -30
+KPX Agrave uogonek -30
+KPX Agrave uring -30
+KPX Agrave v -40
+KPX Agrave w -40
+KPX Agrave y -40
+KPX Agrave yacute -40
+KPX Agrave ydieresis -40
+KPX Amacron C -30
+KPX Amacron Cacute -30
+KPX Amacron Ccaron -30
+KPX Amacron Ccedilla -30
+KPX Amacron G -30
+KPX Amacron Gbreve -30
+KPX Amacron Gcommaaccent -30
+KPX Amacron O -30
+KPX Amacron Oacute -30
+KPX Amacron Ocircumflex -30
+KPX Amacron Odieresis -30
+KPX Amacron Ograve -30
+KPX Amacron Ohungarumlaut -30
+KPX Amacron Omacron -30
+KPX Amacron Oslash -30
+KPX Amacron Otilde -30
+KPX Amacron Q -30
+KPX Amacron T -120
+KPX Amacron Tcaron -120
+KPX Amacron Tcommaaccent -120
+KPX Amacron U -50
+KPX Amacron Uacute -50
+KPX Amacron Ucircumflex -50
+KPX Amacron Udieresis -50
+KPX Amacron Ugrave -50
+KPX Amacron Uhungarumlaut -50
+KPX Amacron Umacron -50
+KPX Amacron Uogonek -50
+KPX Amacron Uring -50
+KPX Amacron V -70
+KPX Amacron W -50
+KPX Amacron Y -100
+KPX Amacron Yacute -100
+KPX Amacron Ydieresis -100
+KPX Amacron u -30
+KPX Amacron uacute -30
+KPX Amacron ucircumflex -30
+KPX Amacron udieresis -30
+KPX Amacron ugrave -30
+KPX Amacron uhungarumlaut -30
+KPX Amacron umacron -30
+KPX Amacron uogonek -30
+KPX Amacron uring -30
+KPX Amacron v -40
+KPX Amacron w -40
+KPX Amacron y -40
+KPX Amacron yacute -40
+KPX Amacron ydieresis -40
+KPX Aogonek C -30
+KPX Aogonek Cacute -30
+KPX Aogonek Ccaron -30
+KPX Aogonek Ccedilla -30
+KPX Aogonek G -30
+KPX Aogonek Gbreve -30
+KPX Aogonek Gcommaaccent -30
+KPX Aogonek O -30
+KPX Aogonek Oacute -30
+KPX Aogonek Ocircumflex -30
+KPX Aogonek Odieresis -30
+KPX Aogonek Ograve -30
+KPX Aogonek Ohungarumlaut -30
+KPX Aogonek Omacron -30
+KPX Aogonek Oslash -30
+KPX Aogonek Otilde -30
+KPX Aogonek Q -30
+KPX Aogonek T -120
+KPX Aogonek Tcaron -120
+KPX Aogonek Tcommaaccent -120
+KPX Aogonek U -50
+KPX Aogonek Uacute -50
+KPX Aogonek Ucircumflex -50
+KPX Aogonek Udieresis -50
+KPX Aogonek Ugrave -50
+KPX Aogonek Uhungarumlaut -50
+KPX Aogonek Umacron -50
+KPX Aogonek Uogonek -50
+KPX Aogonek Uring -50
+KPX Aogonek V -70
+KPX Aogonek W -50
+KPX Aogonek Y -100
+KPX Aogonek Yacute -100
+KPX Aogonek Ydieresis -100
+KPX Aogonek u -30
+KPX Aogonek uacute -30
+KPX Aogonek ucircumflex -30
+KPX Aogonek udieresis -30
+KPX Aogonek ugrave -30
+KPX Aogonek uhungarumlaut -30
+KPX Aogonek umacron -30
+KPX Aogonek uogonek -30
+KPX Aogonek uring -30
+KPX Aogonek v -40
+KPX Aogonek w -40
+KPX Aogonek y -40
+KPX Aogonek yacute -40
+KPX Aogonek ydieresis -40
+KPX Aring C -30
+KPX Aring Cacute -30
+KPX Aring Ccaron -30
+KPX Aring Ccedilla -30
+KPX Aring G -30
+KPX Aring Gbreve -30
+KPX Aring Gcommaaccent -30
+KPX Aring O -30
+KPX Aring Oacute -30
+KPX Aring Ocircumflex -30
+KPX Aring Odieresis -30
+KPX Aring Ograve -30
+KPX Aring Ohungarumlaut -30
+KPX Aring Omacron -30
+KPX Aring Oslash -30
+KPX Aring Otilde -30
+KPX Aring Q -30
+KPX Aring T -120
+KPX Aring Tcaron -120
+KPX Aring Tcommaaccent -120
+KPX Aring U -50
+KPX Aring Uacute -50
+KPX Aring Ucircumflex -50
+KPX Aring Udieresis -50
+KPX Aring Ugrave -50
+KPX Aring Uhungarumlaut -50
+KPX Aring Umacron -50
+KPX Aring Uogonek -50
+KPX Aring Uring -50
+KPX Aring V -70
+KPX Aring W -50
+KPX Aring Y -100
+KPX Aring Yacute -100
+KPX Aring Ydieresis -100
+KPX Aring u -30
+KPX Aring uacute -30
+KPX Aring ucircumflex -30
+KPX Aring udieresis -30
+KPX Aring ugrave -30
+KPX Aring uhungarumlaut -30
+KPX Aring umacron -30
+KPX Aring uogonek -30
+KPX Aring uring -30
+KPX Aring v -40
+KPX Aring w -40
+KPX Aring y -40
+KPX Aring yacute -40
+KPX Aring ydieresis -40
+KPX Atilde C -30
+KPX Atilde Cacute -30
+KPX Atilde Ccaron -30
+KPX Atilde Ccedilla -30
+KPX Atilde G -30
+KPX Atilde Gbreve -30
+KPX Atilde Gcommaaccent -30
+KPX Atilde O -30
+KPX Atilde Oacute -30
+KPX Atilde Ocircumflex -30
+KPX Atilde Odieresis -30
+KPX Atilde Ograve -30
+KPX Atilde Ohungarumlaut -30
+KPX Atilde Omacron -30
+KPX Atilde Oslash -30
+KPX Atilde Otilde -30
+KPX Atilde Q -30
+KPX Atilde T -120
+KPX Atilde Tcaron -120
+KPX Atilde Tcommaaccent -120
+KPX Atilde U -50
+KPX Atilde Uacute -50
+KPX Atilde Ucircumflex -50
+KPX Atilde Udieresis -50
+KPX Atilde Ugrave -50
+KPX Atilde Uhungarumlaut -50
+KPX Atilde Umacron -50
+KPX Atilde Uogonek -50
+KPX Atilde Uring -50
+KPX Atilde V -70
+KPX Atilde W -50
+KPX Atilde Y -100
+KPX Atilde Yacute -100
+KPX Atilde Ydieresis -100
+KPX Atilde u -30
+KPX Atilde uacute -30
+KPX Atilde ucircumflex -30
+KPX Atilde udieresis -30
+KPX Atilde ugrave -30
+KPX Atilde uhungarumlaut -30
+KPX Atilde umacron -30
+KPX Atilde uogonek -30
+KPX Atilde uring -30
+KPX Atilde v -40
+KPX Atilde w -40
+KPX Atilde y -40
+KPX Atilde yacute -40
+KPX Atilde ydieresis -40
+KPX B U -10
+KPX B Uacute -10
+KPX B Ucircumflex -10
+KPX B Udieresis -10
+KPX B Ugrave -10
+KPX B Uhungarumlaut -10
+KPX B Umacron -10
+KPX B Uogonek -10
+KPX B Uring -10
+KPX B comma -20
+KPX B period -20
+KPX C comma -30
+KPX C period -30
+KPX Cacute comma -30
+KPX Cacute period -30
+KPX Ccaron comma -30
+KPX Ccaron period -30
+KPX Ccedilla comma -30
+KPX Ccedilla period -30
+KPX D A -40
+KPX D Aacute -40
+KPX D Abreve -40
+KPX D Acircumflex -40
+KPX D Adieresis -40
+KPX D Agrave -40
+KPX D Amacron -40
+KPX D Aogonek -40
+KPX D Aring -40
+KPX D Atilde -40
+KPX D V -70
+KPX D W -40
+KPX D Y -90
+KPX D Yacute -90
+KPX D Ydieresis -90
+KPX D comma -70
+KPX D period -70
+KPX Dcaron A -40
+KPX Dcaron Aacute -40
+KPX Dcaron Abreve -40
+KPX Dcaron Acircumflex -40
+KPX Dcaron Adieresis -40
+KPX Dcaron Agrave -40
+KPX Dcaron Amacron -40
+KPX Dcaron Aogonek -40
+KPX Dcaron Aring -40
+KPX Dcaron Atilde -40
+KPX Dcaron V -70
+KPX Dcaron W -40
+KPX Dcaron Y -90
+KPX Dcaron Yacute -90
+KPX Dcaron Ydieresis -90
+KPX Dcaron comma -70
+KPX Dcaron period -70
+KPX Dcroat A -40
+KPX Dcroat Aacute -40
+KPX Dcroat Abreve -40
+KPX Dcroat Acircumflex -40
+KPX Dcroat Adieresis -40
+KPX Dcroat Agrave -40
+KPX Dcroat Amacron -40
+KPX Dcroat Aogonek -40
+KPX Dcroat Aring -40
+KPX Dcroat Atilde -40
+KPX Dcroat V -70
+KPX Dcroat W -40
+KPX Dcroat Y -90
+KPX Dcroat Yacute -90
+KPX Dcroat Ydieresis -90
+KPX Dcroat comma -70
+KPX Dcroat period -70
+KPX F A -80
+KPX F Aacute -80
+KPX F Abreve -80
+KPX F Acircumflex -80
+KPX F Adieresis -80
+KPX F Agrave -80
+KPX F Amacron -80
+KPX F Aogonek -80
+KPX F Aring -80
+KPX F Atilde -80
+KPX F a -50
+KPX F aacute -50
+KPX F abreve -50
+KPX F acircumflex -50
+KPX F adieresis -50
+KPX F agrave -50
+KPX F amacron -50
+KPX F aogonek -50
+KPX F aring -50
+KPX F atilde -50
+KPX F comma -150
+KPX F e -30
+KPX F eacute -30
+KPX F ecaron -30
+KPX F ecircumflex -30
+KPX F edieresis -30
+KPX F edotaccent -30
+KPX F egrave -30
+KPX F emacron -30
+KPX F eogonek -30
+KPX F o -30
+KPX F oacute -30
+KPX F ocircumflex -30
+KPX F odieresis -30
+KPX F ograve -30
+KPX F ohungarumlaut -30
+KPX F omacron -30
+KPX F oslash -30
+KPX F otilde -30
+KPX F period -150
+KPX F r -45
+KPX F racute -45
+KPX F rcaron -45
+KPX F rcommaaccent -45
+KPX J A -20
+KPX J Aacute -20
+KPX J Abreve -20
+KPX J Acircumflex -20
+KPX J Adieresis -20
+KPX J Agrave -20
+KPX J Amacron -20
+KPX J Aogonek -20
+KPX J Aring -20
+KPX J Atilde -20
+KPX J a -20
+KPX J aacute -20
+KPX J abreve -20
+KPX J acircumflex -20
+KPX J adieresis -20
+KPX J agrave -20
+KPX J amacron -20
+KPX J aogonek -20
+KPX J aring -20
+KPX J atilde -20
+KPX J comma -30
+KPX J period -30
+KPX J u -20
+KPX J uacute -20
+KPX J ucircumflex -20
+KPX J udieresis -20
+KPX J ugrave -20
+KPX J uhungarumlaut -20
+KPX J umacron -20
+KPX J uogonek -20
+KPX J uring -20
+KPX K O -50
+KPX K Oacute -50
+KPX K Ocircumflex -50
+KPX K Odieresis -50
+KPX K Ograve -50
+KPX K Ohungarumlaut -50
+KPX K Omacron -50
+KPX K Oslash -50
+KPX K Otilde -50
+KPX K e -40
+KPX K eacute -40
+KPX K ecaron -40
+KPX K ecircumflex -40
+KPX K edieresis -40
+KPX K edotaccent -40
+KPX K egrave -40
+KPX K emacron -40
+KPX K eogonek -40
+KPX K o -40
+KPX K oacute -40
+KPX K ocircumflex -40
+KPX K odieresis -40
+KPX K ograve -40
+KPX K ohungarumlaut -40
+KPX K omacron -40
+KPX K oslash -40
+KPX K otilde -40
+KPX K u -30
+KPX K uacute -30
+KPX K ucircumflex -30
+KPX K udieresis -30
+KPX K ugrave -30
+KPX K uhungarumlaut -30
+KPX K umacron -30
+KPX K uogonek -30
+KPX K uring -30
+KPX K y -50
+KPX K yacute -50
+KPX K ydieresis -50
+KPX Kcommaaccent O -50
+KPX Kcommaaccent Oacute -50
+KPX Kcommaaccent Ocircumflex -50
+KPX Kcommaaccent Odieresis -50
+KPX Kcommaaccent Ograve -50
+KPX Kcommaaccent Ohungarumlaut -50
+KPX Kcommaaccent Omacron -50
+KPX Kcommaaccent Oslash -50
+KPX Kcommaaccent Otilde -50
+KPX Kcommaaccent e -40
+KPX Kcommaaccent eacute -40
+KPX Kcommaaccent ecaron -40
+KPX Kcommaaccent ecircumflex -40
+KPX Kcommaaccent edieresis -40
+KPX Kcommaaccent edotaccent -40
+KPX Kcommaaccent egrave -40
+KPX Kcommaaccent emacron -40
+KPX Kcommaaccent eogonek -40
+KPX Kcommaaccent o -40
+KPX Kcommaaccent oacute -40
+KPX Kcommaaccent ocircumflex -40
+KPX Kcommaaccent odieresis -40
+KPX Kcommaaccent ograve -40
+KPX Kcommaaccent ohungarumlaut -40
+KPX Kcommaaccent omacron -40
+KPX Kcommaaccent oslash -40
+KPX Kcommaaccent otilde -40
+KPX Kcommaaccent u -30
+KPX Kcommaaccent uacute -30
+KPX Kcommaaccent ucircumflex -30
+KPX Kcommaaccent udieresis -30
+KPX Kcommaaccent ugrave -30
+KPX Kcommaaccent uhungarumlaut -30
+KPX Kcommaaccent umacron -30
+KPX Kcommaaccent uogonek -30
+KPX Kcommaaccent uring -30
+KPX Kcommaaccent y -50
+KPX Kcommaaccent yacute -50
+KPX Kcommaaccent ydieresis -50
+KPX L T -110
+KPX L Tcaron -110
+KPX L Tcommaaccent -110
+KPX L V -110
+KPX L W -70
+KPX L Y -140
+KPX L Yacute -140
+KPX L Ydieresis -140
+KPX L quotedblright -140
+KPX L quoteright -160
+KPX L y -30
+KPX L yacute -30
+KPX L ydieresis -30
+KPX Lacute T -110
+KPX Lacute Tcaron -110
+KPX Lacute Tcommaaccent -110
+KPX Lacute V -110
+KPX Lacute W -70
+KPX Lacute Y -140
+KPX Lacute Yacute -140
+KPX Lacute Ydieresis -140
+KPX Lacute quotedblright -140
+KPX Lacute quoteright -160
+KPX Lacute y -30
+KPX Lacute yacute -30
+KPX Lacute ydieresis -30
+KPX Lcaron T -110
+KPX Lcaron Tcaron -110
+KPX Lcaron Tcommaaccent -110
+KPX Lcaron V -110
+KPX Lcaron W -70
+KPX Lcaron Y -140
+KPX Lcaron Yacute -140
+KPX Lcaron Ydieresis -140
+KPX Lcaron quotedblright -140
+KPX Lcaron quoteright -160
+KPX Lcaron y -30
+KPX Lcaron yacute -30
+KPX Lcaron ydieresis -30
+KPX Lcommaaccent T -110
+KPX Lcommaaccent Tcaron -110
+KPX Lcommaaccent Tcommaaccent -110
+KPX Lcommaaccent V -110
+KPX Lcommaaccent W -70
+KPX Lcommaaccent Y -140
+KPX Lcommaaccent Yacute -140
+KPX Lcommaaccent Ydieresis -140
+KPX Lcommaaccent quotedblright -140
+KPX Lcommaaccent quoteright -160
+KPX Lcommaaccent y -30
+KPX Lcommaaccent yacute -30
+KPX Lcommaaccent ydieresis -30
+KPX Lslash T -110
+KPX Lslash Tcaron -110
+KPX Lslash Tcommaaccent -110
+KPX Lslash V -110
+KPX Lslash W -70
+KPX Lslash Y -140
+KPX Lslash Yacute -140
+KPX Lslash Ydieresis -140
+KPX Lslash quotedblright -140
+KPX Lslash quoteright -160
+KPX Lslash y -30
+KPX Lslash yacute -30
+KPX Lslash ydieresis -30
+KPX O A -20
+KPX O Aacute -20
+KPX O Abreve -20
+KPX O Acircumflex -20
+KPX O Adieresis -20
+KPX O Agrave -20
+KPX O Amacron -20
+KPX O Aogonek -20
+KPX O Aring -20
+KPX O Atilde -20
+KPX O T -40
+KPX O Tcaron -40
+KPX O Tcommaaccent -40
+KPX O V -50
+KPX O W -30
+KPX O X -60
+KPX O Y -70
+KPX O Yacute -70
+KPX O Ydieresis -70
+KPX O comma -40
+KPX O period -40
+KPX Oacute A -20
+KPX Oacute Aacute -20
+KPX Oacute Abreve -20
+KPX Oacute Acircumflex -20
+KPX Oacute Adieresis -20
+KPX Oacute Agrave -20
+KPX Oacute Amacron -20
+KPX Oacute Aogonek -20
+KPX Oacute Aring -20
+KPX Oacute Atilde -20
+KPX Oacute T -40
+KPX Oacute Tcaron -40
+KPX Oacute Tcommaaccent -40
+KPX Oacute V -50
+KPX Oacute W -30
+KPX Oacute X -60
+KPX Oacute Y -70
+KPX Oacute Yacute -70
+KPX Oacute Ydieresis -70
+KPX Oacute comma -40
+KPX Oacute period -40
+KPX Ocircumflex A -20
+KPX Ocircumflex Aacute -20
+KPX Ocircumflex Abreve -20
+KPX Ocircumflex Acircumflex -20
+KPX Ocircumflex Adieresis -20
+KPX Ocircumflex Agrave -20
+KPX Ocircumflex Amacron -20
+KPX Ocircumflex Aogonek -20
+KPX Ocircumflex Aring -20
+KPX Ocircumflex Atilde -20
+KPX Ocircumflex T -40
+KPX Ocircumflex Tcaron -40
+KPX Ocircumflex Tcommaaccent -40
+KPX Ocircumflex V -50
+KPX Ocircumflex W -30
+KPX Ocircumflex X -60
+KPX Ocircumflex Y -70
+KPX Ocircumflex Yacute -70
+KPX Ocircumflex Ydieresis -70
+KPX Ocircumflex comma -40
+KPX Ocircumflex period -40
+KPX Odieresis A -20
+KPX Odieresis Aacute -20
+KPX Odieresis Abreve -20
+KPX Odieresis Acircumflex -20
+KPX Odieresis Adieresis -20
+KPX Odieresis Agrave -20
+KPX Odieresis Amacron -20
+KPX Odieresis Aogonek -20
+KPX Odieresis Aring -20
+KPX Odieresis Atilde -20
+KPX Odieresis T -40
+KPX Odieresis Tcaron -40
+KPX Odieresis Tcommaaccent -40
+KPX Odieresis V -50
+KPX Odieresis W -30
+KPX Odieresis X -60
+KPX Odieresis Y -70
+KPX Odieresis Yacute -70
+KPX Odieresis Ydieresis -70
+KPX Odieresis comma -40
+KPX Odieresis period -40
+KPX Ograve A -20
+KPX Ograve Aacute -20
+KPX Ograve Abreve -20
+KPX Ograve Acircumflex -20
+KPX Ograve Adieresis -20
+KPX Ograve Agrave -20
+KPX Ograve Amacron -20
+KPX Ograve Aogonek -20
+KPX Ograve Aring -20
+KPX Ograve Atilde -20
+KPX Ograve T -40
+KPX Ograve Tcaron -40
+KPX Ograve Tcommaaccent -40
+KPX Ograve V -50
+KPX Ograve W -30
+KPX Ograve X -60
+KPX Ograve Y -70
+KPX Ograve Yacute -70
+KPX Ograve Ydieresis -70
+KPX Ograve comma -40
+KPX Ograve period -40
+KPX Ohungarumlaut A -20
+KPX Ohungarumlaut Aacute -20
+KPX Ohungarumlaut Abreve -20
+KPX Ohungarumlaut Acircumflex -20
+KPX Ohungarumlaut Adieresis -20
+KPX Ohungarumlaut Agrave -20
+KPX Ohungarumlaut Amacron -20
+KPX Ohungarumlaut Aogonek -20
+KPX Ohungarumlaut Aring -20
+KPX Ohungarumlaut Atilde -20
+KPX Ohungarumlaut T -40
+KPX Ohungarumlaut Tcaron -40
+KPX Ohungarumlaut Tcommaaccent -40
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut W -30
+KPX Ohungarumlaut X -60
+KPX Ohungarumlaut Y -70
+KPX Ohungarumlaut Yacute -70
+KPX Ohungarumlaut Ydieresis -70
+KPX Ohungarumlaut comma -40
+KPX Ohungarumlaut period -40
+KPX Omacron A -20
+KPX Omacron Aacute -20
+KPX Omacron Abreve -20
+KPX Omacron Acircumflex -20
+KPX Omacron Adieresis -20
+KPX Omacron Agrave -20
+KPX Omacron Amacron -20
+KPX Omacron Aogonek -20
+KPX Omacron Aring -20
+KPX Omacron Atilde -20
+KPX Omacron T -40
+KPX Omacron Tcaron -40
+KPX Omacron Tcommaaccent -40
+KPX Omacron V -50
+KPX Omacron W -30
+KPX Omacron X -60
+KPX Omacron Y -70
+KPX Omacron Yacute -70
+KPX Omacron Ydieresis -70
+KPX Omacron comma -40
+KPX Omacron period -40
+KPX Oslash A -20
+KPX Oslash Aacute -20
+KPX Oslash Abreve -20
+KPX Oslash Acircumflex -20
+KPX Oslash Adieresis -20
+KPX Oslash Agrave -20
+KPX Oslash Amacron -20
+KPX Oslash Aogonek -20
+KPX Oslash Aring -20
+KPX Oslash Atilde -20
+KPX Oslash T -40
+KPX Oslash Tcaron -40
+KPX Oslash Tcommaaccent -40
+KPX Oslash V -50
+KPX Oslash W -30
+KPX Oslash X -60
+KPX Oslash Y -70
+KPX Oslash Yacute -70
+KPX Oslash Ydieresis -70
+KPX Oslash comma -40
+KPX Oslash period -40
+KPX Otilde A -20
+KPX Otilde Aacute -20
+KPX Otilde Abreve -20
+KPX Otilde Acircumflex -20
+KPX Otilde Adieresis -20
+KPX Otilde Agrave -20
+KPX Otilde Amacron -20
+KPX Otilde Aogonek -20
+KPX Otilde Aring -20
+KPX Otilde Atilde -20
+KPX Otilde T -40
+KPX Otilde Tcaron -40
+KPX Otilde Tcommaaccent -40
+KPX Otilde V -50
+KPX Otilde W -30
+KPX Otilde X -60
+KPX Otilde Y -70
+KPX Otilde Yacute -70
+KPX Otilde Ydieresis -70
+KPX Otilde comma -40
+KPX Otilde period -40
+KPX P A -120
+KPX P Aacute -120
+KPX P Abreve -120
+KPX P Acircumflex -120
+KPX P Adieresis -120
+KPX P Agrave -120
+KPX P Amacron -120
+KPX P Aogonek -120
+KPX P Aring -120
+KPX P Atilde -120
+KPX P a -40
+KPX P aacute -40
+KPX P abreve -40
+KPX P acircumflex -40
+KPX P adieresis -40
+KPX P agrave -40
+KPX P amacron -40
+KPX P aogonek -40
+KPX P aring -40
+KPX P atilde -40
+KPX P comma -180
+KPX P e -50
+KPX P eacute -50
+KPX P ecaron -50
+KPX P ecircumflex -50
+KPX P edieresis -50
+KPX P edotaccent -50
+KPX P egrave -50
+KPX P emacron -50
+KPX P eogonek -50
+KPX P o -50
+KPX P oacute -50
+KPX P ocircumflex -50
+KPX P odieresis -50
+KPX P ograve -50
+KPX P ohungarumlaut -50
+KPX P omacron -50
+KPX P oslash -50
+KPX P otilde -50
+KPX P period -180
+KPX Q U -10
+KPX Q Uacute -10
+KPX Q Ucircumflex -10
+KPX Q Udieresis -10
+KPX Q Ugrave -10
+KPX Q Uhungarumlaut -10
+KPX Q Umacron -10
+KPX Q Uogonek -10
+KPX Q Uring -10
+KPX R O -20
+KPX R Oacute -20
+KPX R Ocircumflex -20
+KPX R Odieresis -20
+KPX R Ograve -20
+KPX R Ohungarumlaut -20
+KPX R Omacron -20
+KPX R Oslash -20
+KPX R Otilde -20
+KPX R T -30
+KPX R Tcaron -30
+KPX R Tcommaaccent -30
+KPX R U -40
+KPX R Uacute -40
+KPX R Ucircumflex -40
+KPX R Udieresis -40
+KPX R Ugrave -40
+KPX R Uhungarumlaut -40
+KPX R Umacron -40
+KPX R Uogonek -40
+KPX R Uring -40
+KPX R V -50
+KPX R W -30
+KPX R Y -50
+KPX R Yacute -50
+KPX R Ydieresis -50
+KPX Racute O -20
+KPX Racute Oacute -20
+KPX Racute Ocircumflex -20
+KPX Racute Odieresis -20
+KPX Racute Ograve -20
+KPX Racute Ohungarumlaut -20
+KPX Racute Omacron -20
+KPX Racute Oslash -20
+KPX Racute Otilde -20
+KPX Racute T -30
+KPX Racute Tcaron -30
+KPX Racute Tcommaaccent -30
+KPX Racute U -40
+KPX Racute Uacute -40
+KPX Racute Ucircumflex -40
+KPX Racute Udieresis -40
+KPX Racute Ugrave -40
+KPX Racute Uhungarumlaut -40
+KPX Racute Umacron -40
+KPX Racute Uogonek -40
+KPX Racute Uring -40
+KPX Racute V -50
+KPX Racute W -30
+KPX Racute Y -50
+KPX Racute Yacute -50
+KPX Racute Ydieresis -50
+KPX Rcaron O -20
+KPX Rcaron Oacute -20
+KPX Rcaron Ocircumflex -20
+KPX Rcaron Odieresis -20
+KPX Rcaron Ograve -20
+KPX Rcaron Ohungarumlaut -20
+KPX Rcaron Omacron -20
+KPX Rcaron Oslash -20
+KPX Rcaron Otilde -20
+KPX Rcaron T -30
+KPX Rcaron Tcaron -30
+KPX Rcaron Tcommaaccent -30
+KPX Rcaron U -40
+KPX Rcaron Uacute -40
+KPX Rcaron Ucircumflex -40
+KPX Rcaron Udieresis -40
+KPX Rcaron Ugrave -40
+KPX Rcaron Uhungarumlaut -40
+KPX Rcaron Umacron -40
+KPX Rcaron Uogonek -40
+KPX Rcaron Uring -40
+KPX Rcaron V -50
+KPX Rcaron W -30
+KPX Rcaron Y -50
+KPX Rcaron Yacute -50
+KPX Rcaron Ydieresis -50
+KPX Rcommaaccent O -20
+KPX Rcommaaccent Oacute -20
+KPX Rcommaaccent Ocircumflex -20
+KPX Rcommaaccent Odieresis -20
+KPX Rcommaaccent Ograve -20
+KPX Rcommaaccent Ohungarumlaut -20
+KPX Rcommaaccent Omacron -20
+KPX Rcommaaccent Oslash -20
+KPX Rcommaaccent Otilde -20
+KPX Rcommaaccent T -30
+KPX Rcommaaccent Tcaron -30
+KPX Rcommaaccent Tcommaaccent -30
+KPX Rcommaaccent U -40
+KPX Rcommaaccent Uacute -40
+KPX Rcommaaccent Ucircumflex -40
+KPX Rcommaaccent Udieresis -40
+KPX Rcommaaccent Ugrave -40
+KPX Rcommaaccent Uhungarumlaut -40
+KPX Rcommaaccent Umacron -40
+KPX Rcommaaccent Uogonek -40
+KPX Rcommaaccent Uring -40
+KPX Rcommaaccent V -50
+KPX Rcommaaccent W -30
+KPX Rcommaaccent Y -50
+KPX Rcommaaccent Yacute -50
+KPX Rcommaaccent Ydieresis -50
+KPX S comma -20
+KPX S period -20
+KPX Sacute comma -20
+KPX Sacute period -20
+KPX Scaron comma -20
+KPX Scaron period -20
+KPX Scedilla comma -20
+KPX Scedilla period -20
+KPX Scommaaccent comma -20
+KPX Scommaaccent period -20
+KPX T A -120
+KPX T Aacute -120
+KPX T Abreve -120
+KPX T Acircumflex -120
+KPX T Adieresis -120
+KPX T Agrave -120
+KPX T Amacron -120
+KPX T Aogonek -120
+KPX T Aring -120
+KPX T Atilde -120
+KPX T O -40
+KPX T Oacute -40
+KPX T Ocircumflex -40
+KPX T Odieresis -40
+KPX T Ograve -40
+KPX T Ohungarumlaut -40
+KPX T Omacron -40
+KPX T Oslash -40
+KPX T Otilde -40
+KPX T a -120
+KPX T aacute -120
+KPX T abreve -60
+KPX T acircumflex -120
+KPX T adieresis -120
+KPX T agrave -120
+KPX T amacron -60
+KPX T aogonek -120
+KPX T aring -120
+KPX T atilde -60
+KPX T colon -20
+KPX T comma -120
+KPX T e -120
+KPX T eacute -120
+KPX T ecaron -120
+KPX T ecircumflex -120
+KPX T edieresis -120
+KPX T edotaccent -120
+KPX T egrave -60
+KPX T emacron -60
+KPX T eogonek -120
+KPX T hyphen -140
+KPX T o -120
+KPX T oacute -120
+KPX T ocircumflex -120
+KPX T odieresis -120
+KPX T ograve -120
+KPX T ohungarumlaut -120
+KPX T omacron -60
+KPX T oslash -120
+KPX T otilde -60
+KPX T period -120
+KPX T r -120
+KPX T racute -120
+KPX T rcaron -120
+KPX T rcommaaccent -120
+KPX T semicolon -20
+KPX T u -120
+KPX T uacute -120
+KPX T ucircumflex -120
+KPX T udieresis -120
+KPX T ugrave -120
+KPX T uhungarumlaut -120
+KPX T umacron -60
+KPX T uogonek -120
+KPX T uring -120
+KPX T w -120
+KPX T y -120
+KPX T yacute -120
+KPX T ydieresis -60
+KPX Tcaron A -120
+KPX Tcaron Aacute -120
+KPX Tcaron Abreve -120
+KPX Tcaron Acircumflex -120
+KPX Tcaron Adieresis -120
+KPX Tcaron Agrave -120
+KPX Tcaron Amacron -120
+KPX Tcaron Aogonek -120
+KPX Tcaron Aring -120
+KPX Tcaron Atilde -120
+KPX Tcaron O -40
+KPX Tcaron Oacute -40
+KPX Tcaron Ocircumflex -40
+KPX Tcaron Odieresis -40
+KPX Tcaron Ograve -40
+KPX Tcaron Ohungarumlaut -40
+KPX Tcaron Omacron -40
+KPX Tcaron Oslash -40
+KPX Tcaron Otilde -40
+KPX Tcaron a -120
+KPX Tcaron aacute -120
+KPX Tcaron abreve -60
+KPX Tcaron acircumflex -120
+KPX Tcaron adieresis -120
+KPX Tcaron agrave -120
+KPX Tcaron amacron -60
+KPX Tcaron aogonek -120
+KPX Tcaron aring -120
+KPX Tcaron atilde -60
+KPX Tcaron colon -20
+KPX Tcaron comma -120
+KPX Tcaron e -120
+KPX Tcaron eacute -120
+KPX Tcaron ecaron -120
+KPX Tcaron ecircumflex -120
+KPX Tcaron edieresis -120
+KPX Tcaron edotaccent -120
+KPX Tcaron egrave -60
+KPX Tcaron emacron -60
+KPX Tcaron eogonek -120
+KPX Tcaron hyphen -140
+KPX Tcaron o -120
+KPX Tcaron oacute -120
+KPX Tcaron ocircumflex -120
+KPX Tcaron odieresis -120
+KPX Tcaron ograve -120
+KPX Tcaron ohungarumlaut -120
+KPX Tcaron omacron -60
+KPX Tcaron oslash -120
+KPX Tcaron otilde -60
+KPX Tcaron period -120
+KPX Tcaron r -120
+KPX Tcaron racute -120
+KPX Tcaron rcaron -120
+KPX Tcaron rcommaaccent -120
+KPX Tcaron semicolon -20
+KPX Tcaron u -120
+KPX Tcaron uacute -120
+KPX Tcaron ucircumflex -120
+KPX Tcaron udieresis -120
+KPX Tcaron ugrave -120
+KPX Tcaron uhungarumlaut -120
+KPX Tcaron umacron -60
+KPX Tcaron uogonek -120
+KPX Tcaron uring -120
+KPX Tcaron w -120
+KPX Tcaron y -120
+KPX Tcaron yacute -120
+KPX Tcaron ydieresis -60
+KPX Tcommaaccent A -120
+KPX Tcommaaccent Aacute -120
+KPX Tcommaaccent Abreve -120
+KPX Tcommaaccent Acircumflex -120
+KPX Tcommaaccent Adieresis -120
+KPX Tcommaaccent Agrave -120
+KPX Tcommaaccent Amacron -120
+KPX Tcommaaccent Aogonek -120
+KPX Tcommaaccent Aring -120
+KPX Tcommaaccent Atilde -120
+KPX Tcommaaccent O -40
+KPX Tcommaaccent Oacute -40
+KPX Tcommaaccent Ocircumflex -40
+KPX Tcommaaccent Odieresis -40
+KPX Tcommaaccent Ograve -40
+KPX Tcommaaccent Ohungarumlaut -40
+KPX Tcommaaccent Omacron -40
+KPX Tcommaaccent Oslash -40
+KPX Tcommaaccent Otilde -40
+KPX Tcommaaccent a -120
+KPX Tcommaaccent aacute -120
+KPX Tcommaaccent abreve -60
+KPX Tcommaaccent acircumflex -120
+KPX Tcommaaccent adieresis -120
+KPX Tcommaaccent agrave -120
+KPX Tcommaaccent amacron -60
+KPX Tcommaaccent aogonek -120
+KPX Tcommaaccent aring -120
+KPX Tcommaaccent atilde -60
+KPX Tcommaaccent colon -20
+KPX Tcommaaccent comma -120
+KPX Tcommaaccent e -120
+KPX Tcommaaccent eacute -120
+KPX Tcommaaccent ecaron -120
+KPX Tcommaaccent ecircumflex -120
+KPX Tcommaaccent edieresis -120
+KPX Tcommaaccent edotaccent -120
+KPX Tcommaaccent egrave -60
+KPX Tcommaaccent emacron -60
+KPX Tcommaaccent eogonek -120
+KPX Tcommaaccent hyphen -140
+KPX Tcommaaccent o -120
+KPX Tcommaaccent oacute -120
+KPX Tcommaaccent ocircumflex -120
+KPX Tcommaaccent odieresis -120
+KPX Tcommaaccent ograve -120
+KPX Tcommaaccent ohungarumlaut -120
+KPX Tcommaaccent omacron -60
+KPX Tcommaaccent oslash -120
+KPX Tcommaaccent otilde -60
+KPX Tcommaaccent period -120
+KPX Tcommaaccent r -120
+KPX Tcommaaccent racute -120
+KPX Tcommaaccent rcaron -120
+KPX Tcommaaccent rcommaaccent -120
+KPX Tcommaaccent semicolon -20
+KPX Tcommaaccent u -120
+KPX Tcommaaccent uacute -120
+KPX Tcommaaccent ucircumflex -120
+KPX Tcommaaccent udieresis -120
+KPX Tcommaaccent ugrave -120
+KPX Tcommaaccent uhungarumlaut -120
+KPX Tcommaaccent umacron -60
+KPX Tcommaaccent uogonek -120
+KPX Tcommaaccent uring -120
+KPX Tcommaaccent w -120
+KPX Tcommaaccent y -120
+KPX Tcommaaccent yacute -120
+KPX Tcommaaccent ydieresis -60
+KPX U A -40
+KPX U Aacute -40
+KPX U Abreve -40
+KPX U Acircumflex -40
+KPX U Adieresis -40
+KPX U Agrave -40
+KPX U Amacron -40
+KPX U Aogonek -40
+KPX U Aring -40
+KPX U Atilde -40
+KPX U comma -40
+KPX U period -40
+KPX Uacute A -40
+KPX Uacute Aacute -40
+KPX Uacute Abreve -40
+KPX Uacute Acircumflex -40
+KPX Uacute Adieresis -40
+KPX Uacute Agrave -40
+KPX Uacute Amacron -40
+KPX Uacute Aogonek -40
+KPX Uacute Aring -40
+KPX Uacute Atilde -40
+KPX Uacute comma -40
+KPX Uacute period -40
+KPX Ucircumflex A -40
+KPX Ucircumflex Aacute -40
+KPX Ucircumflex Abreve -40
+KPX Ucircumflex Acircumflex -40
+KPX Ucircumflex Adieresis -40
+KPX Ucircumflex Agrave -40
+KPX Ucircumflex Amacron -40
+KPX Ucircumflex Aogonek -40
+KPX Ucircumflex Aring -40
+KPX Ucircumflex Atilde -40
+KPX Ucircumflex comma -40
+KPX Ucircumflex period -40
+KPX Udieresis A -40
+KPX Udieresis Aacute -40
+KPX Udieresis Abreve -40
+KPX Udieresis Acircumflex -40
+KPX Udieresis Adieresis -40
+KPX Udieresis Agrave -40
+KPX Udieresis Amacron -40
+KPX Udieresis Aogonek -40
+KPX Udieresis Aring -40
+KPX Udieresis Atilde -40
+KPX Udieresis comma -40
+KPX Udieresis period -40
+KPX Ugrave A -40
+KPX Ugrave Aacute -40
+KPX Ugrave Abreve -40
+KPX Ugrave Acircumflex -40
+KPX Ugrave Adieresis -40
+KPX Ugrave Agrave -40
+KPX Ugrave Amacron -40
+KPX Ugrave Aogonek -40
+KPX Ugrave Aring -40
+KPX Ugrave Atilde -40
+KPX Ugrave comma -40
+KPX Ugrave period -40
+KPX Uhungarumlaut A -40
+KPX Uhungarumlaut Aacute -40
+KPX Uhungarumlaut Abreve -40
+KPX Uhungarumlaut Acircumflex -40
+KPX Uhungarumlaut Adieresis -40
+KPX Uhungarumlaut Agrave -40
+KPX Uhungarumlaut Amacron -40
+KPX Uhungarumlaut Aogonek -40
+KPX Uhungarumlaut Aring -40
+KPX Uhungarumlaut Atilde -40
+KPX Uhungarumlaut comma -40
+KPX Uhungarumlaut period -40
+KPX Umacron A -40
+KPX Umacron Aacute -40
+KPX Umacron Abreve -40
+KPX Umacron Acircumflex -40
+KPX Umacron Adieresis -40
+KPX Umacron Agrave -40
+KPX Umacron Amacron -40
+KPX Umacron Aogonek -40
+KPX Umacron Aring -40
+KPX Umacron Atilde -40
+KPX Umacron comma -40
+KPX Umacron period -40
+KPX Uogonek A -40
+KPX Uogonek Aacute -40
+KPX Uogonek Abreve -40
+KPX Uogonek Acircumflex -40
+KPX Uogonek Adieresis -40
+KPX Uogonek Agrave -40
+KPX Uogonek Amacron -40
+KPX Uogonek Aogonek -40
+KPX Uogonek Aring -40
+KPX Uogonek Atilde -40
+KPX Uogonek comma -40
+KPX Uogonek period -40
+KPX Uring A -40
+KPX Uring Aacute -40
+KPX Uring Abreve -40
+KPX Uring Acircumflex -40
+KPX Uring Adieresis -40
+KPX Uring Agrave -40
+KPX Uring Amacron -40
+KPX Uring Aogonek -40
+KPX Uring Aring -40
+KPX Uring Atilde -40
+KPX Uring comma -40
+KPX Uring period -40
+KPX V A -80
+KPX V Aacute -80
+KPX V Abreve -80
+KPX V Acircumflex -80
+KPX V Adieresis -80
+KPX V Agrave -80
+KPX V Amacron -80
+KPX V Aogonek -80
+KPX V Aring -80
+KPX V Atilde -80
+KPX V G -40
+KPX V Gbreve -40
+KPX V Gcommaaccent -40
+KPX V O -40
+KPX V Oacute -40
+KPX V Ocircumflex -40
+KPX V Odieresis -40
+KPX V Ograve -40
+KPX V Ohungarumlaut -40
+KPX V Omacron -40
+KPX V Oslash -40
+KPX V Otilde -40
+KPX V a -70
+KPX V aacute -70
+KPX V abreve -70
+KPX V acircumflex -70
+KPX V adieresis -70
+KPX V agrave -70
+KPX V amacron -70
+KPX V aogonek -70
+KPX V aring -70
+KPX V atilde -70
+KPX V colon -40
+KPX V comma -125
+KPX V e -80
+KPX V eacute -80
+KPX V ecaron -80
+KPX V ecircumflex -80
+KPX V edieresis -80
+KPX V edotaccent -80
+KPX V egrave -80
+KPX V emacron -80
+KPX V eogonek -80
+KPX V hyphen -80
+KPX V o -80
+KPX V oacute -80
+KPX V ocircumflex -80
+KPX V odieresis -80
+KPX V ograve -80
+KPX V ohungarumlaut -80
+KPX V omacron -80
+KPX V oslash -80
+KPX V otilde -80
+KPX V period -125
+KPX V semicolon -40
+KPX V u -70
+KPX V uacute -70
+KPX V ucircumflex -70
+KPX V udieresis -70
+KPX V ugrave -70
+KPX V uhungarumlaut -70
+KPX V umacron -70
+KPX V uogonek -70
+KPX V uring -70
+KPX W A -50
+KPX W Aacute -50
+KPX W Abreve -50
+KPX W Acircumflex -50
+KPX W Adieresis -50
+KPX W Agrave -50
+KPX W Amacron -50
+KPX W Aogonek -50
+KPX W Aring -50
+KPX W Atilde -50
+KPX W O -20
+KPX W Oacute -20
+KPX W Ocircumflex -20
+KPX W Odieresis -20
+KPX W Ograve -20
+KPX W Ohungarumlaut -20
+KPX W Omacron -20
+KPX W Oslash -20
+KPX W Otilde -20
+KPX W a -40
+KPX W aacute -40
+KPX W abreve -40
+KPX W acircumflex -40
+KPX W adieresis -40
+KPX W agrave -40
+KPX W amacron -40
+KPX W aogonek -40
+KPX W aring -40
+KPX W atilde -40
+KPX W comma -80
+KPX W e -30
+KPX W eacute -30
+KPX W ecaron -30
+KPX W ecircumflex -30
+KPX W edieresis -30
+KPX W edotaccent -30
+KPX W egrave -30
+KPX W emacron -30
+KPX W eogonek -30
+KPX W hyphen -40
+KPX W o -30
+KPX W oacute -30
+KPX W ocircumflex -30
+KPX W odieresis -30
+KPX W ograve -30
+KPX W ohungarumlaut -30
+KPX W omacron -30
+KPX W oslash -30
+KPX W otilde -30
+KPX W period -80
+KPX W u -30
+KPX W uacute -30
+KPX W ucircumflex -30
+KPX W udieresis -30
+KPX W ugrave -30
+KPX W uhungarumlaut -30
+KPX W umacron -30
+KPX W uogonek -30
+KPX W uring -30
+KPX W y -20
+KPX W yacute -20
+KPX W ydieresis -20
+KPX Y A -110
+KPX Y Aacute -110
+KPX Y Abreve -110
+KPX Y Acircumflex -110
+KPX Y Adieresis -110
+KPX Y Agrave -110
+KPX Y Amacron -110
+KPX Y Aogonek -110
+KPX Y Aring -110
+KPX Y Atilde -110
+KPX Y O -85
+KPX Y Oacute -85
+KPX Y Ocircumflex -85
+KPX Y Odieresis -85
+KPX Y Ograve -85
+KPX Y Ohungarumlaut -85
+KPX Y Omacron -85
+KPX Y Oslash -85
+KPX Y Otilde -85
+KPX Y a -140
+KPX Y aacute -140
+KPX Y abreve -70
+KPX Y acircumflex -140
+KPX Y adieresis -140
+KPX Y agrave -140
+KPX Y amacron -70
+KPX Y aogonek -140
+KPX Y aring -140
+KPX Y atilde -140
+KPX Y colon -60
+KPX Y comma -140
+KPX Y e -140
+KPX Y eacute -140
+KPX Y ecaron -140
+KPX Y ecircumflex -140
+KPX Y edieresis -140
+KPX Y edotaccent -140
+KPX Y egrave -140
+KPX Y emacron -70
+KPX Y eogonek -140
+KPX Y hyphen -140
+KPX Y i -20
+KPX Y iacute -20
+KPX Y iogonek -20
+KPX Y o -140
+KPX Y oacute -140
+KPX Y ocircumflex -140
+KPX Y odieresis -140
+KPX Y ograve -140
+KPX Y ohungarumlaut -140
+KPX Y omacron -140
+KPX Y oslash -140
+KPX Y otilde -140
+KPX Y period -140
+KPX Y semicolon -60
+KPX Y u -110
+KPX Y uacute -110
+KPX Y ucircumflex -110
+KPX Y udieresis -110
+KPX Y ugrave -110
+KPX Y uhungarumlaut -110
+KPX Y umacron -110
+KPX Y uogonek -110
+KPX Y uring -110
+KPX Yacute A -110
+KPX Yacute Aacute -110
+KPX Yacute Abreve -110
+KPX Yacute Acircumflex -110
+KPX Yacute Adieresis -110
+KPX Yacute Agrave -110
+KPX Yacute Amacron -110
+KPX Yacute Aogonek -110
+KPX Yacute Aring -110
+KPX Yacute Atilde -110
+KPX Yacute O -85
+KPX Yacute Oacute -85
+KPX Yacute Ocircumflex -85
+KPX Yacute Odieresis -85
+KPX Yacute Ograve -85
+KPX Yacute Ohungarumlaut -85
+KPX Yacute Omacron -85
+KPX Yacute Oslash -85
+KPX Yacute Otilde -85
+KPX Yacute a -140
+KPX Yacute aacute -140
+KPX Yacute abreve -70
+KPX Yacute acircumflex -140
+KPX Yacute adieresis -140
+KPX Yacute agrave -140
+KPX Yacute amacron -70
+KPX Yacute aogonek -140
+KPX Yacute aring -140
+KPX Yacute atilde -70
+KPX Yacute colon -60
+KPX Yacute comma -140
+KPX Yacute e -140
+KPX Yacute eacute -140
+KPX Yacute ecaron -140
+KPX Yacute ecircumflex -140
+KPX Yacute edieresis -140
+KPX Yacute edotaccent -140
+KPX Yacute egrave -140
+KPX Yacute emacron -70
+KPX Yacute eogonek -140
+KPX Yacute hyphen -140
+KPX Yacute i -20
+KPX Yacute iacute -20
+KPX Yacute iogonek -20
+KPX Yacute o -140
+KPX Yacute oacute -140
+KPX Yacute ocircumflex -140
+KPX Yacute odieresis -140
+KPX Yacute ograve -140
+KPX Yacute ohungarumlaut -140
+KPX Yacute omacron -70
+KPX Yacute oslash -140
+KPX Yacute otilde -140
+KPX Yacute period -140
+KPX Yacute semicolon -60
+KPX Yacute u -110
+KPX Yacute uacute -110
+KPX Yacute ucircumflex -110
+KPX Yacute udieresis -110
+KPX Yacute ugrave -110
+KPX Yacute uhungarumlaut -110
+KPX Yacute umacron -110
+KPX Yacute uogonek -110
+KPX Yacute uring -110
+KPX Ydieresis A -110
+KPX Ydieresis Aacute -110
+KPX Ydieresis Abreve -110
+KPX Ydieresis Acircumflex -110
+KPX Ydieresis Adieresis -110
+KPX Ydieresis Agrave -110
+KPX Ydieresis Amacron -110
+KPX Ydieresis Aogonek -110
+KPX Ydieresis Aring -110
+KPX Ydieresis Atilde -110
+KPX Ydieresis O -85
+KPX Ydieresis Oacute -85
+KPX Ydieresis Ocircumflex -85
+KPX Ydieresis Odieresis -85
+KPX Ydieresis Ograve -85
+KPX Ydieresis Ohungarumlaut -85
+KPX Ydieresis Omacron -85
+KPX Ydieresis Oslash -85
+KPX Ydieresis Otilde -85
+KPX Ydieresis a -140
+KPX Ydieresis aacute -140
+KPX Ydieresis abreve -70
+KPX Ydieresis acircumflex -140
+KPX Ydieresis adieresis -140
+KPX Ydieresis agrave -140
+KPX Ydieresis amacron -70
+KPX Ydieresis aogonek -140
+KPX Ydieresis aring -140
+KPX Ydieresis atilde -70
+KPX Ydieresis colon -60
+KPX Ydieresis comma -140
+KPX Ydieresis e -140
+KPX Ydieresis eacute -140
+KPX Ydieresis ecaron -140
+KPX Ydieresis ecircumflex -140
+KPX Ydieresis edieresis -140
+KPX Ydieresis edotaccent -140
+KPX Ydieresis egrave -140
+KPX Ydieresis emacron -70
+KPX Ydieresis eogonek -140
+KPX Ydieresis hyphen -140
+KPX Ydieresis i -20
+KPX Ydieresis iacute -20
+KPX Ydieresis iogonek -20
+KPX Ydieresis o -140
+KPX Ydieresis oacute -140
+KPX Ydieresis ocircumflex -140
+KPX Ydieresis odieresis -140
+KPX Ydieresis ograve -140
+KPX Ydieresis ohungarumlaut -140
+KPX Ydieresis omacron -140
+KPX Ydieresis oslash -140
+KPX Ydieresis otilde -140
+KPX Ydieresis period -140
+KPX Ydieresis semicolon -60
+KPX Ydieresis u -110
+KPX Ydieresis uacute -110
+KPX Ydieresis ucircumflex -110
+KPX Ydieresis udieresis -110
+KPX Ydieresis ugrave -110
+KPX Ydieresis uhungarumlaut -110
+KPX Ydieresis umacron -110
+KPX Ydieresis uogonek -110
+KPX Ydieresis uring -110
+KPX a v -20
+KPX a w -20
+KPX a y -30
+KPX a yacute -30
+KPX a ydieresis -30
+KPX aacute v -20
+KPX aacute w -20
+KPX aacute y -30
+KPX aacute yacute -30
+KPX aacute ydieresis -30
+KPX abreve v -20
+KPX abreve w -20
+KPX abreve y -30
+KPX abreve yacute -30
+KPX abreve ydieresis -30
+KPX acircumflex v -20
+KPX acircumflex w -20
+KPX acircumflex y -30
+KPX acircumflex yacute -30
+KPX acircumflex ydieresis -30
+KPX adieresis v -20
+KPX adieresis w -20
+KPX adieresis y -30
+KPX adieresis yacute -30
+KPX adieresis ydieresis -30
+KPX agrave v -20
+KPX agrave w -20
+KPX agrave y -30
+KPX agrave yacute -30
+KPX agrave ydieresis -30
+KPX amacron v -20
+KPX amacron w -20
+KPX amacron y -30
+KPX amacron yacute -30
+KPX amacron ydieresis -30
+KPX aogonek v -20
+KPX aogonek w -20
+KPX aogonek y -30
+KPX aogonek yacute -30
+KPX aogonek ydieresis -30
+KPX aring v -20
+KPX aring w -20
+KPX aring y -30
+KPX aring yacute -30
+KPX aring ydieresis -30
+KPX atilde v -20
+KPX atilde w -20
+KPX atilde y -30
+KPX atilde yacute -30
+KPX atilde ydieresis -30
+KPX b b -10
+KPX b comma -40
+KPX b l -20
+KPX b lacute -20
+KPX b lcommaaccent -20
+KPX b lslash -20
+KPX b period -40
+KPX b u -20
+KPX b uacute -20
+KPX b ucircumflex -20
+KPX b udieresis -20
+KPX b ugrave -20
+KPX b uhungarumlaut -20
+KPX b umacron -20
+KPX b uogonek -20
+KPX b uring -20
+KPX b v -20
+KPX b y -20
+KPX b yacute -20
+KPX b ydieresis -20
+KPX c comma -15
+KPX c k -20
+KPX c kcommaaccent -20
+KPX cacute comma -15
+KPX cacute k -20
+KPX cacute kcommaaccent -20
+KPX ccaron comma -15
+KPX ccaron k -20
+KPX ccaron kcommaaccent -20
+KPX ccedilla comma -15
+KPX ccedilla k -20
+KPX ccedilla kcommaaccent -20
+KPX colon space -50
+KPX comma quotedblright -100
+KPX comma quoteright -100
+KPX e comma -15
+KPX e period -15
+KPX e v -30
+KPX e w -20
+KPX e x -30
+KPX e y -20
+KPX e yacute -20
+KPX e ydieresis -20
+KPX eacute comma -15
+KPX eacute period -15
+KPX eacute v -30
+KPX eacute w -20
+KPX eacute x -30
+KPX eacute y -20
+KPX eacute yacute -20
+KPX eacute ydieresis -20
+KPX ecaron comma -15
+KPX ecaron period -15
+KPX ecaron v -30
+KPX ecaron w -20
+KPX ecaron x -30
+KPX ecaron y -20
+KPX ecaron yacute -20
+KPX ecaron ydieresis -20
+KPX ecircumflex comma -15
+KPX ecircumflex period -15
+KPX ecircumflex v -30
+KPX ecircumflex w -20
+KPX ecircumflex x -30
+KPX ecircumflex y -20
+KPX ecircumflex yacute -20
+KPX ecircumflex ydieresis -20
+KPX edieresis comma -15
+KPX edieresis period -15
+KPX edieresis v -30
+KPX edieresis w -20
+KPX edieresis x -30
+KPX edieresis y -20
+KPX edieresis yacute -20
+KPX edieresis ydieresis -20
+KPX edotaccent comma -15
+KPX edotaccent period -15
+KPX edotaccent v -30
+KPX edotaccent w -20
+KPX edotaccent x -30
+KPX edotaccent y -20
+KPX edotaccent yacute -20
+KPX edotaccent ydieresis -20
+KPX egrave comma -15
+KPX egrave period -15
+KPX egrave v -30
+KPX egrave w -20
+KPX egrave x -30
+KPX egrave y -20
+KPX egrave yacute -20
+KPX egrave ydieresis -20
+KPX emacron comma -15
+KPX emacron period -15
+KPX emacron v -30
+KPX emacron w -20
+KPX emacron x -30
+KPX emacron y -20
+KPX emacron yacute -20
+KPX emacron ydieresis -20
+KPX eogonek comma -15
+KPX eogonek period -15
+KPX eogonek v -30
+KPX eogonek w -20
+KPX eogonek x -30
+KPX eogonek y -20
+KPX eogonek yacute -20
+KPX eogonek ydieresis -20
+KPX f a -30
+KPX f aacute -30
+KPX f abreve -30
+KPX f acircumflex -30
+KPX f adieresis -30
+KPX f agrave -30
+KPX f amacron -30
+KPX f aogonek -30
+KPX f aring -30
+KPX f atilde -30
+KPX f comma -30
+KPX f dotlessi -28
+KPX f e -30
+KPX f eacute -30
+KPX f ecaron -30
+KPX f ecircumflex -30
+KPX f edieresis -30
+KPX f edotaccent -30
+KPX f egrave -30
+KPX f emacron -30
+KPX f eogonek -30
+KPX f o -30
+KPX f oacute -30
+KPX f ocircumflex -30
+KPX f odieresis -30
+KPX f ograve -30
+KPX f ohungarumlaut -30
+KPX f omacron -30
+KPX f oslash -30
+KPX f otilde -30
+KPX f period -30
+KPX f quotedblright 60
+KPX f quoteright 50
+KPX g r -10
+KPX g racute -10
+KPX g rcaron -10
+KPX g rcommaaccent -10
+KPX gbreve r -10
+KPX gbreve racute -10
+KPX gbreve rcaron -10
+KPX gbreve rcommaaccent -10
+KPX gcommaaccent r -10
+KPX gcommaaccent racute -10
+KPX gcommaaccent rcaron -10
+KPX gcommaaccent rcommaaccent -10
+KPX h y -30
+KPX h yacute -30
+KPX h ydieresis -30
+KPX k e -20
+KPX k eacute -20
+KPX k ecaron -20
+KPX k ecircumflex -20
+KPX k edieresis -20
+KPX k edotaccent -20
+KPX k egrave -20
+KPX k emacron -20
+KPX k eogonek -20
+KPX k o -20
+KPX k oacute -20
+KPX k ocircumflex -20
+KPX k odieresis -20
+KPX k ograve -20
+KPX k ohungarumlaut -20
+KPX k omacron -20
+KPX k oslash -20
+KPX k otilde -20
+KPX kcommaaccent e -20
+KPX kcommaaccent eacute -20
+KPX kcommaaccent ecaron -20
+KPX kcommaaccent ecircumflex -20
+KPX kcommaaccent edieresis -20
+KPX kcommaaccent edotaccent -20
+KPX kcommaaccent egrave -20
+KPX kcommaaccent emacron -20
+KPX kcommaaccent eogonek -20
+KPX kcommaaccent o -20
+KPX kcommaaccent oacute -20
+KPX kcommaaccent ocircumflex -20
+KPX kcommaaccent odieresis -20
+KPX kcommaaccent ograve -20
+KPX kcommaaccent ohungarumlaut -20
+KPX kcommaaccent omacron -20
+KPX kcommaaccent oslash -20
+KPX kcommaaccent otilde -20
+KPX m u -10
+KPX m uacute -10
+KPX m ucircumflex -10
+KPX m udieresis -10
+KPX m ugrave -10
+KPX m uhungarumlaut -10
+KPX m umacron -10
+KPX m uogonek -10
+KPX m uring -10
+KPX m y -15
+KPX m yacute -15
+KPX m ydieresis -15
+KPX n u -10
+KPX n uacute -10
+KPX n ucircumflex -10
+KPX n udieresis -10
+KPX n ugrave -10
+KPX n uhungarumlaut -10
+KPX n umacron -10
+KPX n uogonek -10
+KPX n uring -10
+KPX n v -20
+KPX n y -15
+KPX n yacute -15
+KPX n ydieresis -15
+KPX nacute u -10
+KPX nacute uacute -10
+KPX nacute ucircumflex -10
+KPX nacute udieresis -10
+KPX nacute ugrave -10
+KPX nacute uhungarumlaut -10
+KPX nacute umacron -10
+KPX nacute uogonek -10
+KPX nacute uring -10
+KPX nacute v -20
+KPX nacute y -15
+KPX nacute yacute -15
+KPX nacute ydieresis -15
+KPX ncaron u -10
+KPX ncaron uacute -10
+KPX ncaron ucircumflex -10
+KPX ncaron udieresis -10
+KPX ncaron ugrave -10
+KPX ncaron uhungarumlaut -10
+KPX ncaron umacron -10
+KPX ncaron uogonek -10
+KPX ncaron uring -10
+KPX ncaron v -20
+KPX ncaron y -15
+KPX ncaron yacute -15
+KPX ncaron ydieresis -15
+KPX ncommaaccent u -10
+KPX ncommaaccent uacute -10
+KPX ncommaaccent ucircumflex -10
+KPX ncommaaccent udieresis -10
+KPX ncommaaccent ugrave -10
+KPX ncommaaccent uhungarumlaut -10
+KPX ncommaaccent umacron -10
+KPX ncommaaccent uogonek -10
+KPX ncommaaccent uring -10
+KPX ncommaaccent v -20
+KPX ncommaaccent y -15
+KPX ncommaaccent yacute -15
+KPX ncommaaccent ydieresis -15
+KPX ntilde u -10
+KPX ntilde uacute -10
+KPX ntilde ucircumflex -10
+KPX ntilde udieresis -10
+KPX ntilde ugrave -10
+KPX ntilde uhungarumlaut -10
+KPX ntilde umacron -10
+KPX ntilde uogonek -10
+KPX ntilde uring -10
+KPX ntilde v -20
+KPX ntilde y -15
+KPX ntilde yacute -15
+KPX ntilde ydieresis -15
+KPX o comma -40
+KPX o period -40
+KPX o v -15
+KPX o w -15
+KPX o x -30
+KPX o y -30
+KPX o yacute -30
+KPX o ydieresis -30
+KPX oacute comma -40
+KPX oacute period -40
+KPX oacute v -15
+KPX oacute w -15
+KPX oacute x -30
+KPX oacute y -30
+KPX oacute yacute -30
+KPX oacute ydieresis -30
+KPX ocircumflex comma -40
+KPX ocircumflex period -40
+KPX ocircumflex v -15
+KPX ocircumflex w -15
+KPX ocircumflex x -30
+KPX ocircumflex y -30
+KPX ocircumflex yacute -30
+KPX ocircumflex ydieresis -30
+KPX odieresis comma -40
+KPX odieresis period -40
+KPX odieresis v -15
+KPX odieresis w -15
+KPX odieresis x -30
+KPX odieresis y -30
+KPX odieresis yacute -30
+KPX odieresis ydieresis -30
+KPX ograve comma -40
+KPX ograve period -40
+KPX ograve v -15
+KPX ograve w -15
+KPX ograve x -30
+KPX ograve y -30
+KPX ograve yacute -30
+KPX ograve ydieresis -30
+KPX ohungarumlaut comma -40
+KPX ohungarumlaut period -40
+KPX ohungarumlaut v -15
+KPX ohungarumlaut w -15
+KPX ohungarumlaut x -30
+KPX ohungarumlaut y -30
+KPX ohungarumlaut yacute -30
+KPX ohungarumlaut ydieresis -30
+KPX omacron comma -40
+KPX omacron period -40
+KPX omacron v -15
+KPX omacron w -15
+KPX omacron x -30
+KPX omacron y -30
+KPX omacron yacute -30
+KPX omacron ydieresis -30
+KPX oslash a -55
+KPX oslash aacute -55
+KPX oslash abreve -55
+KPX oslash acircumflex -55
+KPX oslash adieresis -55
+KPX oslash agrave -55
+KPX oslash amacron -55
+KPX oslash aogonek -55
+KPX oslash aring -55
+KPX oslash atilde -55
+KPX oslash b -55
+KPX oslash c -55
+KPX oslash cacute -55
+KPX oslash ccaron -55
+KPX oslash ccedilla -55
+KPX oslash comma -95
+KPX oslash d -55
+KPX oslash dcroat -55
+KPX oslash e -55
+KPX oslash eacute -55
+KPX oslash ecaron -55
+KPX oslash ecircumflex -55
+KPX oslash edieresis -55
+KPX oslash edotaccent -55
+KPX oslash egrave -55
+KPX oslash emacron -55
+KPX oslash eogonek -55
+KPX oslash f -55
+KPX oslash g -55
+KPX oslash gbreve -55
+KPX oslash gcommaaccent -55
+KPX oslash h -55
+KPX oslash i -55
+KPX oslash iacute -55
+KPX oslash icircumflex -55
+KPX oslash idieresis -55
+KPX oslash igrave -55
+KPX oslash imacron -55
+KPX oslash iogonek -55
+KPX oslash j -55
+KPX oslash k -55
+KPX oslash kcommaaccent -55
+KPX oslash l -55
+KPX oslash lacute -55
+KPX oslash lcommaaccent -55
+KPX oslash lslash -55
+KPX oslash m -55
+KPX oslash n -55
+KPX oslash nacute -55
+KPX oslash ncaron -55
+KPX oslash ncommaaccent -55
+KPX oslash ntilde -55
+KPX oslash o -55
+KPX oslash oacute -55
+KPX oslash ocircumflex -55
+KPX oslash odieresis -55
+KPX oslash ograve -55
+KPX oslash ohungarumlaut -55
+KPX oslash omacron -55
+KPX oslash oslash -55
+KPX oslash otilde -55
+KPX oslash p -55
+KPX oslash period -95
+KPX oslash q -55
+KPX oslash r -55
+KPX oslash racute -55
+KPX oslash rcaron -55
+KPX oslash rcommaaccent -55
+KPX oslash s -55
+KPX oslash sacute -55
+KPX oslash scaron -55
+KPX oslash scedilla -55
+KPX oslash scommaaccent -55
+KPX oslash t -55
+KPX oslash tcommaaccent -55
+KPX oslash u -55
+KPX oslash uacute -55
+KPX oslash ucircumflex -55
+KPX oslash udieresis -55
+KPX oslash ugrave -55
+KPX oslash uhungarumlaut -55
+KPX oslash umacron -55
+KPX oslash uogonek -55
+KPX oslash uring -55
+KPX oslash v -70
+KPX oslash w -70
+KPX oslash x -85
+KPX oslash y -70
+KPX oslash yacute -70
+KPX oslash ydieresis -70
+KPX oslash z -55
+KPX oslash zacute -55
+KPX oslash zcaron -55
+KPX oslash zdotaccent -55
+KPX otilde comma -40
+KPX otilde period -40
+KPX otilde v -15
+KPX otilde w -15
+KPX otilde x -30
+KPX otilde y -30
+KPX otilde yacute -30
+KPX otilde ydieresis -30
+KPX p comma -35
+KPX p period -35
+KPX p y -30
+KPX p yacute -30
+KPX p ydieresis -30
+KPX period quotedblright -100
+KPX period quoteright -100
+KPX period space -60
+KPX quotedblright space -40
+KPX quoteleft quoteleft -57
+KPX quoteright d -50
+KPX quoteright dcroat -50
+KPX quoteright quoteright -57
+KPX quoteright r -50
+KPX quoteright racute -50
+KPX quoteright rcaron -50
+KPX quoteright rcommaaccent -50
+KPX quoteright s -50
+KPX quoteright sacute -50
+KPX quoteright scaron -50
+KPX quoteright scedilla -50
+KPX quoteright scommaaccent -50
+KPX quoteright space -70
+KPX r a -10
+KPX r aacute -10
+KPX r abreve -10
+KPX r acircumflex -10
+KPX r adieresis -10
+KPX r agrave -10
+KPX r amacron -10
+KPX r aogonek -10
+KPX r aring -10
+KPX r atilde -10
+KPX r colon 30
+KPX r comma -50
+KPX r i 15
+KPX r iacute 15
+KPX r icircumflex 15
+KPX r idieresis 15
+KPX r igrave 15
+KPX r imacron 15
+KPX r iogonek 15
+KPX r k 15
+KPX r kcommaaccent 15
+KPX r l 15
+KPX r lacute 15
+KPX r lcommaaccent 15
+KPX r lslash 15
+KPX r m 25
+KPX r n 25
+KPX r nacute 25
+KPX r ncaron 25
+KPX r ncommaaccent 25
+KPX r ntilde 25
+KPX r p 30
+KPX r period -50
+KPX r semicolon 30
+KPX r t 40
+KPX r tcommaaccent 40
+KPX r u 15
+KPX r uacute 15
+KPX r ucircumflex 15
+KPX r udieresis 15
+KPX r ugrave 15
+KPX r uhungarumlaut 15
+KPX r umacron 15
+KPX r uogonek 15
+KPX r uring 15
+KPX r v 30
+KPX r y 30
+KPX r yacute 30
+KPX r ydieresis 30
+KPX racute a -10
+KPX racute aacute -10
+KPX racute abreve -10
+KPX racute acircumflex -10
+KPX racute adieresis -10
+KPX racute agrave -10
+KPX racute amacron -10
+KPX racute aogonek -10
+KPX racute aring -10
+KPX racute atilde -10
+KPX racute colon 30
+KPX racute comma -50
+KPX racute i 15
+KPX racute iacute 15
+KPX racute icircumflex 15
+KPX racute idieresis 15
+KPX racute igrave 15
+KPX racute imacron 15
+KPX racute iogonek 15
+KPX racute k 15
+KPX racute kcommaaccent 15
+KPX racute l 15
+KPX racute lacute 15
+KPX racute lcommaaccent 15
+KPX racute lslash 15
+KPX racute m 25
+KPX racute n 25
+KPX racute nacute 25
+KPX racute ncaron 25
+KPX racute ncommaaccent 25
+KPX racute ntilde 25
+KPX racute p 30
+KPX racute period -50
+KPX racute semicolon 30
+KPX racute t 40
+KPX racute tcommaaccent 40
+KPX racute u 15
+KPX racute uacute 15
+KPX racute ucircumflex 15
+KPX racute udieresis 15
+KPX racute ugrave 15
+KPX racute uhungarumlaut 15
+KPX racute umacron 15
+KPX racute uogonek 15
+KPX racute uring 15
+KPX racute v 30
+KPX racute y 30
+KPX racute yacute 30
+KPX racute ydieresis 30
+KPX rcaron a -10
+KPX rcaron aacute -10
+KPX rcaron abreve -10
+KPX rcaron acircumflex -10
+KPX rcaron adieresis -10
+KPX rcaron agrave -10
+KPX rcaron amacron -10
+KPX rcaron aogonek -10
+KPX rcaron aring -10
+KPX rcaron atilde -10
+KPX rcaron colon 30
+KPX rcaron comma -50
+KPX rcaron i 15
+KPX rcaron iacute 15
+KPX rcaron icircumflex 15
+KPX rcaron idieresis 15
+KPX rcaron igrave 15
+KPX rcaron imacron 15
+KPX rcaron iogonek 15
+KPX rcaron k 15
+KPX rcaron kcommaaccent 15
+KPX rcaron l 15
+KPX rcaron lacute 15
+KPX rcaron lcommaaccent 15
+KPX rcaron lslash 15
+KPX rcaron m 25
+KPX rcaron n 25
+KPX rcaron nacute 25
+KPX rcaron ncaron 25
+KPX rcaron ncommaaccent 25
+KPX rcaron ntilde 25
+KPX rcaron p 30
+KPX rcaron period -50
+KPX rcaron semicolon 30
+KPX rcaron t 40
+KPX rcaron tcommaaccent 40
+KPX rcaron u 15
+KPX rcaron uacute 15
+KPX rcaron ucircumflex 15
+KPX rcaron udieresis 15
+KPX rcaron ugrave 15
+KPX rcaron uhungarumlaut 15
+KPX rcaron umacron 15
+KPX rcaron uogonek 15
+KPX rcaron uring 15
+KPX rcaron v 30
+KPX rcaron y 30
+KPX rcaron yacute 30
+KPX rcaron ydieresis 30
+KPX rcommaaccent a -10
+KPX rcommaaccent aacute -10
+KPX rcommaaccent abreve -10
+KPX rcommaaccent acircumflex -10
+KPX rcommaaccent adieresis -10
+KPX rcommaaccent agrave -10
+KPX rcommaaccent amacron -10
+KPX rcommaaccent aogonek -10
+KPX rcommaaccent aring -10
+KPX rcommaaccent atilde -10
+KPX rcommaaccent colon 30
+KPX rcommaaccent comma -50
+KPX rcommaaccent i 15
+KPX rcommaaccent iacute 15
+KPX rcommaaccent icircumflex 15
+KPX rcommaaccent idieresis 15
+KPX rcommaaccent igrave 15
+KPX rcommaaccent imacron 15
+KPX rcommaaccent iogonek 15
+KPX rcommaaccent k 15
+KPX rcommaaccent kcommaaccent 15
+KPX rcommaaccent l 15
+KPX rcommaaccent lacute 15
+KPX rcommaaccent lcommaaccent 15
+KPX rcommaaccent lslash 15
+KPX rcommaaccent m 25
+KPX rcommaaccent n 25
+KPX rcommaaccent nacute 25
+KPX rcommaaccent ncaron 25
+KPX rcommaaccent ncommaaccent 25
+KPX rcommaaccent ntilde 25
+KPX rcommaaccent p 30
+KPX rcommaaccent period -50
+KPX rcommaaccent semicolon 30
+KPX rcommaaccent t 40
+KPX rcommaaccent tcommaaccent 40
+KPX rcommaaccent u 15
+KPX rcommaaccent uacute 15
+KPX rcommaaccent ucircumflex 15
+KPX rcommaaccent udieresis 15
+KPX rcommaaccent ugrave 15
+KPX rcommaaccent uhungarumlaut 15
+KPX rcommaaccent umacron 15
+KPX rcommaaccent uogonek 15
+KPX rcommaaccent uring 15
+KPX rcommaaccent v 30
+KPX rcommaaccent y 30
+KPX rcommaaccent yacute 30
+KPX rcommaaccent ydieresis 30
+KPX s comma -15
+KPX s period -15
+KPX s w -30
+KPX sacute comma -15
+KPX sacute period -15
+KPX sacute w -30
+KPX scaron comma -15
+KPX scaron period -15
+KPX scaron w -30
+KPX scedilla comma -15
+KPX scedilla period -15
+KPX scedilla w -30
+KPX scommaaccent comma -15
+KPX scommaaccent period -15
+KPX scommaaccent w -30
+KPX semicolon space -50
+KPX space T -50
+KPX space Tcaron -50
+KPX space Tcommaaccent -50
+KPX space V -50
+KPX space W -40
+KPX space Y -90
+KPX space Yacute -90
+KPX space Ydieresis -90
+KPX space quotedblleft -30
+KPX space quoteleft -60
+KPX v a -25
+KPX v aacute -25
+KPX v abreve -25
+KPX v acircumflex -25
+KPX v adieresis -25
+KPX v agrave -25
+KPX v amacron -25
+KPX v aogonek -25
+KPX v aring -25
+KPX v atilde -25
+KPX v comma -80
+KPX v e -25
+KPX v eacute -25
+KPX v ecaron -25
+KPX v ecircumflex -25
+KPX v edieresis -25
+KPX v edotaccent -25
+KPX v egrave -25
+KPX v emacron -25
+KPX v eogonek -25
+KPX v o -25
+KPX v oacute -25
+KPX v ocircumflex -25
+KPX v odieresis -25
+KPX v ograve -25
+KPX v ohungarumlaut -25
+KPX v omacron -25
+KPX v oslash -25
+KPX v otilde -25
+KPX v period -80
+KPX w a -15
+KPX w aacute -15
+KPX w abreve -15
+KPX w acircumflex -15
+KPX w adieresis -15
+KPX w agrave -15
+KPX w amacron -15
+KPX w aogonek -15
+KPX w aring -15
+KPX w atilde -15
+KPX w comma -60
+KPX w e -10
+KPX w eacute -10
+KPX w ecaron -10
+KPX w ecircumflex -10
+KPX w edieresis -10
+KPX w edotaccent -10
+KPX w egrave -10
+KPX w emacron -10
+KPX w eogonek -10
+KPX w o -10
+KPX w oacute -10
+KPX w ocircumflex -10
+KPX w odieresis -10
+KPX w ograve -10
+KPX w ohungarumlaut -10
+KPX w omacron -10
+KPX w oslash -10
+KPX w otilde -10
+KPX w period -60
+KPX x e -30
+KPX x eacute -30
+KPX x ecaron -30
+KPX x ecircumflex -30
+KPX x edieresis -30
+KPX x edotaccent -30
+KPX x egrave -30
+KPX x emacron -30
+KPX x eogonek -30
+KPX y a -20
+KPX y aacute -20
+KPX y abreve -20
+KPX y acircumflex -20
+KPX y adieresis -20
+KPX y agrave -20
+KPX y amacron -20
+KPX y aogonek -20
+KPX y aring -20
+KPX y atilde -20
+KPX y comma -100
+KPX y e -20
+KPX y eacute -20
+KPX y ecaron -20
+KPX y ecircumflex -20
+KPX y edieresis -20
+KPX y edotaccent -20
+KPX y egrave -20
+KPX y emacron -20
+KPX y eogonek -20
+KPX y o -20
+KPX y oacute -20
+KPX y ocircumflex -20
+KPX y odieresis -20
+KPX y ograve -20
+KPX y ohungarumlaut -20
+KPX y omacron -20
+KPX y oslash -20
+KPX y otilde -20
+KPX y period -100
+KPX yacute a -20
+KPX yacute aacute -20
+KPX yacute abreve -20
+KPX yacute acircumflex -20
+KPX yacute adieresis -20
+KPX yacute agrave -20
+KPX yacute amacron -20
+KPX yacute aogonek -20
+KPX yacute aring -20
+KPX yacute atilde -20
+KPX yacute comma -100
+KPX yacute e -20
+KPX yacute eacute -20
+KPX yacute ecaron -20
+KPX yacute ecircumflex -20
+KPX yacute edieresis -20
+KPX yacute edotaccent -20
+KPX yacute egrave -20
+KPX yacute emacron -20
+KPX yacute eogonek -20
+KPX yacute o -20
+KPX yacute oacute -20
+KPX yacute ocircumflex -20
+KPX yacute odieresis -20
+KPX yacute ograve -20
+KPX yacute ohungarumlaut -20
+KPX yacute omacron -20
+KPX yacute oslash -20
+KPX yacute otilde -20
+KPX yacute period -100
+KPX ydieresis a -20
+KPX ydieresis aacute -20
+KPX ydieresis abreve -20
+KPX ydieresis acircumflex -20
+KPX ydieresis adieresis -20
+KPX ydieresis agrave -20
+KPX ydieresis amacron -20
+KPX ydieresis aogonek -20
+KPX ydieresis aring -20
+KPX ydieresis atilde -20
+KPX ydieresis comma -100
+KPX ydieresis e -20
+KPX ydieresis eacute -20
+KPX ydieresis ecaron -20
+KPX ydieresis ecircumflex -20
+KPX ydieresis edieresis -20
+KPX ydieresis edotaccent -20
+KPX ydieresis egrave -20
+KPX ydieresis emacron -20
+KPX ydieresis eogonek -20
+KPX ydieresis o -20
+KPX ydieresis oacute -20
+KPX ydieresis ocircumflex -20
+KPX ydieresis odieresis -20
+KPX ydieresis ograve -20
+KPX ydieresis ohungarumlaut -20
+KPX ydieresis omacron -20
+KPX ydieresis oslash -20
+KPX ydieresis otilde -20
+KPX ydieresis period -100
+KPX z e -15
+KPX z eacute -15
+KPX z ecaron -15
+KPX z ecircumflex -15
+KPX z edieresis -15
+KPX z edotaccent -15
+KPX z egrave -15
+KPX z emacron -15
+KPX z eogonek -15
+KPX z o -15
+KPX z oacute -15
+KPX z ocircumflex -15
+KPX z odieresis -15
+KPX z ograve -15
+KPX z ohungarumlaut -15
+KPX z omacron -15
+KPX z oslash -15
+KPX z otilde -15
+KPX zacute e -15
+KPX zacute eacute -15
+KPX zacute ecaron -15
+KPX zacute ecircumflex -15
+KPX zacute edieresis -15
+KPX zacute edotaccent -15
+KPX zacute egrave -15
+KPX zacute emacron -15
+KPX zacute eogonek -15
+KPX zacute o -15
+KPX zacute oacute -15
+KPX zacute ocircumflex -15
+KPX zacute odieresis -15
+KPX zacute ograve -15
+KPX zacute ohungarumlaut -15
+KPX zacute omacron -15
+KPX zacute oslash -15
+KPX zacute otilde -15
+KPX zcaron e -15
+KPX zcaron eacute -15
+KPX zcaron ecaron -15
+KPX zcaron ecircumflex -15
+KPX zcaron edieresis -15
+KPX zcaron edotaccent -15
+KPX zcaron egrave -15
+KPX zcaron emacron -15
+KPX zcaron eogonek -15
+KPX zcaron o -15
+KPX zcaron oacute -15
+KPX zcaron ocircumflex -15
+KPX zcaron odieresis -15
+KPX zcaron ograve -15
+KPX zcaron ohungarumlaut -15
+KPX zcaron omacron -15
+KPX zcaron oslash -15
+KPX zcaron otilde -15
+KPX zdotaccent e -15
+KPX zdotaccent eacute -15
+KPX zdotaccent ecaron -15
+KPX zdotaccent ecircumflex -15
+KPX zdotaccent edieresis -15
+KPX zdotaccent edotaccent -15
+KPX zdotaccent egrave -15
+KPX zdotaccent emacron -15
+KPX zdotaccent eogonek -15
+KPX zdotaccent o -15
+KPX zdotaccent oacute -15
+KPX zdotaccent ocircumflex -15
+KPX zdotaccent odieresis -15
+KPX zdotaccent ograve -15
+KPX zdotaccent ohungarumlaut -15
+KPX zdotaccent omacron -15
+KPX zdotaccent oslash -15
+KPX zdotaccent otilde -15
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Symbol.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Symbol.afm
new file mode 100644
index 0000000..440ff94
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Symbol.afm
@@ -0,0 +1,213 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Thu May 1 15:12:25 1997
+Comment UniqueID 43064
+Comment VMusage 30820 39997
+FontName Symbol
+FullName Symbol
+FamilyName Symbol
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+CharacterSet Special
+FontBBox -180 -293 1090 1010
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.008
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved.
+EncodingScheme FontSpecific
+StdHW 92
+StdVW 85
+StartCharMetrics 190
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ;
+C 34 ; WX 713 ; N universal ; B 31 0 681 705 ;
+C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ;
+C 36 ; WX 549 ; N existential ; B 25 0 478 707 ;
+C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ;
+C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ;
+C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ;
+C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ;
+C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ;
+C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ;
+C 43 ; WX 549 ; N plus ; B 10 0 539 533 ;
+C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ;
+C 45 ; WX 549 ; N minus ; B 11 233 535 288 ;
+C 46 ; WX 250 ; N period ; B 69 -17 181 95 ;
+C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ;
+C 48 ; WX 500 ; N zero ; B 24 -14 476 685 ;
+C 49 ; WX 500 ; N one ; B 117 0 390 673 ;
+C 50 ; WX 500 ; N two ; B 25 0 475 685 ;
+C 51 ; WX 500 ; N three ; B 43 -14 435 685 ;
+C 52 ; WX 500 ; N four ; B 15 0 469 685 ;
+C 53 ; WX 500 ; N five ; B 32 -14 445 690 ;
+C 54 ; WX 500 ; N six ; B 34 -14 468 685 ;
+C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ;
+C 56 ; WX 500 ; N eight ; B 56 -14 445 685 ;
+C 57 ; WX 500 ; N nine ; B 30 -18 459 685 ;
+C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ;
+C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ;
+C 60 ; WX 549 ; N less ; B 26 0 523 522 ;
+C 61 ; WX 549 ; N equal ; B 11 141 537 390 ;
+C 62 ; WX 549 ; N greater ; B 26 0 523 522 ;
+C 63 ; WX 444 ; N question ; B 70 -17 412 686 ;
+C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ;
+C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ;
+C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ;
+C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ;
+C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ;
+C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ;
+C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ;
+C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ;
+C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ;
+C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ;
+C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ;
+C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ;
+C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ;
+C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ;
+C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ;
+C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ;
+C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ;
+C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ;
+C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ;
+C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ;
+C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ;
+C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ;
+C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ;
+C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ;
+C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ;
+C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ;
+C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ;
+C 92 ; WX 863 ; N therefore ; B 163 0 701 487 ;
+C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ;
+C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ;
+C 95 ; WX 500 ; N underscore ; B -2 -125 502 -75 ;
+C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ;
+C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ;
+C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ;
+C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ;
+C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ;
+C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ;
+C 102 ; WX 521 ; N phi ; B 28 -224 492 673 ;
+C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ;
+C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ;
+C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ;
+C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ;
+C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ;
+C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ;
+C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ;
+C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ;
+C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ;
+C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ;
+C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ;
+C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ;
+C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ;
+C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ;
+C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ;
+C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ;
+C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ;
+C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ;
+C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ;
+C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ;
+C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ;
+C 124 ; WX 200 ; N bar ; B 65 -293 135 707 ;
+C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ;
+C 126 ; WX 549 ; N similar ; B 17 203 529 307 ;
+C 160 ; WX 750 ; N Euro ; B 20 -12 714 685 ;
+C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ;
+C 162 ; WX 247 ; N minute ; B 27 459 228 735 ;
+C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ;
+C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ;
+C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ;
+C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ;
+C 167 ; WX 753 ; N club ; B 86 -26 660 533 ;
+C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ;
+C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ;
+C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ;
+C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ;
+C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ;
+C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ;
+C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ;
+C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ;
+C 176 ; WX 400 ; N degree ; B 50 385 350 685 ;
+C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ;
+C 178 ; WX 411 ; N second ; B 20 459 413 737 ;
+C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ;
+C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ;
+C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ;
+C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ;
+C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ;
+C 184 ; WX 549 ; N divide ; B 10 71 536 456 ;
+C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ;
+C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ;
+C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ;
+C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ;
+C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ;
+C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ;
+C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ;
+C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ;
+C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ;
+C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ;
+C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ;
+C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ;
+C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ;
+C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ;
+C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ;
+C 200 ; WX 768 ; N union ; B 40 -17 732 492 ;
+C 201 ; WX 713 ; N properbaseset ; B 20 0 673 470 ;
+C 202 ; WX 713 ; N reflexbaseset ; B 20 -125 673 470 ;
+C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ;
+C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ;
+C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ;
+C 206 ; WX 713 ; N element ; B 45 0 505 468 ;
+C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ;
+C 208 ; WX 768 ; N angle ; B 26 0 738 673 ;
+C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ;
+C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ;
+C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ;
+C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ;
+C 213 ; WX 823 ; N product ; B 25 -101 803 751 ;
+C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ;
+C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ;
+C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ;
+C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ;
+C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ;
+C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ;
+C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ;
+C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ;
+C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ;
+C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ;
+C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ;
+C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ;
+C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ;
+C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ;
+C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ;
+C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ;
+C 230 ; WX 384 ; N parenlefttp ; B 24 -293 436 926 ;
+C 231 ; WX 384 ; N parenleftex ; B 24 -85 108 925 ;
+C 232 ; WX 384 ; N parenleftbt ; B 24 -293 436 926 ;
+C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 349 926 ;
+C 234 ; WX 384 ; N bracketleftex ; B 0 -79 77 925 ;
+C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 349 926 ;
+C 236 ; WX 494 ; N bracelefttp ; B 209 -85 445 925 ;
+C 237 ; WX 494 ; N braceleftmid ; B 20 -85 284 935 ;
+C 238 ; WX 494 ; N braceleftbt ; B 209 -75 445 935 ;
+C 239 ; WX 494 ; N braceex ; B 209 -85 284 935 ;
+C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ;
+C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ;
+C 243 ; WX 686 ; N integraltp ; B 308 -88 675 920 ;
+C 244 ; WX 686 ; N integralex ; B 308 -88 378 975 ;
+C 245 ; WX 686 ; N integralbt ; B 11 -87 378 921 ;
+C 246 ; WX 384 ; N parenrighttp ; B 54 -293 466 926 ;
+C 247 ; WX 384 ; N parenrightex ; B 382 -85 466 925 ;
+C 248 ; WX 384 ; N parenrightbt ; B 54 -293 466 926 ;
+C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 371 926 ;
+C 250 ; WX 384 ; N bracketrightex ; B 294 -79 371 925 ;
+C 251 ; WX 384 ; N bracketrightbt ; B 22 -80 371 926 ;
+C 252 ; WX 494 ; N bracerighttp ; B 48 -85 284 925 ;
+C 253 ; WX 494 ; N bracerightmid ; B 209 -85 473 935 ;
+C 254 ; WX 494 ; N bracerightbt ; B 48 -75 284 935 ;
+C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Times-Bold.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Times-Bold.afm
new file mode 100644
index 0000000..ecd30f7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Times-Bold.afm
@@ -0,0 +1,2588 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 12:52:56 1997
+Comment UniqueID 43065
+Comment VMusage 41636 52661
+FontName Times-Bold
+FullName Times Bold
+FamilyName Times
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+CharacterSet ExtendedRoman
+FontBBox -168 -218 1000 935
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 676
+XHeight 461
+Ascender 683
+Descender -217
+StdHW 44
+StdVW 139
+StartCharMetrics 315
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ;
+C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ;
+C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ;
+C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ;
+C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ;
+C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ;
+C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ;
+C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ;
+C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
+C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ;
+C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ;
+C 46 ; WX 250 ; N period ; B 41 -13 210 156 ;
+C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ;
+C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ;
+C 49 ; WX 500 ; N one ; B 65 0 442 688 ;
+C 50 ; WX 500 ; N two ; B 17 0 478 688 ;
+C 51 ; WX 500 ; N three ; B 16 -14 468 688 ;
+C 52 ; WX 500 ; N four ; B 19 0 475 688 ;
+C 53 ; WX 500 ; N five ; B 22 -8 470 676 ;
+C 54 ; WX 500 ; N six ; B 28 -13 475 688 ;
+C 55 ; WX 500 ; N seven ; B 17 0 477 676 ;
+C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ;
+C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ;
+C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ;
+C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ;
+C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
+C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
+C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
+C 63 ; WX 500 ; N question ; B 57 -13 445 689 ;
+C 64 ; WX 930 ; N at ; B 108 -19 822 691 ;
+C 65 ; WX 722 ; N A ; B 9 0 689 690 ;
+C 66 ; WX 667 ; N B ; B 16 0 619 676 ;
+C 67 ; WX 722 ; N C ; B 49 -19 687 691 ;
+C 68 ; WX 722 ; N D ; B 14 0 690 676 ;
+C 69 ; WX 667 ; N E ; B 16 0 641 676 ;
+C 70 ; WX 611 ; N F ; B 16 0 583 676 ;
+C 71 ; WX 778 ; N G ; B 37 -19 755 691 ;
+C 72 ; WX 778 ; N H ; B 21 0 759 676 ;
+C 73 ; WX 389 ; N I ; B 20 0 370 676 ;
+C 74 ; WX 500 ; N J ; B 3 -96 479 676 ;
+C 75 ; WX 778 ; N K ; B 30 0 769 676 ;
+C 76 ; WX 667 ; N L ; B 19 0 638 676 ;
+C 77 ; WX 944 ; N M ; B 14 0 921 676 ;
+C 78 ; WX 722 ; N N ; B 16 -18 701 676 ;
+C 79 ; WX 778 ; N O ; B 35 -19 743 691 ;
+C 80 ; WX 611 ; N P ; B 16 0 600 676 ;
+C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ;
+C 82 ; WX 722 ; N R ; B 26 0 715 676 ;
+C 83 ; WX 556 ; N S ; B 35 -19 513 692 ;
+C 84 ; WX 667 ; N T ; B 31 0 636 676 ;
+C 85 ; WX 722 ; N U ; B 16 -19 701 676 ;
+C 86 ; WX 722 ; N V ; B 16 -18 701 676 ;
+C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ;
+C 88 ; WX 722 ; N X ; B 16 0 699 676 ;
+C 89 ; WX 722 ; N Y ; B 15 0 699 676 ;
+C 90 ; WX 667 ; N Z ; B 28 0 634 676 ;
+C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ;
+C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ;
+C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ;
+C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ;
+C 97 ; WX 500 ; N a ; B 25 -14 488 473 ;
+C 98 ; WX 556 ; N b ; B 17 -14 521 676 ;
+C 99 ; WX 444 ; N c ; B 25 -14 430 473 ;
+C 100 ; WX 556 ; N d ; B 25 -14 534 676 ;
+C 101 ; WX 444 ; N e ; B 25 -14 426 473 ;
+C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 28 -206 483 473 ;
+C 104 ; WX 556 ; N h ; B 16 0 534 676 ;
+C 105 ; WX 278 ; N i ; B 16 0 255 691 ;
+C 106 ; WX 333 ; N j ; B -57 -203 263 691 ;
+C 107 ; WX 556 ; N k ; B 22 0 543 676 ;
+C 108 ; WX 278 ; N l ; B 16 0 255 676 ;
+C 109 ; WX 833 ; N m ; B 16 0 814 473 ;
+C 110 ; WX 556 ; N n ; B 21 0 539 473 ;
+C 111 ; WX 500 ; N o ; B 25 -14 476 473 ;
+C 112 ; WX 556 ; N p ; B 19 -205 524 473 ;
+C 113 ; WX 556 ; N q ; B 34 -205 536 473 ;
+C 114 ; WX 444 ; N r ; B 29 0 434 473 ;
+C 115 ; WX 389 ; N s ; B 25 -14 361 473 ;
+C 116 ; WX 333 ; N t ; B 20 -12 332 630 ;
+C 117 ; WX 556 ; N u ; B 16 -14 537 461 ;
+C 118 ; WX 500 ; N v ; B 21 -14 485 461 ;
+C 119 ; WX 722 ; N w ; B 23 -14 707 461 ;
+C 120 ; WX 500 ; N x ; B 12 0 484 461 ;
+C 121 ; WX 500 ; N y ; B 16 -205 480 461 ;
+C 122 ; WX 444 ; N z ; B 21 0 420 461 ;
+C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ;
+C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ;
+C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ;
+C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ;
+C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ;
+C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ;
+C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ;
+C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ;
+C 165 ; WX 500 ; N yen ; B -64 0 547 676 ;
+C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ;
+C 167 ; WX 500 ; N section ; B 57 -132 443 691 ;
+C 168 ; WX 500 ; N currency ; B -26 61 526 613 ;
+C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ;
+C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ;
+C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ;
+C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ;
+C 174 ; WX 556 ; N fi ; B 14 0 536 691 ;
+C 175 ; WX 556 ; N fl ; B 14 0 536 691 ;
+C 177 ; WX 500 ; N endash ; B 0 181 500 271 ;
+C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ;
+C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ;
+C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ;
+C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ;
+C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ;
+C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ;
+C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ;
+C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ;
+C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ;
+C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ;
+C 193 ; WX 333 ; N grave ; B 8 528 246 713 ;
+C 194 ; WX 333 ; N acute ; B 86 528 324 713 ;
+C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ;
+C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ;
+C 197 ; WX 333 ; N macron ; B 1 565 331 637 ;
+C 198 ; WX 333 ; N breve ; B 15 528 318 691 ;
+C 199 ; WX 333 ; N dotaccent ; B 103 536 258 691 ;
+C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ;
+C 202 ; WX 333 ; N ring ; B 60 527 273 740 ;
+C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ;
+C 206 ; WX 333 ; N ogonek ; B 90 -193 319 24 ;
+C 207 ; WX 333 ; N caron ; B -2 528 335 704 ;
+C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ;
+C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ;
+C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ;
+C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ;
+C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ;
+C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ;
+C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ;
+C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ;
+C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ;
+C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ;
+C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ;
+C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ;
+C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ;
+C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ;
+C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ;
+C -1 ; WX 500 ; N abreve ; B 25 -14 488 691 ;
+C -1 ; WX 556 ; N uhungarumlaut ; B 16 -14 557 713 ;
+C -1 ; WX 444 ; N ecaron ; B 25 -14 426 704 ;
+C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ;
+C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ;
+C -1 ; WX 722 ; N Yacute ; B 15 0 699 923 ;
+C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ;
+C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ;
+C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ;
+C -1 ; WX 389 ; N scommaaccent ; B 25 -218 361 473 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ;
+C -1 ; WX 722 ; N Uring ; B 16 -19 701 935 ;
+C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ;
+C -1 ; WX 500 ; N aogonek ; B 25 -193 504 473 ;
+C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ;
+C -1 ; WX 556 ; N uogonek ; B 16 -193 539 461 ;
+C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ;
+C -1 ; WX 722 ; N Dcroat ; B 6 0 690 676 ;
+C -1 ; WX 250 ; N commaaccent ; B 47 -218 203 -50 ;
+C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ;
+C -1 ; WX 667 ; N Emacron ; B 16 0 641 847 ;
+C -1 ; WX 444 ; N ccaron ; B 25 -14 430 704 ;
+C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ;
+C -1 ; WX 722 ; N Ncommaaccent ; B 16 -188 701 676 ;
+C -1 ; WX 278 ; N lacute ; B 16 0 297 923 ;
+C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ;
+C -1 ; WX 667 ; N Tcommaaccent ; B 31 -218 636 676 ;
+C -1 ; WX 722 ; N Cacute ; B 49 -19 687 923 ;
+C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ;
+C -1 ; WX 667 ; N Edotaccent ; B 16 0 641 901 ;
+C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ;
+C -1 ; WX 389 ; N scedilla ; B 25 -218 361 473 ;
+C -1 ; WX 278 ; N iacute ; B 16 0 289 713 ;
+C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ;
+C -1 ; WX 722 ; N Rcaron ; B 26 0 715 914 ;
+C -1 ; WX 778 ; N Gcommaaccent ; B 37 -218 755 691 ;
+C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ;
+C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ;
+C -1 ; WX 722 ; N Amacron ; B 9 0 689 847 ;
+C -1 ; WX 444 ; N rcaron ; B 29 0 434 704 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ;
+C -1 ; WX 667 ; N Zdotaccent ; B 28 0 634 901 ;
+C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ;
+C -1 ; WX 778 ; N Omacron ; B 35 -19 743 847 ;
+C -1 ; WX 722 ; N Racute ; B 26 0 715 923 ;
+C -1 ; WX 556 ; N Sacute ; B 35 -19 513 923 ;
+C -1 ; WX 672 ; N dcaron ; B 25 -14 681 682 ;
+C -1 ; WX 722 ; N Umacron ; B 16 -19 701 847 ;
+C -1 ; WX 556 ; N uring ; B 16 -14 537 740 ;
+C -1 ; WX 300 ; N threebaseior ; B 3 268 297 688 ;
+C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ;
+C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ;
+C -1 ; WX 722 ; N Abreve ; B 9 0 689 901 ;
+C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
+C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ;
+C -1 ; WX 667 ; N Tcaron ; B 31 0 636 914 ;
+C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ;
+C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ;
+C -1 ; WX 722 ; N Nacute ; B 16 -18 701 923 ;
+C -1 ; WX 278 ; N icircumflex ; B -37 0 300 704 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ;
+C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ;
+C -1 ; WX 444 ; N cacute ; B 25 -14 430 713 ;
+C -1 ; WX 556 ; N nacute ; B 21 0 539 713 ;
+C -1 ; WX 556 ; N umacron ; B 16 -14 537 637 ;
+C -1 ; WX 722 ; N Ncaron ; B 16 -18 701 914 ;
+C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
+C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ;
+C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ;
+C -1 ; WX 778 ; N Gbreve ; B 37 -19 755 901 ;
+C -1 ; WX 389 ; N Idotaccent ; B 20 0 370 901 ;
+C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ;
+C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ;
+C -1 ; WX 444 ; N racute ; B 29 0 434 713 ;
+C -1 ; WX 500 ; N omacron ; B 25 -14 476 637 ;
+C -1 ; WX 667 ; N Zacute ; B 28 0 634 923 ;
+C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ;
+C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ;
+C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ;
+C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ;
+C -1 ; WX 278 ; N lcommaaccent ; B 16 -218 255 676 ;
+C -1 ; WX 416 ; N tcaron ; B 20 -12 425 815 ;
+C -1 ; WX 444 ; N eogonek ; B 25 -193 426 473 ;
+C -1 ; WX 722 ; N Uogonek ; B 16 -193 701 676 ;
+C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ;
+C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ;
+C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ;
+C -1 ; WX 444 ; N zacute ; B 21 0 420 713 ;
+C -1 ; WX 278 ; N iogonek ; B 16 -193 274 691 ;
+C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ;
+C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ;
+C -1 ; WX 500 ; N amacron ; B 25 -14 488 637 ;
+C -1 ; WX 389 ; N sacute ; B 25 -14 361 713 ;
+C -1 ; WX 278 ; N idieresis ; B -37 0 300 667 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ;
+C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ;
+C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ;
+C -1 ; WX 300 ; N twobaseior ; B 0 275 300 688 ;
+C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ;
+C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ;
+C -1 ; WX 278 ; N igrave ; B -27 0 255 713 ;
+C -1 ; WX 500 ; N ohungarumlaut ; B 25 -14 529 713 ;
+C -1 ; WX 667 ; N Eogonek ; B 16 -193 644 676 ;
+C -1 ; WX 556 ; N dcroat ; B 25 -14 534 676 ;
+C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ;
+C -1 ; WX 556 ; N Scedilla ; B 35 -218 513 692 ;
+C -1 ; WX 394 ; N lcaron ; B 16 0 412 682 ;
+C -1 ; WX 778 ; N Kcommaaccent ; B 30 -218 769 676 ;
+C -1 ; WX 667 ; N Lacute ; B 19 0 638 923 ;
+C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ;
+C -1 ; WX 444 ; N edotaccent ; B 25 -14 426 691 ;
+C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ;
+C -1 ; WX 389 ; N Imacron ; B 20 0 370 847 ;
+C -1 ; WX 667 ; N Lcaron ; B 19 0 652 682 ;
+C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ;
+C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ;
+C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ;
+C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ;
+C -1 ; WX 722 ; N Uhungarumlaut ; B 16 -19 701 923 ;
+C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ;
+C -1 ; WX 444 ; N emacron ; B 25 -14 426 637 ;
+C -1 ; WX 500 ; N gbreve ; B 28 -206 483 691 ;
+C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ;
+C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ;
+C -1 ; WX 556 ; N Scommaaccent ; B 35 -218 513 692 ;
+C -1 ; WX 778 ; N Ohungarumlaut ; B 35 -19 743 923 ;
+C -1 ; WX 400 ; N degree ; B 57 402 343 688 ;
+C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ;
+C -1 ; WX 722 ; N Ccaron ; B 49 -19 687 914 ;
+C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ;
+C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ;
+C -1 ; WX 722 ; N Dcaron ; B 14 0 690 914 ;
+C -1 ; WX 444 ; N rcommaaccent ; B 29 -218 434 473 ;
+C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ;
+C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ;
+C -1 ; WX 722 ; N Rcommaaccent ; B 26 -218 715 676 ;
+C -1 ; WX 667 ; N Lcommaaccent ; B 19 -218 638 676 ;
+C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ;
+C -1 ; WX 722 ; N Aogonek ; B 9 -193 699 690 ;
+C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ;
+C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ;
+C -1 ; WX 444 ; N zdotaccent ; B 21 0 420 691 ;
+C -1 ; WX 667 ; N Ecaron ; B 16 0 641 914 ;
+C -1 ; WX 389 ; N Iogonek ; B 20 -193 370 676 ;
+C -1 ; WX 556 ; N kcommaaccent ; B 22 -218 543 676 ;
+C -1 ; WX 570 ; N minus ; B 33 209 537 297 ;
+C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ;
+C -1 ; WX 556 ; N ncaron ; B 21 0 539 704 ;
+C -1 ; WX 333 ; N tcommaaccent ; B 20 -218 332 630 ;
+C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ;
+C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ;
+C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ;
+C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ;
+C -1 ; WX 500 ; N gcommaaccent ; B 28 -206 483 829 ;
+C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ;
+C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ;
+C -1 ; WX 556 ; N ncommaaccent ; B 21 -218 539 473 ;
+C -1 ; WX 300 ; N onebaseior ; B 28 275 273 688 ;
+C -1 ; WX 278 ; N imacron ; B -8 0 272 637 ;
+C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 2242
+KPX A C -55
+KPX A Cacute -55
+KPX A Ccaron -55
+KPX A Ccedilla -55
+KPX A G -55
+KPX A Gbreve -55
+KPX A Gcommaaccent -55
+KPX A O -45
+KPX A Oacute -45
+KPX A Ocircumflex -45
+KPX A Odieresis -45
+KPX A Ograve -45
+KPX A Ohungarumlaut -45
+KPX A Omacron -45
+KPX A Oslash -45
+KPX A Otilde -45
+KPX A Q -45
+KPX A T -95
+KPX A Tcaron -95
+KPX A Tcommaaccent -95
+KPX A U -50
+KPX A Uacute -50
+KPX A Ucircumflex -50
+KPX A Udieresis -50
+KPX A Ugrave -50
+KPX A Uhungarumlaut -50
+KPX A Umacron -50
+KPX A Uogonek -50
+KPX A Uring -50
+KPX A V -145
+KPX A W -130
+KPX A Y -100
+KPX A Yacute -100
+KPX A Ydieresis -100
+KPX A p -25
+KPX A quoteright -74
+KPX A u -50
+KPX A uacute -50
+KPX A ucircumflex -50
+KPX A udieresis -50
+KPX A ugrave -50
+KPX A uhungarumlaut -50
+KPX A umacron -50
+KPX A uogonek -50
+KPX A uring -50
+KPX A v -100
+KPX A w -90
+KPX A y -74
+KPX A yacute -74
+KPX A ydieresis -74
+KPX Aacute C -55
+KPX Aacute Cacute -55
+KPX Aacute Ccaron -55
+KPX Aacute Ccedilla -55
+KPX Aacute G -55
+KPX Aacute Gbreve -55
+KPX Aacute Gcommaaccent -55
+KPX Aacute O -45
+KPX Aacute Oacute -45
+KPX Aacute Ocircumflex -45
+KPX Aacute Odieresis -45
+KPX Aacute Ograve -45
+KPX Aacute Ohungarumlaut -45
+KPX Aacute Omacron -45
+KPX Aacute Oslash -45
+KPX Aacute Otilde -45
+KPX Aacute Q -45
+KPX Aacute T -95
+KPX Aacute Tcaron -95
+KPX Aacute Tcommaaccent -95
+KPX Aacute U -50
+KPX Aacute Uacute -50
+KPX Aacute Ucircumflex -50
+KPX Aacute Udieresis -50
+KPX Aacute Ugrave -50
+KPX Aacute Uhungarumlaut -50
+KPX Aacute Umacron -50
+KPX Aacute Uogonek -50
+KPX Aacute Uring -50
+KPX Aacute V -145
+KPX Aacute W -130
+KPX Aacute Y -100
+KPX Aacute Yacute -100
+KPX Aacute Ydieresis -100
+KPX Aacute p -25
+KPX Aacute quoteright -74
+KPX Aacute u -50
+KPX Aacute uacute -50
+KPX Aacute ucircumflex -50
+KPX Aacute udieresis -50
+KPX Aacute ugrave -50
+KPX Aacute uhungarumlaut -50
+KPX Aacute umacron -50
+KPX Aacute uogonek -50
+KPX Aacute uring -50
+KPX Aacute v -100
+KPX Aacute w -90
+KPX Aacute y -74
+KPX Aacute yacute -74
+KPX Aacute ydieresis -74
+KPX Abreve C -55
+KPX Abreve Cacute -55
+KPX Abreve Ccaron -55
+KPX Abreve Ccedilla -55
+KPX Abreve G -55
+KPX Abreve Gbreve -55
+KPX Abreve Gcommaaccent -55
+KPX Abreve O -45
+KPX Abreve Oacute -45
+KPX Abreve Ocircumflex -45
+KPX Abreve Odieresis -45
+KPX Abreve Ograve -45
+KPX Abreve Ohungarumlaut -45
+KPX Abreve Omacron -45
+KPX Abreve Oslash -45
+KPX Abreve Otilde -45
+KPX Abreve Q -45
+KPX Abreve T -95
+KPX Abreve Tcaron -95
+KPX Abreve Tcommaaccent -95
+KPX Abreve U -50
+KPX Abreve Uacute -50
+KPX Abreve Ucircumflex -50
+KPX Abreve Udieresis -50
+KPX Abreve Ugrave -50
+KPX Abreve Uhungarumlaut -50
+KPX Abreve Umacron -50
+KPX Abreve Uogonek -50
+KPX Abreve Uring -50
+KPX Abreve V -145
+KPX Abreve W -130
+KPX Abreve Y -100
+KPX Abreve Yacute -100
+KPX Abreve Ydieresis -100
+KPX Abreve p -25
+KPX Abreve quoteright -74
+KPX Abreve u -50
+KPX Abreve uacute -50
+KPX Abreve ucircumflex -50
+KPX Abreve udieresis -50
+KPX Abreve ugrave -50
+KPX Abreve uhungarumlaut -50
+KPX Abreve umacron -50
+KPX Abreve uogonek -50
+KPX Abreve uring -50
+KPX Abreve v -100
+KPX Abreve w -90
+KPX Abreve y -74
+KPX Abreve yacute -74
+KPX Abreve ydieresis -74
+KPX Acircumflex C -55
+KPX Acircumflex Cacute -55
+KPX Acircumflex Ccaron -55
+KPX Acircumflex Ccedilla -55
+KPX Acircumflex G -55
+KPX Acircumflex Gbreve -55
+KPX Acircumflex Gcommaaccent -55
+KPX Acircumflex O -45
+KPX Acircumflex Oacute -45
+KPX Acircumflex Ocircumflex -45
+KPX Acircumflex Odieresis -45
+KPX Acircumflex Ograve -45
+KPX Acircumflex Ohungarumlaut -45
+KPX Acircumflex Omacron -45
+KPX Acircumflex Oslash -45
+KPX Acircumflex Otilde -45
+KPX Acircumflex Q -45
+KPX Acircumflex T -95
+KPX Acircumflex Tcaron -95
+KPX Acircumflex Tcommaaccent -95
+KPX Acircumflex U -50
+KPX Acircumflex Uacute -50
+KPX Acircumflex Ucircumflex -50
+KPX Acircumflex Udieresis -50
+KPX Acircumflex Ugrave -50
+KPX Acircumflex Uhungarumlaut -50
+KPX Acircumflex Umacron -50
+KPX Acircumflex Uogonek -50
+KPX Acircumflex Uring -50
+KPX Acircumflex V -145
+KPX Acircumflex W -130
+KPX Acircumflex Y -100
+KPX Acircumflex Yacute -100
+KPX Acircumflex Ydieresis -100
+KPX Acircumflex p -25
+KPX Acircumflex quoteright -74
+KPX Acircumflex u -50
+KPX Acircumflex uacute -50
+KPX Acircumflex ucircumflex -50
+KPX Acircumflex udieresis -50
+KPX Acircumflex ugrave -50
+KPX Acircumflex uhungarumlaut -50
+KPX Acircumflex umacron -50
+KPX Acircumflex uogonek -50
+KPX Acircumflex uring -50
+KPX Acircumflex v -100
+KPX Acircumflex w -90
+KPX Acircumflex y -74
+KPX Acircumflex yacute -74
+KPX Acircumflex ydieresis -74
+KPX Adieresis C -55
+KPX Adieresis Cacute -55
+KPX Adieresis Ccaron -55
+KPX Adieresis Ccedilla -55
+KPX Adieresis G -55
+KPX Adieresis Gbreve -55
+KPX Adieresis Gcommaaccent -55
+KPX Adieresis O -45
+KPX Adieresis Oacute -45
+KPX Adieresis Ocircumflex -45
+KPX Adieresis Odieresis -45
+KPX Adieresis Ograve -45
+KPX Adieresis Ohungarumlaut -45
+KPX Adieresis Omacron -45
+KPX Adieresis Oslash -45
+KPX Adieresis Otilde -45
+KPX Adieresis Q -45
+KPX Adieresis T -95
+KPX Adieresis Tcaron -95
+KPX Adieresis Tcommaaccent -95
+KPX Adieresis U -50
+KPX Adieresis Uacute -50
+KPX Adieresis Ucircumflex -50
+KPX Adieresis Udieresis -50
+KPX Adieresis Ugrave -50
+KPX Adieresis Uhungarumlaut -50
+KPX Adieresis Umacron -50
+KPX Adieresis Uogonek -50
+KPX Adieresis Uring -50
+KPX Adieresis V -145
+KPX Adieresis W -130
+KPX Adieresis Y -100
+KPX Adieresis Yacute -100
+KPX Adieresis Ydieresis -100
+KPX Adieresis p -25
+KPX Adieresis quoteright -74
+KPX Adieresis u -50
+KPX Adieresis uacute -50
+KPX Adieresis ucircumflex -50
+KPX Adieresis udieresis -50
+KPX Adieresis ugrave -50
+KPX Adieresis uhungarumlaut -50
+KPX Adieresis umacron -50
+KPX Adieresis uogonek -50
+KPX Adieresis uring -50
+KPX Adieresis v -100
+KPX Adieresis w -90
+KPX Adieresis y -74
+KPX Adieresis yacute -74
+KPX Adieresis ydieresis -74
+KPX Agrave C -55
+KPX Agrave Cacute -55
+KPX Agrave Ccaron -55
+KPX Agrave Ccedilla -55
+KPX Agrave G -55
+KPX Agrave Gbreve -55
+KPX Agrave Gcommaaccent -55
+KPX Agrave O -45
+KPX Agrave Oacute -45
+KPX Agrave Ocircumflex -45
+KPX Agrave Odieresis -45
+KPX Agrave Ograve -45
+KPX Agrave Ohungarumlaut -45
+KPX Agrave Omacron -45
+KPX Agrave Oslash -45
+KPX Agrave Otilde -45
+KPX Agrave Q -45
+KPX Agrave T -95
+KPX Agrave Tcaron -95
+KPX Agrave Tcommaaccent -95
+KPX Agrave U -50
+KPX Agrave Uacute -50
+KPX Agrave Ucircumflex -50
+KPX Agrave Udieresis -50
+KPX Agrave Ugrave -50
+KPX Agrave Uhungarumlaut -50
+KPX Agrave Umacron -50
+KPX Agrave Uogonek -50
+KPX Agrave Uring -50
+KPX Agrave V -145
+KPX Agrave W -130
+KPX Agrave Y -100
+KPX Agrave Yacute -100
+KPX Agrave Ydieresis -100
+KPX Agrave p -25
+KPX Agrave quoteright -74
+KPX Agrave u -50
+KPX Agrave uacute -50
+KPX Agrave ucircumflex -50
+KPX Agrave udieresis -50
+KPX Agrave ugrave -50
+KPX Agrave uhungarumlaut -50
+KPX Agrave umacron -50
+KPX Agrave uogonek -50
+KPX Agrave uring -50
+KPX Agrave v -100
+KPX Agrave w -90
+KPX Agrave y -74
+KPX Agrave yacute -74
+KPX Agrave ydieresis -74
+KPX Amacron C -55
+KPX Amacron Cacute -55
+KPX Amacron Ccaron -55
+KPX Amacron Ccedilla -55
+KPX Amacron G -55
+KPX Amacron Gbreve -55
+KPX Amacron Gcommaaccent -55
+KPX Amacron O -45
+KPX Amacron Oacute -45
+KPX Amacron Ocircumflex -45
+KPX Amacron Odieresis -45
+KPX Amacron Ograve -45
+KPX Amacron Ohungarumlaut -45
+KPX Amacron Omacron -45
+KPX Amacron Oslash -45
+KPX Amacron Otilde -45
+KPX Amacron Q -45
+KPX Amacron T -95
+KPX Amacron Tcaron -95
+KPX Amacron Tcommaaccent -95
+KPX Amacron U -50
+KPX Amacron Uacute -50
+KPX Amacron Ucircumflex -50
+KPX Amacron Udieresis -50
+KPX Amacron Ugrave -50
+KPX Amacron Uhungarumlaut -50
+KPX Amacron Umacron -50
+KPX Amacron Uogonek -50
+KPX Amacron Uring -50
+KPX Amacron V -145
+KPX Amacron W -130
+KPX Amacron Y -100
+KPX Amacron Yacute -100
+KPX Amacron Ydieresis -100
+KPX Amacron p -25
+KPX Amacron quoteright -74
+KPX Amacron u -50
+KPX Amacron uacute -50
+KPX Amacron ucircumflex -50
+KPX Amacron udieresis -50
+KPX Amacron ugrave -50
+KPX Amacron uhungarumlaut -50
+KPX Amacron umacron -50
+KPX Amacron uogonek -50
+KPX Amacron uring -50
+KPX Amacron v -100
+KPX Amacron w -90
+KPX Amacron y -74
+KPX Amacron yacute -74
+KPX Amacron ydieresis -74
+KPX Aogonek C -55
+KPX Aogonek Cacute -55
+KPX Aogonek Ccaron -55
+KPX Aogonek Ccedilla -55
+KPX Aogonek G -55
+KPX Aogonek Gbreve -55
+KPX Aogonek Gcommaaccent -55
+KPX Aogonek O -45
+KPX Aogonek Oacute -45
+KPX Aogonek Ocircumflex -45
+KPX Aogonek Odieresis -45
+KPX Aogonek Ograve -45
+KPX Aogonek Ohungarumlaut -45
+KPX Aogonek Omacron -45
+KPX Aogonek Oslash -45
+KPX Aogonek Otilde -45
+KPX Aogonek Q -45
+KPX Aogonek T -95
+KPX Aogonek Tcaron -95
+KPX Aogonek Tcommaaccent -95
+KPX Aogonek U -50
+KPX Aogonek Uacute -50
+KPX Aogonek Ucircumflex -50
+KPX Aogonek Udieresis -50
+KPX Aogonek Ugrave -50
+KPX Aogonek Uhungarumlaut -50
+KPX Aogonek Umacron -50
+KPX Aogonek Uogonek -50
+KPX Aogonek Uring -50
+KPX Aogonek V -145
+KPX Aogonek W -130
+KPX Aogonek Y -100
+KPX Aogonek Yacute -100
+KPX Aogonek Ydieresis -100
+KPX Aogonek p -25
+KPX Aogonek quoteright -74
+KPX Aogonek u -50
+KPX Aogonek uacute -50
+KPX Aogonek ucircumflex -50
+KPX Aogonek udieresis -50
+KPX Aogonek ugrave -50
+KPX Aogonek uhungarumlaut -50
+KPX Aogonek umacron -50
+KPX Aogonek uogonek -50
+KPX Aogonek uring -50
+KPX Aogonek v -100
+KPX Aogonek w -90
+KPX Aogonek y -34
+KPX Aogonek yacute -34
+KPX Aogonek ydieresis -34
+KPX Aring C -55
+KPX Aring Cacute -55
+KPX Aring Ccaron -55
+KPX Aring Ccedilla -55
+KPX Aring G -55
+KPX Aring Gbreve -55
+KPX Aring Gcommaaccent -55
+KPX Aring O -45
+KPX Aring Oacute -45
+KPX Aring Ocircumflex -45
+KPX Aring Odieresis -45
+KPX Aring Ograve -45
+KPX Aring Ohungarumlaut -45
+KPX Aring Omacron -45
+KPX Aring Oslash -45
+KPX Aring Otilde -45
+KPX Aring Q -45
+KPX Aring T -95
+KPX Aring Tcaron -95
+KPX Aring Tcommaaccent -95
+KPX Aring U -50
+KPX Aring Uacute -50
+KPX Aring Ucircumflex -50
+KPX Aring Udieresis -50
+KPX Aring Ugrave -50
+KPX Aring Uhungarumlaut -50
+KPX Aring Umacron -50
+KPX Aring Uogonek -50
+KPX Aring Uring -50
+KPX Aring V -145
+KPX Aring W -130
+KPX Aring Y -100
+KPX Aring Yacute -100
+KPX Aring Ydieresis -100
+KPX Aring p -25
+KPX Aring quoteright -74
+KPX Aring u -50
+KPX Aring uacute -50
+KPX Aring ucircumflex -50
+KPX Aring udieresis -50
+KPX Aring ugrave -50
+KPX Aring uhungarumlaut -50
+KPX Aring umacron -50
+KPX Aring uogonek -50
+KPX Aring uring -50
+KPX Aring v -100
+KPX Aring w -90
+KPX Aring y -74
+KPX Aring yacute -74
+KPX Aring ydieresis -74
+KPX Atilde C -55
+KPX Atilde Cacute -55
+KPX Atilde Ccaron -55
+KPX Atilde Ccedilla -55
+KPX Atilde G -55
+KPX Atilde Gbreve -55
+KPX Atilde Gcommaaccent -55
+KPX Atilde O -45
+KPX Atilde Oacute -45
+KPX Atilde Ocircumflex -45
+KPX Atilde Odieresis -45
+KPX Atilde Ograve -45
+KPX Atilde Ohungarumlaut -45
+KPX Atilde Omacron -45
+KPX Atilde Oslash -45
+KPX Atilde Otilde -45
+KPX Atilde Q -45
+KPX Atilde T -95
+KPX Atilde Tcaron -95
+KPX Atilde Tcommaaccent -95
+KPX Atilde U -50
+KPX Atilde Uacute -50
+KPX Atilde Ucircumflex -50
+KPX Atilde Udieresis -50
+KPX Atilde Ugrave -50
+KPX Atilde Uhungarumlaut -50
+KPX Atilde Umacron -50
+KPX Atilde Uogonek -50
+KPX Atilde Uring -50
+KPX Atilde V -145
+KPX Atilde W -130
+KPX Atilde Y -100
+KPX Atilde Yacute -100
+KPX Atilde Ydieresis -100
+KPX Atilde p -25
+KPX Atilde quoteright -74
+KPX Atilde u -50
+KPX Atilde uacute -50
+KPX Atilde ucircumflex -50
+KPX Atilde udieresis -50
+KPX Atilde ugrave -50
+KPX Atilde uhungarumlaut -50
+KPX Atilde umacron -50
+KPX Atilde uogonek -50
+KPX Atilde uring -50
+KPX Atilde v -100
+KPX Atilde w -90
+KPX Atilde y -74
+KPX Atilde yacute -74
+KPX Atilde ydieresis -74
+KPX B A -30
+KPX B Aacute -30
+KPX B Abreve -30
+KPX B Acircumflex -30
+KPX B Adieresis -30
+KPX B Agrave -30
+KPX B Amacron -30
+KPX B Aogonek -30
+KPX B Aring -30
+KPX B Atilde -30
+KPX B U -10
+KPX B Uacute -10
+KPX B Ucircumflex -10
+KPX B Udieresis -10
+KPX B Ugrave -10
+KPX B Uhungarumlaut -10
+KPX B Umacron -10
+KPX B Uogonek -10
+KPX B Uring -10
+KPX D A -35
+KPX D Aacute -35
+KPX D Abreve -35
+KPX D Acircumflex -35
+KPX D Adieresis -35
+KPX D Agrave -35
+KPX D Amacron -35
+KPX D Aogonek -35
+KPX D Aring -35
+KPX D Atilde -35
+KPX D V -40
+KPX D W -40
+KPX D Y -40
+KPX D Yacute -40
+KPX D Ydieresis -40
+KPX D period -20
+KPX Dcaron A -35
+KPX Dcaron Aacute -35
+KPX Dcaron Abreve -35
+KPX Dcaron Acircumflex -35
+KPX Dcaron Adieresis -35
+KPX Dcaron Agrave -35
+KPX Dcaron Amacron -35
+KPX Dcaron Aogonek -35
+KPX Dcaron Aring -35
+KPX Dcaron Atilde -35
+KPX Dcaron V -40
+KPX Dcaron W -40
+KPX Dcaron Y -40
+KPX Dcaron Yacute -40
+KPX Dcaron Ydieresis -40
+KPX Dcaron period -20
+KPX Dcroat A -35
+KPX Dcroat Aacute -35
+KPX Dcroat Abreve -35
+KPX Dcroat Acircumflex -35
+KPX Dcroat Adieresis -35
+KPX Dcroat Agrave -35
+KPX Dcroat Amacron -35
+KPX Dcroat Aogonek -35
+KPX Dcroat Aring -35
+KPX Dcroat Atilde -35
+KPX Dcroat V -40
+KPX Dcroat W -40
+KPX Dcroat Y -40
+KPX Dcroat Yacute -40
+KPX Dcroat Ydieresis -40
+KPX Dcroat period -20
+KPX F A -90
+KPX F Aacute -90
+KPX F Abreve -90
+KPX F Acircumflex -90
+KPX F Adieresis -90
+KPX F Agrave -90
+KPX F Amacron -90
+KPX F Aogonek -90
+KPX F Aring -90
+KPX F Atilde -90
+KPX F a -25
+KPX F aacute -25
+KPX F abreve -25
+KPX F acircumflex -25
+KPX F adieresis -25
+KPX F agrave -25
+KPX F amacron -25
+KPX F aogonek -25
+KPX F aring -25
+KPX F atilde -25
+KPX F comma -92
+KPX F e -25
+KPX F eacute -25
+KPX F ecaron -25
+KPX F ecircumflex -25
+KPX F edieresis -25
+KPX F edotaccent -25
+KPX F egrave -25
+KPX F emacron -25
+KPX F eogonek -25
+KPX F o -25
+KPX F oacute -25
+KPX F ocircumflex -25
+KPX F odieresis -25
+KPX F ograve -25
+KPX F ohungarumlaut -25
+KPX F omacron -25
+KPX F oslash -25
+KPX F otilde -25
+KPX F period -110
+KPX J A -30
+KPX J Aacute -30
+KPX J Abreve -30
+KPX J Acircumflex -30
+KPX J Adieresis -30
+KPX J Agrave -30
+KPX J Amacron -30
+KPX J Aogonek -30
+KPX J Aring -30
+KPX J Atilde -30
+KPX J a -15
+KPX J aacute -15
+KPX J abreve -15
+KPX J acircumflex -15
+KPX J adieresis -15
+KPX J agrave -15
+KPX J amacron -15
+KPX J aogonek -15
+KPX J aring -15
+KPX J atilde -15
+KPX J e -15
+KPX J eacute -15
+KPX J ecaron -15
+KPX J ecircumflex -15
+KPX J edieresis -15
+KPX J edotaccent -15
+KPX J egrave -15
+KPX J emacron -15
+KPX J eogonek -15
+KPX J o -15
+KPX J oacute -15
+KPX J ocircumflex -15
+KPX J odieresis -15
+KPX J ograve -15
+KPX J ohungarumlaut -15
+KPX J omacron -15
+KPX J oslash -15
+KPX J otilde -15
+KPX J period -20
+KPX J u -15
+KPX J uacute -15
+KPX J ucircumflex -15
+KPX J udieresis -15
+KPX J ugrave -15
+KPX J uhungarumlaut -15
+KPX J umacron -15
+KPX J uogonek -15
+KPX J uring -15
+KPX K O -30
+KPX K Oacute -30
+KPX K Ocircumflex -30
+KPX K Odieresis -30
+KPX K Ograve -30
+KPX K Ohungarumlaut -30
+KPX K Omacron -30
+KPX K Oslash -30
+KPX K Otilde -30
+KPX K e -25
+KPX K eacute -25
+KPX K ecaron -25
+KPX K ecircumflex -25
+KPX K edieresis -25
+KPX K edotaccent -25
+KPX K egrave -25
+KPX K emacron -25
+KPX K eogonek -25
+KPX K o -25
+KPX K oacute -25
+KPX K ocircumflex -25
+KPX K odieresis -25
+KPX K ograve -25
+KPX K ohungarumlaut -25
+KPX K omacron -25
+KPX K oslash -25
+KPX K otilde -25
+KPX K u -15
+KPX K uacute -15
+KPX K ucircumflex -15
+KPX K udieresis -15
+KPX K ugrave -15
+KPX K uhungarumlaut -15
+KPX K umacron -15
+KPX K uogonek -15
+KPX K uring -15
+KPX K y -45
+KPX K yacute -45
+KPX K ydieresis -45
+KPX Kcommaaccent O -30
+KPX Kcommaaccent Oacute -30
+KPX Kcommaaccent Ocircumflex -30
+KPX Kcommaaccent Odieresis -30
+KPX Kcommaaccent Ograve -30
+KPX Kcommaaccent Ohungarumlaut -30
+KPX Kcommaaccent Omacron -30
+KPX Kcommaaccent Oslash -30
+KPX Kcommaaccent Otilde -30
+KPX Kcommaaccent e -25
+KPX Kcommaaccent eacute -25
+KPX Kcommaaccent ecaron -25
+KPX Kcommaaccent ecircumflex -25
+KPX Kcommaaccent edieresis -25
+KPX Kcommaaccent edotaccent -25
+KPX Kcommaaccent egrave -25
+KPX Kcommaaccent emacron -25
+KPX Kcommaaccent eogonek -25
+KPX Kcommaaccent o -25
+KPX Kcommaaccent oacute -25
+KPX Kcommaaccent ocircumflex -25
+KPX Kcommaaccent odieresis -25
+KPX Kcommaaccent ograve -25
+KPX Kcommaaccent ohungarumlaut -25
+KPX Kcommaaccent omacron -25
+KPX Kcommaaccent oslash -25
+KPX Kcommaaccent otilde -25
+KPX Kcommaaccent u -15
+KPX Kcommaaccent uacute -15
+KPX Kcommaaccent ucircumflex -15
+KPX Kcommaaccent udieresis -15
+KPX Kcommaaccent ugrave -15
+KPX Kcommaaccent uhungarumlaut -15
+KPX Kcommaaccent umacron -15
+KPX Kcommaaccent uogonek -15
+KPX Kcommaaccent uring -15
+KPX Kcommaaccent y -45
+KPX Kcommaaccent yacute -45
+KPX Kcommaaccent ydieresis -45
+KPX L T -92
+KPX L Tcaron -92
+KPX L Tcommaaccent -92
+KPX L V -92
+KPX L W -92
+KPX L Y -92
+KPX L Yacute -92
+KPX L Ydieresis -92
+KPX L quotedblright -20
+KPX L quoteright -110
+KPX L y -55
+KPX L yacute -55
+KPX L ydieresis -55
+KPX Lacute T -92
+KPX Lacute Tcaron -92
+KPX Lacute Tcommaaccent -92
+KPX Lacute V -92
+KPX Lacute W -92
+KPX Lacute Y -92
+KPX Lacute Yacute -92
+KPX Lacute Ydieresis -92
+KPX Lacute quotedblright -20
+KPX Lacute quoteright -110
+KPX Lacute y -55
+KPX Lacute yacute -55
+KPX Lacute ydieresis -55
+KPX Lcommaaccent T -92
+KPX Lcommaaccent Tcaron -92
+KPX Lcommaaccent Tcommaaccent -92
+KPX Lcommaaccent V -92
+KPX Lcommaaccent W -92
+KPX Lcommaaccent Y -92
+KPX Lcommaaccent Yacute -92
+KPX Lcommaaccent Ydieresis -92
+KPX Lcommaaccent quotedblright -20
+KPX Lcommaaccent quoteright -110
+KPX Lcommaaccent y -55
+KPX Lcommaaccent yacute -55
+KPX Lcommaaccent ydieresis -55
+KPX Lslash T -92
+KPX Lslash Tcaron -92
+KPX Lslash Tcommaaccent -92
+KPX Lslash V -92
+KPX Lslash W -92
+KPX Lslash Y -92
+KPX Lslash Yacute -92
+KPX Lslash Ydieresis -92
+KPX Lslash quotedblright -20
+KPX Lslash quoteright -110
+KPX Lslash y -55
+KPX Lslash yacute -55
+KPX Lslash ydieresis -55
+KPX N A -20
+KPX N Aacute -20
+KPX N Abreve -20
+KPX N Acircumflex -20
+KPX N Adieresis -20
+KPX N Agrave -20
+KPX N Amacron -20
+KPX N Aogonek -20
+KPX N Aring -20
+KPX N Atilde -20
+KPX Nacute A -20
+KPX Nacute Aacute -20
+KPX Nacute Abreve -20
+KPX Nacute Acircumflex -20
+KPX Nacute Adieresis -20
+KPX Nacute Agrave -20
+KPX Nacute Amacron -20
+KPX Nacute Aogonek -20
+KPX Nacute Aring -20
+KPX Nacute Atilde -20
+KPX Ncaron A -20
+KPX Ncaron Aacute -20
+KPX Ncaron Abreve -20
+KPX Ncaron Acircumflex -20
+KPX Ncaron Adieresis -20
+KPX Ncaron Agrave -20
+KPX Ncaron Amacron -20
+KPX Ncaron Aogonek -20
+KPX Ncaron Aring -20
+KPX Ncaron Atilde -20
+KPX Ncommaaccent A -20
+KPX Ncommaaccent Aacute -20
+KPX Ncommaaccent Abreve -20
+KPX Ncommaaccent Acircumflex -20
+KPX Ncommaaccent Adieresis -20
+KPX Ncommaaccent Agrave -20
+KPX Ncommaaccent Amacron -20
+KPX Ncommaaccent Aogonek -20
+KPX Ncommaaccent Aring -20
+KPX Ncommaaccent Atilde -20
+KPX Ntilde A -20
+KPX Ntilde Aacute -20
+KPX Ntilde Abreve -20
+KPX Ntilde Acircumflex -20
+KPX Ntilde Adieresis -20
+KPX Ntilde Agrave -20
+KPX Ntilde Amacron -20
+KPX Ntilde Aogonek -20
+KPX Ntilde Aring -20
+KPX Ntilde Atilde -20
+KPX O A -40
+KPX O Aacute -40
+KPX O Abreve -40
+KPX O Acircumflex -40
+KPX O Adieresis -40
+KPX O Agrave -40
+KPX O Amacron -40
+KPX O Aogonek -40
+KPX O Aring -40
+KPX O Atilde -40
+KPX O T -40
+KPX O Tcaron -40
+KPX O Tcommaaccent -40
+KPX O V -50
+KPX O W -50
+KPX O X -40
+KPX O Y -50
+KPX O Yacute -50
+KPX O Ydieresis -50
+KPX Oacute A -40
+KPX Oacute Aacute -40
+KPX Oacute Abreve -40
+KPX Oacute Acircumflex -40
+KPX Oacute Adieresis -40
+KPX Oacute Agrave -40
+KPX Oacute Amacron -40
+KPX Oacute Aogonek -40
+KPX Oacute Aring -40
+KPX Oacute Atilde -40
+KPX Oacute T -40
+KPX Oacute Tcaron -40
+KPX Oacute Tcommaaccent -40
+KPX Oacute V -50
+KPX Oacute W -50
+KPX Oacute X -40
+KPX Oacute Y -50
+KPX Oacute Yacute -50
+KPX Oacute Ydieresis -50
+KPX Ocircumflex A -40
+KPX Ocircumflex Aacute -40
+KPX Ocircumflex Abreve -40
+KPX Ocircumflex Acircumflex -40
+KPX Ocircumflex Adieresis -40
+KPX Ocircumflex Agrave -40
+KPX Ocircumflex Amacron -40
+KPX Ocircumflex Aogonek -40
+KPX Ocircumflex Aring -40
+KPX Ocircumflex Atilde -40
+KPX Ocircumflex T -40
+KPX Ocircumflex Tcaron -40
+KPX Ocircumflex Tcommaaccent -40
+KPX Ocircumflex V -50
+KPX Ocircumflex W -50
+KPX Ocircumflex X -40
+KPX Ocircumflex Y -50
+KPX Ocircumflex Yacute -50
+KPX Ocircumflex Ydieresis -50
+KPX Odieresis A -40
+KPX Odieresis Aacute -40
+KPX Odieresis Abreve -40
+KPX Odieresis Acircumflex -40
+KPX Odieresis Adieresis -40
+KPX Odieresis Agrave -40
+KPX Odieresis Amacron -40
+KPX Odieresis Aogonek -40
+KPX Odieresis Aring -40
+KPX Odieresis Atilde -40
+KPX Odieresis T -40
+KPX Odieresis Tcaron -40
+KPX Odieresis Tcommaaccent -40
+KPX Odieresis V -50
+KPX Odieresis W -50
+KPX Odieresis X -40
+KPX Odieresis Y -50
+KPX Odieresis Yacute -50
+KPX Odieresis Ydieresis -50
+KPX Ograve A -40
+KPX Ograve Aacute -40
+KPX Ograve Abreve -40
+KPX Ograve Acircumflex -40
+KPX Ograve Adieresis -40
+KPX Ograve Agrave -40
+KPX Ograve Amacron -40
+KPX Ograve Aogonek -40
+KPX Ograve Aring -40
+KPX Ograve Atilde -40
+KPX Ograve T -40
+KPX Ograve Tcaron -40
+KPX Ograve Tcommaaccent -40
+KPX Ograve V -50
+KPX Ograve W -50
+KPX Ograve X -40
+KPX Ograve Y -50
+KPX Ograve Yacute -50
+KPX Ograve Ydieresis -50
+KPX Ohungarumlaut A -40
+KPX Ohungarumlaut Aacute -40
+KPX Ohungarumlaut Abreve -40
+KPX Ohungarumlaut Acircumflex -40
+KPX Ohungarumlaut Adieresis -40
+KPX Ohungarumlaut Agrave -40
+KPX Ohungarumlaut Amacron -40
+KPX Ohungarumlaut Aogonek -40
+KPX Ohungarumlaut Aring -40
+KPX Ohungarumlaut Atilde -40
+KPX Ohungarumlaut T -40
+KPX Ohungarumlaut Tcaron -40
+KPX Ohungarumlaut Tcommaaccent -40
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut W -50
+KPX Ohungarumlaut X -40
+KPX Ohungarumlaut Y -50
+KPX Ohungarumlaut Yacute -50
+KPX Ohungarumlaut Ydieresis -50
+KPX Omacron A -40
+KPX Omacron Aacute -40
+KPX Omacron Abreve -40
+KPX Omacron Acircumflex -40
+KPX Omacron Adieresis -40
+KPX Omacron Agrave -40
+KPX Omacron Amacron -40
+KPX Omacron Aogonek -40
+KPX Omacron Aring -40
+KPX Omacron Atilde -40
+KPX Omacron T -40
+KPX Omacron Tcaron -40
+KPX Omacron Tcommaaccent -40
+KPX Omacron V -50
+KPX Omacron W -50
+KPX Omacron X -40
+KPX Omacron Y -50
+KPX Omacron Yacute -50
+KPX Omacron Ydieresis -50
+KPX Oslash A -40
+KPX Oslash Aacute -40
+KPX Oslash Abreve -40
+KPX Oslash Acircumflex -40
+KPX Oslash Adieresis -40
+KPX Oslash Agrave -40
+KPX Oslash Amacron -40
+KPX Oslash Aogonek -40
+KPX Oslash Aring -40
+KPX Oslash Atilde -40
+KPX Oslash T -40
+KPX Oslash Tcaron -40
+KPX Oslash Tcommaaccent -40
+KPX Oslash V -50
+KPX Oslash W -50
+KPX Oslash X -40
+KPX Oslash Y -50
+KPX Oslash Yacute -50
+KPX Oslash Ydieresis -50
+KPX Otilde A -40
+KPX Otilde Aacute -40
+KPX Otilde Abreve -40
+KPX Otilde Acircumflex -40
+KPX Otilde Adieresis -40
+KPX Otilde Agrave -40
+KPX Otilde Amacron -40
+KPX Otilde Aogonek -40
+KPX Otilde Aring -40
+KPX Otilde Atilde -40
+KPX Otilde T -40
+KPX Otilde Tcaron -40
+KPX Otilde Tcommaaccent -40
+KPX Otilde V -50
+KPX Otilde W -50
+KPX Otilde X -40
+KPX Otilde Y -50
+KPX Otilde Yacute -50
+KPX Otilde Ydieresis -50
+KPX P A -74
+KPX P Aacute -74
+KPX P Abreve -74
+KPX P Acircumflex -74
+KPX P Adieresis -74
+KPX P Agrave -74
+KPX P Amacron -74
+KPX P Aogonek -74
+KPX P Aring -74
+KPX P Atilde -74
+KPX P a -10
+KPX P aacute -10
+KPX P abreve -10
+KPX P acircumflex -10
+KPX P adieresis -10
+KPX P agrave -10
+KPX P amacron -10
+KPX P aogonek -10
+KPX P aring -10
+KPX P atilde -10
+KPX P comma -92
+KPX P e -20
+KPX P eacute -20
+KPX P ecaron -20
+KPX P ecircumflex -20
+KPX P edieresis -20
+KPX P edotaccent -20
+KPX P egrave -20
+KPX P emacron -20
+KPX P eogonek -20
+KPX P o -20
+KPX P oacute -20
+KPX P ocircumflex -20
+KPX P odieresis -20
+KPX P ograve -20
+KPX P ohungarumlaut -20
+KPX P omacron -20
+KPX P oslash -20
+KPX P otilde -20
+KPX P period -110
+KPX Q U -10
+KPX Q Uacute -10
+KPX Q Ucircumflex -10
+KPX Q Udieresis -10
+KPX Q Ugrave -10
+KPX Q Uhungarumlaut -10
+KPX Q Umacron -10
+KPX Q Uogonek -10
+KPX Q Uring -10
+KPX Q period -20
+KPX R O -30
+KPX R Oacute -30
+KPX R Ocircumflex -30
+KPX R Odieresis -30
+KPX R Ograve -30
+KPX R Ohungarumlaut -30
+KPX R Omacron -30
+KPX R Oslash -30
+KPX R Otilde -30
+KPX R T -40
+KPX R Tcaron -40
+KPX R Tcommaaccent -40
+KPX R U -30
+KPX R Uacute -30
+KPX R Ucircumflex -30
+KPX R Udieresis -30
+KPX R Ugrave -30
+KPX R Uhungarumlaut -30
+KPX R Umacron -30
+KPX R Uogonek -30
+KPX R Uring -30
+KPX R V -55
+KPX R W -35
+KPX R Y -35
+KPX R Yacute -35
+KPX R Ydieresis -35
+KPX Racute O -30
+KPX Racute Oacute -30
+KPX Racute Ocircumflex -30
+KPX Racute Odieresis -30
+KPX Racute Ograve -30
+KPX Racute Ohungarumlaut -30
+KPX Racute Omacron -30
+KPX Racute Oslash -30
+KPX Racute Otilde -30
+KPX Racute T -40
+KPX Racute Tcaron -40
+KPX Racute Tcommaaccent -40
+KPX Racute U -30
+KPX Racute Uacute -30
+KPX Racute Ucircumflex -30
+KPX Racute Udieresis -30
+KPX Racute Ugrave -30
+KPX Racute Uhungarumlaut -30
+KPX Racute Umacron -30
+KPX Racute Uogonek -30
+KPX Racute Uring -30
+KPX Racute V -55
+KPX Racute W -35
+KPX Racute Y -35
+KPX Racute Yacute -35
+KPX Racute Ydieresis -35
+KPX Rcaron O -30
+KPX Rcaron Oacute -30
+KPX Rcaron Ocircumflex -30
+KPX Rcaron Odieresis -30
+KPX Rcaron Ograve -30
+KPX Rcaron Ohungarumlaut -30
+KPX Rcaron Omacron -30
+KPX Rcaron Oslash -30
+KPX Rcaron Otilde -30
+KPX Rcaron T -40
+KPX Rcaron Tcaron -40
+KPX Rcaron Tcommaaccent -40
+KPX Rcaron U -30
+KPX Rcaron Uacute -30
+KPX Rcaron Ucircumflex -30
+KPX Rcaron Udieresis -30
+KPX Rcaron Ugrave -30
+KPX Rcaron Uhungarumlaut -30
+KPX Rcaron Umacron -30
+KPX Rcaron Uogonek -30
+KPX Rcaron Uring -30
+KPX Rcaron V -55
+KPX Rcaron W -35
+KPX Rcaron Y -35
+KPX Rcaron Yacute -35
+KPX Rcaron Ydieresis -35
+KPX Rcommaaccent O -30
+KPX Rcommaaccent Oacute -30
+KPX Rcommaaccent Ocircumflex -30
+KPX Rcommaaccent Odieresis -30
+KPX Rcommaaccent Ograve -30
+KPX Rcommaaccent Ohungarumlaut -30
+KPX Rcommaaccent Omacron -30
+KPX Rcommaaccent Oslash -30
+KPX Rcommaaccent Otilde -30
+KPX Rcommaaccent T -40
+KPX Rcommaaccent Tcaron -40
+KPX Rcommaaccent Tcommaaccent -40
+KPX Rcommaaccent U -30
+KPX Rcommaaccent Uacute -30
+KPX Rcommaaccent Ucircumflex -30
+KPX Rcommaaccent Udieresis -30
+KPX Rcommaaccent Ugrave -30
+KPX Rcommaaccent Uhungarumlaut -30
+KPX Rcommaaccent Umacron -30
+KPX Rcommaaccent Uogonek -30
+KPX Rcommaaccent Uring -30
+KPX Rcommaaccent V -55
+KPX Rcommaaccent W -35
+KPX Rcommaaccent Y -35
+KPX Rcommaaccent Yacute -35
+KPX Rcommaaccent Ydieresis -35
+KPX T A -90
+KPX T Aacute -90
+KPX T Abreve -90
+KPX T Acircumflex -90
+KPX T Adieresis -90
+KPX T Agrave -90
+KPX T Amacron -90
+KPX T Aogonek -90
+KPX T Aring -90
+KPX T Atilde -90
+KPX T O -18
+KPX T Oacute -18
+KPX T Ocircumflex -18
+KPX T Odieresis -18
+KPX T Ograve -18
+KPX T Ohungarumlaut -18
+KPX T Omacron -18
+KPX T Oslash -18
+KPX T Otilde -18
+KPX T a -92
+KPX T aacute -92
+KPX T abreve -52
+KPX T acircumflex -52
+KPX T adieresis -52
+KPX T agrave -52
+KPX T amacron -52
+KPX T aogonek -92
+KPX T aring -92
+KPX T atilde -52
+KPX T colon -74
+KPX T comma -74
+KPX T e -92
+KPX T eacute -92
+KPX T ecaron -92
+KPX T ecircumflex -92
+KPX T edieresis -52
+KPX T edotaccent -92
+KPX T egrave -52
+KPX T emacron -52
+KPX T eogonek -92
+KPX T hyphen -92
+KPX T i -18
+KPX T iacute -18
+KPX T iogonek -18
+KPX T o -92
+KPX T oacute -92
+KPX T ocircumflex -92
+KPX T odieresis -92
+KPX T ograve -92
+KPX T ohungarumlaut -92
+KPX T omacron -92
+KPX T oslash -92
+KPX T otilde -92
+KPX T period -90
+KPX T r -74
+KPX T racute -74
+KPX T rcaron -74
+KPX T rcommaaccent -74
+KPX T semicolon -74
+KPX T u -92
+KPX T uacute -92
+KPX T ucircumflex -92
+KPX T udieresis -92
+KPX T ugrave -92
+KPX T uhungarumlaut -92
+KPX T umacron -92
+KPX T uogonek -92
+KPX T uring -92
+KPX T w -74
+KPX T y -34
+KPX T yacute -34
+KPX T ydieresis -34
+KPX Tcaron A -90
+KPX Tcaron Aacute -90
+KPX Tcaron Abreve -90
+KPX Tcaron Acircumflex -90
+KPX Tcaron Adieresis -90
+KPX Tcaron Agrave -90
+KPX Tcaron Amacron -90
+KPX Tcaron Aogonek -90
+KPX Tcaron Aring -90
+KPX Tcaron Atilde -90
+KPX Tcaron O -18
+KPX Tcaron Oacute -18
+KPX Tcaron Ocircumflex -18
+KPX Tcaron Odieresis -18
+KPX Tcaron Ograve -18
+KPX Tcaron Ohungarumlaut -18
+KPX Tcaron Omacron -18
+KPX Tcaron Oslash -18
+KPX Tcaron Otilde -18
+KPX Tcaron a -92
+KPX Tcaron aacute -92
+KPX Tcaron abreve -52
+KPX Tcaron acircumflex -52
+KPX Tcaron adieresis -52
+KPX Tcaron agrave -52
+KPX Tcaron amacron -52
+KPX Tcaron aogonek -92
+KPX Tcaron aring -92
+KPX Tcaron atilde -52
+KPX Tcaron colon -74
+KPX Tcaron comma -74
+KPX Tcaron e -92
+KPX Tcaron eacute -92
+KPX Tcaron ecaron -92
+KPX Tcaron ecircumflex -92
+KPX Tcaron edieresis -52
+KPX Tcaron edotaccent -92
+KPX Tcaron egrave -52
+KPX Tcaron emacron -52
+KPX Tcaron eogonek -92
+KPX Tcaron hyphen -92
+KPX Tcaron i -18
+KPX Tcaron iacute -18
+KPX Tcaron iogonek -18
+KPX Tcaron o -92
+KPX Tcaron oacute -92
+KPX Tcaron ocircumflex -92
+KPX Tcaron odieresis -92
+KPX Tcaron ograve -92
+KPX Tcaron ohungarumlaut -92
+KPX Tcaron omacron -92
+KPX Tcaron oslash -92
+KPX Tcaron otilde -92
+KPX Tcaron period -90
+KPX Tcaron r -74
+KPX Tcaron racute -74
+KPX Tcaron rcaron -74
+KPX Tcaron rcommaaccent -74
+KPX Tcaron semicolon -74
+KPX Tcaron u -92
+KPX Tcaron uacute -92
+KPX Tcaron ucircumflex -92
+KPX Tcaron udieresis -92
+KPX Tcaron ugrave -92
+KPX Tcaron uhungarumlaut -92
+KPX Tcaron umacron -92
+KPX Tcaron uogonek -92
+KPX Tcaron uring -92
+KPX Tcaron w -74
+KPX Tcaron y -34
+KPX Tcaron yacute -34
+KPX Tcaron ydieresis -34
+KPX Tcommaaccent A -90
+KPX Tcommaaccent Aacute -90
+KPX Tcommaaccent Abreve -90
+KPX Tcommaaccent Acircumflex -90
+KPX Tcommaaccent Adieresis -90
+KPX Tcommaaccent Agrave -90
+KPX Tcommaaccent Amacron -90
+KPX Tcommaaccent Aogonek -90
+KPX Tcommaaccent Aring -90
+KPX Tcommaaccent Atilde -90
+KPX Tcommaaccent O -18
+KPX Tcommaaccent Oacute -18
+KPX Tcommaaccent Ocircumflex -18
+KPX Tcommaaccent Odieresis -18
+KPX Tcommaaccent Ograve -18
+KPX Tcommaaccent Ohungarumlaut -18
+KPX Tcommaaccent Omacron -18
+KPX Tcommaaccent Oslash -18
+KPX Tcommaaccent Otilde -18
+KPX Tcommaaccent a -92
+KPX Tcommaaccent aacute -92
+KPX Tcommaaccent abreve -52
+KPX Tcommaaccent acircumflex -52
+KPX Tcommaaccent adieresis -52
+KPX Tcommaaccent agrave -52
+KPX Tcommaaccent amacron -52
+KPX Tcommaaccent aogonek -92
+KPX Tcommaaccent aring -92
+KPX Tcommaaccent atilde -52
+KPX Tcommaaccent colon -74
+KPX Tcommaaccent comma -74
+KPX Tcommaaccent e -92
+KPX Tcommaaccent eacute -92
+KPX Tcommaaccent ecaron -92
+KPX Tcommaaccent ecircumflex -92
+KPX Tcommaaccent edieresis -52
+KPX Tcommaaccent edotaccent -92
+KPX Tcommaaccent egrave -52
+KPX Tcommaaccent emacron -52
+KPX Tcommaaccent eogonek -92
+KPX Tcommaaccent hyphen -92
+KPX Tcommaaccent i -18
+KPX Tcommaaccent iacute -18
+KPX Tcommaaccent iogonek -18
+KPX Tcommaaccent o -92
+KPX Tcommaaccent oacute -92
+KPX Tcommaaccent ocircumflex -92
+KPX Tcommaaccent odieresis -92
+KPX Tcommaaccent ograve -92
+KPX Tcommaaccent ohungarumlaut -92
+KPX Tcommaaccent omacron -92
+KPX Tcommaaccent oslash -92
+KPX Tcommaaccent otilde -92
+KPX Tcommaaccent period -90
+KPX Tcommaaccent r -74
+KPX Tcommaaccent racute -74
+KPX Tcommaaccent rcaron -74
+KPX Tcommaaccent rcommaaccent -74
+KPX Tcommaaccent semicolon -74
+KPX Tcommaaccent u -92
+KPX Tcommaaccent uacute -92
+KPX Tcommaaccent ucircumflex -92
+KPX Tcommaaccent udieresis -92
+KPX Tcommaaccent ugrave -92
+KPX Tcommaaccent uhungarumlaut -92
+KPX Tcommaaccent umacron -92
+KPX Tcommaaccent uogonek -92
+KPX Tcommaaccent uring -92
+KPX Tcommaaccent w -74
+KPX Tcommaaccent y -34
+KPX Tcommaaccent yacute -34
+KPX Tcommaaccent ydieresis -34
+KPX U A -60
+KPX U Aacute -60
+KPX U Abreve -60
+KPX U Acircumflex -60
+KPX U Adieresis -60
+KPX U Agrave -60
+KPX U Amacron -60
+KPX U Aogonek -60
+KPX U Aring -60
+KPX U Atilde -60
+KPX U comma -50
+KPX U period -50
+KPX Uacute A -60
+KPX Uacute Aacute -60
+KPX Uacute Abreve -60
+KPX Uacute Acircumflex -60
+KPX Uacute Adieresis -60
+KPX Uacute Agrave -60
+KPX Uacute Amacron -60
+KPX Uacute Aogonek -60
+KPX Uacute Aring -60
+KPX Uacute Atilde -60
+KPX Uacute comma -50
+KPX Uacute period -50
+KPX Ucircumflex A -60
+KPX Ucircumflex Aacute -60
+KPX Ucircumflex Abreve -60
+KPX Ucircumflex Acircumflex -60
+KPX Ucircumflex Adieresis -60
+KPX Ucircumflex Agrave -60
+KPX Ucircumflex Amacron -60
+KPX Ucircumflex Aogonek -60
+KPX Ucircumflex Aring -60
+KPX Ucircumflex Atilde -60
+KPX Ucircumflex comma -50
+KPX Ucircumflex period -50
+KPX Udieresis A -60
+KPX Udieresis Aacute -60
+KPX Udieresis Abreve -60
+KPX Udieresis Acircumflex -60
+KPX Udieresis Adieresis -60
+KPX Udieresis Agrave -60
+KPX Udieresis Amacron -60
+KPX Udieresis Aogonek -60
+KPX Udieresis Aring -60
+KPX Udieresis Atilde -60
+KPX Udieresis comma -50
+KPX Udieresis period -50
+KPX Ugrave A -60
+KPX Ugrave Aacute -60
+KPX Ugrave Abreve -60
+KPX Ugrave Acircumflex -60
+KPX Ugrave Adieresis -60
+KPX Ugrave Agrave -60
+KPX Ugrave Amacron -60
+KPX Ugrave Aogonek -60
+KPX Ugrave Aring -60
+KPX Ugrave Atilde -60
+KPX Ugrave comma -50
+KPX Ugrave period -50
+KPX Uhungarumlaut A -60
+KPX Uhungarumlaut Aacute -60
+KPX Uhungarumlaut Abreve -60
+KPX Uhungarumlaut Acircumflex -60
+KPX Uhungarumlaut Adieresis -60
+KPX Uhungarumlaut Agrave -60
+KPX Uhungarumlaut Amacron -60
+KPX Uhungarumlaut Aogonek -60
+KPX Uhungarumlaut Aring -60
+KPX Uhungarumlaut Atilde -60
+KPX Uhungarumlaut comma -50
+KPX Uhungarumlaut period -50
+KPX Umacron A -60
+KPX Umacron Aacute -60
+KPX Umacron Abreve -60
+KPX Umacron Acircumflex -60
+KPX Umacron Adieresis -60
+KPX Umacron Agrave -60
+KPX Umacron Amacron -60
+KPX Umacron Aogonek -60
+KPX Umacron Aring -60
+KPX Umacron Atilde -60
+KPX Umacron comma -50
+KPX Umacron period -50
+KPX Uogonek A -60
+KPX Uogonek Aacute -60
+KPX Uogonek Abreve -60
+KPX Uogonek Acircumflex -60
+KPX Uogonek Adieresis -60
+KPX Uogonek Agrave -60
+KPX Uogonek Amacron -60
+KPX Uogonek Aogonek -60
+KPX Uogonek Aring -60
+KPX Uogonek Atilde -60
+KPX Uogonek comma -50
+KPX Uogonek period -50
+KPX Uring A -60
+KPX Uring Aacute -60
+KPX Uring Abreve -60
+KPX Uring Acircumflex -60
+KPX Uring Adieresis -60
+KPX Uring Agrave -60
+KPX Uring Amacron -60
+KPX Uring Aogonek -60
+KPX Uring Aring -60
+KPX Uring Atilde -60
+KPX Uring comma -50
+KPX Uring period -50
+KPX V A -135
+KPX V Aacute -135
+KPX V Abreve -135
+KPX V Acircumflex -135
+KPX V Adieresis -135
+KPX V Agrave -135
+KPX V Amacron -135
+KPX V Aogonek -135
+KPX V Aring -135
+KPX V Atilde -135
+KPX V G -30
+KPX V Gbreve -30
+KPX V Gcommaaccent -30
+KPX V O -45
+KPX V Oacute -45
+KPX V Ocircumflex -45
+KPX V Odieresis -45
+KPX V Ograve -45
+KPX V Ohungarumlaut -45
+KPX V Omacron -45
+KPX V Oslash -45
+KPX V Otilde -45
+KPX V a -92
+KPX V aacute -92
+KPX V abreve -92
+KPX V acircumflex -92
+KPX V adieresis -92
+KPX V agrave -92
+KPX V amacron -92
+KPX V aogonek -92
+KPX V aring -92
+KPX V atilde -92
+KPX V colon -92
+KPX V comma -129
+KPX V e -100
+KPX V eacute -100
+KPX V ecaron -100
+KPX V ecircumflex -100
+KPX V edieresis -100
+KPX V edotaccent -100
+KPX V egrave -100
+KPX V emacron -100
+KPX V eogonek -100
+KPX V hyphen -74
+KPX V i -37
+KPX V iacute -37
+KPX V icircumflex -37
+KPX V idieresis -37
+KPX V igrave -37
+KPX V imacron -37
+KPX V iogonek -37
+KPX V o -100
+KPX V oacute -100
+KPX V ocircumflex -100
+KPX V odieresis -100
+KPX V ograve -100
+KPX V ohungarumlaut -100
+KPX V omacron -100
+KPX V oslash -100
+KPX V otilde -100
+KPX V period -145
+KPX V semicolon -92
+KPX V u -92
+KPX V uacute -92
+KPX V ucircumflex -92
+KPX V udieresis -92
+KPX V ugrave -92
+KPX V uhungarumlaut -92
+KPX V umacron -92
+KPX V uogonek -92
+KPX V uring -92
+KPX W A -120
+KPX W Aacute -120
+KPX W Abreve -120
+KPX W Acircumflex -120
+KPX W Adieresis -120
+KPX W Agrave -120
+KPX W Amacron -120
+KPX W Aogonek -120
+KPX W Aring -120
+KPX W Atilde -120
+KPX W O -10
+KPX W Oacute -10
+KPX W Ocircumflex -10
+KPX W Odieresis -10
+KPX W Ograve -10
+KPX W Ohungarumlaut -10
+KPX W Omacron -10
+KPX W Oslash -10
+KPX W Otilde -10
+KPX W a -65
+KPX W aacute -65
+KPX W abreve -65
+KPX W acircumflex -65
+KPX W adieresis -65
+KPX W agrave -65
+KPX W amacron -65
+KPX W aogonek -65
+KPX W aring -65
+KPX W atilde -65
+KPX W colon -55
+KPX W comma -92
+KPX W e -65
+KPX W eacute -65
+KPX W ecaron -65
+KPX W ecircumflex -65
+KPX W edieresis -65
+KPX W edotaccent -65
+KPX W egrave -65
+KPX W emacron -65
+KPX W eogonek -65
+KPX W hyphen -37
+KPX W i -18
+KPX W iacute -18
+KPX W iogonek -18
+KPX W o -75
+KPX W oacute -75
+KPX W ocircumflex -75
+KPX W odieresis -75
+KPX W ograve -75
+KPX W ohungarumlaut -75
+KPX W omacron -75
+KPX W oslash -75
+KPX W otilde -75
+KPX W period -92
+KPX W semicolon -55
+KPX W u -50
+KPX W uacute -50
+KPX W ucircumflex -50
+KPX W udieresis -50
+KPX W ugrave -50
+KPX W uhungarumlaut -50
+KPX W umacron -50
+KPX W uogonek -50
+KPX W uring -50
+KPX W y -60
+KPX W yacute -60
+KPX W ydieresis -60
+KPX Y A -110
+KPX Y Aacute -110
+KPX Y Abreve -110
+KPX Y Acircumflex -110
+KPX Y Adieresis -110
+KPX Y Agrave -110
+KPX Y Amacron -110
+KPX Y Aogonek -110
+KPX Y Aring -110
+KPX Y Atilde -110
+KPX Y O -35
+KPX Y Oacute -35
+KPX Y Ocircumflex -35
+KPX Y Odieresis -35
+KPX Y Ograve -35
+KPX Y Ohungarumlaut -35
+KPX Y Omacron -35
+KPX Y Oslash -35
+KPX Y Otilde -35
+KPX Y a -85
+KPX Y aacute -85
+KPX Y abreve -85
+KPX Y acircumflex -85
+KPX Y adieresis -85
+KPX Y agrave -85
+KPX Y amacron -85
+KPX Y aogonek -85
+KPX Y aring -85
+KPX Y atilde -85
+KPX Y colon -92
+KPX Y comma -92
+KPX Y e -111
+KPX Y eacute -111
+KPX Y ecaron -111
+KPX Y ecircumflex -111
+KPX Y edieresis -71
+KPX Y edotaccent -111
+KPX Y egrave -71
+KPX Y emacron -71
+KPX Y eogonek -111
+KPX Y hyphen -92
+KPX Y i -37
+KPX Y iacute -37
+KPX Y iogonek -37
+KPX Y o -111
+KPX Y oacute -111
+KPX Y ocircumflex -111
+KPX Y odieresis -111
+KPX Y ograve -111
+KPX Y ohungarumlaut -111
+KPX Y omacron -111
+KPX Y oslash -111
+KPX Y otilde -111
+KPX Y period -92
+KPX Y semicolon -92
+KPX Y u -92
+KPX Y uacute -92
+KPX Y ucircumflex -92
+KPX Y udieresis -92
+KPX Y ugrave -92
+KPX Y uhungarumlaut -92
+KPX Y umacron -92
+KPX Y uogonek -92
+KPX Y uring -92
+KPX Yacute A -110
+KPX Yacute Aacute -110
+KPX Yacute Abreve -110
+KPX Yacute Acircumflex -110
+KPX Yacute Adieresis -110
+KPX Yacute Agrave -110
+KPX Yacute Amacron -110
+KPX Yacute Aogonek -110
+KPX Yacute Aring -110
+KPX Yacute Atilde -110
+KPX Yacute O -35
+KPX Yacute Oacute -35
+KPX Yacute Ocircumflex -35
+KPX Yacute Odieresis -35
+KPX Yacute Ograve -35
+KPX Yacute Ohungarumlaut -35
+KPX Yacute Omacron -35
+KPX Yacute Oslash -35
+KPX Yacute Otilde -35
+KPX Yacute a -85
+KPX Yacute aacute -85
+KPX Yacute abreve -85
+KPX Yacute acircumflex -85
+KPX Yacute adieresis -85
+KPX Yacute agrave -85
+KPX Yacute amacron -85
+KPX Yacute aogonek -85
+KPX Yacute aring -85
+KPX Yacute atilde -85
+KPX Yacute colon -92
+KPX Yacute comma -92
+KPX Yacute e -111
+KPX Yacute eacute -111
+KPX Yacute ecaron -111
+KPX Yacute ecircumflex -111
+KPX Yacute edieresis -71
+KPX Yacute edotaccent -111
+KPX Yacute egrave -71
+KPX Yacute emacron -71
+KPX Yacute eogonek -111
+KPX Yacute hyphen -92
+KPX Yacute i -37
+KPX Yacute iacute -37
+KPX Yacute iogonek -37
+KPX Yacute o -111
+KPX Yacute oacute -111
+KPX Yacute ocircumflex -111
+KPX Yacute odieresis -111
+KPX Yacute ograve -111
+KPX Yacute ohungarumlaut -111
+KPX Yacute omacron -111
+KPX Yacute oslash -111
+KPX Yacute otilde -111
+KPX Yacute period -92
+KPX Yacute semicolon -92
+KPX Yacute u -92
+KPX Yacute uacute -92
+KPX Yacute ucircumflex -92
+KPX Yacute udieresis -92
+KPX Yacute ugrave -92
+KPX Yacute uhungarumlaut -92
+KPX Yacute umacron -92
+KPX Yacute uogonek -92
+KPX Yacute uring -92
+KPX Ydieresis A -110
+KPX Ydieresis Aacute -110
+KPX Ydieresis Abreve -110
+KPX Ydieresis Acircumflex -110
+KPX Ydieresis Adieresis -110
+KPX Ydieresis Agrave -110
+KPX Ydieresis Amacron -110
+KPX Ydieresis Aogonek -110
+KPX Ydieresis Aring -110
+KPX Ydieresis Atilde -110
+KPX Ydieresis O -35
+KPX Ydieresis Oacute -35
+KPX Ydieresis Ocircumflex -35
+KPX Ydieresis Odieresis -35
+KPX Ydieresis Ograve -35
+KPX Ydieresis Ohungarumlaut -35
+KPX Ydieresis Omacron -35
+KPX Ydieresis Oslash -35
+KPX Ydieresis Otilde -35
+KPX Ydieresis a -85
+KPX Ydieresis aacute -85
+KPX Ydieresis abreve -85
+KPX Ydieresis acircumflex -85
+KPX Ydieresis adieresis -85
+KPX Ydieresis agrave -85
+KPX Ydieresis amacron -85
+KPX Ydieresis aogonek -85
+KPX Ydieresis aring -85
+KPX Ydieresis atilde -85
+KPX Ydieresis colon -92
+KPX Ydieresis comma -92
+KPX Ydieresis e -111
+KPX Ydieresis eacute -111
+KPX Ydieresis ecaron -111
+KPX Ydieresis ecircumflex -111
+KPX Ydieresis edieresis -71
+KPX Ydieresis edotaccent -111
+KPX Ydieresis egrave -71
+KPX Ydieresis emacron -71
+KPX Ydieresis eogonek -111
+KPX Ydieresis hyphen -92
+KPX Ydieresis i -37
+KPX Ydieresis iacute -37
+KPX Ydieresis iogonek -37
+KPX Ydieresis o -111
+KPX Ydieresis oacute -111
+KPX Ydieresis ocircumflex -111
+KPX Ydieresis odieresis -111
+KPX Ydieresis ograve -111
+KPX Ydieresis ohungarumlaut -111
+KPX Ydieresis omacron -111
+KPX Ydieresis oslash -111
+KPX Ydieresis otilde -111
+KPX Ydieresis period -92
+KPX Ydieresis semicolon -92
+KPX Ydieresis u -92
+KPX Ydieresis uacute -92
+KPX Ydieresis ucircumflex -92
+KPX Ydieresis udieresis -92
+KPX Ydieresis ugrave -92
+KPX Ydieresis uhungarumlaut -92
+KPX Ydieresis umacron -92
+KPX Ydieresis uogonek -92
+KPX Ydieresis uring -92
+KPX a v -25
+KPX aacute v -25
+KPX abreve v -25
+KPX acircumflex v -25
+KPX adieresis v -25
+KPX agrave v -25
+KPX amacron v -25
+KPX aogonek v -25
+KPX aring v -25
+KPX atilde v -25
+KPX b b -10
+KPX b period -40
+KPX b u -20
+KPX b uacute -20
+KPX b ucircumflex -20
+KPX b udieresis -20
+KPX b ugrave -20
+KPX b uhungarumlaut -20
+KPX b umacron -20
+KPX b uogonek -20
+KPX b uring -20
+KPX b v -15
+KPX comma quotedblright -45
+KPX comma quoteright -55
+KPX d w -15
+KPX dcroat w -15
+KPX e v -15
+KPX eacute v -15
+KPX ecaron v -15
+KPX ecircumflex v -15
+KPX edieresis v -15
+KPX edotaccent v -15
+KPX egrave v -15
+KPX emacron v -15
+KPX eogonek v -15
+KPX f comma -15
+KPX f dotlessi -35
+KPX f i -25
+KPX f o -25
+KPX f oacute -25
+KPX f ocircumflex -25
+KPX f odieresis -25
+KPX f ograve -25
+KPX f ohungarumlaut -25
+KPX f omacron -25
+KPX f oslash -25
+KPX f otilde -25
+KPX f period -15
+KPX f quotedblright 50
+KPX f quoteright 55
+KPX g period -15
+KPX gbreve period -15
+KPX gcommaaccent period -15
+KPX h y -15
+KPX h yacute -15
+KPX h ydieresis -15
+KPX i v -10
+KPX iacute v -10
+KPX icircumflex v -10
+KPX idieresis v -10
+KPX igrave v -10
+KPX imacron v -10
+KPX iogonek v -10
+KPX k e -10
+KPX k eacute -10
+KPX k ecaron -10
+KPX k ecircumflex -10
+KPX k edieresis -10
+KPX k edotaccent -10
+KPX k egrave -10
+KPX k emacron -10
+KPX k eogonek -10
+KPX k o -15
+KPX k oacute -15
+KPX k ocircumflex -15
+KPX k odieresis -15
+KPX k ograve -15
+KPX k ohungarumlaut -15
+KPX k omacron -15
+KPX k oslash -15
+KPX k otilde -15
+KPX k y -15
+KPX k yacute -15
+KPX k ydieresis -15
+KPX kcommaaccent e -10
+KPX kcommaaccent eacute -10
+KPX kcommaaccent ecaron -10
+KPX kcommaaccent ecircumflex -10
+KPX kcommaaccent edieresis -10
+KPX kcommaaccent edotaccent -10
+KPX kcommaaccent egrave -10
+KPX kcommaaccent emacron -10
+KPX kcommaaccent eogonek -10
+KPX kcommaaccent o -15
+KPX kcommaaccent oacute -15
+KPX kcommaaccent ocircumflex -15
+KPX kcommaaccent odieresis -15
+KPX kcommaaccent ograve -15
+KPX kcommaaccent ohungarumlaut -15
+KPX kcommaaccent omacron -15
+KPX kcommaaccent oslash -15
+KPX kcommaaccent otilde -15
+KPX kcommaaccent y -15
+KPX kcommaaccent yacute -15
+KPX kcommaaccent ydieresis -15
+KPX n v -40
+KPX nacute v -40
+KPX ncaron v -40
+KPX ncommaaccent v -40
+KPX ntilde v -40
+KPX o v -10
+KPX o w -10
+KPX oacute v -10
+KPX oacute w -10
+KPX ocircumflex v -10
+KPX ocircumflex w -10
+KPX odieresis v -10
+KPX odieresis w -10
+KPX ograve v -10
+KPX ograve w -10
+KPX ohungarumlaut v -10
+KPX ohungarumlaut w -10
+KPX omacron v -10
+KPX omacron w -10
+KPX oslash v -10
+KPX oslash w -10
+KPX otilde v -10
+KPX otilde w -10
+KPX period quotedblright -55
+KPX period quoteright -55
+KPX quotedblleft A -10
+KPX quotedblleft Aacute -10
+KPX quotedblleft Abreve -10
+KPX quotedblleft Acircumflex -10
+KPX quotedblleft Adieresis -10
+KPX quotedblleft Agrave -10
+KPX quotedblleft Amacron -10
+KPX quotedblleft Aogonek -10
+KPX quotedblleft Aring -10
+KPX quotedblleft Atilde -10
+KPX quoteleft A -10
+KPX quoteleft Aacute -10
+KPX quoteleft Abreve -10
+KPX quoteleft Acircumflex -10
+KPX quoteleft Adieresis -10
+KPX quoteleft Agrave -10
+KPX quoteleft Amacron -10
+KPX quoteleft Aogonek -10
+KPX quoteleft Aring -10
+KPX quoteleft Atilde -10
+KPX quoteleft quoteleft -63
+KPX quoteright d -20
+KPX quoteright dcroat -20
+KPX quoteright quoteright -63
+KPX quoteright r -20
+KPX quoteright racute -20
+KPX quoteright rcaron -20
+KPX quoteright rcommaaccent -20
+KPX quoteright s -37
+KPX quoteright sacute -37
+KPX quoteright scaron -37
+KPX quoteright scedilla -37
+KPX quoteright scommaaccent -37
+KPX quoteright space -74
+KPX quoteright v -20
+KPX r c -18
+KPX r cacute -18
+KPX r ccaron -18
+KPX r ccedilla -18
+KPX r comma -92
+KPX r e -18
+KPX r eacute -18
+KPX r ecaron -18
+KPX r ecircumflex -18
+KPX r edieresis -18
+KPX r edotaccent -18
+KPX r egrave -18
+KPX r emacron -18
+KPX r eogonek -18
+KPX r g -10
+KPX r gbreve -10
+KPX r gcommaaccent -10
+KPX r hyphen -37
+KPX r n -15
+KPX r nacute -15
+KPX r ncaron -15
+KPX r ncommaaccent -15
+KPX r ntilde -15
+KPX r o -18
+KPX r oacute -18
+KPX r ocircumflex -18
+KPX r odieresis -18
+KPX r ograve -18
+KPX r ohungarumlaut -18
+KPX r omacron -18
+KPX r oslash -18
+KPX r otilde -18
+KPX r p -10
+KPX r period -100
+KPX r q -18
+KPX r v -10
+KPX racute c -18
+KPX racute cacute -18
+KPX racute ccaron -18
+KPX racute ccedilla -18
+KPX racute comma -92
+KPX racute e -18
+KPX racute eacute -18
+KPX racute ecaron -18
+KPX racute ecircumflex -18
+KPX racute edieresis -18
+KPX racute edotaccent -18
+KPX racute egrave -18
+KPX racute emacron -18
+KPX racute eogonek -18
+KPX racute g -10
+KPX racute gbreve -10
+KPX racute gcommaaccent -10
+KPX racute hyphen -37
+KPX racute n -15
+KPX racute nacute -15
+KPX racute ncaron -15
+KPX racute ncommaaccent -15
+KPX racute ntilde -15
+KPX racute o -18
+KPX racute oacute -18
+KPX racute ocircumflex -18
+KPX racute odieresis -18
+KPX racute ograve -18
+KPX racute ohungarumlaut -18
+KPX racute omacron -18
+KPX racute oslash -18
+KPX racute otilde -18
+KPX racute p -10
+KPX racute period -100
+KPX racute q -18
+KPX racute v -10
+KPX rcaron c -18
+KPX rcaron cacute -18
+KPX rcaron ccaron -18
+KPX rcaron ccedilla -18
+KPX rcaron comma -92
+KPX rcaron e -18
+KPX rcaron eacute -18
+KPX rcaron ecaron -18
+KPX rcaron ecircumflex -18
+KPX rcaron edieresis -18
+KPX rcaron edotaccent -18
+KPX rcaron egrave -18
+KPX rcaron emacron -18
+KPX rcaron eogonek -18
+KPX rcaron g -10
+KPX rcaron gbreve -10
+KPX rcaron gcommaaccent -10
+KPX rcaron hyphen -37
+KPX rcaron n -15
+KPX rcaron nacute -15
+KPX rcaron ncaron -15
+KPX rcaron ncommaaccent -15
+KPX rcaron ntilde -15
+KPX rcaron o -18
+KPX rcaron oacute -18
+KPX rcaron ocircumflex -18
+KPX rcaron odieresis -18
+KPX rcaron ograve -18
+KPX rcaron ohungarumlaut -18
+KPX rcaron omacron -18
+KPX rcaron oslash -18
+KPX rcaron otilde -18
+KPX rcaron p -10
+KPX rcaron period -100
+KPX rcaron q -18
+KPX rcaron v -10
+KPX rcommaaccent c -18
+KPX rcommaaccent cacute -18
+KPX rcommaaccent ccaron -18
+KPX rcommaaccent ccedilla -18
+KPX rcommaaccent comma -92
+KPX rcommaaccent e -18
+KPX rcommaaccent eacute -18
+KPX rcommaaccent ecaron -18
+KPX rcommaaccent ecircumflex -18
+KPX rcommaaccent edieresis -18
+KPX rcommaaccent edotaccent -18
+KPX rcommaaccent egrave -18
+KPX rcommaaccent emacron -18
+KPX rcommaaccent eogonek -18
+KPX rcommaaccent g -10
+KPX rcommaaccent gbreve -10
+KPX rcommaaccent gcommaaccent -10
+KPX rcommaaccent hyphen -37
+KPX rcommaaccent n -15
+KPX rcommaaccent nacute -15
+KPX rcommaaccent ncaron -15
+KPX rcommaaccent ncommaaccent -15
+KPX rcommaaccent ntilde -15
+KPX rcommaaccent o -18
+KPX rcommaaccent oacute -18
+KPX rcommaaccent ocircumflex -18
+KPX rcommaaccent odieresis -18
+KPX rcommaaccent ograve -18
+KPX rcommaaccent ohungarumlaut -18
+KPX rcommaaccent omacron -18
+KPX rcommaaccent oslash -18
+KPX rcommaaccent otilde -18
+KPX rcommaaccent p -10
+KPX rcommaaccent period -100
+KPX rcommaaccent q -18
+KPX rcommaaccent v -10
+KPX space A -55
+KPX space Aacute -55
+KPX space Abreve -55
+KPX space Acircumflex -55
+KPX space Adieresis -55
+KPX space Agrave -55
+KPX space Amacron -55
+KPX space Aogonek -55
+KPX space Aring -55
+KPX space Atilde -55
+KPX space T -30
+KPX space Tcaron -30
+KPX space Tcommaaccent -30
+KPX space V -45
+KPX space W -30
+KPX space Y -55
+KPX space Yacute -55
+KPX space Ydieresis -55
+KPX v a -10
+KPX v aacute -10
+KPX v abreve -10
+KPX v acircumflex -10
+KPX v adieresis -10
+KPX v agrave -10
+KPX v amacron -10
+KPX v aogonek -10
+KPX v aring -10
+KPX v atilde -10
+KPX v comma -55
+KPX v e -10
+KPX v eacute -10
+KPX v ecaron -10
+KPX v ecircumflex -10
+KPX v edieresis -10
+KPX v edotaccent -10
+KPX v egrave -10
+KPX v emacron -10
+KPX v eogonek -10
+KPX v o -10
+KPX v oacute -10
+KPX v ocircumflex -10
+KPX v odieresis -10
+KPX v ograve -10
+KPX v ohungarumlaut -10
+KPX v omacron -10
+KPX v oslash -10
+KPX v otilde -10
+KPX v period -70
+KPX w comma -55
+KPX w o -10
+KPX w oacute -10
+KPX w ocircumflex -10
+KPX w odieresis -10
+KPX w ograve -10
+KPX w ohungarumlaut -10
+KPX w omacron -10
+KPX w oslash -10
+KPX w otilde -10
+KPX w period -70
+KPX y comma -55
+KPX y e -10
+KPX y eacute -10
+KPX y ecaron -10
+KPX y ecircumflex -10
+KPX y edieresis -10
+KPX y edotaccent -10
+KPX y egrave -10
+KPX y emacron -10
+KPX y eogonek -10
+KPX y o -25
+KPX y oacute -25
+KPX y ocircumflex -25
+KPX y odieresis -25
+KPX y ograve -25
+KPX y ohungarumlaut -25
+KPX y omacron -25
+KPX y oslash -25
+KPX y otilde -25
+KPX y period -70
+KPX yacute comma -55
+KPX yacute e -10
+KPX yacute eacute -10
+KPX yacute ecaron -10
+KPX yacute ecircumflex -10
+KPX yacute edieresis -10
+KPX yacute edotaccent -10
+KPX yacute egrave -10
+KPX yacute emacron -10
+KPX yacute eogonek -10
+KPX yacute o -25
+KPX yacute oacute -25
+KPX yacute ocircumflex -25
+KPX yacute odieresis -25
+KPX yacute ograve -25
+KPX yacute ohungarumlaut -25
+KPX yacute omacron -25
+KPX yacute oslash -25
+KPX yacute otilde -25
+KPX yacute period -70
+KPX ydieresis comma -55
+KPX ydieresis e -10
+KPX ydieresis eacute -10
+KPX ydieresis ecaron -10
+KPX ydieresis ecircumflex -10
+KPX ydieresis edieresis -10
+KPX ydieresis edotaccent -10
+KPX ydieresis egrave -10
+KPX ydieresis emacron -10
+KPX ydieresis eogonek -10
+KPX ydieresis o -25
+KPX ydieresis oacute -25
+KPX ydieresis ocircumflex -25
+KPX ydieresis odieresis -25
+KPX ydieresis ograve -25
+KPX ydieresis ohungarumlaut -25
+KPX ydieresis omacron -25
+KPX ydieresis oslash -25
+KPX ydieresis otilde -25
+KPX ydieresis period -70
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Times-BoldItalic.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Times-BoldItalic.afm
new file mode 100644
index 0000000..180e81e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Times-BoldItalic.afm
@@ -0,0 +1,2384 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 13:04:06 1997
+Comment UniqueID 43066
+Comment VMusage 45874 56899
+FontName Times-BoldItalic
+FullName Times Bold Italic
+FamilyName Times
+Weight Bold
+ItalicAngle -15
+IsFixedPitch false
+CharacterSet ExtendedRoman
+FontBBox -200 -218 996 921
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 669
+XHeight 462
+Ascender 683
+Descender -217
+StdHW 42
+StdVW 121
+StartCharMetrics 315
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ;
+C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ;
+C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ;
+C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ;
+C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ;
+C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ;
+C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ;
+C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ;
+C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ;
+C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
+C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ;
+C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ;
+C 46 ; WX 250 ; N period ; B -9 -13 139 135 ;
+C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ;
+C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ;
+C 49 ; WX 500 ; N one ; B 5 0 419 683 ;
+C 50 ; WX 500 ; N two ; B -27 0 446 683 ;
+C 51 ; WX 500 ; N three ; B -15 -13 450 683 ;
+C 52 ; WX 500 ; N four ; B -15 0 503 683 ;
+C 53 ; WX 500 ; N five ; B -11 -13 487 669 ;
+C 54 ; WX 500 ; N six ; B 23 -15 509 679 ;
+C 55 ; WX 500 ; N seven ; B 52 0 525 669 ;
+C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ;
+C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ;
+C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ;
+C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ;
+C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
+C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
+C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
+C 63 ; WX 500 ; N question ; B 79 -13 470 684 ;
+C 64 ; WX 832 ; N at ; B 63 -18 770 685 ;
+C 65 ; WX 667 ; N A ; B -67 0 593 683 ;
+C 66 ; WX 667 ; N B ; B -24 0 624 669 ;
+C 67 ; WX 667 ; N C ; B 32 -18 677 685 ;
+C 68 ; WX 722 ; N D ; B -46 0 685 669 ;
+C 69 ; WX 667 ; N E ; B -27 0 653 669 ;
+C 70 ; WX 667 ; N F ; B -13 0 660 669 ;
+C 71 ; WX 722 ; N G ; B 21 -18 706 685 ;
+C 72 ; WX 778 ; N H ; B -24 0 799 669 ;
+C 73 ; WX 389 ; N I ; B -32 0 406 669 ;
+C 74 ; WX 500 ; N J ; B -46 -99 524 669 ;
+C 75 ; WX 667 ; N K ; B -21 0 702 669 ;
+C 76 ; WX 611 ; N L ; B -22 0 590 669 ;
+C 77 ; WX 889 ; N M ; B -29 -12 917 669 ;
+C 78 ; WX 722 ; N N ; B -27 -15 748 669 ;
+C 79 ; WX 722 ; N O ; B 27 -18 691 685 ;
+C 80 ; WX 611 ; N P ; B -27 0 613 669 ;
+C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ;
+C 82 ; WX 667 ; N R ; B -29 0 623 669 ;
+C 83 ; WX 556 ; N S ; B 2 -18 526 685 ;
+C 84 ; WX 611 ; N T ; B 50 0 650 669 ;
+C 85 ; WX 722 ; N U ; B 67 -18 744 669 ;
+C 86 ; WX 667 ; N V ; B 65 -18 715 669 ;
+C 87 ; WX 889 ; N W ; B 65 -18 940 669 ;
+C 88 ; WX 667 ; N X ; B -24 0 694 669 ;
+C 89 ; WX 611 ; N Y ; B 73 0 659 669 ;
+C 90 ; WX 611 ; N Z ; B -11 0 590 669 ;
+C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ;
+C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ;
+C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ;
+C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ;
+C 97 ; WX 500 ; N a ; B -21 -14 455 462 ;
+C 98 ; WX 500 ; N b ; B -14 -13 444 699 ;
+C 99 ; WX 444 ; N c ; B -5 -13 392 462 ;
+C 100 ; WX 500 ; N d ; B -21 -13 517 699 ;
+C 101 ; WX 444 ; N e ; B 5 -13 398 462 ;
+C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B -52 -203 478 462 ;
+C 104 ; WX 556 ; N h ; B -13 -9 498 699 ;
+C 105 ; WX 278 ; N i ; B 2 -9 263 684 ;
+C 106 ; WX 278 ; N j ; B -189 -207 279 684 ;
+C 107 ; WX 500 ; N k ; B -23 -8 483 699 ;
+C 108 ; WX 278 ; N l ; B 2 -9 290 699 ;
+C 109 ; WX 778 ; N m ; B -14 -9 722 462 ;
+C 110 ; WX 556 ; N n ; B -6 -9 493 462 ;
+C 111 ; WX 500 ; N o ; B -3 -13 441 462 ;
+C 112 ; WX 500 ; N p ; B -120 -205 446 462 ;
+C 113 ; WX 500 ; N q ; B 1 -205 471 462 ;
+C 114 ; WX 389 ; N r ; B -21 0 389 462 ;
+C 115 ; WX 389 ; N s ; B -19 -13 333 462 ;
+C 116 ; WX 278 ; N t ; B -11 -9 281 594 ;
+C 117 ; WX 556 ; N u ; B 15 -9 492 462 ;
+C 118 ; WX 444 ; N v ; B 16 -13 401 462 ;
+C 119 ; WX 667 ; N w ; B 16 -13 614 462 ;
+C 120 ; WX 500 ; N x ; B -46 -13 469 462 ;
+C 121 ; WX 444 ; N y ; B -94 -205 392 462 ;
+C 122 ; WX 389 ; N z ; B -43 -78 368 449 ;
+C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ;
+C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ;
+C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ;
+C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ;
+C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ;
+C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ;
+C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ;
+C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ;
+C 165 ; WX 500 ; N yen ; B 33 0 628 669 ;
+C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ;
+C 167 ; WX 500 ; N section ; B 36 -143 459 685 ;
+C 168 ; WX 500 ; N currency ; B -26 34 526 586 ;
+C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ;
+C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ;
+C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ;
+C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ;
+C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ;
+C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ;
+C 177 ; WX 500 ; N endash ; B -40 178 477 269 ;
+C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ;
+C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ;
+C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ;
+C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ;
+C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ;
+C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ;
+C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ;
+C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ;
+C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ;
+C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ;
+C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ;
+C 193 ; WX 333 ; N grave ; B 85 516 297 697 ;
+C 194 ; WX 333 ; N acute ; B 139 516 379 697 ;
+C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ;
+C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ;
+C 197 ; WX 333 ; N macron ; B 51 553 393 623 ;
+C 198 ; WX 333 ; N breve ; B 71 516 387 678 ;
+C 199 ; WX 333 ; N dotaccent ; B 163 550 298 684 ;
+C 200 ; WX 333 ; N dieresis ; B 55 550 402 684 ;
+C 202 ; WX 333 ; N ring ; B 127 516 340 729 ;
+C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ;
+C 206 ; WX 333 ; N ogonek ; B 15 -183 244 34 ;
+C 207 ; WX 333 ; N caron ; B 79 516 411 690 ;
+C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ;
+C 225 ; WX 944 ; N AE ; B -64 0 918 669 ;
+C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ;
+C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ;
+C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ;
+C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ;
+C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ;
+C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ;
+C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ;
+C 248 ; WX 278 ; N lslash ; B -7 -9 307 699 ;
+C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ;
+C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ;
+C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ;
+C -1 ; WX 389 ; N Idieresis ; B -32 0 450 862 ;
+C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ;
+C -1 ; WX 500 ; N abreve ; B -21 -14 471 678 ;
+C -1 ; WX 556 ; N uhungarumlaut ; B 15 -9 610 697 ;
+C -1 ; WX 444 ; N ecaron ; B 5 -13 467 690 ;
+C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ;
+C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ;
+C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ;
+C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ;
+C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ;
+C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ;
+C -1 ; WX 389 ; N scommaaccent ; B -19 -218 333 462 ;
+C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ;
+C -1 ; WX 722 ; N Uring ; B 67 -18 744 921 ;
+C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ;
+C -1 ; WX 500 ; N aogonek ; B -21 -183 455 462 ;
+C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ;
+C -1 ; WX 556 ; N uogonek ; B 15 -183 492 462 ;
+C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ;
+C -1 ; WX 722 ; N Dcroat ; B -31 0 700 669 ;
+C -1 ; WX 250 ; N commaaccent ; B -36 -218 131 -50 ;
+C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ;
+C -1 ; WX 667 ; N Emacron ; B -27 0 653 830 ;
+C -1 ; WX 444 ; N ccaron ; B -5 -13 467 690 ;
+C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ;
+C -1 ; WX 722 ; N Ncommaaccent ; B -27 -218 748 669 ;
+C -1 ; WX 278 ; N lacute ; B 2 -9 392 904 ;
+C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ;
+C -1 ; WX 611 ; N Tcommaaccent ; B 50 -218 650 669 ;
+C -1 ; WX 667 ; N Cacute ; B 32 -18 677 904 ;
+C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ;
+C -1 ; WX 667 ; N Edotaccent ; B -27 0 653 862 ;
+C -1 ; WX 389 ; N scaron ; B -19 -13 424 690 ;
+C -1 ; WX 389 ; N scedilla ; B -19 -218 333 462 ;
+C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ;
+C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ;
+C -1 ; WX 667 ; N Rcaron ; B -29 0 623 897 ;
+C -1 ; WX 722 ; N Gcommaaccent ; B 21 -218 706 685 ;
+C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ;
+C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ;
+C -1 ; WX 667 ; N Amacron ; B -67 0 593 830 ;
+C -1 ; WX 389 ; N rcaron ; B -21 0 424 690 ;
+C -1 ; WX 444 ; N ccedilla ; B -5 -218 392 462 ;
+C -1 ; WX 611 ; N Zdotaccent ; B -11 0 590 862 ;
+C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ;
+C -1 ; WX 722 ; N Omacron ; B 27 -18 691 830 ;
+C -1 ; WX 667 ; N Racute ; B -29 0 623 904 ;
+C -1 ; WX 556 ; N Sacute ; B 2 -18 531 904 ;
+C -1 ; WX 608 ; N dcaron ; B -21 -13 675 708 ;
+C -1 ; WX 722 ; N Umacron ; B 67 -18 744 830 ;
+C -1 ; WX 556 ; N uring ; B 15 -9 492 729 ;
+C -1 ; WX 300 ; N threebaseior ; B 17 265 321 683 ;
+C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ;
+C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ;
+C -1 ; WX 667 ; N Abreve ; B -67 0 593 885 ;
+C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
+C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ;
+C -1 ; WX 611 ; N Tcaron ; B 50 0 650 897 ;
+C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ;
+C -1 ; WX 444 ; N ydieresis ; B -94 -205 443 655 ;
+C -1 ; WX 722 ; N Nacute ; B -27 -15 748 904 ;
+C -1 ; WX 278 ; N icircumflex ; B -3 -9 324 690 ;
+C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ;
+C -1 ; WX 500 ; N adieresis ; B -21 -14 476 655 ;
+C -1 ; WX 444 ; N edieresis ; B 5 -13 448 655 ;
+C -1 ; WX 444 ; N cacute ; B -5 -13 435 697 ;
+C -1 ; WX 556 ; N nacute ; B -6 -9 493 697 ;
+C -1 ; WX 556 ; N umacron ; B 15 -9 492 623 ;
+C -1 ; WX 722 ; N Ncaron ; B -27 -15 748 897 ;
+C -1 ; WX 389 ; N Iacute ; B -32 0 432 904 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
+C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ;
+C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ;
+C -1 ; WX 722 ; N Gbreve ; B 21 -18 706 885 ;
+C -1 ; WX 389 ; N Idotaccent ; B -32 0 406 862 ;
+C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ;
+C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ;
+C -1 ; WX 389 ; N racute ; B -21 0 407 697 ;
+C -1 ; WX 500 ; N omacron ; B -3 -13 462 623 ;
+C -1 ; WX 611 ; N Zacute ; B -11 0 590 904 ;
+C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ;
+C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ;
+C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ;
+C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ;
+C -1 ; WX 278 ; N lcommaaccent ; B -42 -218 290 699 ;
+C -1 ; WX 366 ; N tcaron ; B -11 -9 434 754 ;
+C -1 ; WX 444 ; N eogonek ; B 5 -183 398 462 ;
+C -1 ; WX 722 ; N Uogonek ; B 67 -183 744 669 ;
+C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ;
+C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ;
+C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ;
+C -1 ; WX 389 ; N zacute ; B -43 -78 407 697 ;
+C -1 ; WX 278 ; N iogonek ; B -20 -183 263 684 ;
+C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ;
+C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ;
+C -1 ; WX 500 ; N amacron ; B -21 -14 467 623 ;
+C -1 ; WX 389 ; N sacute ; B -19 -13 407 697 ;
+C -1 ; WX 278 ; N idieresis ; B 2 -9 364 655 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ;
+C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ;
+C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ;
+C -1 ; WX 300 ; N twobaseior ; B 2 274 313 683 ;
+C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ;
+C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ;
+C -1 ; WX 278 ; N igrave ; B 2 -9 259 697 ;
+C -1 ; WX 500 ; N ohungarumlaut ; B -3 -13 582 697 ;
+C -1 ; WX 667 ; N Eogonek ; B -27 -183 653 669 ;
+C -1 ; WX 500 ; N dcroat ; B -21 -13 552 699 ;
+C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ;
+C -1 ; WX 556 ; N Scedilla ; B 2 -218 526 685 ;
+C -1 ; WX 382 ; N lcaron ; B 2 -9 448 708 ;
+C -1 ; WX 667 ; N Kcommaaccent ; B -21 -218 702 669 ;
+C -1 ; WX 611 ; N Lacute ; B -22 0 590 904 ;
+C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ;
+C -1 ; WX 444 ; N edotaccent ; B 5 -13 398 655 ;
+C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ;
+C -1 ; WX 389 ; N Imacron ; B -32 0 461 830 ;
+C -1 ; WX 611 ; N Lcaron ; B -22 0 671 718 ;
+C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ;
+C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ;
+C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ;
+C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ;
+C -1 ; WX 722 ; N Uhungarumlaut ; B 67 -18 744 904 ;
+C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ;
+C -1 ; WX 444 ; N emacron ; B 5 -13 439 623 ;
+C -1 ; WX 500 ; N gbreve ; B -52 -203 478 678 ;
+C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ;
+C -1 ; WX 556 ; N Scaron ; B 2 -18 553 897 ;
+C -1 ; WX 556 ; N Scommaaccent ; B 2 -218 526 685 ;
+C -1 ; WX 722 ; N Ohungarumlaut ; B 27 -18 723 904 ;
+C -1 ; WX 400 ; N degree ; B 83 397 369 683 ;
+C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ;
+C -1 ; WX 667 ; N Ccaron ; B 32 -18 677 897 ;
+C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ;
+C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ;
+C -1 ; WX 722 ; N Dcaron ; B -46 0 685 897 ;
+C -1 ; WX 389 ; N rcommaaccent ; B -67 -218 389 462 ;
+C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ;
+C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ;
+C -1 ; WX 667 ; N Rcommaaccent ; B -29 -218 623 669 ;
+C -1 ; WX 611 ; N Lcommaaccent ; B -22 -218 590 669 ;
+C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ;
+C -1 ; WX 667 ; N Aogonek ; B -67 -183 604 683 ;
+C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ;
+C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ;
+C -1 ; WX 389 ; N zdotaccent ; B -43 -78 368 655 ;
+C -1 ; WX 667 ; N Ecaron ; B -27 0 653 897 ;
+C -1 ; WX 389 ; N Iogonek ; B -32 -183 406 669 ;
+C -1 ; WX 500 ; N kcommaaccent ; B -23 -218 483 699 ;
+C -1 ; WX 606 ; N minus ; B 51 209 555 297 ;
+C -1 ; WX 389 ; N Icircumflex ; B -32 0 450 897 ;
+C -1 ; WX 556 ; N ncaron ; B -6 -9 523 690 ;
+C -1 ; WX 278 ; N tcommaaccent ; B -62 -218 281 594 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ;
+C -1 ; WX 500 ; N odieresis ; B -3 -13 471 655 ;
+C -1 ; WX 556 ; N udieresis ; B 15 -9 499 655 ;
+C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ;
+C -1 ; WX 500 ; N gcommaaccent ; B -52 -203 478 767 ;
+C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ;
+C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ;
+C -1 ; WX 556 ; N ncommaaccent ; B -6 -218 493 462 ;
+C -1 ; WX 300 ; N onebaseior ; B 30 274 301 683 ;
+C -1 ; WX 278 ; N imacron ; B 2 -9 294 623 ;
+C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 2038
+KPX A C -65
+KPX A Cacute -65
+KPX A Ccaron -65
+KPX A Ccedilla -65
+KPX A G -60
+KPX A Gbreve -60
+KPX A Gcommaaccent -60
+KPX A O -50
+KPX A Oacute -50
+KPX A Ocircumflex -50
+KPX A Odieresis -50
+KPX A Ograve -50
+KPX A Ohungarumlaut -50
+KPX A Omacron -50
+KPX A Oslash -50
+KPX A Otilde -50
+KPX A Q -55
+KPX A T -55
+KPX A Tcaron -55
+KPX A Tcommaaccent -55
+KPX A U -50
+KPX A Uacute -50
+KPX A Ucircumflex -50
+KPX A Udieresis -50
+KPX A Ugrave -50
+KPX A Uhungarumlaut -50
+KPX A Umacron -50
+KPX A Uogonek -50
+KPX A Uring -50
+KPX A V -95
+KPX A W -100
+KPX A Y -70
+KPX A Yacute -70
+KPX A Ydieresis -70
+KPX A quoteright -74
+KPX A u -30
+KPX A uacute -30
+KPX A ucircumflex -30
+KPX A udieresis -30
+KPX A ugrave -30
+KPX A uhungarumlaut -30
+KPX A umacron -30
+KPX A uogonek -30
+KPX A uring -30
+KPX A v -74
+KPX A w -74
+KPX A y -74
+KPX A yacute -74
+KPX A ydieresis -74
+KPX Aacute C -65
+KPX Aacute Cacute -65
+KPX Aacute Ccaron -65
+KPX Aacute Ccedilla -65
+KPX Aacute G -60
+KPX Aacute Gbreve -60
+KPX Aacute Gcommaaccent -60
+KPX Aacute O -50
+KPX Aacute Oacute -50
+KPX Aacute Ocircumflex -50
+KPX Aacute Odieresis -50
+KPX Aacute Ograve -50
+KPX Aacute Ohungarumlaut -50
+KPX Aacute Omacron -50
+KPX Aacute Oslash -50
+KPX Aacute Otilde -50
+KPX Aacute Q -55
+KPX Aacute T -55
+KPX Aacute Tcaron -55
+KPX Aacute Tcommaaccent -55
+KPX Aacute U -50
+KPX Aacute Uacute -50
+KPX Aacute Ucircumflex -50
+KPX Aacute Udieresis -50
+KPX Aacute Ugrave -50
+KPX Aacute Uhungarumlaut -50
+KPX Aacute Umacron -50
+KPX Aacute Uogonek -50
+KPX Aacute Uring -50
+KPX Aacute V -95
+KPX Aacute W -100
+KPX Aacute Y -70
+KPX Aacute Yacute -70
+KPX Aacute Ydieresis -70
+KPX Aacute quoteright -74
+KPX Aacute u -30
+KPX Aacute uacute -30
+KPX Aacute ucircumflex -30
+KPX Aacute udieresis -30
+KPX Aacute ugrave -30
+KPX Aacute uhungarumlaut -30
+KPX Aacute umacron -30
+KPX Aacute uogonek -30
+KPX Aacute uring -30
+KPX Aacute v -74
+KPX Aacute w -74
+KPX Aacute y -74
+KPX Aacute yacute -74
+KPX Aacute ydieresis -74
+KPX Abreve C -65
+KPX Abreve Cacute -65
+KPX Abreve Ccaron -65
+KPX Abreve Ccedilla -65
+KPX Abreve G -60
+KPX Abreve Gbreve -60
+KPX Abreve Gcommaaccent -60
+KPX Abreve O -50
+KPX Abreve Oacute -50
+KPX Abreve Ocircumflex -50
+KPX Abreve Odieresis -50
+KPX Abreve Ograve -50
+KPX Abreve Ohungarumlaut -50
+KPX Abreve Omacron -50
+KPX Abreve Oslash -50
+KPX Abreve Otilde -50
+KPX Abreve Q -55
+KPX Abreve T -55
+KPX Abreve Tcaron -55
+KPX Abreve Tcommaaccent -55
+KPX Abreve U -50
+KPX Abreve Uacute -50
+KPX Abreve Ucircumflex -50
+KPX Abreve Udieresis -50
+KPX Abreve Ugrave -50
+KPX Abreve Uhungarumlaut -50
+KPX Abreve Umacron -50
+KPX Abreve Uogonek -50
+KPX Abreve Uring -50
+KPX Abreve V -95
+KPX Abreve W -100
+KPX Abreve Y -70
+KPX Abreve Yacute -70
+KPX Abreve Ydieresis -70
+KPX Abreve quoteright -74
+KPX Abreve u -30
+KPX Abreve uacute -30
+KPX Abreve ucircumflex -30
+KPX Abreve udieresis -30
+KPX Abreve ugrave -30
+KPX Abreve uhungarumlaut -30
+KPX Abreve umacron -30
+KPX Abreve uogonek -30
+KPX Abreve uring -30
+KPX Abreve v -74
+KPX Abreve w -74
+KPX Abreve y -74
+KPX Abreve yacute -74
+KPX Abreve ydieresis -74
+KPX Acircumflex C -65
+KPX Acircumflex Cacute -65
+KPX Acircumflex Ccaron -65
+KPX Acircumflex Ccedilla -65
+KPX Acircumflex G -60
+KPX Acircumflex Gbreve -60
+KPX Acircumflex Gcommaaccent -60
+KPX Acircumflex O -50
+KPX Acircumflex Oacute -50
+KPX Acircumflex Ocircumflex -50
+KPX Acircumflex Odieresis -50
+KPX Acircumflex Ograve -50
+KPX Acircumflex Ohungarumlaut -50
+KPX Acircumflex Omacron -50
+KPX Acircumflex Oslash -50
+KPX Acircumflex Otilde -50
+KPX Acircumflex Q -55
+KPX Acircumflex T -55
+KPX Acircumflex Tcaron -55
+KPX Acircumflex Tcommaaccent -55
+KPX Acircumflex U -50
+KPX Acircumflex Uacute -50
+KPX Acircumflex Ucircumflex -50
+KPX Acircumflex Udieresis -50
+KPX Acircumflex Ugrave -50
+KPX Acircumflex Uhungarumlaut -50
+KPX Acircumflex Umacron -50
+KPX Acircumflex Uogonek -50
+KPX Acircumflex Uring -50
+KPX Acircumflex V -95
+KPX Acircumflex W -100
+KPX Acircumflex Y -70
+KPX Acircumflex Yacute -70
+KPX Acircumflex Ydieresis -70
+KPX Acircumflex quoteright -74
+KPX Acircumflex u -30
+KPX Acircumflex uacute -30
+KPX Acircumflex ucircumflex -30
+KPX Acircumflex udieresis -30
+KPX Acircumflex ugrave -30
+KPX Acircumflex uhungarumlaut -30
+KPX Acircumflex umacron -30
+KPX Acircumflex uogonek -30
+KPX Acircumflex uring -30
+KPX Acircumflex v -74
+KPX Acircumflex w -74
+KPX Acircumflex y -74
+KPX Acircumflex yacute -74
+KPX Acircumflex ydieresis -74
+KPX Adieresis C -65
+KPX Adieresis Cacute -65
+KPX Adieresis Ccaron -65
+KPX Adieresis Ccedilla -65
+KPX Adieresis G -60
+KPX Adieresis Gbreve -60
+KPX Adieresis Gcommaaccent -60
+KPX Adieresis O -50
+KPX Adieresis Oacute -50
+KPX Adieresis Ocircumflex -50
+KPX Adieresis Odieresis -50
+KPX Adieresis Ograve -50
+KPX Adieresis Ohungarumlaut -50
+KPX Adieresis Omacron -50
+KPX Adieresis Oslash -50
+KPX Adieresis Otilde -50
+KPX Adieresis Q -55
+KPX Adieresis T -55
+KPX Adieresis Tcaron -55
+KPX Adieresis Tcommaaccent -55
+KPX Adieresis U -50
+KPX Adieresis Uacute -50
+KPX Adieresis Ucircumflex -50
+KPX Adieresis Udieresis -50
+KPX Adieresis Ugrave -50
+KPX Adieresis Uhungarumlaut -50
+KPX Adieresis Umacron -50
+KPX Adieresis Uogonek -50
+KPX Adieresis Uring -50
+KPX Adieresis V -95
+KPX Adieresis W -100
+KPX Adieresis Y -70
+KPX Adieresis Yacute -70
+KPX Adieresis Ydieresis -70
+KPX Adieresis quoteright -74
+KPX Adieresis u -30
+KPX Adieresis uacute -30
+KPX Adieresis ucircumflex -30
+KPX Adieresis udieresis -30
+KPX Adieresis ugrave -30
+KPX Adieresis uhungarumlaut -30
+KPX Adieresis umacron -30
+KPX Adieresis uogonek -30
+KPX Adieresis uring -30
+KPX Adieresis v -74
+KPX Adieresis w -74
+KPX Adieresis y -74
+KPX Adieresis yacute -74
+KPX Adieresis ydieresis -74
+KPX Agrave C -65
+KPX Agrave Cacute -65
+KPX Agrave Ccaron -65
+KPX Agrave Ccedilla -65
+KPX Agrave G -60
+KPX Agrave Gbreve -60
+KPX Agrave Gcommaaccent -60
+KPX Agrave O -50
+KPX Agrave Oacute -50
+KPX Agrave Ocircumflex -50
+KPX Agrave Odieresis -50
+KPX Agrave Ograve -50
+KPX Agrave Ohungarumlaut -50
+KPX Agrave Omacron -50
+KPX Agrave Oslash -50
+KPX Agrave Otilde -50
+KPX Agrave Q -55
+KPX Agrave T -55
+KPX Agrave Tcaron -55
+KPX Agrave Tcommaaccent -55
+KPX Agrave U -50
+KPX Agrave Uacute -50
+KPX Agrave Ucircumflex -50
+KPX Agrave Udieresis -50
+KPX Agrave Ugrave -50
+KPX Agrave Uhungarumlaut -50
+KPX Agrave Umacron -50
+KPX Agrave Uogonek -50
+KPX Agrave Uring -50
+KPX Agrave V -95
+KPX Agrave W -100
+KPX Agrave Y -70
+KPX Agrave Yacute -70
+KPX Agrave Ydieresis -70
+KPX Agrave quoteright -74
+KPX Agrave u -30
+KPX Agrave uacute -30
+KPX Agrave ucircumflex -30
+KPX Agrave udieresis -30
+KPX Agrave ugrave -30
+KPX Agrave uhungarumlaut -30
+KPX Agrave umacron -30
+KPX Agrave uogonek -30
+KPX Agrave uring -30
+KPX Agrave v -74
+KPX Agrave w -74
+KPX Agrave y -74
+KPX Agrave yacute -74
+KPX Agrave ydieresis -74
+KPX Amacron C -65
+KPX Amacron Cacute -65
+KPX Amacron Ccaron -65
+KPX Amacron Ccedilla -65
+KPX Amacron G -60
+KPX Amacron Gbreve -60
+KPX Amacron Gcommaaccent -60
+KPX Amacron O -50
+KPX Amacron Oacute -50
+KPX Amacron Ocircumflex -50
+KPX Amacron Odieresis -50
+KPX Amacron Ograve -50
+KPX Amacron Ohungarumlaut -50
+KPX Amacron Omacron -50
+KPX Amacron Oslash -50
+KPX Amacron Otilde -50
+KPX Amacron Q -55
+KPX Amacron T -55
+KPX Amacron Tcaron -55
+KPX Amacron Tcommaaccent -55
+KPX Amacron U -50
+KPX Amacron Uacute -50
+KPX Amacron Ucircumflex -50
+KPX Amacron Udieresis -50
+KPX Amacron Ugrave -50
+KPX Amacron Uhungarumlaut -50
+KPX Amacron Umacron -50
+KPX Amacron Uogonek -50
+KPX Amacron Uring -50
+KPX Amacron V -95
+KPX Amacron W -100
+KPX Amacron Y -70
+KPX Amacron Yacute -70
+KPX Amacron Ydieresis -70
+KPX Amacron quoteright -74
+KPX Amacron u -30
+KPX Amacron uacute -30
+KPX Amacron ucircumflex -30
+KPX Amacron udieresis -30
+KPX Amacron ugrave -30
+KPX Amacron uhungarumlaut -30
+KPX Amacron umacron -30
+KPX Amacron uogonek -30
+KPX Amacron uring -30
+KPX Amacron v -74
+KPX Amacron w -74
+KPX Amacron y -74
+KPX Amacron yacute -74
+KPX Amacron ydieresis -74
+KPX Aogonek C -65
+KPX Aogonek Cacute -65
+KPX Aogonek Ccaron -65
+KPX Aogonek Ccedilla -65
+KPX Aogonek G -60
+KPX Aogonek Gbreve -60
+KPX Aogonek Gcommaaccent -60
+KPX Aogonek O -50
+KPX Aogonek Oacute -50
+KPX Aogonek Ocircumflex -50
+KPX Aogonek Odieresis -50
+KPX Aogonek Ograve -50
+KPX Aogonek Ohungarumlaut -50
+KPX Aogonek Omacron -50
+KPX Aogonek Oslash -50
+KPX Aogonek Otilde -50
+KPX Aogonek Q -55
+KPX Aogonek T -55
+KPX Aogonek Tcaron -55
+KPX Aogonek Tcommaaccent -55
+KPX Aogonek U -50
+KPX Aogonek Uacute -50
+KPX Aogonek Ucircumflex -50
+KPX Aogonek Udieresis -50
+KPX Aogonek Ugrave -50
+KPX Aogonek Uhungarumlaut -50
+KPX Aogonek Umacron -50
+KPX Aogonek Uogonek -50
+KPX Aogonek Uring -50
+KPX Aogonek V -95
+KPX Aogonek W -100
+KPX Aogonek Y -70
+KPX Aogonek Yacute -70
+KPX Aogonek Ydieresis -70
+KPX Aogonek quoteright -74
+KPX Aogonek u -30
+KPX Aogonek uacute -30
+KPX Aogonek ucircumflex -30
+KPX Aogonek udieresis -30
+KPX Aogonek ugrave -30
+KPX Aogonek uhungarumlaut -30
+KPX Aogonek umacron -30
+KPX Aogonek uogonek -30
+KPX Aogonek uring -30
+KPX Aogonek v -74
+KPX Aogonek w -74
+KPX Aogonek y -34
+KPX Aogonek yacute -34
+KPX Aogonek ydieresis -34
+KPX Aring C -65
+KPX Aring Cacute -65
+KPX Aring Ccaron -65
+KPX Aring Ccedilla -65
+KPX Aring G -60
+KPX Aring Gbreve -60
+KPX Aring Gcommaaccent -60
+KPX Aring O -50
+KPX Aring Oacute -50
+KPX Aring Ocircumflex -50
+KPX Aring Odieresis -50
+KPX Aring Ograve -50
+KPX Aring Ohungarumlaut -50
+KPX Aring Omacron -50
+KPX Aring Oslash -50
+KPX Aring Otilde -50
+KPX Aring Q -55
+KPX Aring T -55
+KPX Aring Tcaron -55
+KPX Aring Tcommaaccent -55
+KPX Aring U -50
+KPX Aring Uacute -50
+KPX Aring Ucircumflex -50
+KPX Aring Udieresis -50
+KPX Aring Ugrave -50
+KPX Aring Uhungarumlaut -50
+KPX Aring Umacron -50
+KPX Aring Uogonek -50
+KPX Aring Uring -50
+KPX Aring V -95
+KPX Aring W -100
+KPX Aring Y -70
+KPX Aring Yacute -70
+KPX Aring Ydieresis -70
+KPX Aring quoteright -74
+KPX Aring u -30
+KPX Aring uacute -30
+KPX Aring ucircumflex -30
+KPX Aring udieresis -30
+KPX Aring ugrave -30
+KPX Aring uhungarumlaut -30
+KPX Aring umacron -30
+KPX Aring uogonek -30
+KPX Aring uring -30
+KPX Aring v -74
+KPX Aring w -74
+KPX Aring y -74
+KPX Aring yacute -74
+KPX Aring ydieresis -74
+KPX Atilde C -65
+KPX Atilde Cacute -65
+KPX Atilde Ccaron -65
+KPX Atilde Ccedilla -65
+KPX Atilde G -60
+KPX Atilde Gbreve -60
+KPX Atilde Gcommaaccent -60
+KPX Atilde O -50
+KPX Atilde Oacute -50
+KPX Atilde Ocircumflex -50
+KPX Atilde Odieresis -50
+KPX Atilde Ograve -50
+KPX Atilde Ohungarumlaut -50
+KPX Atilde Omacron -50
+KPX Atilde Oslash -50
+KPX Atilde Otilde -50
+KPX Atilde Q -55
+KPX Atilde T -55
+KPX Atilde Tcaron -55
+KPX Atilde Tcommaaccent -55
+KPX Atilde U -50
+KPX Atilde Uacute -50
+KPX Atilde Ucircumflex -50
+KPX Atilde Udieresis -50
+KPX Atilde Ugrave -50
+KPX Atilde Uhungarumlaut -50
+KPX Atilde Umacron -50
+KPX Atilde Uogonek -50
+KPX Atilde Uring -50
+KPX Atilde V -95
+KPX Atilde W -100
+KPX Atilde Y -70
+KPX Atilde Yacute -70
+KPX Atilde Ydieresis -70
+KPX Atilde quoteright -74
+KPX Atilde u -30
+KPX Atilde uacute -30
+KPX Atilde ucircumflex -30
+KPX Atilde udieresis -30
+KPX Atilde ugrave -30
+KPX Atilde uhungarumlaut -30
+KPX Atilde umacron -30
+KPX Atilde uogonek -30
+KPX Atilde uring -30
+KPX Atilde v -74
+KPX Atilde w -74
+KPX Atilde y -74
+KPX Atilde yacute -74
+KPX Atilde ydieresis -74
+KPX B A -25
+KPX B Aacute -25
+KPX B Abreve -25
+KPX B Acircumflex -25
+KPX B Adieresis -25
+KPX B Agrave -25
+KPX B Amacron -25
+KPX B Aogonek -25
+KPX B Aring -25
+KPX B Atilde -25
+KPX B U -10
+KPX B Uacute -10
+KPX B Ucircumflex -10
+KPX B Udieresis -10
+KPX B Ugrave -10
+KPX B Uhungarumlaut -10
+KPX B Umacron -10
+KPX B Uogonek -10
+KPX B Uring -10
+KPX D A -25
+KPX D Aacute -25
+KPX D Abreve -25
+KPX D Acircumflex -25
+KPX D Adieresis -25
+KPX D Agrave -25
+KPX D Amacron -25
+KPX D Aogonek -25
+KPX D Aring -25
+KPX D Atilde -25
+KPX D V -50
+KPX D W -40
+KPX D Y -50
+KPX D Yacute -50
+KPX D Ydieresis -50
+KPX Dcaron A -25
+KPX Dcaron Aacute -25
+KPX Dcaron Abreve -25
+KPX Dcaron Acircumflex -25
+KPX Dcaron Adieresis -25
+KPX Dcaron Agrave -25
+KPX Dcaron Amacron -25
+KPX Dcaron Aogonek -25
+KPX Dcaron Aring -25
+KPX Dcaron Atilde -25
+KPX Dcaron V -50
+KPX Dcaron W -40
+KPX Dcaron Y -50
+KPX Dcaron Yacute -50
+KPX Dcaron Ydieresis -50
+KPX Dcroat A -25
+KPX Dcroat Aacute -25
+KPX Dcroat Abreve -25
+KPX Dcroat Acircumflex -25
+KPX Dcroat Adieresis -25
+KPX Dcroat Agrave -25
+KPX Dcroat Amacron -25
+KPX Dcroat Aogonek -25
+KPX Dcroat Aring -25
+KPX Dcroat Atilde -25
+KPX Dcroat V -50
+KPX Dcroat W -40
+KPX Dcroat Y -50
+KPX Dcroat Yacute -50
+KPX Dcroat Ydieresis -50
+KPX F A -100
+KPX F Aacute -100
+KPX F Abreve -100
+KPX F Acircumflex -100
+KPX F Adieresis -100
+KPX F Agrave -100
+KPX F Amacron -100
+KPX F Aogonek -100
+KPX F Aring -100
+KPX F Atilde -100
+KPX F a -95
+KPX F aacute -95
+KPX F abreve -95
+KPX F acircumflex -95
+KPX F adieresis -95
+KPX F agrave -95
+KPX F amacron -95
+KPX F aogonek -95
+KPX F aring -95
+KPX F atilde -95
+KPX F comma -129
+KPX F e -100
+KPX F eacute -100
+KPX F ecaron -100
+KPX F ecircumflex -100
+KPX F edieresis -100
+KPX F edotaccent -100
+KPX F egrave -100
+KPX F emacron -100
+KPX F eogonek -100
+KPX F i -40
+KPX F iacute -40
+KPX F icircumflex -40
+KPX F idieresis -40
+KPX F igrave -40
+KPX F imacron -40
+KPX F iogonek -40
+KPX F o -70
+KPX F oacute -70
+KPX F ocircumflex -70
+KPX F odieresis -70
+KPX F ograve -70
+KPX F ohungarumlaut -70
+KPX F omacron -70
+KPX F oslash -70
+KPX F otilde -70
+KPX F period -129
+KPX F r -50
+KPX F racute -50
+KPX F rcaron -50
+KPX F rcommaaccent -50
+KPX J A -25
+KPX J Aacute -25
+KPX J Abreve -25
+KPX J Acircumflex -25
+KPX J Adieresis -25
+KPX J Agrave -25
+KPX J Amacron -25
+KPX J Aogonek -25
+KPX J Aring -25
+KPX J Atilde -25
+KPX J a -40
+KPX J aacute -40
+KPX J abreve -40
+KPX J acircumflex -40
+KPX J adieresis -40
+KPX J agrave -40
+KPX J amacron -40
+KPX J aogonek -40
+KPX J aring -40
+KPX J atilde -40
+KPX J comma -10
+KPX J e -40
+KPX J eacute -40
+KPX J ecaron -40
+KPX J ecircumflex -40
+KPX J edieresis -40
+KPX J edotaccent -40
+KPX J egrave -40
+KPX J emacron -40
+KPX J eogonek -40
+KPX J o -40
+KPX J oacute -40
+KPX J ocircumflex -40
+KPX J odieresis -40
+KPX J ograve -40
+KPX J ohungarumlaut -40
+KPX J omacron -40
+KPX J oslash -40
+KPX J otilde -40
+KPX J period -10
+KPX J u -40
+KPX J uacute -40
+KPX J ucircumflex -40
+KPX J udieresis -40
+KPX J ugrave -40
+KPX J uhungarumlaut -40
+KPX J umacron -40
+KPX J uogonek -40
+KPX J uring -40
+KPX K O -30
+KPX K Oacute -30
+KPX K Ocircumflex -30
+KPX K Odieresis -30
+KPX K Ograve -30
+KPX K Ohungarumlaut -30
+KPX K Omacron -30
+KPX K Oslash -30
+KPX K Otilde -30
+KPX K e -25
+KPX K eacute -25
+KPX K ecaron -25
+KPX K ecircumflex -25
+KPX K edieresis -25
+KPX K edotaccent -25
+KPX K egrave -25
+KPX K emacron -25
+KPX K eogonek -25
+KPX K o -25
+KPX K oacute -25
+KPX K ocircumflex -25
+KPX K odieresis -25
+KPX K ograve -25
+KPX K ohungarumlaut -25
+KPX K omacron -25
+KPX K oslash -25
+KPX K otilde -25
+KPX K u -20
+KPX K uacute -20
+KPX K ucircumflex -20
+KPX K udieresis -20
+KPX K ugrave -20
+KPX K uhungarumlaut -20
+KPX K umacron -20
+KPX K uogonek -20
+KPX K uring -20
+KPX K y -20
+KPX K yacute -20
+KPX K ydieresis -20
+KPX Kcommaaccent O -30
+KPX Kcommaaccent Oacute -30
+KPX Kcommaaccent Ocircumflex -30
+KPX Kcommaaccent Odieresis -30
+KPX Kcommaaccent Ograve -30
+KPX Kcommaaccent Ohungarumlaut -30
+KPX Kcommaaccent Omacron -30
+KPX Kcommaaccent Oslash -30
+KPX Kcommaaccent Otilde -30
+KPX Kcommaaccent e -25
+KPX Kcommaaccent eacute -25
+KPX Kcommaaccent ecaron -25
+KPX Kcommaaccent ecircumflex -25
+KPX Kcommaaccent edieresis -25
+KPX Kcommaaccent edotaccent -25
+KPX Kcommaaccent egrave -25
+KPX Kcommaaccent emacron -25
+KPX Kcommaaccent eogonek -25
+KPX Kcommaaccent o -25
+KPX Kcommaaccent oacute -25
+KPX Kcommaaccent ocircumflex -25
+KPX Kcommaaccent odieresis -25
+KPX Kcommaaccent ograve -25
+KPX Kcommaaccent ohungarumlaut -25
+KPX Kcommaaccent omacron -25
+KPX Kcommaaccent oslash -25
+KPX Kcommaaccent otilde -25
+KPX Kcommaaccent u -20
+KPX Kcommaaccent uacute -20
+KPX Kcommaaccent ucircumflex -20
+KPX Kcommaaccent udieresis -20
+KPX Kcommaaccent ugrave -20
+KPX Kcommaaccent uhungarumlaut -20
+KPX Kcommaaccent umacron -20
+KPX Kcommaaccent uogonek -20
+KPX Kcommaaccent uring -20
+KPX Kcommaaccent y -20
+KPX Kcommaaccent yacute -20
+KPX Kcommaaccent ydieresis -20
+KPX L T -18
+KPX L Tcaron -18
+KPX L Tcommaaccent -18
+KPX L V -37
+KPX L W -37
+KPX L Y -37
+KPX L Yacute -37
+KPX L Ydieresis -37
+KPX L quoteright -55
+KPX L y -37
+KPX L yacute -37
+KPX L ydieresis -37
+KPX Lacute T -18
+KPX Lacute Tcaron -18
+KPX Lacute Tcommaaccent -18
+KPX Lacute V -37
+KPX Lacute W -37
+KPX Lacute Y -37
+KPX Lacute Yacute -37
+KPX Lacute Ydieresis -37
+KPX Lacute quoteright -55
+KPX Lacute y -37
+KPX Lacute yacute -37
+KPX Lacute ydieresis -37
+KPX Lcommaaccent T -18
+KPX Lcommaaccent Tcaron -18
+KPX Lcommaaccent Tcommaaccent -18
+KPX Lcommaaccent V -37
+KPX Lcommaaccent W -37
+KPX Lcommaaccent Y -37
+KPX Lcommaaccent Yacute -37
+KPX Lcommaaccent Ydieresis -37
+KPX Lcommaaccent quoteright -55
+KPX Lcommaaccent y -37
+KPX Lcommaaccent yacute -37
+KPX Lcommaaccent ydieresis -37
+KPX Lslash T -18
+KPX Lslash Tcaron -18
+KPX Lslash Tcommaaccent -18
+KPX Lslash V -37
+KPX Lslash W -37
+KPX Lslash Y -37
+KPX Lslash Yacute -37
+KPX Lslash Ydieresis -37
+KPX Lslash quoteright -55
+KPX Lslash y -37
+KPX Lslash yacute -37
+KPX Lslash ydieresis -37
+KPX N A -30
+KPX N Aacute -30
+KPX N Abreve -30
+KPX N Acircumflex -30
+KPX N Adieresis -30
+KPX N Agrave -30
+KPX N Amacron -30
+KPX N Aogonek -30
+KPX N Aring -30
+KPX N Atilde -30
+KPX Nacute A -30
+KPX Nacute Aacute -30
+KPX Nacute Abreve -30
+KPX Nacute Acircumflex -30
+KPX Nacute Adieresis -30
+KPX Nacute Agrave -30
+KPX Nacute Amacron -30
+KPX Nacute Aogonek -30
+KPX Nacute Aring -30
+KPX Nacute Atilde -30
+KPX Ncaron A -30
+KPX Ncaron Aacute -30
+KPX Ncaron Abreve -30
+KPX Ncaron Acircumflex -30
+KPX Ncaron Adieresis -30
+KPX Ncaron Agrave -30
+KPX Ncaron Amacron -30
+KPX Ncaron Aogonek -30
+KPX Ncaron Aring -30
+KPX Ncaron Atilde -30
+KPX Ncommaaccent A -30
+KPX Ncommaaccent Aacute -30
+KPX Ncommaaccent Abreve -30
+KPX Ncommaaccent Acircumflex -30
+KPX Ncommaaccent Adieresis -30
+KPX Ncommaaccent Agrave -30
+KPX Ncommaaccent Amacron -30
+KPX Ncommaaccent Aogonek -30
+KPX Ncommaaccent Aring -30
+KPX Ncommaaccent Atilde -30
+KPX Ntilde A -30
+KPX Ntilde Aacute -30
+KPX Ntilde Abreve -30
+KPX Ntilde Acircumflex -30
+KPX Ntilde Adieresis -30
+KPX Ntilde Agrave -30
+KPX Ntilde Amacron -30
+KPX Ntilde Aogonek -30
+KPX Ntilde Aring -30
+KPX Ntilde Atilde -30
+KPX O A -40
+KPX O Aacute -40
+KPX O Abreve -40
+KPX O Acircumflex -40
+KPX O Adieresis -40
+KPX O Agrave -40
+KPX O Amacron -40
+KPX O Aogonek -40
+KPX O Aring -40
+KPX O Atilde -40
+KPX O T -40
+KPX O Tcaron -40
+KPX O Tcommaaccent -40
+KPX O V -50
+KPX O W -50
+KPX O X -40
+KPX O Y -50
+KPX O Yacute -50
+KPX O Ydieresis -50
+KPX Oacute A -40
+KPX Oacute Aacute -40
+KPX Oacute Abreve -40
+KPX Oacute Acircumflex -40
+KPX Oacute Adieresis -40
+KPX Oacute Agrave -40
+KPX Oacute Amacron -40
+KPX Oacute Aogonek -40
+KPX Oacute Aring -40
+KPX Oacute Atilde -40
+KPX Oacute T -40
+KPX Oacute Tcaron -40
+KPX Oacute Tcommaaccent -40
+KPX Oacute V -50
+KPX Oacute W -50
+KPX Oacute X -40
+KPX Oacute Y -50
+KPX Oacute Yacute -50
+KPX Oacute Ydieresis -50
+KPX Ocircumflex A -40
+KPX Ocircumflex Aacute -40
+KPX Ocircumflex Abreve -40
+KPX Ocircumflex Acircumflex -40
+KPX Ocircumflex Adieresis -40
+KPX Ocircumflex Agrave -40
+KPX Ocircumflex Amacron -40
+KPX Ocircumflex Aogonek -40
+KPX Ocircumflex Aring -40
+KPX Ocircumflex Atilde -40
+KPX Ocircumflex T -40
+KPX Ocircumflex Tcaron -40
+KPX Ocircumflex Tcommaaccent -40
+KPX Ocircumflex V -50
+KPX Ocircumflex W -50
+KPX Ocircumflex X -40
+KPX Ocircumflex Y -50
+KPX Ocircumflex Yacute -50
+KPX Ocircumflex Ydieresis -50
+KPX Odieresis A -40
+KPX Odieresis Aacute -40
+KPX Odieresis Abreve -40
+KPX Odieresis Acircumflex -40
+KPX Odieresis Adieresis -40
+KPX Odieresis Agrave -40
+KPX Odieresis Amacron -40
+KPX Odieresis Aogonek -40
+KPX Odieresis Aring -40
+KPX Odieresis Atilde -40
+KPX Odieresis T -40
+KPX Odieresis Tcaron -40
+KPX Odieresis Tcommaaccent -40
+KPX Odieresis V -50
+KPX Odieresis W -50
+KPX Odieresis X -40
+KPX Odieresis Y -50
+KPX Odieresis Yacute -50
+KPX Odieresis Ydieresis -50
+KPX Ograve A -40
+KPX Ograve Aacute -40
+KPX Ograve Abreve -40
+KPX Ograve Acircumflex -40
+KPX Ograve Adieresis -40
+KPX Ograve Agrave -40
+KPX Ograve Amacron -40
+KPX Ograve Aogonek -40
+KPX Ograve Aring -40
+KPX Ograve Atilde -40
+KPX Ograve T -40
+KPX Ograve Tcaron -40
+KPX Ograve Tcommaaccent -40
+KPX Ograve V -50
+KPX Ograve W -50
+KPX Ograve X -40
+KPX Ograve Y -50
+KPX Ograve Yacute -50
+KPX Ograve Ydieresis -50
+KPX Ohungarumlaut A -40
+KPX Ohungarumlaut Aacute -40
+KPX Ohungarumlaut Abreve -40
+KPX Ohungarumlaut Acircumflex -40
+KPX Ohungarumlaut Adieresis -40
+KPX Ohungarumlaut Agrave -40
+KPX Ohungarumlaut Amacron -40
+KPX Ohungarumlaut Aogonek -40
+KPX Ohungarumlaut Aring -40
+KPX Ohungarumlaut Atilde -40
+KPX Ohungarumlaut T -40
+KPX Ohungarumlaut Tcaron -40
+KPX Ohungarumlaut Tcommaaccent -40
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut W -50
+KPX Ohungarumlaut X -40
+KPX Ohungarumlaut Y -50
+KPX Ohungarumlaut Yacute -50
+KPX Ohungarumlaut Ydieresis -50
+KPX Omacron A -40
+KPX Omacron Aacute -40
+KPX Omacron Abreve -40
+KPX Omacron Acircumflex -40
+KPX Omacron Adieresis -40
+KPX Omacron Agrave -40
+KPX Omacron Amacron -40
+KPX Omacron Aogonek -40
+KPX Omacron Aring -40
+KPX Omacron Atilde -40
+KPX Omacron T -40
+KPX Omacron Tcaron -40
+KPX Omacron Tcommaaccent -40
+KPX Omacron V -50
+KPX Omacron W -50
+KPX Omacron X -40
+KPX Omacron Y -50
+KPX Omacron Yacute -50
+KPX Omacron Ydieresis -50
+KPX Oslash A -40
+KPX Oslash Aacute -40
+KPX Oslash Abreve -40
+KPX Oslash Acircumflex -40
+KPX Oslash Adieresis -40
+KPX Oslash Agrave -40
+KPX Oslash Amacron -40
+KPX Oslash Aogonek -40
+KPX Oslash Aring -40
+KPX Oslash Atilde -40
+KPX Oslash T -40
+KPX Oslash Tcaron -40
+KPX Oslash Tcommaaccent -40
+KPX Oslash V -50
+KPX Oslash W -50
+KPX Oslash X -40
+KPX Oslash Y -50
+KPX Oslash Yacute -50
+KPX Oslash Ydieresis -50
+KPX Otilde A -40
+KPX Otilde Aacute -40
+KPX Otilde Abreve -40
+KPX Otilde Acircumflex -40
+KPX Otilde Adieresis -40
+KPX Otilde Agrave -40
+KPX Otilde Amacron -40
+KPX Otilde Aogonek -40
+KPX Otilde Aring -40
+KPX Otilde Atilde -40
+KPX Otilde T -40
+KPX Otilde Tcaron -40
+KPX Otilde Tcommaaccent -40
+KPX Otilde V -50
+KPX Otilde W -50
+KPX Otilde X -40
+KPX Otilde Y -50
+KPX Otilde Yacute -50
+KPX Otilde Ydieresis -50
+KPX P A -85
+KPX P Aacute -85
+KPX P Abreve -85
+KPX P Acircumflex -85
+KPX P Adieresis -85
+KPX P Agrave -85
+KPX P Amacron -85
+KPX P Aogonek -85
+KPX P Aring -85
+KPX P Atilde -85
+KPX P a -40
+KPX P aacute -40
+KPX P abreve -40
+KPX P acircumflex -40
+KPX P adieresis -40
+KPX P agrave -40
+KPX P amacron -40
+KPX P aogonek -40
+KPX P aring -40
+KPX P atilde -40
+KPX P comma -129
+KPX P e -50
+KPX P eacute -50
+KPX P ecaron -50
+KPX P ecircumflex -50
+KPX P edieresis -50
+KPX P edotaccent -50
+KPX P egrave -50
+KPX P emacron -50
+KPX P eogonek -50
+KPX P o -55
+KPX P oacute -55
+KPX P ocircumflex -55
+KPX P odieresis -55
+KPX P ograve -55
+KPX P ohungarumlaut -55
+KPX P omacron -55
+KPX P oslash -55
+KPX P otilde -55
+KPX P period -129
+KPX Q U -10
+KPX Q Uacute -10
+KPX Q Ucircumflex -10
+KPX Q Udieresis -10
+KPX Q Ugrave -10
+KPX Q Uhungarumlaut -10
+KPX Q Umacron -10
+KPX Q Uogonek -10
+KPX Q Uring -10
+KPX R O -40
+KPX R Oacute -40
+KPX R Ocircumflex -40
+KPX R Odieresis -40
+KPX R Ograve -40
+KPX R Ohungarumlaut -40
+KPX R Omacron -40
+KPX R Oslash -40
+KPX R Otilde -40
+KPX R T -30
+KPX R Tcaron -30
+KPX R Tcommaaccent -30
+KPX R U -40
+KPX R Uacute -40
+KPX R Ucircumflex -40
+KPX R Udieresis -40
+KPX R Ugrave -40
+KPX R Uhungarumlaut -40
+KPX R Umacron -40
+KPX R Uogonek -40
+KPX R Uring -40
+KPX R V -18
+KPX R W -18
+KPX R Y -18
+KPX R Yacute -18
+KPX R Ydieresis -18
+KPX Racute O -40
+KPX Racute Oacute -40
+KPX Racute Ocircumflex -40
+KPX Racute Odieresis -40
+KPX Racute Ograve -40
+KPX Racute Ohungarumlaut -40
+KPX Racute Omacron -40
+KPX Racute Oslash -40
+KPX Racute Otilde -40
+KPX Racute T -30
+KPX Racute Tcaron -30
+KPX Racute Tcommaaccent -30
+KPX Racute U -40
+KPX Racute Uacute -40
+KPX Racute Ucircumflex -40
+KPX Racute Udieresis -40
+KPX Racute Ugrave -40
+KPX Racute Uhungarumlaut -40
+KPX Racute Umacron -40
+KPX Racute Uogonek -40
+KPX Racute Uring -40
+KPX Racute V -18
+KPX Racute W -18
+KPX Racute Y -18
+KPX Racute Yacute -18
+KPX Racute Ydieresis -18
+KPX Rcaron O -40
+KPX Rcaron Oacute -40
+KPX Rcaron Ocircumflex -40
+KPX Rcaron Odieresis -40
+KPX Rcaron Ograve -40
+KPX Rcaron Ohungarumlaut -40
+KPX Rcaron Omacron -40
+KPX Rcaron Oslash -40
+KPX Rcaron Otilde -40
+KPX Rcaron T -30
+KPX Rcaron Tcaron -30
+KPX Rcaron Tcommaaccent -30
+KPX Rcaron U -40
+KPX Rcaron Uacute -40
+KPX Rcaron Ucircumflex -40
+KPX Rcaron Udieresis -40
+KPX Rcaron Ugrave -40
+KPX Rcaron Uhungarumlaut -40
+KPX Rcaron Umacron -40
+KPX Rcaron Uogonek -40
+KPX Rcaron Uring -40
+KPX Rcaron V -18
+KPX Rcaron W -18
+KPX Rcaron Y -18
+KPX Rcaron Yacute -18
+KPX Rcaron Ydieresis -18
+KPX Rcommaaccent O -40
+KPX Rcommaaccent Oacute -40
+KPX Rcommaaccent Ocircumflex -40
+KPX Rcommaaccent Odieresis -40
+KPX Rcommaaccent Ograve -40
+KPX Rcommaaccent Ohungarumlaut -40
+KPX Rcommaaccent Omacron -40
+KPX Rcommaaccent Oslash -40
+KPX Rcommaaccent Otilde -40
+KPX Rcommaaccent T -30
+KPX Rcommaaccent Tcaron -30
+KPX Rcommaaccent Tcommaaccent -30
+KPX Rcommaaccent U -40
+KPX Rcommaaccent Uacute -40
+KPX Rcommaaccent Ucircumflex -40
+KPX Rcommaaccent Udieresis -40
+KPX Rcommaaccent Ugrave -40
+KPX Rcommaaccent Uhungarumlaut -40
+KPX Rcommaaccent Umacron -40
+KPX Rcommaaccent Uogonek -40
+KPX Rcommaaccent Uring -40
+KPX Rcommaaccent V -18
+KPX Rcommaaccent W -18
+KPX Rcommaaccent Y -18
+KPX Rcommaaccent Yacute -18
+KPX Rcommaaccent Ydieresis -18
+KPX T A -55
+KPX T Aacute -55
+KPX T Abreve -55
+KPX T Acircumflex -55
+KPX T Adieresis -55
+KPX T Agrave -55
+KPX T Amacron -55
+KPX T Aogonek -55
+KPX T Aring -55
+KPX T Atilde -55
+KPX T O -18
+KPX T Oacute -18
+KPX T Ocircumflex -18
+KPX T Odieresis -18
+KPX T Ograve -18
+KPX T Ohungarumlaut -18
+KPX T Omacron -18
+KPX T Oslash -18
+KPX T Otilde -18
+KPX T a -92
+KPX T aacute -92
+KPX T abreve -92
+KPX T acircumflex -92
+KPX T adieresis -92
+KPX T agrave -92
+KPX T amacron -92
+KPX T aogonek -92
+KPX T aring -92
+KPX T atilde -92
+KPX T colon -74
+KPX T comma -92
+KPX T e -92
+KPX T eacute -92
+KPX T ecaron -92
+KPX T ecircumflex -92
+KPX T edieresis -52
+KPX T edotaccent -92
+KPX T egrave -52
+KPX T emacron -52
+KPX T eogonek -92
+KPX T hyphen -92
+KPX T i -37
+KPX T iacute -37
+KPX T iogonek -37
+KPX T o -95
+KPX T oacute -95
+KPX T ocircumflex -95
+KPX T odieresis -95
+KPX T ograve -95
+KPX T ohungarumlaut -95
+KPX T omacron -95
+KPX T oslash -95
+KPX T otilde -95
+KPX T period -92
+KPX T r -37
+KPX T racute -37
+KPX T rcaron -37
+KPX T rcommaaccent -37
+KPX T semicolon -74
+KPX T u -37
+KPX T uacute -37
+KPX T ucircumflex -37
+KPX T udieresis -37
+KPX T ugrave -37
+KPX T uhungarumlaut -37
+KPX T umacron -37
+KPX T uogonek -37
+KPX T uring -37
+KPX T w -37
+KPX T y -37
+KPX T yacute -37
+KPX T ydieresis -37
+KPX Tcaron A -55
+KPX Tcaron Aacute -55
+KPX Tcaron Abreve -55
+KPX Tcaron Acircumflex -55
+KPX Tcaron Adieresis -55
+KPX Tcaron Agrave -55
+KPX Tcaron Amacron -55
+KPX Tcaron Aogonek -55
+KPX Tcaron Aring -55
+KPX Tcaron Atilde -55
+KPX Tcaron O -18
+KPX Tcaron Oacute -18
+KPX Tcaron Ocircumflex -18
+KPX Tcaron Odieresis -18
+KPX Tcaron Ograve -18
+KPX Tcaron Ohungarumlaut -18
+KPX Tcaron Omacron -18
+KPX Tcaron Oslash -18
+KPX Tcaron Otilde -18
+KPX Tcaron a -92
+KPX Tcaron aacute -92
+KPX Tcaron abreve -92
+KPX Tcaron acircumflex -92
+KPX Tcaron adieresis -92
+KPX Tcaron agrave -92
+KPX Tcaron amacron -92
+KPX Tcaron aogonek -92
+KPX Tcaron aring -92
+KPX Tcaron atilde -92
+KPX Tcaron colon -74
+KPX Tcaron comma -92
+KPX Tcaron e -92
+KPX Tcaron eacute -92
+KPX Tcaron ecaron -92
+KPX Tcaron ecircumflex -92
+KPX Tcaron edieresis -52
+KPX Tcaron edotaccent -92
+KPX Tcaron egrave -52
+KPX Tcaron emacron -52
+KPX Tcaron eogonek -92
+KPX Tcaron hyphen -92
+KPX Tcaron i -37
+KPX Tcaron iacute -37
+KPX Tcaron iogonek -37
+KPX Tcaron o -95
+KPX Tcaron oacute -95
+KPX Tcaron ocircumflex -95
+KPX Tcaron odieresis -95
+KPX Tcaron ograve -95
+KPX Tcaron ohungarumlaut -95
+KPX Tcaron omacron -95
+KPX Tcaron oslash -95
+KPX Tcaron otilde -95
+KPX Tcaron period -92
+KPX Tcaron r -37
+KPX Tcaron racute -37
+KPX Tcaron rcaron -37
+KPX Tcaron rcommaaccent -37
+KPX Tcaron semicolon -74
+KPX Tcaron u -37
+KPX Tcaron uacute -37
+KPX Tcaron ucircumflex -37
+KPX Tcaron udieresis -37
+KPX Tcaron ugrave -37
+KPX Tcaron uhungarumlaut -37
+KPX Tcaron umacron -37
+KPX Tcaron uogonek -37
+KPX Tcaron uring -37
+KPX Tcaron w -37
+KPX Tcaron y -37
+KPX Tcaron yacute -37
+KPX Tcaron ydieresis -37
+KPX Tcommaaccent A -55
+KPX Tcommaaccent Aacute -55
+KPX Tcommaaccent Abreve -55
+KPX Tcommaaccent Acircumflex -55
+KPX Tcommaaccent Adieresis -55
+KPX Tcommaaccent Agrave -55
+KPX Tcommaaccent Amacron -55
+KPX Tcommaaccent Aogonek -55
+KPX Tcommaaccent Aring -55
+KPX Tcommaaccent Atilde -55
+KPX Tcommaaccent O -18
+KPX Tcommaaccent Oacute -18
+KPX Tcommaaccent Ocircumflex -18
+KPX Tcommaaccent Odieresis -18
+KPX Tcommaaccent Ograve -18
+KPX Tcommaaccent Ohungarumlaut -18
+KPX Tcommaaccent Omacron -18
+KPX Tcommaaccent Oslash -18
+KPX Tcommaaccent Otilde -18
+KPX Tcommaaccent a -92
+KPX Tcommaaccent aacute -92
+KPX Tcommaaccent abreve -92
+KPX Tcommaaccent acircumflex -92
+KPX Tcommaaccent adieresis -92
+KPX Tcommaaccent agrave -92
+KPX Tcommaaccent amacron -92
+KPX Tcommaaccent aogonek -92
+KPX Tcommaaccent aring -92
+KPX Tcommaaccent atilde -92
+KPX Tcommaaccent colon -74
+KPX Tcommaaccent comma -92
+KPX Tcommaaccent e -92
+KPX Tcommaaccent eacute -92
+KPX Tcommaaccent ecaron -92
+KPX Tcommaaccent ecircumflex -92
+KPX Tcommaaccent edieresis -52
+KPX Tcommaaccent edotaccent -92
+KPX Tcommaaccent egrave -52
+KPX Tcommaaccent emacron -52
+KPX Tcommaaccent eogonek -92
+KPX Tcommaaccent hyphen -92
+KPX Tcommaaccent i -37
+KPX Tcommaaccent iacute -37
+KPX Tcommaaccent iogonek -37
+KPX Tcommaaccent o -95
+KPX Tcommaaccent oacute -95
+KPX Tcommaaccent ocircumflex -95
+KPX Tcommaaccent odieresis -95
+KPX Tcommaaccent ograve -95
+KPX Tcommaaccent ohungarumlaut -95
+KPX Tcommaaccent omacron -95
+KPX Tcommaaccent oslash -95
+KPX Tcommaaccent otilde -95
+KPX Tcommaaccent period -92
+KPX Tcommaaccent r -37
+KPX Tcommaaccent racute -37
+KPX Tcommaaccent rcaron -37
+KPX Tcommaaccent rcommaaccent -37
+KPX Tcommaaccent semicolon -74
+KPX Tcommaaccent u -37
+KPX Tcommaaccent uacute -37
+KPX Tcommaaccent ucircumflex -37
+KPX Tcommaaccent udieresis -37
+KPX Tcommaaccent ugrave -37
+KPX Tcommaaccent uhungarumlaut -37
+KPX Tcommaaccent umacron -37
+KPX Tcommaaccent uogonek -37
+KPX Tcommaaccent uring -37
+KPX Tcommaaccent w -37
+KPX Tcommaaccent y -37
+KPX Tcommaaccent yacute -37
+KPX Tcommaaccent ydieresis -37
+KPX U A -45
+KPX U Aacute -45
+KPX U Abreve -45
+KPX U Acircumflex -45
+KPX U Adieresis -45
+KPX U Agrave -45
+KPX U Amacron -45
+KPX U Aogonek -45
+KPX U Aring -45
+KPX U Atilde -45
+KPX Uacute A -45
+KPX Uacute Aacute -45
+KPX Uacute Abreve -45
+KPX Uacute Acircumflex -45
+KPX Uacute Adieresis -45
+KPX Uacute Agrave -45
+KPX Uacute Amacron -45
+KPX Uacute Aogonek -45
+KPX Uacute Aring -45
+KPX Uacute Atilde -45
+KPX Ucircumflex A -45
+KPX Ucircumflex Aacute -45
+KPX Ucircumflex Abreve -45
+KPX Ucircumflex Acircumflex -45
+KPX Ucircumflex Adieresis -45
+KPX Ucircumflex Agrave -45
+KPX Ucircumflex Amacron -45
+KPX Ucircumflex Aogonek -45
+KPX Ucircumflex Aring -45
+KPX Ucircumflex Atilde -45
+KPX Udieresis A -45
+KPX Udieresis Aacute -45
+KPX Udieresis Abreve -45
+KPX Udieresis Acircumflex -45
+KPX Udieresis Adieresis -45
+KPX Udieresis Agrave -45
+KPX Udieresis Amacron -45
+KPX Udieresis Aogonek -45
+KPX Udieresis Aring -45
+KPX Udieresis Atilde -45
+KPX Ugrave A -45
+KPX Ugrave Aacute -45
+KPX Ugrave Abreve -45
+KPX Ugrave Acircumflex -45
+KPX Ugrave Adieresis -45
+KPX Ugrave Agrave -45
+KPX Ugrave Amacron -45
+KPX Ugrave Aogonek -45
+KPX Ugrave Aring -45
+KPX Ugrave Atilde -45
+KPX Uhungarumlaut A -45
+KPX Uhungarumlaut Aacute -45
+KPX Uhungarumlaut Abreve -45
+KPX Uhungarumlaut Acircumflex -45
+KPX Uhungarumlaut Adieresis -45
+KPX Uhungarumlaut Agrave -45
+KPX Uhungarumlaut Amacron -45
+KPX Uhungarumlaut Aogonek -45
+KPX Uhungarumlaut Aring -45
+KPX Uhungarumlaut Atilde -45
+KPX Umacron A -45
+KPX Umacron Aacute -45
+KPX Umacron Abreve -45
+KPX Umacron Acircumflex -45
+KPX Umacron Adieresis -45
+KPX Umacron Agrave -45
+KPX Umacron Amacron -45
+KPX Umacron Aogonek -45
+KPX Umacron Aring -45
+KPX Umacron Atilde -45
+KPX Uogonek A -45
+KPX Uogonek Aacute -45
+KPX Uogonek Abreve -45
+KPX Uogonek Acircumflex -45
+KPX Uogonek Adieresis -45
+KPX Uogonek Agrave -45
+KPX Uogonek Amacron -45
+KPX Uogonek Aogonek -45
+KPX Uogonek Aring -45
+KPX Uogonek Atilde -45
+KPX Uring A -45
+KPX Uring Aacute -45
+KPX Uring Abreve -45
+KPX Uring Acircumflex -45
+KPX Uring Adieresis -45
+KPX Uring Agrave -45
+KPX Uring Amacron -45
+KPX Uring Aogonek -45
+KPX Uring Aring -45
+KPX Uring Atilde -45
+KPX V A -85
+KPX V Aacute -85
+KPX V Abreve -85
+KPX V Acircumflex -85
+KPX V Adieresis -85
+KPX V Agrave -85
+KPX V Amacron -85
+KPX V Aogonek -85
+KPX V Aring -85
+KPX V Atilde -85
+KPX V G -10
+KPX V Gbreve -10
+KPX V Gcommaaccent -10
+KPX V O -30
+KPX V Oacute -30
+KPX V Ocircumflex -30
+KPX V Odieresis -30
+KPX V Ograve -30
+KPX V Ohungarumlaut -30
+KPX V Omacron -30
+KPX V Oslash -30
+KPX V Otilde -30
+KPX V a -111
+KPX V aacute -111
+KPX V abreve -111
+KPX V acircumflex -111
+KPX V adieresis -111
+KPX V agrave -111
+KPX V amacron -111
+KPX V aogonek -111
+KPX V aring -111
+KPX V atilde -111
+KPX V colon -74
+KPX V comma -129
+KPX V e -111
+KPX V eacute -111
+KPX V ecaron -111
+KPX V ecircumflex -111
+KPX V edieresis -71
+KPX V edotaccent -111
+KPX V egrave -71
+KPX V emacron -71
+KPX V eogonek -111
+KPX V hyphen -70
+KPX V i -55
+KPX V iacute -55
+KPX V iogonek -55
+KPX V o -111
+KPX V oacute -111
+KPX V ocircumflex -111
+KPX V odieresis -111
+KPX V ograve -111
+KPX V ohungarumlaut -111
+KPX V omacron -111
+KPX V oslash -111
+KPX V otilde -111
+KPX V period -129
+KPX V semicolon -74
+KPX V u -55
+KPX V uacute -55
+KPX V ucircumflex -55
+KPX V udieresis -55
+KPX V ugrave -55
+KPX V uhungarumlaut -55
+KPX V umacron -55
+KPX V uogonek -55
+KPX V uring -55
+KPX W A -74
+KPX W Aacute -74
+KPX W Abreve -74
+KPX W Acircumflex -74
+KPX W Adieresis -74
+KPX W Agrave -74
+KPX W Amacron -74
+KPX W Aogonek -74
+KPX W Aring -74
+KPX W Atilde -74
+KPX W O -15
+KPX W Oacute -15
+KPX W Ocircumflex -15
+KPX W Odieresis -15
+KPX W Ograve -15
+KPX W Ohungarumlaut -15
+KPX W Omacron -15
+KPX W Oslash -15
+KPX W Otilde -15
+KPX W a -85
+KPX W aacute -85
+KPX W abreve -85
+KPX W acircumflex -85
+KPX W adieresis -85
+KPX W agrave -85
+KPX W amacron -85
+KPX W aogonek -85
+KPX W aring -85
+KPX W atilde -85
+KPX W colon -55
+KPX W comma -74
+KPX W e -90
+KPX W eacute -90
+KPX W ecaron -90
+KPX W ecircumflex -90
+KPX W edieresis -50
+KPX W edotaccent -90
+KPX W egrave -50
+KPX W emacron -50
+KPX W eogonek -90
+KPX W hyphen -50
+KPX W i -37
+KPX W iacute -37
+KPX W iogonek -37
+KPX W o -80
+KPX W oacute -80
+KPX W ocircumflex -80
+KPX W odieresis -80
+KPX W ograve -80
+KPX W ohungarumlaut -80
+KPX W omacron -80
+KPX W oslash -80
+KPX W otilde -80
+KPX W period -74
+KPX W semicolon -55
+KPX W u -55
+KPX W uacute -55
+KPX W ucircumflex -55
+KPX W udieresis -55
+KPX W ugrave -55
+KPX W uhungarumlaut -55
+KPX W umacron -55
+KPX W uogonek -55
+KPX W uring -55
+KPX W y -55
+KPX W yacute -55
+KPX W ydieresis -55
+KPX Y A -74
+KPX Y Aacute -74
+KPX Y Abreve -74
+KPX Y Acircumflex -74
+KPX Y Adieresis -74
+KPX Y Agrave -74
+KPX Y Amacron -74
+KPX Y Aogonek -74
+KPX Y Aring -74
+KPX Y Atilde -74
+KPX Y O -25
+KPX Y Oacute -25
+KPX Y Ocircumflex -25
+KPX Y Odieresis -25
+KPX Y Ograve -25
+KPX Y Ohungarumlaut -25
+KPX Y Omacron -25
+KPX Y Oslash -25
+KPX Y Otilde -25
+KPX Y a -92
+KPX Y aacute -92
+KPX Y abreve -92
+KPX Y acircumflex -92
+KPX Y adieresis -92
+KPX Y agrave -92
+KPX Y amacron -92
+KPX Y aogonek -92
+KPX Y aring -92
+KPX Y atilde -92
+KPX Y colon -92
+KPX Y comma -92
+KPX Y e -111
+KPX Y eacute -111
+KPX Y ecaron -111
+KPX Y ecircumflex -71
+KPX Y edieresis -71
+KPX Y edotaccent -111
+KPX Y egrave -71
+KPX Y emacron -71
+KPX Y eogonek -111
+KPX Y hyphen -92
+KPX Y i -55
+KPX Y iacute -55
+KPX Y iogonek -55
+KPX Y o -111
+KPX Y oacute -111
+KPX Y ocircumflex -111
+KPX Y odieresis -111
+KPX Y ograve -111
+KPX Y ohungarumlaut -111
+KPX Y omacron -111
+KPX Y oslash -111
+KPX Y otilde -111
+KPX Y period -74
+KPX Y semicolon -92
+KPX Y u -92
+KPX Y uacute -92
+KPX Y ucircumflex -92
+KPX Y udieresis -92
+KPX Y ugrave -92
+KPX Y uhungarumlaut -92
+KPX Y umacron -92
+KPX Y uogonek -92
+KPX Y uring -92
+KPX Yacute A -74
+KPX Yacute Aacute -74
+KPX Yacute Abreve -74
+KPX Yacute Acircumflex -74
+KPX Yacute Adieresis -74
+KPX Yacute Agrave -74
+KPX Yacute Amacron -74
+KPX Yacute Aogonek -74
+KPX Yacute Aring -74
+KPX Yacute Atilde -74
+KPX Yacute O -25
+KPX Yacute Oacute -25
+KPX Yacute Ocircumflex -25
+KPX Yacute Odieresis -25
+KPX Yacute Ograve -25
+KPX Yacute Ohungarumlaut -25
+KPX Yacute Omacron -25
+KPX Yacute Oslash -25
+KPX Yacute Otilde -25
+KPX Yacute a -92
+KPX Yacute aacute -92
+KPX Yacute abreve -92
+KPX Yacute acircumflex -92
+KPX Yacute adieresis -92
+KPX Yacute agrave -92
+KPX Yacute amacron -92
+KPX Yacute aogonek -92
+KPX Yacute aring -92
+KPX Yacute atilde -92
+KPX Yacute colon -92
+KPX Yacute comma -92
+KPX Yacute e -111
+KPX Yacute eacute -111
+KPX Yacute ecaron -111
+KPX Yacute ecircumflex -71
+KPX Yacute edieresis -71
+KPX Yacute edotaccent -111
+KPX Yacute egrave -71
+KPX Yacute emacron -71
+KPX Yacute eogonek -111
+KPX Yacute hyphen -92
+KPX Yacute i -55
+KPX Yacute iacute -55
+KPX Yacute iogonek -55
+KPX Yacute o -111
+KPX Yacute oacute -111
+KPX Yacute ocircumflex -111
+KPX Yacute odieresis -111
+KPX Yacute ograve -111
+KPX Yacute ohungarumlaut -111
+KPX Yacute omacron -111
+KPX Yacute oslash -111
+KPX Yacute otilde -111
+KPX Yacute period -74
+KPX Yacute semicolon -92
+KPX Yacute u -92
+KPX Yacute uacute -92
+KPX Yacute ucircumflex -92
+KPX Yacute udieresis -92
+KPX Yacute ugrave -92
+KPX Yacute uhungarumlaut -92
+KPX Yacute umacron -92
+KPX Yacute uogonek -92
+KPX Yacute uring -92
+KPX Ydieresis A -74
+KPX Ydieresis Aacute -74
+KPX Ydieresis Abreve -74
+KPX Ydieresis Acircumflex -74
+KPX Ydieresis Adieresis -74
+KPX Ydieresis Agrave -74
+KPX Ydieresis Amacron -74
+KPX Ydieresis Aogonek -74
+KPX Ydieresis Aring -74
+KPX Ydieresis Atilde -74
+KPX Ydieresis O -25
+KPX Ydieresis Oacute -25
+KPX Ydieresis Ocircumflex -25
+KPX Ydieresis Odieresis -25
+KPX Ydieresis Ograve -25
+KPX Ydieresis Ohungarumlaut -25
+KPX Ydieresis Omacron -25
+KPX Ydieresis Oslash -25
+KPX Ydieresis Otilde -25
+KPX Ydieresis a -92
+KPX Ydieresis aacute -92
+KPX Ydieresis abreve -92
+KPX Ydieresis acircumflex -92
+KPX Ydieresis adieresis -92
+KPX Ydieresis agrave -92
+KPX Ydieresis amacron -92
+KPX Ydieresis aogonek -92
+KPX Ydieresis aring -92
+KPX Ydieresis atilde -92
+KPX Ydieresis colon -92
+KPX Ydieresis comma -92
+KPX Ydieresis e -111
+KPX Ydieresis eacute -111
+KPX Ydieresis ecaron -111
+KPX Ydieresis ecircumflex -71
+KPX Ydieresis edieresis -71
+KPX Ydieresis edotaccent -111
+KPX Ydieresis egrave -71
+KPX Ydieresis emacron -71
+KPX Ydieresis eogonek -111
+KPX Ydieresis hyphen -92
+KPX Ydieresis i -55
+KPX Ydieresis iacute -55
+KPX Ydieresis iogonek -55
+KPX Ydieresis o -111
+KPX Ydieresis oacute -111
+KPX Ydieresis ocircumflex -111
+KPX Ydieresis odieresis -111
+KPX Ydieresis ograve -111
+KPX Ydieresis ohungarumlaut -111
+KPX Ydieresis omacron -111
+KPX Ydieresis oslash -111
+KPX Ydieresis otilde -111
+KPX Ydieresis period -74
+KPX Ydieresis semicolon -92
+KPX Ydieresis u -92
+KPX Ydieresis uacute -92
+KPX Ydieresis ucircumflex -92
+KPX Ydieresis udieresis -92
+KPX Ydieresis ugrave -92
+KPX Ydieresis uhungarumlaut -92
+KPX Ydieresis umacron -92
+KPX Ydieresis uogonek -92
+KPX Ydieresis uring -92
+KPX b b -10
+KPX b period -40
+KPX b u -20
+KPX b uacute -20
+KPX b ucircumflex -20
+KPX b udieresis -20
+KPX b ugrave -20
+KPX b uhungarumlaut -20
+KPX b umacron -20
+KPX b uogonek -20
+KPX b uring -20
+KPX c h -10
+KPX c k -10
+KPX c kcommaaccent -10
+KPX cacute h -10
+KPX cacute k -10
+KPX cacute kcommaaccent -10
+KPX ccaron h -10
+KPX ccaron k -10
+KPX ccaron kcommaaccent -10
+KPX ccedilla h -10
+KPX ccedilla k -10
+KPX ccedilla kcommaaccent -10
+KPX comma quotedblright -95
+KPX comma quoteright -95
+KPX e b -10
+KPX eacute b -10
+KPX ecaron b -10
+KPX ecircumflex b -10
+KPX edieresis b -10
+KPX edotaccent b -10
+KPX egrave b -10
+KPX emacron b -10
+KPX eogonek b -10
+KPX f comma -10
+KPX f dotlessi -30
+KPX f e -10
+KPX f eacute -10
+KPX f edotaccent -10
+KPX f eogonek -10
+KPX f f -18
+KPX f o -10
+KPX f oacute -10
+KPX f ocircumflex -10
+KPX f ograve -10
+KPX f ohungarumlaut -10
+KPX f oslash -10
+KPX f otilde -10
+KPX f period -10
+KPX f quoteright 55
+KPX k e -30
+KPX k eacute -30
+KPX k ecaron -30
+KPX k ecircumflex -30
+KPX k edieresis -30
+KPX k edotaccent -30
+KPX k egrave -30
+KPX k emacron -30
+KPX k eogonek -30
+KPX k o -10
+KPX k oacute -10
+KPX k ocircumflex -10
+KPX k odieresis -10
+KPX k ograve -10
+KPX k ohungarumlaut -10
+KPX k omacron -10
+KPX k oslash -10
+KPX k otilde -10
+KPX kcommaaccent e -30
+KPX kcommaaccent eacute -30
+KPX kcommaaccent ecaron -30
+KPX kcommaaccent ecircumflex -30
+KPX kcommaaccent edieresis -30
+KPX kcommaaccent edotaccent -30
+KPX kcommaaccent egrave -30
+KPX kcommaaccent emacron -30
+KPX kcommaaccent eogonek -30
+KPX kcommaaccent o -10
+KPX kcommaaccent oacute -10
+KPX kcommaaccent ocircumflex -10
+KPX kcommaaccent odieresis -10
+KPX kcommaaccent ograve -10
+KPX kcommaaccent ohungarumlaut -10
+KPX kcommaaccent omacron -10
+KPX kcommaaccent oslash -10
+KPX kcommaaccent otilde -10
+KPX n v -40
+KPX nacute v -40
+KPX ncaron v -40
+KPX ncommaaccent v -40
+KPX ntilde v -40
+KPX o v -15
+KPX o w -25
+KPX o x -10
+KPX o y -10
+KPX o yacute -10
+KPX o ydieresis -10
+KPX oacute v -15
+KPX oacute w -25
+KPX oacute x -10
+KPX oacute y -10
+KPX oacute yacute -10
+KPX oacute ydieresis -10
+KPX ocircumflex v -15
+KPX ocircumflex w -25
+KPX ocircumflex x -10
+KPX ocircumflex y -10
+KPX ocircumflex yacute -10
+KPX ocircumflex ydieresis -10
+KPX odieresis v -15
+KPX odieresis w -25
+KPX odieresis x -10
+KPX odieresis y -10
+KPX odieresis yacute -10
+KPX odieresis ydieresis -10
+KPX ograve v -15
+KPX ograve w -25
+KPX ograve x -10
+KPX ograve y -10
+KPX ograve yacute -10
+KPX ograve ydieresis -10
+KPX ohungarumlaut v -15
+KPX ohungarumlaut w -25
+KPX ohungarumlaut x -10
+KPX ohungarumlaut y -10
+KPX ohungarumlaut yacute -10
+KPX ohungarumlaut ydieresis -10
+KPX omacron v -15
+KPX omacron w -25
+KPX omacron x -10
+KPX omacron y -10
+KPX omacron yacute -10
+KPX omacron ydieresis -10
+KPX oslash v -15
+KPX oslash w -25
+KPX oslash x -10
+KPX oslash y -10
+KPX oslash yacute -10
+KPX oslash ydieresis -10
+KPX otilde v -15
+KPX otilde w -25
+KPX otilde x -10
+KPX otilde y -10
+KPX otilde yacute -10
+KPX otilde ydieresis -10
+KPX period quotedblright -95
+KPX period quoteright -95
+KPX quoteleft quoteleft -74
+KPX quoteright d -15
+KPX quoteright dcroat -15
+KPX quoteright quoteright -74
+KPX quoteright r -15
+KPX quoteright racute -15
+KPX quoteright rcaron -15
+KPX quoteright rcommaaccent -15
+KPX quoteright s -74
+KPX quoteright sacute -74
+KPX quoteright scaron -74
+KPX quoteright scedilla -74
+KPX quoteright scommaaccent -74
+KPX quoteright space -74
+KPX quoteright t -37
+KPX quoteright tcommaaccent -37
+KPX quoteright v -15
+KPX r comma -65
+KPX r period -65
+KPX racute comma -65
+KPX racute period -65
+KPX rcaron comma -65
+KPX rcaron period -65
+KPX rcommaaccent comma -65
+KPX rcommaaccent period -65
+KPX space A -37
+KPX space Aacute -37
+KPX space Abreve -37
+KPX space Acircumflex -37
+KPX space Adieresis -37
+KPX space Agrave -37
+KPX space Amacron -37
+KPX space Aogonek -37
+KPX space Aring -37
+KPX space Atilde -37
+KPX space V -70
+KPX space W -70
+KPX space Y -70
+KPX space Yacute -70
+KPX space Ydieresis -70
+KPX v comma -37
+KPX v e -15
+KPX v eacute -15
+KPX v ecaron -15
+KPX v ecircumflex -15
+KPX v edieresis -15
+KPX v edotaccent -15
+KPX v egrave -15
+KPX v emacron -15
+KPX v eogonek -15
+KPX v o -15
+KPX v oacute -15
+KPX v ocircumflex -15
+KPX v odieresis -15
+KPX v ograve -15
+KPX v ohungarumlaut -15
+KPX v omacron -15
+KPX v oslash -15
+KPX v otilde -15
+KPX v period -37
+KPX w a -10
+KPX w aacute -10
+KPX w abreve -10
+KPX w acircumflex -10
+KPX w adieresis -10
+KPX w agrave -10
+KPX w amacron -10
+KPX w aogonek -10
+KPX w aring -10
+KPX w atilde -10
+KPX w comma -37
+KPX w e -10
+KPX w eacute -10
+KPX w ecaron -10
+KPX w ecircumflex -10
+KPX w edieresis -10
+KPX w edotaccent -10
+KPX w egrave -10
+KPX w emacron -10
+KPX w eogonek -10
+KPX w o -15
+KPX w oacute -15
+KPX w ocircumflex -15
+KPX w odieresis -15
+KPX w ograve -15
+KPX w ohungarumlaut -15
+KPX w omacron -15
+KPX w oslash -15
+KPX w otilde -15
+KPX w period -37
+KPX x e -10
+KPX x eacute -10
+KPX x ecaron -10
+KPX x ecircumflex -10
+KPX x edieresis -10
+KPX x edotaccent -10
+KPX x egrave -10
+KPX x emacron -10
+KPX x eogonek -10
+KPX y comma -37
+KPX y period -37
+KPX yacute comma -37
+KPX yacute period -37
+KPX ydieresis comma -37
+KPX ydieresis period -37
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Times-Italic.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Times-Italic.afm
new file mode 100644
index 0000000..041f0e8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Times-Italic.afm
@@ -0,0 +1,2667 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 12:56:55 1997
+Comment UniqueID 43067
+Comment VMusage 47727 58752
+FontName Times-Italic
+FullName Times Italic
+FamilyName Times
+Weight Medium
+ItalicAngle -15.5
+IsFixedPitch false
+CharacterSet ExtendedRoman
+FontBBox -169 -217 1010 883
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 653
+XHeight 441
+Ascender 683
+Descender -217
+StdHW 32
+StdVW 76
+StartCharMetrics 315
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ;
+C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ;
+C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ;
+C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ;
+C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ;
+C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ;
+C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ;
+C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ;
+C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ;
+C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ;
+C 43 ; WX 675 ; N plus ; B 86 0 590 506 ;
+C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ;
+C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ;
+C 46 ; WX 250 ; N period ; B 27 -11 138 100 ;
+C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ;
+C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ;
+C 49 ; WX 500 ; N one ; B 49 0 409 676 ;
+C 50 ; WX 500 ; N two ; B 12 0 452 676 ;
+C 51 ; WX 500 ; N three ; B 15 -7 465 676 ;
+C 52 ; WX 500 ; N four ; B 1 0 479 676 ;
+C 53 ; WX 500 ; N five ; B 15 -7 491 666 ;
+C 54 ; WX 500 ; N six ; B 30 -7 521 686 ;
+C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ;
+C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ;
+C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ;
+C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ;
+C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ;
+C 60 ; WX 675 ; N less ; B 84 -8 592 514 ;
+C 61 ; WX 675 ; N equal ; B 86 120 590 386 ;
+C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ;
+C 63 ; WX 500 ; N question ; B 132 -12 472 664 ;
+C 64 ; WX 920 ; N at ; B 118 -18 806 666 ;
+C 65 ; WX 611 ; N A ; B -51 0 564 668 ;
+C 66 ; WX 611 ; N B ; B -8 0 588 653 ;
+C 67 ; WX 667 ; N C ; B 66 -18 689 666 ;
+C 68 ; WX 722 ; N D ; B -8 0 700 653 ;
+C 69 ; WX 611 ; N E ; B -1 0 634 653 ;
+C 70 ; WX 611 ; N F ; B 8 0 645 653 ;
+C 71 ; WX 722 ; N G ; B 52 -18 722 666 ;
+C 72 ; WX 722 ; N H ; B -8 0 767 653 ;
+C 73 ; WX 333 ; N I ; B -8 0 384 653 ;
+C 74 ; WX 444 ; N J ; B -6 -18 491 653 ;
+C 75 ; WX 667 ; N K ; B 7 0 722 653 ;
+C 76 ; WX 556 ; N L ; B -8 0 559 653 ;
+C 77 ; WX 833 ; N M ; B -18 0 873 653 ;
+C 78 ; WX 667 ; N N ; B -20 -15 727 653 ;
+C 79 ; WX 722 ; N O ; B 60 -18 699 666 ;
+C 80 ; WX 611 ; N P ; B 0 0 605 653 ;
+C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ;
+C 82 ; WX 611 ; N R ; B -13 0 588 653 ;
+C 83 ; WX 500 ; N S ; B 17 -18 508 667 ;
+C 84 ; WX 556 ; N T ; B 59 0 633 653 ;
+C 85 ; WX 722 ; N U ; B 102 -18 765 653 ;
+C 86 ; WX 611 ; N V ; B 76 -18 688 653 ;
+C 87 ; WX 833 ; N W ; B 71 -18 906 653 ;
+C 88 ; WX 611 ; N X ; B -29 0 655 653 ;
+C 89 ; WX 556 ; N Y ; B 78 0 633 653 ;
+C 90 ; WX 556 ; N Z ; B -6 0 606 653 ;
+C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ;
+C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ;
+C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ;
+C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ;
+C 97 ; WX 500 ; N a ; B 17 -11 476 441 ;
+C 98 ; WX 500 ; N b ; B 23 -11 473 683 ;
+C 99 ; WX 444 ; N c ; B 30 -11 425 441 ;
+C 100 ; WX 500 ; N d ; B 15 -13 527 683 ;
+C 101 ; WX 444 ; N e ; B 31 -11 412 441 ;
+C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 8 -206 472 441 ;
+C 104 ; WX 500 ; N h ; B 19 -9 478 683 ;
+C 105 ; WX 278 ; N i ; B 49 -11 264 654 ;
+C 106 ; WX 278 ; N j ; B -124 -207 276 654 ;
+C 107 ; WX 444 ; N k ; B 14 -11 461 683 ;
+C 108 ; WX 278 ; N l ; B 41 -11 279 683 ;
+C 109 ; WX 722 ; N m ; B 12 -9 704 441 ;
+C 110 ; WX 500 ; N n ; B 14 -9 474 441 ;
+C 111 ; WX 500 ; N o ; B 27 -11 468 441 ;
+C 112 ; WX 500 ; N p ; B -75 -205 469 441 ;
+C 113 ; WX 500 ; N q ; B 25 -209 483 441 ;
+C 114 ; WX 389 ; N r ; B 45 0 412 441 ;
+C 115 ; WX 389 ; N s ; B 16 -13 366 442 ;
+C 116 ; WX 278 ; N t ; B 37 -11 296 546 ;
+C 117 ; WX 500 ; N u ; B 42 -11 475 441 ;
+C 118 ; WX 444 ; N v ; B 21 -18 426 441 ;
+C 119 ; WX 667 ; N w ; B 16 -18 648 441 ;
+C 120 ; WX 444 ; N x ; B -27 -11 447 441 ;
+C 121 ; WX 444 ; N y ; B -24 -206 426 441 ;
+C 122 ; WX 389 ; N z ; B -2 -81 380 428 ;
+C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ;
+C 124 ; WX 275 ; N bar ; B 105 -217 171 783 ;
+C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ;
+C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
+C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ;
+C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ;
+C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ;
+C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ;
+C 165 ; WX 500 ; N yen ; B 27 0 603 653 ;
+C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ;
+C 167 ; WX 500 ; N section ; B 53 -162 461 666 ;
+C 168 ; WX 500 ; N currency ; B -22 53 522 597 ;
+C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ;
+C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ;
+C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ;
+C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ;
+C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ;
+C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ;
+C 177 ; WX 500 ; N endash ; B -6 197 505 243 ;
+C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ;
+C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ;
+C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
+C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ;
+C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ;
+C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ;
+C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ;
+C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ;
+C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ;
+C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ;
+C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ;
+C 193 ; WX 333 ; N grave ; B 121 492 311 664 ;
+C 194 ; WX 333 ; N acute ; B 180 494 403 664 ;
+C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ;
+C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ;
+C 197 ; WX 333 ; N macron ; B 99 532 411 583 ;
+C 198 ; WX 333 ; N breve ; B 117 492 418 650 ;
+C 199 ; WX 333 ; N dotaccent ; B 207 548 305 646 ;
+C 200 ; WX 333 ; N dieresis ; B 107 548 405 646 ;
+C 202 ; WX 333 ; N ring ; B 155 492 355 691 ;
+C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ;
+C 206 ; WX 333 ; N ogonek ; B 20 -169 203 40 ;
+C 207 ; WX 333 ; N caron ; B 121 492 426 661 ;
+C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ;
+C 225 ; WX 889 ; N AE ; B -27 0 911 653 ;
+C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ;
+C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ;
+C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ;
+C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ;
+C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ;
+C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ;
+C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ;
+C 248 ; WX 278 ; N lslash ; B 41 -11 312 683 ;
+C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ;
+C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ;
+C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ;
+C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ;
+C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ;
+C -1 ; WX 500 ; N abreve ; B 17 -11 502 650 ;
+C -1 ; WX 500 ; N uhungarumlaut ; B 42 -11 580 664 ;
+C -1 ; WX 444 ; N ecaron ; B 31 -11 482 661 ;
+C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ;
+C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ;
+C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ;
+C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ;
+C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ;
+C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ;
+C -1 ; WX 389 ; N scommaaccent ; B 16 -217 366 442 ;
+C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ;
+C -1 ; WX 722 ; N Uring ; B 102 -18 765 883 ;
+C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ;
+C -1 ; WX 500 ; N aogonek ; B 17 -169 476 441 ;
+C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ;
+C -1 ; WX 500 ; N uogonek ; B 42 -169 477 441 ;
+C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ;
+C -1 ; WX 722 ; N Dcroat ; B -8 0 700 653 ;
+C -1 ; WX 250 ; N commaaccent ; B 8 -217 133 -50 ;
+C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ;
+C -1 ; WX 611 ; N Emacron ; B -1 0 634 795 ;
+C -1 ; WX 444 ; N ccaron ; B 30 -11 482 661 ;
+C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ;
+C -1 ; WX 667 ; N Ncommaaccent ; B -20 -187 727 653 ;
+C -1 ; WX 278 ; N lacute ; B 41 -11 395 876 ;
+C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ;
+C -1 ; WX 556 ; N Tcommaaccent ; B 59 -217 633 653 ;
+C -1 ; WX 667 ; N Cacute ; B 66 -18 690 876 ;
+C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ;
+C -1 ; WX 611 ; N Edotaccent ; B -1 0 634 818 ;
+C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ;
+C -1 ; WX 389 ; N scedilla ; B 16 -217 366 442 ;
+C -1 ; WX 278 ; N iacute ; B 49 -11 355 664 ;
+C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ;
+C -1 ; WX 611 ; N Rcaron ; B -13 0 588 873 ;
+C -1 ; WX 722 ; N Gcommaaccent ; B 52 -217 722 666 ;
+C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ;
+C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ;
+C -1 ; WX 611 ; N Amacron ; B -51 0 564 795 ;
+C -1 ; WX 389 ; N rcaron ; B 45 0 434 661 ;
+C -1 ; WX 444 ; N ccedilla ; B 30 -217 425 441 ;
+C -1 ; WX 556 ; N Zdotaccent ; B -6 0 606 818 ;
+C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ;
+C -1 ; WX 722 ; N Omacron ; B 60 -18 699 795 ;
+C -1 ; WX 611 ; N Racute ; B -13 0 588 876 ;
+C -1 ; WX 500 ; N Sacute ; B 17 -18 508 876 ;
+C -1 ; WX 544 ; N dcaron ; B 15 -13 658 683 ;
+C -1 ; WX 722 ; N Umacron ; B 102 -18 765 795 ;
+C -1 ; WX 500 ; N uring ; B 42 -11 475 691 ;
+C -1 ; WX 300 ; N threebaseior ; B 43 268 339 676 ;
+C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ;
+C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ;
+C -1 ; WX 611 ; N Abreve ; B -51 0 564 862 ;
+C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ;
+C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ;
+C -1 ; WX 556 ; N Tcaron ; B 59 0 633 873 ;
+C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ;
+C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ;
+C -1 ; WX 667 ; N Nacute ; B -20 -15 727 876 ;
+C -1 ; WX 278 ; N icircumflex ; B 33 -11 327 661 ;
+C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ;
+C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ;
+C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ;
+C -1 ; WX 444 ; N cacute ; B 30 -11 459 664 ;
+C -1 ; WX 500 ; N nacute ; B 14 -9 477 664 ;
+C -1 ; WX 500 ; N umacron ; B 42 -11 485 583 ;
+C -1 ; WX 667 ; N Ncaron ; B -20 -15 727 873 ;
+C -1 ; WX 333 ; N Iacute ; B -8 0 433 876 ;
+C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ;
+C -1 ; WX 275 ; N brokenbar ; B 105 -142 171 708 ;
+C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ;
+C -1 ; WX 722 ; N Gbreve ; B 52 -18 722 862 ;
+C -1 ; WX 333 ; N Idotaccent ; B -8 0 384 818 ;
+C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ;
+C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ;
+C -1 ; WX 389 ; N racute ; B 45 0 431 664 ;
+C -1 ; WX 500 ; N omacron ; B 27 -11 495 583 ;
+C -1 ; WX 556 ; N Zacute ; B -6 0 606 876 ;
+C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ;
+C -1 ; WX 549 ; N greaterequal ; B 26 0 523 658 ;
+C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ;
+C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ;
+C -1 ; WX 278 ; N lcommaaccent ; B 22 -217 279 683 ;
+C -1 ; WX 300 ; N tcaron ; B 37 -11 407 681 ;
+C -1 ; WX 444 ; N eogonek ; B 31 -169 412 441 ;
+C -1 ; WX 722 ; N Uogonek ; B 102 -184 765 653 ;
+C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ;
+C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ;
+C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ;
+C -1 ; WX 389 ; N zacute ; B -2 -81 431 664 ;
+C -1 ; WX 278 ; N iogonek ; B 49 -169 264 654 ;
+C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ;
+C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ;
+C -1 ; WX 500 ; N amacron ; B 17 -11 495 583 ;
+C -1 ; WX 389 ; N sacute ; B 16 -13 431 664 ;
+C -1 ; WX 278 ; N idieresis ; B 49 -11 352 606 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ;
+C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ;
+C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ;
+C -1 ; WX 300 ; N twobaseior ; B 33 271 324 676 ;
+C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ;
+C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ;
+C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ;
+C -1 ; WX 500 ; N ohungarumlaut ; B 27 -11 590 664 ;
+C -1 ; WX 611 ; N Eogonek ; B -1 -169 634 653 ;
+C -1 ; WX 500 ; N dcroat ; B 15 -13 572 683 ;
+C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ;
+C -1 ; WX 500 ; N Scedilla ; B 17 -217 508 667 ;
+C -1 ; WX 300 ; N lcaron ; B 41 -11 407 683 ;
+C -1 ; WX 667 ; N Kcommaaccent ; B 7 -217 722 653 ;
+C -1 ; WX 556 ; N Lacute ; B -8 0 559 876 ;
+C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ;
+C -1 ; WX 444 ; N edotaccent ; B 31 -11 412 606 ;
+C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ;
+C -1 ; WX 333 ; N Imacron ; B -8 0 441 795 ;
+C -1 ; WX 611 ; N Lcaron ; B -8 0 586 653 ;
+C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ;
+C -1 ; WX 549 ; N lessequal ; B 26 0 523 658 ;
+C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ;
+C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ;
+C -1 ; WX 722 ; N Uhungarumlaut ; B 102 -18 765 876 ;
+C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ;
+C -1 ; WX 444 ; N emacron ; B 31 -11 457 583 ;
+C -1 ; WX 500 ; N gbreve ; B 8 -206 487 650 ;
+C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ;
+C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ;
+C -1 ; WX 500 ; N Scommaaccent ; B 17 -217 508 667 ;
+C -1 ; WX 722 ; N Ohungarumlaut ; B 60 -18 699 876 ;
+C -1 ; WX 400 ; N degree ; B 101 390 387 676 ;
+C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ;
+C -1 ; WX 667 ; N Ccaron ; B 66 -18 689 873 ;
+C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ;
+C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ;
+C -1 ; WX 722 ; N Dcaron ; B -8 0 700 873 ;
+C -1 ; WX 389 ; N rcommaaccent ; B -3 -217 412 441 ;
+C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ;
+C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ;
+C -1 ; WX 611 ; N Rcommaaccent ; B -13 -187 588 653 ;
+C -1 ; WX 556 ; N Lcommaaccent ; B -8 -217 559 653 ;
+C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ;
+C -1 ; WX 611 ; N Aogonek ; B -51 -169 566 668 ;
+C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ;
+C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ;
+C -1 ; WX 389 ; N zdotaccent ; B -2 -81 380 606 ;
+C -1 ; WX 611 ; N Ecaron ; B -1 0 634 873 ;
+C -1 ; WX 333 ; N Iogonek ; B -8 -169 384 653 ;
+C -1 ; WX 444 ; N kcommaaccent ; B 14 -187 461 683 ;
+C -1 ; WX 675 ; N minus ; B 86 220 590 286 ;
+C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ;
+C -1 ; WX 500 ; N ncaron ; B 14 -9 510 661 ;
+C -1 ; WX 278 ; N tcommaaccent ; B 2 -217 296 546 ;
+C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ;
+C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ;
+C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ;
+C -1 ; WX 549 ; N notequal ; B 12 -29 537 541 ;
+C -1 ; WX 500 ; N gcommaaccent ; B 8 -206 472 706 ;
+C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ;
+C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ;
+C -1 ; WX 500 ; N ncommaaccent ; B 14 -187 474 441 ;
+C -1 ; WX 300 ; N onebaseior ; B 43 271 284 676 ;
+C -1 ; WX 278 ; N imacron ; B 46 -11 311 583 ;
+C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 2321
+KPX A C -30
+KPX A Cacute -30
+KPX A Ccaron -30
+KPX A Ccedilla -30
+KPX A G -35
+KPX A Gbreve -35
+KPX A Gcommaaccent -35
+KPX A O -40
+KPX A Oacute -40
+KPX A Ocircumflex -40
+KPX A Odieresis -40
+KPX A Ograve -40
+KPX A Ohungarumlaut -40
+KPX A Omacron -40
+KPX A Oslash -40
+KPX A Otilde -40
+KPX A Q -40
+KPX A T -37
+KPX A Tcaron -37
+KPX A Tcommaaccent -37
+KPX A U -50
+KPX A Uacute -50
+KPX A Ucircumflex -50
+KPX A Udieresis -50
+KPX A Ugrave -50
+KPX A Uhungarumlaut -50
+KPX A Umacron -50
+KPX A Uogonek -50
+KPX A Uring -50
+KPX A V -105
+KPX A W -95
+KPX A Y -55
+KPX A Yacute -55
+KPX A Ydieresis -55
+KPX A quoteright -37
+KPX A u -20
+KPX A uacute -20
+KPX A ucircumflex -20
+KPX A udieresis -20
+KPX A ugrave -20
+KPX A uhungarumlaut -20
+KPX A umacron -20
+KPX A uogonek -20
+KPX A uring -20
+KPX A v -55
+KPX A w -55
+KPX A y -55
+KPX A yacute -55
+KPX A ydieresis -55
+KPX Aacute C -30
+KPX Aacute Cacute -30
+KPX Aacute Ccaron -30
+KPX Aacute Ccedilla -30
+KPX Aacute G -35
+KPX Aacute Gbreve -35
+KPX Aacute Gcommaaccent -35
+KPX Aacute O -40
+KPX Aacute Oacute -40
+KPX Aacute Ocircumflex -40
+KPX Aacute Odieresis -40
+KPX Aacute Ograve -40
+KPX Aacute Ohungarumlaut -40
+KPX Aacute Omacron -40
+KPX Aacute Oslash -40
+KPX Aacute Otilde -40
+KPX Aacute Q -40
+KPX Aacute T -37
+KPX Aacute Tcaron -37
+KPX Aacute Tcommaaccent -37
+KPX Aacute U -50
+KPX Aacute Uacute -50
+KPX Aacute Ucircumflex -50
+KPX Aacute Udieresis -50
+KPX Aacute Ugrave -50
+KPX Aacute Uhungarumlaut -50
+KPX Aacute Umacron -50
+KPX Aacute Uogonek -50
+KPX Aacute Uring -50
+KPX Aacute V -105
+KPX Aacute W -95
+KPX Aacute Y -55
+KPX Aacute Yacute -55
+KPX Aacute Ydieresis -55
+KPX Aacute quoteright -37
+KPX Aacute u -20
+KPX Aacute uacute -20
+KPX Aacute ucircumflex -20
+KPX Aacute udieresis -20
+KPX Aacute ugrave -20
+KPX Aacute uhungarumlaut -20
+KPX Aacute umacron -20
+KPX Aacute uogonek -20
+KPX Aacute uring -20
+KPX Aacute v -55
+KPX Aacute w -55
+KPX Aacute y -55
+KPX Aacute yacute -55
+KPX Aacute ydieresis -55
+KPX Abreve C -30
+KPX Abreve Cacute -30
+KPX Abreve Ccaron -30
+KPX Abreve Ccedilla -30
+KPX Abreve G -35
+KPX Abreve Gbreve -35
+KPX Abreve Gcommaaccent -35
+KPX Abreve O -40
+KPX Abreve Oacute -40
+KPX Abreve Ocircumflex -40
+KPX Abreve Odieresis -40
+KPX Abreve Ograve -40
+KPX Abreve Ohungarumlaut -40
+KPX Abreve Omacron -40
+KPX Abreve Oslash -40
+KPX Abreve Otilde -40
+KPX Abreve Q -40
+KPX Abreve T -37
+KPX Abreve Tcaron -37
+KPX Abreve Tcommaaccent -37
+KPX Abreve U -50
+KPX Abreve Uacute -50
+KPX Abreve Ucircumflex -50
+KPX Abreve Udieresis -50
+KPX Abreve Ugrave -50
+KPX Abreve Uhungarumlaut -50
+KPX Abreve Umacron -50
+KPX Abreve Uogonek -50
+KPX Abreve Uring -50
+KPX Abreve V -105
+KPX Abreve W -95
+KPX Abreve Y -55
+KPX Abreve Yacute -55
+KPX Abreve Ydieresis -55
+KPX Abreve quoteright -37
+KPX Abreve u -20
+KPX Abreve uacute -20
+KPX Abreve ucircumflex -20
+KPX Abreve udieresis -20
+KPX Abreve ugrave -20
+KPX Abreve uhungarumlaut -20
+KPX Abreve umacron -20
+KPX Abreve uogonek -20
+KPX Abreve uring -20
+KPX Abreve v -55
+KPX Abreve w -55
+KPX Abreve y -55
+KPX Abreve yacute -55
+KPX Abreve ydieresis -55
+KPX Acircumflex C -30
+KPX Acircumflex Cacute -30
+KPX Acircumflex Ccaron -30
+KPX Acircumflex Ccedilla -30
+KPX Acircumflex G -35
+KPX Acircumflex Gbreve -35
+KPX Acircumflex Gcommaaccent -35
+KPX Acircumflex O -40
+KPX Acircumflex Oacute -40
+KPX Acircumflex Ocircumflex -40
+KPX Acircumflex Odieresis -40
+KPX Acircumflex Ograve -40
+KPX Acircumflex Ohungarumlaut -40
+KPX Acircumflex Omacron -40
+KPX Acircumflex Oslash -40
+KPX Acircumflex Otilde -40
+KPX Acircumflex Q -40
+KPX Acircumflex T -37
+KPX Acircumflex Tcaron -37
+KPX Acircumflex Tcommaaccent -37
+KPX Acircumflex U -50
+KPX Acircumflex Uacute -50
+KPX Acircumflex Ucircumflex -50
+KPX Acircumflex Udieresis -50
+KPX Acircumflex Ugrave -50
+KPX Acircumflex Uhungarumlaut -50
+KPX Acircumflex Umacron -50
+KPX Acircumflex Uogonek -50
+KPX Acircumflex Uring -50
+KPX Acircumflex V -105
+KPX Acircumflex W -95
+KPX Acircumflex Y -55
+KPX Acircumflex Yacute -55
+KPX Acircumflex Ydieresis -55
+KPX Acircumflex quoteright -37
+KPX Acircumflex u -20
+KPX Acircumflex uacute -20
+KPX Acircumflex ucircumflex -20
+KPX Acircumflex udieresis -20
+KPX Acircumflex ugrave -20
+KPX Acircumflex uhungarumlaut -20
+KPX Acircumflex umacron -20
+KPX Acircumflex uogonek -20
+KPX Acircumflex uring -20
+KPX Acircumflex v -55
+KPX Acircumflex w -55
+KPX Acircumflex y -55
+KPX Acircumflex yacute -55
+KPX Acircumflex ydieresis -55
+KPX Adieresis C -30
+KPX Adieresis Cacute -30
+KPX Adieresis Ccaron -30
+KPX Adieresis Ccedilla -30
+KPX Adieresis G -35
+KPX Adieresis Gbreve -35
+KPX Adieresis Gcommaaccent -35
+KPX Adieresis O -40
+KPX Adieresis Oacute -40
+KPX Adieresis Ocircumflex -40
+KPX Adieresis Odieresis -40
+KPX Adieresis Ograve -40
+KPX Adieresis Ohungarumlaut -40
+KPX Adieresis Omacron -40
+KPX Adieresis Oslash -40
+KPX Adieresis Otilde -40
+KPX Adieresis Q -40
+KPX Adieresis T -37
+KPX Adieresis Tcaron -37
+KPX Adieresis Tcommaaccent -37
+KPX Adieresis U -50
+KPX Adieresis Uacute -50
+KPX Adieresis Ucircumflex -50
+KPX Adieresis Udieresis -50
+KPX Adieresis Ugrave -50
+KPX Adieresis Uhungarumlaut -50
+KPX Adieresis Umacron -50
+KPX Adieresis Uogonek -50
+KPX Adieresis Uring -50
+KPX Adieresis V -105
+KPX Adieresis W -95
+KPX Adieresis Y -55
+KPX Adieresis Yacute -55
+KPX Adieresis Ydieresis -55
+KPX Adieresis quoteright -37
+KPX Adieresis u -20
+KPX Adieresis uacute -20
+KPX Adieresis ucircumflex -20
+KPX Adieresis udieresis -20
+KPX Adieresis ugrave -20
+KPX Adieresis uhungarumlaut -20
+KPX Adieresis umacron -20
+KPX Adieresis uogonek -20
+KPX Adieresis uring -20
+KPX Adieresis v -55
+KPX Adieresis w -55
+KPX Adieresis y -55
+KPX Adieresis yacute -55
+KPX Adieresis ydieresis -55
+KPX Agrave C -30
+KPX Agrave Cacute -30
+KPX Agrave Ccaron -30
+KPX Agrave Ccedilla -30
+KPX Agrave G -35
+KPX Agrave Gbreve -35
+KPX Agrave Gcommaaccent -35
+KPX Agrave O -40
+KPX Agrave Oacute -40
+KPX Agrave Ocircumflex -40
+KPX Agrave Odieresis -40
+KPX Agrave Ograve -40
+KPX Agrave Ohungarumlaut -40
+KPX Agrave Omacron -40
+KPX Agrave Oslash -40
+KPX Agrave Otilde -40
+KPX Agrave Q -40
+KPX Agrave T -37
+KPX Agrave Tcaron -37
+KPX Agrave Tcommaaccent -37
+KPX Agrave U -50
+KPX Agrave Uacute -50
+KPX Agrave Ucircumflex -50
+KPX Agrave Udieresis -50
+KPX Agrave Ugrave -50
+KPX Agrave Uhungarumlaut -50
+KPX Agrave Umacron -50
+KPX Agrave Uogonek -50
+KPX Agrave Uring -50
+KPX Agrave V -105
+KPX Agrave W -95
+KPX Agrave Y -55
+KPX Agrave Yacute -55
+KPX Agrave Ydieresis -55
+KPX Agrave quoteright -37
+KPX Agrave u -20
+KPX Agrave uacute -20
+KPX Agrave ucircumflex -20
+KPX Agrave udieresis -20
+KPX Agrave ugrave -20
+KPX Agrave uhungarumlaut -20
+KPX Agrave umacron -20
+KPX Agrave uogonek -20
+KPX Agrave uring -20
+KPX Agrave v -55
+KPX Agrave w -55
+KPX Agrave y -55
+KPX Agrave yacute -55
+KPX Agrave ydieresis -55
+KPX Amacron C -30
+KPX Amacron Cacute -30
+KPX Amacron Ccaron -30
+KPX Amacron Ccedilla -30
+KPX Amacron G -35
+KPX Amacron Gbreve -35
+KPX Amacron Gcommaaccent -35
+KPX Amacron O -40
+KPX Amacron Oacute -40
+KPX Amacron Ocircumflex -40
+KPX Amacron Odieresis -40
+KPX Amacron Ograve -40
+KPX Amacron Ohungarumlaut -40
+KPX Amacron Omacron -40
+KPX Amacron Oslash -40
+KPX Amacron Otilde -40
+KPX Amacron Q -40
+KPX Amacron T -37
+KPX Amacron Tcaron -37
+KPX Amacron Tcommaaccent -37
+KPX Amacron U -50
+KPX Amacron Uacute -50
+KPX Amacron Ucircumflex -50
+KPX Amacron Udieresis -50
+KPX Amacron Ugrave -50
+KPX Amacron Uhungarumlaut -50
+KPX Amacron Umacron -50
+KPX Amacron Uogonek -50
+KPX Amacron Uring -50
+KPX Amacron V -105
+KPX Amacron W -95
+KPX Amacron Y -55
+KPX Amacron Yacute -55
+KPX Amacron Ydieresis -55
+KPX Amacron quoteright -37
+KPX Amacron u -20
+KPX Amacron uacute -20
+KPX Amacron ucircumflex -20
+KPX Amacron udieresis -20
+KPX Amacron ugrave -20
+KPX Amacron uhungarumlaut -20
+KPX Amacron umacron -20
+KPX Amacron uogonek -20
+KPX Amacron uring -20
+KPX Amacron v -55
+KPX Amacron w -55
+KPX Amacron y -55
+KPX Amacron yacute -55
+KPX Amacron ydieresis -55
+KPX Aogonek C -30
+KPX Aogonek Cacute -30
+KPX Aogonek Ccaron -30
+KPX Aogonek Ccedilla -30
+KPX Aogonek G -35
+KPX Aogonek Gbreve -35
+KPX Aogonek Gcommaaccent -35
+KPX Aogonek O -40
+KPX Aogonek Oacute -40
+KPX Aogonek Ocircumflex -40
+KPX Aogonek Odieresis -40
+KPX Aogonek Ograve -40
+KPX Aogonek Ohungarumlaut -40
+KPX Aogonek Omacron -40
+KPX Aogonek Oslash -40
+KPX Aogonek Otilde -40
+KPX Aogonek Q -40
+KPX Aogonek T -37
+KPX Aogonek Tcaron -37
+KPX Aogonek Tcommaaccent -37
+KPX Aogonek U -50
+KPX Aogonek Uacute -50
+KPX Aogonek Ucircumflex -50
+KPX Aogonek Udieresis -50
+KPX Aogonek Ugrave -50
+KPX Aogonek Uhungarumlaut -50
+KPX Aogonek Umacron -50
+KPX Aogonek Uogonek -50
+KPX Aogonek Uring -50
+KPX Aogonek V -105
+KPX Aogonek W -95
+KPX Aogonek Y -55
+KPX Aogonek Yacute -55
+KPX Aogonek Ydieresis -55
+KPX Aogonek quoteright -37
+KPX Aogonek u -20
+KPX Aogonek uacute -20
+KPX Aogonek ucircumflex -20
+KPX Aogonek udieresis -20
+KPX Aogonek ugrave -20
+KPX Aogonek uhungarumlaut -20
+KPX Aogonek umacron -20
+KPX Aogonek uogonek -20
+KPX Aogonek uring -20
+KPX Aogonek v -55
+KPX Aogonek w -55
+KPX Aogonek y -55
+KPX Aogonek yacute -55
+KPX Aogonek ydieresis -55
+KPX Aring C -30
+KPX Aring Cacute -30
+KPX Aring Ccaron -30
+KPX Aring Ccedilla -30
+KPX Aring G -35
+KPX Aring Gbreve -35
+KPX Aring Gcommaaccent -35
+KPX Aring O -40
+KPX Aring Oacute -40
+KPX Aring Ocircumflex -40
+KPX Aring Odieresis -40
+KPX Aring Ograve -40
+KPX Aring Ohungarumlaut -40
+KPX Aring Omacron -40
+KPX Aring Oslash -40
+KPX Aring Otilde -40
+KPX Aring Q -40
+KPX Aring T -37
+KPX Aring Tcaron -37
+KPX Aring Tcommaaccent -37
+KPX Aring U -50
+KPX Aring Uacute -50
+KPX Aring Ucircumflex -50
+KPX Aring Udieresis -50
+KPX Aring Ugrave -50
+KPX Aring Uhungarumlaut -50
+KPX Aring Umacron -50
+KPX Aring Uogonek -50
+KPX Aring Uring -50
+KPX Aring V -105
+KPX Aring W -95
+KPX Aring Y -55
+KPX Aring Yacute -55
+KPX Aring Ydieresis -55
+KPX Aring quoteright -37
+KPX Aring u -20
+KPX Aring uacute -20
+KPX Aring ucircumflex -20
+KPX Aring udieresis -20
+KPX Aring ugrave -20
+KPX Aring uhungarumlaut -20
+KPX Aring umacron -20
+KPX Aring uogonek -20
+KPX Aring uring -20
+KPX Aring v -55
+KPX Aring w -55
+KPX Aring y -55
+KPX Aring yacute -55
+KPX Aring ydieresis -55
+KPX Atilde C -30
+KPX Atilde Cacute -30
+KPX Atilde Ccaron -30
+KPX Atilde Ccedilla -30
+KPX Atilde G -35
+KPX Atilde Gbreve -35
+KPX Atilde Gcommaaccent -35
+KPX Atilde O -40
+KPX Atilde Oacute -40
+KPX Atilde Ocircumflex -40
+KPX Atilde Odieresis -40
+KPX Atilde Ograve -40
+KPX Atilde Ohungarumlaut -40
+KPX Atilde Omacron -40
+KPX Atilde Oslash -40
+KPX Atilde Otilde -40
+KPX Atilde Q -40
+KPX Atilde T -37
+KPX Atilde Tcaron -37
+KPX Atilde Tcommaaccent -37
+KPX Atilde U -50
+KPX Atilde Uacute -50
+KPX Atilde Ucircumflex -50
+KPX Atilde Udieresis -50
+KPX Atilde Ugrave -50
+KPX Atilde Uhungarumlaut -50
+KPX Atilde Umacron -50
+KPX Atilde Uogonek -50
+KPX Atilde Uring -50
+KPX Atilde V -105
+KPX Atilde W -95
+KPX Atilde Y -55
+KPX Atilde Yacute -55
+KPX Atilde Ydieresis -55
+KPX Atilde quoteright -37
+KPX Atilde u -20
+KPX Atilde uacute -20
+KPX Atilde ucircumflex -20
+KPX Atilde udieresis -20
+KPX Atilde ugrave -20
+KPX Atilde uhungarumlaut -20
+KPX Atilde umacron -20
+KPX Atilde uogonek -20
+KPX Atilde uring -20
+KPX Atilde v -55
+KPX Atilde w -55
+KPX Atilde y -55
+KPX Atilde yacute -55
+KPX Atilde ydieresis -55
+KPX B A -25
+KPX B Aacute -25
+KPX B Abreve -25
+KPX B Acircumflex -25
+KPX B Adieresis -25
+KPX B Agrave -25
+KPX B Amacron -25
+KPX B Aogonek -25
+KPX B Aring -25
+KPX B Atilde -25
+KPX B U -10
+KPX B Uacute -10
+KPX B Ucircumflex -10
+KPX B Udieresis -10
+KPX B Ugrave -10
+KPX B Uhungarumlaut -10
+KPX B Umacron -10
+KPX B Uogonek -10
+KPX B Uring -10
+KPX D A -35
+KPX D Aacute -35
+KPX D Abreve -35
+KPX D Acircumflex -35
+KPX D Adieresis -35
+KPX D Agrave -35
+KPX D Amacron -35
+KPX D Aogonek -35
+KPX D Aring -35
+KPX D Atilde -35
+KPX D V -40
+KPX D W -40
+KPX D Y -40
+KPX D Yacute -40
+KPX D Ydieresis -40
+KPX Dcaron A -35
+KPX Dcaron Aacute -35
+KPX Dcaron Abreve -35
+KPX Dcaron Acircumflex -35
+KPX Dcaron Adieresis -35
+KPX Dcaron Agrave -35
+KPX Dcaron Amacron -35
+KPX Dcaron Aogonek -35
+KPX Dcaron Aring -35
+KPX Dcaron Atilde -35
+KPX Dcaron V -40
+KPX Dcaron W -40
+KPX Dcaron Y -40
+KPX Dcaron Yacute -40
+KPX Dcaron Ydieresis -40
+KPX Dcroat A -35
+KPX Dcroat Aacute -35
+KPX Dcroat Abreve -35
+KPX Dcroat Acircumflex -35
+KPX Dcroat Adieresis -35
+KPX Dcroat Agrave -35
+KPX Dcroat Amacron -35
+KPX Dcroat Aogonek -35
+KPX Dcroat Aring -35
+KPX Dcroat Atilde -35
+KPX Dcroat V -40
+KPX Dcroat W -40
+KPX Dcroat Y -40
+KPX Dcroat Yacute -40
+KPX Dcroat Ydieresis -40
+KPX F A -115
+KPX F Aacute -115
+KPX F Abreve -115
+KPX F Acircumflex -115
+KPX F Adieresis -115
+KPX F Agrave -115
+KPX F Amacron -115
+KPX F Aogonek -115
+KPX F Aring -115
+KPX F Atilde -115
+KPX F a -75
+KPX F aacute -75
+KPX F abreve -75
+KPX F acircumflex -75
+KPX F adieresis -75
+KPX F agrave -75
+KPX F amacron -75
+KPX F aogonek -75
+KPX F aring -75
+KPX F atilde -75
+KPX F comma -135
+KPX F e -75
+KPX F eacute -75
+KPX F ecaron -75
+KPX F ecircumflex -75
+KPX F edieresis -75
+KPX F edotaccent -75
+KPX F egrave -75
+KPX F emacron -75
+KPX F eogonek -75
+KPX F i -45
+KPX F iacute -45
+KPX F icircumflex -45
+KPX F idieresis -45
+KPX F igrave -45
+KPX F imacron -45
+KPX F iogonek -45
+KPX F o -105
+KPX F oacute -105
+KPX F ocircumflex -105
+KPX F odieresis -105
+KPX F ograve -105
+KPX F ohungarumlaut -105
+KPX F omacron -105
+KPX F oslash -105
+KPX F otilde -105
+KPX F period -135
+KPX F r -55
+KPX F racute -55
+KPX F rcaron -55
+KPX F rcommaaccent -55
+KPX J A -40
+KPX J Aacute -40
+KPX J Abreve -40
+KPX J Acircumflex -40
+KPX J Adieresis -40
+KPX J Agrave -40
+KPX J Amacron -40
+KPX J Aogonek -40
+KPX J Aring -40
+KPX J Atilde -40
+KPX J a -35
+KPX J aacute -35
+KPX J abreve -35
+KPX J acircumflex -35
+KPX J adieresis -35
+KPX J agrave -35
+KPX J amacron -35
+KPX J aogonek -35
+KPX J aring -35
+KPX J atilde -35
+KPX J comma -25
+KPX J e -25
+KPX J eacute -25
+KPX J ecaron -25
+KPX J ecircumflex -25
+KPX J edieresis -25
+KPX J edotaccent -25
+KPX J egrave -25
+KPX J emacron -25
+KPX J eogonek -25
+KPX J o -25
+KPX J oacute -25
+KPX J ocircumflex -25
+KPX J odieresis -25
+KPX J ograve -25
+KPX J ohungarumlaut -25
+KPX J omacron -25
+KPX J oslash -25
+KPX J otilde -25
+KPX J period -25
+KPX J u -35
+KPX J uacute -35
+KPX J ucircumflex -35
+KPX J udieresis -35
+KPX J ugrave -35
+KPX J uhungarumlaut -35
+KPX J umacron -35
+KPX J uogonek -35
+KPX J uring -35
+KPX K O -50
+KPX K Oacute -50
+KPX K Ocircumflex -50
+KPX K Odieresis -50
+KPX K Ograve -50
+KPX K Ohungarumlaut -50
+KPX K Omacron -50
+KPX K Oslash -50
+KPX K Otilde -50
+KPX K e -35
+KPX K eacute -35
+KPX K ecaron -35
+KPX K ecircumflex -35
+KPX K edieresis -35
+KPX K edotaccent -35
+KPX K egrave -35
+KPX K emacron -35
+KPX K eogonek -35
+KPX K o -40
+KPX K oacute -40
+KPX K ocircumflex -40
+KPX K odieresis -40
+KPX K ograve -40
+KPX K ohungarumlaut -40
+KPX K omacron -40
+KPX K oslash -40
+KPX K otilde -40
+KPX K u -40
+KPX K uacute -40
+KPX K ucircumflex -40
+KPX K udieresis -40
+KPX K ugrave -40
+KPX K uhungarumlaut -40
+KPX K umacron -40
+KPX K uogonek -40
+KPX K uring -40
+KPX K y -40
+KPX K yacute -40
+KPX K ydieresis -40
+KPX Kcommaaccent O -50
+KPX Kcommaaccent Oacute -50
+KPX Kcommaaccent Ocircumflex -50
+KPX Kcommaaccent Odieresis -50
+KPX Kcommaaccent Ograve -50
+KPX Kcommaaccent Ohungarumlaut -50
+KPX Kcommaaccent Omacron -50
+KPX Kcommaaccent Oslash -50
+KPX Kcommaaccent Otilde -50
+KPX Kcommaaccent e -35
+KPX Kcommaaccent eacute -35
+KPX Kcommaaccent ecaron -35
+KPX Kcommaaccent ecircumflex -35
+KPX Kcommaaccent edieresis -35
+KPX Kcommaaccent edotaccent -35
+KPX Kcommaaccent egrave -35
+KPX Kcommaaccent emacron -35
+KPX Kcommaaccent eogonek -35
+KPX Kcommaaccent o -40
+KPX Kcommaaccent oacute -40
+KPX Kcommaaccent ocircumflex -40
+KPX Kcommaaccent odieresis -40
+KPX Kcommaaccent ograve -40
+KPX Kcommaaccent ohungarumlaut -40
+KPX Kcommaaccent omacron -40
+KPX Kcommaaccent oslash -40
+KPX Kcommaaccent otilde -40
+KPX Kcommaaccent u -40
+KPX Kcommaaccent uacute -40
+KPX Kcommaaccent ucircumflex -40
+KPX Kcommaaccent udieresis -40
+KPX Kcommaaccent ugrave -40
+KPX Kcommaaccent uhungarumlaut -40
+KPX Kcommaaccent umacron -40
+KPX Kcommaaccent uogonek -40
+KPX Kcommaaccent uring -40
+KPX Kcommaaccent y -40
+KPX Kcommaaccent yacute -40
+KPX Kcommaaccent ydieresis -40
+KPX L T -20
+KPX L Tcaron -20
+KPX L Tcommaaccent -20
+KPX L V -55
+KPX L W -55
+KPX L Y -20
+KPX L Yacute -20
+KPX L Ydieresis -20
+KPX L quoteright -37
+KPX L y -30
+KPX L yacute -30
+KPX L ydieresis -30
+KPX Lacute T -20
+KPX Lacute Tcaron -20
+KPX Lacute Tcommaaccent -20
+KPX Lacute V -55
+KPX Lacute W -55
+KPX Lacute Y -20
+KPX Lacute Yacute -20
+KPX Lacute Ydieresis -20
+KPX Lacute quoteright -37
+KPX Lacute y -30
+KPX Lacute yacute -30
+KPX Lacute ydieresis -30
+KPX Lcommaaccent T -20
+KPX Lcommaaccent Tcaron -20
+KPX Lcommaaccent Tcommaaccent -20
+KPX Lcommaaccent V -55
+KPX Lcommaaccent W -55
+KPX Lcommaaccent Y -20
+KPX Lcommaaccent Yacute -20
+KPX Lcommaaccent Ydieresis -20
+KPX Lcommaaccent quoteright -37
+KPX Lcommaaccent y -30
+KPX Lcommaaccent yacute -30
+KPX Lcommaaccent ydieresis -30
+KPX Lslash T -20
+KPX Lslash Tcaron -20
+KPX Lslash Tcommaaccent -20
+KPX Lslash V -55
+KPX Lslash W -55
+KPX Lslash Y -20
+KPX Lslash Yacute -20
+KPX Lslash Ydieresis -20
+KPX Lslash quoteright -37
+KPX Lslash y -30
+KPX Lslash yacute -30
+KPX Lslash ydieresis -30
+KPX N A -27
+KPX N Aacute -27
+KPX N Abreve -27
+KPX N Acircumflex -27
+KPX N Adieresis -27
+KPX N Agrave -27
+KPX N Amacron -27
+KPX N Aogonek -27
+KPX N Aring -27
+KPX N Atilde -27
+KPX Nacute A -27
+KPX Nacute Aacute -27
+KPX Nacute Abreve -27
+KPX Nacute Acircumflex -27
+KPX Nacute Adieresis -27
+KPX Nacute Agrave -27
+KPX Nacute Amacron -27
+KPX Nacute Aogonek -27
+KPX Nacute Aring -27
+KPX Nacute Atilde -27
+KPX Ncaron A -27
+KPX Ncaron Aacute -27
+KPX Ncaron Abreve -27
+KPX Ncaron Acircumflex -27
+KPX Ncaron Adieresis -27
+KPX Ncaron Agrave -27
+KPX Ncaron Amacron -27
+KPX Ncaron Aogonek -27
+KPX Ncaron Aring -27
+KPX Ncaron Atilde -27
+KPX Ncommaaccent A -27
+KPX Ncommaaccent Aacute -27
+KPX Ncommaaccent Abreve -27
+KPX Ncommaaccent Acircumflex -27
+KPX Ncommaaccent Adieresis -27
+KPX Ncommaaccent Agrave -27
+KPX Ncommaaccent Amacron -27
+KPX Ncommaaccent Aogonek -27
+KPX Ncommaaccent Aring -27
+KPX Ncommaaccent Atilde -27
+KPX Ntilde A -27
+KPX Ntilde Aacute -27
+KPX Ntilde Abreve -27
+KPX Ntilde Acircumflex -27
+KPX Ntilde Adieresis -27
+KPX Ntilde Agrave -27
+KPX Ntilde Amacron -27
+KPX Ntilde Aogonek -27
+KPX Ntilde Aring -27
+KPX Ntilde Atilde -27
+KPX O A -55
+KPX O Aacute -55
+KPX O Abreve -55
+KPX O Acircumflex -55
+KPX O Adieresis -55
+KPX O Agrave -55
+KPX O Amacron -55
+KPX O Aogonek -55
+KPX O Aring -55
+KPX O Atilde -55
+KPX O T -40
+KPX O Tcaron -40
+KPX O Tcommaaccent -40
+KPX O V -50
+KPX O W -50
+KPX O X -40
+KPX O Y -50
+KPX O Yacute -50
+KPX O Ydieresis -50
+KPX Oacute A -55
+KPX Oacute Aacute -55
+KPX Oacute Abreve -55
+KPX Oacute Acircumflex -55
+KPX Oacute Adieresis -55
+KPX Oacute Agrave -55
+KPX Oacute Amacron -55
+KPX Oacute Aogonek -55
+KPX Oacute Aring -55
+KPX Oacute Atilde -55
+KPX Oacute T -40
+KPX Oacute Tcaron -40
+KPX Oacute Tcommaaccent -40
+KPX Oacute V -50
+KPX Oacute W -50
+KPX Oacute X -40
+KPX Oacute Y -50
+KPX Oacute Yacute -50
+KPX Oacute Ydieresis -50
+KPX Ocircumflex A -55
+KPX Ocircumflex Aacute -55
+KPX Ocircumflex Abreve -55
+KPX Ocircumflex Acircumflex -55
+KPX Ocircumflex Adieresis -55
+KPX Ocircumflex Agrave -55
+KPX Ocircumflex Amacron -55
+KPX Ocircumflex Aogonek -55
+KPX Ocircumflex Aring -55
+KPX Ocircumflex Atilde -55
+KPX Ocircumflex T -40
+KPX Ocircumflex Tcaron -40
+KPX Ocircumflex Tcommaaccent -40
+KPX Ocircumflex V -50
+KPX Ocircumflex W -50
+KPX Ocircumflex X -40
+KPX Ocircumflex Y -50
+KPX Ocircumflex Yacute -50
+KPX Ocircumflex Ydieresis -50
+KPX Odieresis A -55
+KPX Odieresis Aacute -55
+KPX Odieresis Abreve -55
+KPX Odieresis Acircumflex -55
+KPX Odieresis Adieresis -55
+KPX Odieresis Agrave -55
+KPX Odieresis Amacron -55
+KPX Odieresis Aogonek -55
+KPX Odieresis Aring -55
+KPX Odieresis Atilde -55
+KPX Odieresis T -40
+KPX Odieresis Tcaron -40
+KPX Odieresis Tcommaaccent -40
+KPX Odieresis V -50
+KPX Odieresis W -50
+KPX Odieresis X -40
+KPX Odieresis Y -50
+KPX Odieresis Yacute -50
+KPX Odieresis Ydieresis -50
+KPX Ograve A -55
+KPX Ograve Aacute -55
+KPX Ograve Abreve -55
+KPX Ograve Acircumflex -55
+KPX Ograve Adieresis -55
+KPX Ograve Agrave -55
+KPX Ograve Amacron -55
+KPX Ograve Aogonek -55
+KPX Ograve Aring -55
+KPX Ograve Atilde -55
+KPX Ograve T -40
+KPX Ograve Tcaron -40
+KPX Ograve Tcommaaccent -40
+KPX Ograve V -50
+KPX Ograve W -50
+KPX Ograve X -40
+KPX Ograve Y -50
+KPX Ograve Yacute -50
+KPX Ograve Ydieresis -50
+KPX Ohungarumlaut A -55
+KPX Ohungarumlaut Aacute -55
+KPX Ohungarumlaut Abreve -55
+KPX Ohungarumlaut Acircumflex -55
+KPX Ohungarumlaut Adieresis -55
+KPX Ohungarumlaut Agrave -55
+KPX Ohungarumlaut Amacron -55
+KPX Ohungarumlaut Aogonek -55
+KPX Ohungarumlaut Aring -55
+KPX Ohungarumlaut Atilde -55
+KPX Ohungarumlaut T -40
+KPX Ohungarumlaut Tcaron -40
+KPX Ohungarumlaut Tcommaaccent -40
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut W -50
+KPX Ohungarumlaut X -40
+KPX Ohungarumlaut Y -50
+KPX Ohungarumlaut Yacute -50
+KPX Ohungarumlaut Ydieresis -50
+KPX Omacron A -55
+KPX Omacron Aacute -55
+KPX Omacron Abreve -55
+KPX Omacron Acircumflex -55
+KPX Omacron Adieresis -55
+KPX Omacron Agrave -55
+KPX Omacron Amacron -55
+KPX Omacron Aogonek -55
+KPX Omacron Aring -55
+KPX Omacron Atilde -55
+KPX Omacron T -40
+KPX Omacron Tcaron -40
+KPX Omacron Tcommaaccent -40
+KPX Omacron V -50
+KPX Omacron W -50
+KPX Omacron X -40
+KPX Omacron Y -50
+KPX Omacron Yacute -50
+KPX Omacron Ydieresis -50
+KPX Oslash A -55
+KPX Oslash Aacute -55
+KPX Oslash Abreve -55
+KPX Oslash Acircumflex -55
+KPX Oslash Adieresis -55
+KPX Oslash Agrave -55
+KPX Oslash Amacron -55
+KPX Oslash Aogonek -55
+KPX Oslash Aring -55
+KPX Oslash Atilde -55
+KPX Oslash T -40
+KPX Oslash Tcaron -40
+KPX Oslash Tcommaaccent -40
+KPX Oslash V -50
+KPX Oslash W -50
+KPX Oslash X -40
+KPX Oslash Y -50
+KPX Oslash Yacute -50
+KPX Oslash Ydieresis -50
+KPX Otilde A -55
+KPX Otilde Aacute -55
+KPX Otilde Abreve -55
+KPX Otilde Acircumflex -55
+KPX Otilde Adieresis -55
+KPX Otilde Agrave -55
+KPX Otilde Amacron -55
+KPX Otilde Aogonek -55
+KPX Otilde Aring -55
+KPX Otilde Atilde -55
+KPX Otilde T -40
+KPX Otilde Tcaron -40
+KPX Otilde Tcommaaccent -40
+KPX Otilde V -50
+KPX Otilde W -50
+KPX Otilde X -40
+KPX Otilde Y -50
+KPX Otilde Yacute -50
+KPX Otilde Ydieresis -50
+KPX P A -90
+KPX P Aacute -90
+KPX P Abreve -90
+KPX P Acircumflex -90
+KPX P Adieresis -90
+KPX P Agrave -90
+KPX P Amacron -90
+KPX P Aogonek -90
+KPX P Aring -90
+KPX P Atilde -90
+KPX P a -80
+KPX P aacute -80
+KPX P abreve -80
+KPX P acircumflex -80
+KPX P adieresis -80
+KPX P agrave -80
+KPX P amacron -80
+KPX P aogonek -80
+KPX P aring -80
+KPX P atilde -80
+KPX P comma -135
+KPX P e -80
+KPX P eacute -80
+KPX P ecaron -80
+KPX P ecircumflex -80
+KPX P edieresis -80
+KPX P edotaccent -80
+KPX P egrave -80
+KPX P emacron -80
+KPX P eogonek -80
+KPX P o -80
+KPX P oacute -80
+KPX P ocircumflex -80
+KPX P odieresis -80
+KPX P ograve -80
+KPX P ohungarumlaut -80
+KPX P omacron -80
+KPX P oslash -80
+KPX P otilde -80
+KPX P period -135
+KPX Q U -10
+KPX Q Uacute -10
+KPX Q Ucircumflex -10
+KPX Q Udieresis -10
+KPX Q Ugrave -10
+KPX Q Uhungarumlaut -10
+KPX Q Umacron -10
+KPX Q Uogonek -10
+KPX Q Uring -10
+KPX R O -40
+KPX R Oacute -40
+KPX R Ocircumflex -40
+KPX R Odieresis -40
+KPX R Ograve -40
+KPX R Ohungarumlaut -40
+KPX R Omacron -40
+KPX R Oslash -40
+KPX R Otilde -40
+KPX R U -40
+KPX R Uacute -40
+KPX R Ucircumflex -40
+KPX R Udieresis -40
+KPX R Ugrave -40
+KPX R Uhungarumlaut -40
+KPX R Umacron -40
+KPX R Uogonek -40
+KPX R Uring -40
+KPX R V -18
+KPX R W -18
+KPX R Y -18
+KPX R Yacute -18
+KPX R Ydieresis -18
+KPX Racute O -40
+KPX Racute Oacute -40
+KPX Racute Ocircumflex -40
+KPX Racute Odieresis -40
+KPX Racute Ograve -40
+KPX Racute Ohungarumlaut -40
+KPX Racute Omacron -40
+KPX Racute Oslash -40
+KPX Racute Otilde -40
+KPX Racute U -40
+KPX Racute Uacute -40
+KPX Racute Ucircumflex -40
+KPX Racute Udieresis -40
+KPX Racute Ugrave -40
+KPX Racute Uhungarumlaut -40
+KPX Racute Umacron -40
+KPX Racute Uogonek -40
+KPX Racute Uring -40
+KPX Racute V -18
+KPX Racute W -18
+KPX Racute Y -18
+KPX Racute Yacute -18
+KPX Racute Ydieresis -18
+KPX Rcaron O -40
+KPX Rcaron Oacute -40
+KPX Rcaron Ocircumflex -40
+KPX Rcaron Odieresis -40
+KPX Rcaron Ograve -40
+KPX Rcaron Ohungarumlaut -40
+KPX Rcaron Omacron -40
+KPX Rcaron Oslash -40
+KPX Rcaron Otilde -40
+KPX Rcaron U -40
+KPX Rcaron Uacute -40
+KPX Rcaron Ucircumflex -40
+KPX Rcaron Udieresis -40
+KPX Rcaron Ugrave -40
+KPX Rcaron Uhungarumlaut -40
+KPX Rcaron Umacron -40
+KPX Rcaron Uogonek -40
+KPX Rcaron Uring -40
+KPX Rcaron V -18
+KPX Rcaron W -18
+KPX Rcaron Y -18
+KPX Rcaron Yacute -18
+KPX Rcaron Ydieresis -18
+KPX Rcommaaccent O -40
+KPX Rcommaaccent Oacute -40
+KPX Rcommaaccent Ocircumflex -40
+KPX Rcommaaccent Odieresis -40
+KPX Rcommaaccent Ograve -40
+KPX Rcommaaccent Ohungarumlaut -40
+KPX Rcommaaccent Omacron -40
+KPX Rcommaaccent Oslash -40
+KPX Rcommaaccent Otilde -40
+KPX Rcommaaccent U -40
+KPX Rcommaaccent Uacute -40
+KPX Rcommaaccent Ucircumflex -40
+KPX Rcommaaccent Udieresis -40
+KPX Rcommaaccent Ugrave -40
+KPX Rcommaaccent Uhungarumlaut -40
+KPX Rcommaaccent Umacron -40
+KPX Rcommaaccent Uogonek -40
+KPX Rcommaaccent Uring -40
+KPX Rcommaaccent V -18
+KPX Rcommaaccent W -18
+KPX Rcommaaccent Y -18
+KPX Rcommaaccent Yacute -18
+KPX Rcommaaccent Ydieresis -18
+KPX T A -50
+KPX T Aacute -50
+KPX T Abreve -50
+KPX T Acircumflex -50
+KPX T Adieresis -50
+KPX T Agrave -50
+KPX T Amacron -50
+KPX T Aogonek -50
+KPX T Aring -50
+KPX T Atilde -50
+KPX T O -18
+KPX T Oacute -18
+KPX T Ocircumflex -18
+KPX T Odieresis -18
+KPX T Ograve -18
+KPX T Ohungarumlaut -18
+KPX T Omacron -18
+KPX T Oslash -18
+KPX T Otilde -18
+KPX T a -92
+KPX T aacute -92
+KPX T abreve -92
+KPX T acircumflex -92
+KPX T adieresis -92
+KPX T agrave -92
+KPX T amacron -92
+KPX T aogonek -92
+KPX T aring -92
+KPX T atilde -92
+KPX T colon -55
+KPX T comma -74
+KPX T e -92
+KPX T eacute -92
+KPX T ecaron -92
+KPX T ecircumflex -52
+KPX T edieresis -52
+KPX T edotaccent -92
+KPX T egrave -52
+KPX T emacron -52
+KPX T eogonek -92
+KPX T hyphen -74
+KPX T i -55
+KPX T iacute -55
+KPX T iogonek -55
+KPX T o -92
+KPX T oacute -92
+KPX T ocircumflex -92
+KPX T odieresis -92
+KPX T ograve -92
+KPX T ohungarumlaut -92
+KPX T omacron -92
+KPX T oslash -92
+KPX T otilde -92
+KPX T period -74
+KPX T r -55
+KPX T racute -55
+KPX T rcaron -55
+KPX T rcommaaccent -55
+KPX T semicolon -65
+KPX T u -55
+KPX T uacute -55
+KPX T ucircumflex -55
+KPX T udieresis -55
+KPX T ugrave -55
+KPX T uhungarumlaut -55
+KPX T umacron -55
+KPX T uogonek -55
+KPX T uring -55
+KPX T w -74
+KPX T y -74
+KPX T yacute -74
+KPX T ydieresis -34
+KPX Tcaron A -50
+KPX Tcaron Aacute -50
+KPX Tcaron Abreve -50
+KPX Tcaron Acircumflex -50
+KPX Tcaron Adieresis -50
+KPX Tcaron Agrave -50
+KPX Tcaron Amacron -50
+KPX Tcaron Aogonek -50
+KPX Tcaron Aring -50
+KPX Tcaron Atilde -50
+KPX Tcaron O -18
+KPX Tcaron Oacute -18
+KPX Tcaron Ocircumflex -18
+KPX Tcaron Odieresis -18
+KPX Tcaron Ograve -18
+KPX Tcaron Ohungarumlaut -18
+KPX Tcaron Omacron -18
+KPX Tcaron Oslash -18
+KPX Tcaron Otilde -18
+KPX Tcaron a -92
+KPX Tcaron aacute -92
+KPX Tcaron abreve -92
+KPX Tcaron acircumflex -92
+KPX Tcaron adieresis -92
+KPX Tcaron agrave -92
+KPX Tcaron amacron -92
+KPX Tcaron aogonek -92
+KPX Tcaron aring -92
+KPX Tcaron atilde -92
+KPX Tcaron colon -55
+KPX Tcaron comma -74
+KPX Tcaron e -92
+KPX Tcaron eacute -92
+KPX Tcaron ecaron -92
+KPX Tcaron ecircumflex -52
+KPX Tcaron edieresis -52
+KPX Tcaron edotaccent -92
+KPX Tcaron egrave -52
+KPX Tcaron emacron -52
+KPX Tcaron eogonek -92
+KPX Tcaron hyphen -74
+KPX Tcaron i -55
+KPX Tcaron iacute -55
+KPX Tcaron iogonek -55
+KPX Tcaron o -92
+KPX Tcaron oacute -92
+KPX Tcaron ocircumflex -92
+KPX Tcaron odieresis -92
+KPX Tcaron ograve -92
+KPX Tcaron ohungarumlaut -92
+KPX Tcaron omacron -92
+KPX Tcaron oslash -92
+KPX Tcaron otilde -92
+KPX Tcaron period -74
+KPX Tcaron r -55
+KPX Tcaron racute -55
+KPX Tcaron rcaron -55
+KPX Tcaron rcommaaccent -55
+KPX Tcaron semicolon -65
+KPX Tcaron u -55
+KPX Tcaron uacute -55
+KPX Tcaron ucircumflex -55
+KPX Tcaron udieresis -55
+KPX Tcaron ugrave -55
+KPX Tcaron uhungarumlaut -55
+KPX Tcaron umacron -55
+KPX Tcaron uogonek -55
+KPX Tcaron uring -55
+KPX Tcaron w -74
+KPX Tcaron y -74
+KPX Tcaron yacute -74
+KPX Tcaron ydieresis -34
+KPX Tcommaaccent A -50
+KPX Tcommaaccent Aacute -50
+KPX Tcommaaccent Abreve -50
+KPX Tcommaaccent Acircumflex -50
+KPX Tcommaaccent Adieresis -50
+KPX Tcommaaccent Agrave -50
+KPX Tcommaaccent Amacron -50
+KPX Tcommaaccent Aogonek -50
+KPX Tcommaaccent Aring -50
+KPX Tcommaaccent Atilde -50
+KPX Tcommaaccent O -18
+KPX Tcommaaccent Oacute -18
+KPX Tcommaaccent Ocircumflex -18
+KPX Tcommaaccent Odieresis -18
+KPX Tcommaaccent Ograve -18
+KPX Tcommaaccent Ohungarumlaut -18
+KPX Tcommaaccent Omacron -18
+KPX Tcommaaccent Oslash -18
+KPX Tcommaaccent Otilde -18
+KPX Tcommaaccent a -92
+KPX Tcommaaccent aacute -92
+KPX Tcommaaccent abreve -92
+KPX Tcommaaccent acircumflex -92
+KPX Tcommaaccent adieresis -92
+KPX Tcommaaccent agrave -92
+KPX Tcommaaccent amacron -92
+KPX Tcommaaccent aogonek -92
+KPX Tcommaaccent aring -92
+KPX Tcommaaccent atilde -92
+KPX Tcommaaccent colon -55
+KPX Tcommaaccent comma -74
+KPX Tcommaaccent e -92
+KPX Tcommaaccent eacute -92
+KPX Tcommaaccent ecaron -92
+KPX Tcommaaccent ecircumflex -52
+KPX Tcommaaccent edieresis -52
+KPX Tcommaaccent edotaccent -92
+KPX Tcommaaccent egrave -52
+KPX Tcommaaccent emacron -52
+KPX Tcommaaccent eogonek -92
+KPX Tcommaaccent hyphen -74
+KPX Tcommaaccent i -55
+KPX Tcommaaccent iacute -55
+KPX Tcommaaccent iogonek -55
+KPX Tcommaaccent o -92
+KPX Tcommaaccent oacute -92
+KPX Tcommaaccent ocircumflex -92
+KPX Tcommaaccent odieresis -92
+KPX Tcommaaccent ograve -92
+KPX Tcommaaccent ohungarumlaut -92
+KPX Tcommaaccent omacron -92
+KPX Tcommaaccent oslash -92
+KPX Tcommaaccent otilde -92
+KPX Tcommaaccent period -74
+KPX Tcommaaccent r -55
+KPX Tcommaaccent racute -55
+KPX Tcommaaccent rcaron -55
+KPX Tcommaaccent rcommaaccent -55
+KPX Tcommaaccent semicolon -65
+KPX Tcommaaccent u -55
+KPX Tcommaaccent uacute -55
+KPX Tcommaaccent ucircumflex -55
+KPX Tcommaaccent udieresis -55
+KPX Tcommaaccent ugrave -55
+KPX Tcommaaccent uhungarumlaut -55
+KPX Tcommaaccent umacron -55
+KPX Tcommaaccent uogonek -55
+KPX Tcommaaccent uring -55
+KPX Tcommaaccent w -74
+KPX Tcommaaccent y -74
+KPX Tcommaaccent yacute -74
+KPX Tcommaaccent ydieresis -34
+KPX U A -40
+KPX U Aacute -40
+KPX U Abreve -40
+KPX U Acircumflex -40
+KPX U Adieresis -40
+KPX U Agrave -40
+KPX U Amacron -40
+KPX U Aogonek -40
+KPX U Aring -40
+KPX U Atilde -40
+KPX U comma -25
+KPX U period -25
+KPX Uacute A -40
+KPX Uacute Aacute -40
+KPX Uacute Abreve -40
+KPX Uacute Acircumflex -40
+KPX Uacute Adieresis -40
+KPX Uacute Agrave -40
+KPX Uacute Amacron -40
+KPX Uacute Aogonek -40
+KPX Uacute Aring -40
+KPX Uacute Atilde -40
+KPX Uacute comma -25
+KPX Uacute period -25
+KPX Ucircumflex A -40
+KPX Ucircumflex Aacute -40
+KPX Ucircumflex Abreve -40
+KPX Ucircumflex Acircumflex -40
+KPX Ucircumflex Adieresis -40
+KPX Ucircumflex Agrave -40
+KPX Ucircumflex Amacron -40
+KPX Ucircumflex Aogonek -40
+KPX Ucircumflex Aring -40
+KPX Ucircumflex Atilde -40
+KPX Ucircumflex comma -25
+KPX Ucircumflex period -25
+KPX Udieresis A -40
+KPX Udieresis Aacute -40
+KPX Udieresis Abreve -40
+KPX Udieresis Acircumflex -40
+KPX Udieresis Adieresis -40
+KPX Udieresis Agrave -40
+KPX Udieresis Amacron -40
+KPX Udieresis Aogonek -40
+KPX Udieresis Aring -40
+KPX Udieresis Atilde -40
+KPX Udieresis comma -25
+KPX Udieresis period -25
+KPX Ugrave A -40
+KPX Ugrave Aacute -40
+KPX Ugrave Abreve -40
+KPX Ugrave Acircumflex -40
+KPX Ugrave Adieresis -40
+KPX Ugrave Agrave -40
+KPX Ugrave Amacron -40
+KPX Ugrave Aogonek -40
+KPX Ugrave Aring -40
+KPX Ugrave Atilde -40
+KPX Ugrave comma -25
+KPX Ugrave period -25
+KPX Uhungarumlaut A -40
+KPX Uhungarumlaut Aacute -40
+KPX Uhungarumlaut Abreve -40
+KPX Uhungarumlaut Acircumflex -40
+KPX Uhungarumlaut Adieresis -40
+KPX Uhungarumlaut Agrave -40
+KPX Uhungarumlaut Amacron -40
+KPX Uhungarumlaut Aogonek -40
+KPX Uhungarumlaut Aring -40
+KPX Uhungarumlaut Atilde -40
+KPX Uhungarumlaut comma -25
+KPX Uhungarumlaut period -25
+KPX Umacron A -40
+KPX Umacron Aacute -40
+KPX Umacron Abreve -40
+KPX Umacron Acircumflex -40
+KPX Umacron Adieresis -40
+KPX Umacron Agrave -40
+KPX Umacron Amacron -40
+KPX Umacron Aogonek -40
+KPX Umacron Aring -40
+KPX Umacron Atilde -40
+KPX Umacron comma -25
+KPX Umacron period -25
+KPX Uogonek A -40
+KPX Uogonek Aacute -40
+KPX Uogonek Abreve -40
+KPX Uogonek Acircumflex -40
+KPX Uogonek Adieresis -40
+KPX Uogonek Agrave -40
+KPX Uogonek Amacron -40
+KPX Uogonek Aogonek -40
+KPX Uogonek Aring -40
+KPX Uogonek Atilde -40
+KPX Uogonek comma -25
+KPX Uogonek period -25
+KPX Uring A -40
+KPX Uring Aacute -40
+KPX Uring Abreve -40
+KPX Uring Acircumflex -40
+KPX Uring Adieresis -40
+KPX Uring Agrave -40
+KPX Uring Amacron -40
+KPX Uring Aogonek -40
+KPX Uring Aring -40
+KPX Uring Atilde -40
+KPX Uring comma -25
+KPX Uring period -25
+KPX V A -60
+KPX V Aacute -60
+KPX V Abreve -60
+KPX V Acircumflex -60
+KPX V Adieresis -60
+KPX V Agrave -60
+KPX V Amacron -60
+KPX V Aogonek -60
+KPX V Aring -60
+KPX V Atilde -60
+KPX V O -30
+KPX V Oacute -30
+KPX V Ocircumflex -30
+KPX V Odieresis -30
+KPX V Ograve -30
+KPX V Ohungarumlaut -30
+KPX V Omacron -30
+KPX V Oslash -30
+KPX V Otilde -30
+KPX V a -111
+KPX V aacute -111
+KPX V abreve -111
+KPX V acircumflex -111
+KPX V adieresis -111
+KPX V agrave -111
+KPX V amacron -111
+KPX V aogonek -111
+KPX V aring -111
+KPX V atilde -111
+KPX V colon -65
+KPX V comma -129
+KPX V e -111
+KPX V eacute -111
+KPX V ecaron -111
+KPX V ecircumflex -111
+KPX V edieresis -71
+KPX V edotaccent -111
+KPX V egrave -71
+KPX V emacron -71
+KPX V eogonek -111
+KPX V hyphen -55
+KPX V i -74
+KPX V iacute -74
+KPX V icircumflex -34
+KPX V idieresis -34
+KPX V igrave -34
+KPX V imacron -34
+KPX V iogonek -74
+KPX V o -111
+KPX V oacute -111
+KPX V ocircumflex -111
+KPX V odieresis -111
+KPX V ograve -111
+KPX V ohungarumlaut -111
+KPX V omacron -111
+KPX V oslash -111
+KPX V otilde -111
+KPX V period -129
+KPX V semicolon -74
+KPX V u -74
+KPX V uacute -74
+KPX V ucircumflex -74
+KPX V udieresis -74
+KPX V ugrave -74
+KPX V uhungarumlaut -74
+KPX V umacron -74
+KPX V uogonek -74
+KPX V uring -74
+KPX W A -60
+KPX W Aacute -60
+KPX W Abreve -60
+KPX W Acircumflex -60
+KPX W Adieresis -60
+KPX W Agrave -60
+KPX W Amacron -60
+KPX W Aogonek -60
+KPX W Aring -60
+KPX W Atilde -60
+KPX W O -25
+KPX W Oacute -25
+KPX W Ocircumflex -25
+KPX W Odieresis -25
+KPX W Ograve -25
+KPX W Ohungarumlaut -25
+KPX W Omacron -25
+KPX W Oslash -25
+KPX W Otilde -25
+KPX W a -92
+KPX W aacute -92
+KPX W abreve -92
+KPX W acircumflex -92
+KPX W adieresis -92
+KPX W agrave -92
+KPX W amacron -92
+KPX W aogonek -92
+KPX W aring -92
+KPX W atilde -92
+KPX W colon -65
+KPX W comma -92
+KPX W e -92
+KPX W eacute -92
+KPX W ecaron -92
+KPX W ecircumflex -92
+KPX W edieresis -52
+KPX W edotaccent -92
+KPX W egrave -52
+KPX W emacron -52
+KPX W eogonek -92
+KPX W hyphen -37
+KPX W i -55
+KPX W iacute -55
+KPX W iogonek -55
+KPX W o -92
+KPX W oacute -92
+KPX W ocircumflex -92
+KPX W odieresis -92
+KPX W ograve -92
+KPX W ohungarumlaut -92
+KPX W omacron -92
+KPX W oslash -92
+KPX W otilde -92
+KPX W period -92
+KPX W semicolon -65
+KPX W u -55
+KPX W uacute -55
+KPX W ucircumflex -55
+KPX W udieresis -55
+KPX W ugrave -55
+KPX W uhungarumlaut -55
+KPX W umacron -55
+KPX W uogonek -55
+KPX W uring -55
+KPX W y -70
+KPX W yacute -70
+KPX W ydieresis -70
+KPX Y A -50
+KPX Y Aacute -50
+KPX Y Abreve -50
+KPX Y Acircumflex -50
+KPX Y Adieresis -50
+KPX Y Agrave -50
+KPX Y Amacron -50
+KPX Y Aogonek -50
+KPX Y Aring -50
+KPX Y Atilde -50
+KPX Y O -15
+KPX Y Oacute -15
+KPX Y Ocircumflex -15
+KPX Y Odieresis -15
+KPX Y Ograve -15
+KPX Y Ohungarumlaut -15
+KPX Y Omacron -15
+KPX Y Oslash -15
+KPX Y Otilde -15
+KPX Y a -92
+KPX Y aacute -92
+KPX Y abreve -92
+KPX Y acircumflex -92
+KPX Y adieresis -92
+KPX Y agrave -92
+KPX Y amacron -92
+KPX Y aogonek -92
+KPX Y aring -92
+KPX Y atilde -92
+KPX Y colon -65
+KPX Y comma -92
+KPX Y e -92
+KPX Y eacute -92
+KPX Y ecaron -92
+KPX Y ecircumflex -92
+KPX Y edieresis -52
+KPX Y edotaccent -92
+KPX Y egrave -52
+KPX Y emacron -52
+KPX Y eogonek -92
+KPX Y hyphen -74
+KPX Y i -74
+KPX Y iacute -74
+KPX Y icircumflex -34
+KPX Y idieresis -34
+KPX Y igrave -34
+KPX Y imacron -34
+KPX Y iogonek -74
+KPX Y o -92
+KPX Y oacute -92
+KPX Y ocircumflex -92
+KPX Y odieresis -92
+KPX Y ograve -92
+KPX Y ohungarumlaut -92
+KPX Y omacron -92
+KPX Y oslash -92
+KPX Y otilde -92
+KPX Y period -92
+KPX Y semicolon -65
+KPX Y u -92
+KPX Y uacute -92
+KPX Y ucircumflex -92
+KPX Y udieresis -92
+KPX Y ugrave -92
+KPX Y uhungarumlaut -92
+KPX Y umacron -92
+KPX Y uogonek -92
+KPX Y uring -92
+KPX Yacute A -50
+KPX Yacute Aacute -50
+KPX Yacute Abreve -50
+KPX Yacute Acircumflex -50
+KPX Yacute Adieresis -50
+KPX Yacute Agrave -50
+KPX Yacute Amacron -50
+KPX Yacute Aogonek -50
+KPX Yacute Aring -50
+KPX Yacute Atilde -50
+KPX Yacute O -15
+KPX Yacute Oacute -15
+KPX Yacute Ocircumflex -15
+KPX Yacute Odieresis -15
+KPX Yacute Ograve -15
+KPX Yacute Ohungarumlaut -15
+KPX Yacute Omacron -15
+KPX Yacute Oslash -15
+KPX Yacute Otilde -15
+KPX Yacute a -92
+KPX Yacute aacute -92
+KPX Yacute abreve -92
+KPX Yacute acircumflex -92
+KPX Yacute adieresis -92
+KPX Yacute agrave -92
+KPX Yacute amacron -92
+KPX Yacute aogonek -92
+KPX Yacute aring -92
+KPX Yacute atilde -92
+KPX Yacute colon -65
+KPX Yacute comma -92
+KPX Yacute e -92
+KPX Yacute eacute -92
+KPX Yacute ecaron -92
+KPX Yacute ecircumflex -92
+KPX Yacute edieresis -52
+KPX Yacute edotaccent -92
+KPX Yacute egrave -52
+KPX Yacute emacron -52
+KPX Yacute eogonek -92
+KPX Yacute hyphen -74
+KPX Yacute i -74
+KPX Yacute iacute -74
+KPX Yacute icircumflex -34
+KPX Yacute idieresis -34
+KPX Yacute igrave -34
+KPX Yacute imacron -34
+KPX Yacute iogonek -74
+KPX Yacute o -92
+KPX Yacute oacute -92
+KPX Yacute ocircumflex -92
+KPX Yacute odieresis -92
+KPX Yacute ograve -92
+KPX Yacute ohungarumlaut -92
+KPX Yacute omacron -92
+KPX Yacute oslash -92
+KPX Yacute otilde -92
+KPX Yacute period -92
+KPX Yacute semicolon -65
+KPX Yacute u -92
+KPX Yacute uacute -92
+KPX Yacute ucircumflex -92
+KPX Yacute udieresis -92
+KPX Yacute ugrave -92
+KPX Yacute uhungarumlaut -92
+KPX Yacute umacron -92
+KPX Yacute uogonek -92
+KPX Yacute uring -92
+KPX Ydieresis A -50
+KPX Ydieresis Aacute -50
+KPX Ydieresis Abreve -50
+KPX Ydieresis Acircumflex -50
+KPX Ydieresis Adieresis -50
+KPX Ydieresis Agrave -50
+KPX Ydieresis Amacron -50
+KPX Ydieresis Aogonek -50
+KPX Ydieresis Aring -50
+KPX Ydieresis Atilde -50
+KPX Ydieresis O -15
+KPX Ydieresis Oacute -15
+KPX Ydieresis Ocircumflex -15
+KPX Ydieresis Odieresis -15
+KPX Ydieresis Ograve -15
+KPX Ydieresis Ohungarumlaut -15
+KPX Ydieresis Omacron -15
+KPX Ydieresis Oslash -15
+KPX Ydieresis Otilde -15
+KPX Ydieresis a -92
+KPX Ydieresis aacute -92
+KPX Ydieresis abreve -92
+KPX Ydieresis acircumflex -92
+KPX Ydieresis adieresis -92
+KPX Ydieresis agrave -92
+KPX Ydieresis amacron -92
+KPX Ydieresis aogonek -92
+KPX Ydieresis aring -92
+KPX Ydieresis atilde -92
+KPX Ydieresis colon -65
+KPX Ydieresis comma -92
+KPX Ydieresis e -92
+KPX Ydieresis eacute -92
+KPX Ydieresis ecaron -92
+KPX Ydieresis ecircumflex -92
+KPX Ydieresis edieresis -52
+KPX Ydieresis edotaccent -92
+KPX Ydieresis egrave -52
+KPX Ydieresis emacron -52
+KPX Ydieresis eogonek -92
+KPX Ydieresis hyphen -74
+KPX Ydieresis i -74
+KPX Ydieresis iacute -74
+KPX Ydieresis icircumflex -34
+KPX Ydieresis idieresis -34
+KPX Ydieresis igrave -34
+KPX Ydieresis imacron -34
+KPX Ydieresis iogonek -74
+KPX Ydieresis o -92
+KPX Ydieresis oacute -92
+KPX Ydieresis ocircumflex -92
+KPX Ydieresis odieresis -92
+KPX Ydieresis ograve -92
+KPX Ydieresis ohungarumlaut -92
+KPX Ydieresis omacron -92
+KPX Ydieresis oslash -92
+KPX Ydieresis otilde -92
+KPX Ydieresis period -92
+KPX Ydieresis semicolon -65
+KPX Ydieresis u -92
+KPX Ydieresis uacute -92
+KPX Ydieresis ucircumflex -92
+KPX Ydieresis udieresis -92
+KPX Ydieresis ugrave -92
+KPX Ydieresis uhungarumlaut -92
+KPX Ydieresis umacron -92
+KPX Ydieresis uogonek -92
+KPX Ydieresis uring -92
+KPX a g -10
+KPX a gbreve -10
+KPX a gcommaaccent -10
+KPX aacute g -10
+KPX aacute gbreve -10
+KPX aacute gcommaaccent -10
+KPX abreve g -10
+KPX abreve gbreve -10
+KPX abreve gcommaaccent -10
+KPX acircumflex g -10
+KPX acircumflex gbreve -10
+KPX acircumflex gcommaaccent -10
+KPX adieresis g -10
+KPX adieresis gbreve -10
+KPX adieresis gcommaaccent -10
+KPX agrave g -10
+KPX agrave gbreve -10
+KPX agrave gcommaaccent -10
+KPX amacron g -10
+KPX amacron gbreve -10
+KPX amacron gcommaaccent -10
+KPX aogonek g -10
+KPX aogonek gbreve -10
+KPX aogonek gcommaaccent -10
+KPX aring g -10
+KPX aring gbreve -10
+KPX aring gcommaaccent -10
+KPX atilde g -10
+KPX atilde gbreve -10
+KPX atilde gcommaaccent -10
+KPX b period -40
+KPX b u -20
+KPX b uacute -20
+KPX b ucircumflex -20
+KPX b udieresis -20
+KPX b ugrave -20
+KPX b uhungarumlaut -20
+KPX b umacron -20
+KPX b uogonek -20
+KPX b uring -20
+KPX c h -15
+KPX c k -20
+KPX c kcommaaccent -20
+KPX cacute h -15
+KPX cacute k -20
+KPX cacute kcommaaccent -20
+KPX ccaron h -15
+KPX ccaron k -20
+KPX ccaron kcommaaccent -20
+KPX ccedilla h -15
+KPX ccedilla k -20
+KPX ccedilla kcommaaccent -20
+KPX comma quotedblright -140
+KPX comma quoteright -140
+KPX e comma -10
+KPX e g -40
+KPX e gbreve -40
+KPX e gcommaaccent -40
+KPX e period -15
+KPX e v -15
+KPX e w -15
+KPX e x -20
+KPX e y -30
+KPX e yacute -30
+KPX e ydieresis -30
+KPX eacute comma -10
+KPX eacute g -40
+KPX eacute gbreve -40
+KPX eacute gcommaaccent -40
+KPX eacute period -15
+KPX eacute v -15
+KPX eacute w -15
+KPX eacute x -20
+KPX eacute y -30
+KPX eacute yacute -30
+KPX eacute ydieresis -30
+KPX ecaron comma -10
+KPX ecaron g -40
+KPX ecaron gbreve -40
+KPX ecaron gcommaaccent -40
+KPX ecaron period -15
+KPX ecaron v -15
+KPX ecaron w -15
+KPX ecaron x -20
+KPX ecaron y -30
+KPX ecaron yacute -30
+KPX ecaron ydieresis -30
+KPX ecircumflex comma -10
+KPX ecircumflex g -40
+KPX ecircumflex gbreve -40
+KPX ecircumflex gcommaaccent -40
+KPX ecircumflex period -15
+KPX ecircumflex v -15
+KPX ecircumflex w -15
+KPX ecircumflex x -20
+KPX ecircumflex y -30
+KPX ecircumflex yacute -30
+KPX ecircumflex ydieresis -30
+KPX edieresis comma -10
+KPX edieresis g -40
+KPX edieresis gbreve -40
+KPX edieresis gcommaaccent -40
+KPX edieresis period -15
+KPX edieresis v -15
+KPX edieresis w -15
+KPX edieresis x -20
+KPX edieresis y -30
+KPX edieresis yacute -30
+KPX edieresis ydieresis -30
+KPX edotaccent comma -10
+KPX edotaccent g -40
+KPX edotaccent gbreve -40
+KPX edotaccent gcommaaccent -40
+KPX edotaccent period -15
+KPX edotaccent v -15
+KPX edotaccent w -15
+KPX edotaccent x -20
+KPX edotaccent y -30
+KPX edotaccent yacute -30
+KPX edotaccent ydieresis -30
+KPX egrave comma -10
+KPX egrave g -40
+KPX egrave gbreve -40
+KPX egrave gcommaaccent -40
+KPX egrave period -15
+KPX egrave v -15
+KPX egrave w -15
+KPX egrave x -20
+KPX egrave y -30
+KPX egrave yacute -30
+KPX egrave ydieresis -30
+KPX emacron comma -10
+KPX emacron g -40
+KPX emacron gbreve -40
+KPX emacron gcommaaccent -40
+KPX emacron period -15
+KPX emacron v -15
+KPX emacron w -15
+KPX emacron x -20
+KPX emacron y -30
+KPX emacron yacute -30
+KPX emacron ydieresis -30
+KPX eogonek comma -10
+KPX eogonek g -40
+KPX eogonek gbreve -40
+KPX eogonek gcommaaccent -40
+KPX eogonek period -15
+KPX eogonek v -15
+KPX eogonek w -15
+KPX eogonek x -20
+KPX eogonek y -30
+KPX eogonek yacute -30
+KPX eogonek ydieresis -30
+KPX f comma -10
+KPX f dotlessi -60
+KPX f f -18
+KPX f i -20
+KPX f iogonek -20
+KPX f period -15
+KPX f quoteright 92
+KPX g comma -10
+KPX g e -10
+KPX g eacute -10
+KPX g ecaron -10
+KPX g ecircumflex -10
+KPX g edieresis -10
+KPX g edotaccent -10
+KPX g egrave -10
+KPX g emacron -10
+KPX g eogonek -10
+KPX g g -10
+KPX g gbreve -10
+KPX g gcommaaccent -10
+KPX g period -15
+KPX gbreve comma -10
+KPX gbreve e -10
+KPX gbreve eacute -10
+KPX gbreve ecaron -10
+KPX gbreve ecircumflex -10
+KPX gbreve edieresis -10
+KPX gbreve edotaccent -10
+KPX gbreve egrave -10
+KPX gbreve emacron -10
+KPX gbreve eogonek -10
+KPX gbreve g -10
+KPX gbreve gbreve -10
+KPX gbreve gcommaaccent -10
+KPX gbreve period -15
+KPX gcommaaccent comma -10
+KPX gcommaaccent e -10
+KPX gcommaaccent eacute -10
+KPX gcommaaccent ecaron -10
+KPX gcommaaccent ecircumflex -10
+KPX gcommaaccent edieresis -10
+KPX gcommaaccent edotaccent -10
+KPX gcommaaccent egrave -10
+KPX gcommaaccent emacron -10
+KPX gcommaaccent eogonek -10
+KPX gcommaaccent g -10
+KPX gcommaaccent gbreve -10
+KPX gcommaaccent gcommaaccent -10
+KPX gcommaaccent period -15
+KPX k e -10
+KPX k eacute -10
+KPX k ecaron -10
+KPX k ecircumflex -10
+KPX k edieresis -10
+KPX k edotaccent -10
+KPX k egrave -10
+KPX k emacron -10
+KPX k eogonek -10
+KPX k o -10
+KPX k oacute -10
+KPX k ocircumflex -10
+KPX k odieresis -10
+KPX k ograve -10
+KPX k ohungarumlaut -10
+KPX k omacron -10
+KPX k oslash -10
+KPX k otilde -10
+KPX k y -10
+KPX k yacute -10
+KPX k ydieresis -10
+KPX kcommaaccent e -10
+KPX kcommaaccent eacute -10
+KPX kcommaaccent ecaron -10
+KPX kcommaaccent ecircumflex -10
+KPX kcommaaccent edieresis -10
+KPX kcommaaccent edotaccent -10
+KPX kcommaaccent egrave -10
+KPX kcommaaccent emacron -10
+KPX kcommaaccent eogonek -10
+KPX kcommaaccent o -10
+KPX kcommaaccent oacute -10
+KPX kcommaaccent ocircumflex -10
+KPX kcommaaccent odieresis -10
+KPX kcommaaccent ograve -10
+KPX kcommaaccent ohungarumlaut -10
+KPX kcommaaccent omacron -10
+KPX kcommaaccent oslash -10
+KPX kcommaaccent otilde -10
+KPX kcommaaccent y -10
+KPX kcommaaccent yacute -10
+KPX kcommaaccent ydieresis -10
+KPX n v -40
+KPX nacute v -40
+KPX ncaron v -40
+KPX ncommaaccent v -40
+KPX ntilde v -40
+KPX o g -10
+KPX o gbreve -10
+KPX o gcommaaccent -10
+KPX o v -10
+KPX oacute g -10
+KPX oacute gbreve -10
+KPX oacute gcommaaccent -10
+KPX oacute v -10
+KPX ocircumflex g -10
+KPX ocircumflex gbreve -10
+KPX ocircumflex gcommaaccent -10
+KPX ocircumflex v -10
+KPX odieresis g -10
+KPX odieresis gbreve -10
+KPX odieresis gcommaaccent -10
+KPX odieresis v -10
+KPX ograve g -10
+KPX ograve gbreve -10
+KPX ograve gcommaaccent -10
+KPX ograve v -10
+KPX ohungarumlaut g -10
+KPX ohungarumlaut gbreve -10
+KPX ohungarumlaut gcommaaccent -10
+KPX ohungarumlaut v -10
+KPX omacron g -10
+KPX omacron gbreve -10
+KPX omacron gcommaaccent -10
+KPX omacron v -10
+KPX oslash g -10
+KPX oslash gbreve -10
+KPX oslash gcommaaccent -10
+KPX oslash v -10
+KPX otilde g -10
+KPX otilde gbreve -10
+KPX otilde gcommaaccent -10
+KPX otilde v -10
+KPX period quotedblright -140
+KPX period quoteright -140
+KPX quoteleft quoteleft -111
+KPX quoteright d -25
+KPX quoteright dcroat -25
+KPX quoteright quoteright -111
+KPX quoteright r -25
+KPX quoteright racute -25
+KPX quoteright rcaron -25
+KPX quoteright rcommaaccent -25
+KPX quoteright s -40
+KPX quoteright sacute -40
+KPX quoteright scaron -40
+KPX quoteright scedilla -40
+KPX quoteright scommaaccent -40
+KPX quoteright space -111
+KPX quoteright t -30
+KPX quoteright tcommaaccent -30
+KPX quoteright v -10
+KPX r a -15
+KPX r aacute -15
+KPX r abreve -15
+KPX r acircumflex -15
+KPX r adieresis -15
+KPX r agrave -15
+KPX r amacron -15
+KPX r aogonek -15
+KPX r aring -15
+KPX r atilde -15
+KPX r c -37
+KPX r cacute -37
+KPX r ccaron -37
+KPX r ccedilla -37
+KPX r comma -111
+KPX r d -37
+KPX r dcroat -37
+KPX r e -37
+KPX r eacute -37
+KPX r ecaron -37
+KPX r ecircumflex -37
+KPX r edieresis -37
+KPX r edotaccent -37
+KPX r egrave -37
+KPX r emacron -37
+KPX r eogonek -37
+KPX r g -37
+KPX r gbreve -37
+KPX r gcommaaccent -37
+KPX r hyphen -20
+KPX r o -45
+KPX r oacute -45
+KPX r ocircumflex -45
+KPX r odieresis -45
+KPX r ograve -45
+KPX r ohungarumlaut -45
+KPX r omacron -45
+KPX r oslash -45
+KPX r otilde -45
+KPX r period -111
+KPX r q -37
+KPX r s -10
+KPX r sacute -10
+KPX r scaron -10
+KPX r scedilla -10
+KPX r scommaaccent -10
+KPX racute a -15
+KPX racute aacute -15
+KPX racute abreve -15
+KPX racute acircumflex -15
+KPX racute adieresis -15
+KPX racute agrave -15
+KPX racute amacron -15
+KPX racute aogonek -15
+KPX racute aring -15
+KPX racute atilde -15
+KPX racute c -37
+KPX racute cacute -37
+KPX racute ccaron -37
+KPX racute ccedilla -37
+KPX racute comma -111
+KPX racute d -37
+KPX racute dcroat -37
+KPX racute e -37
+KPX racute eacute -37
+KPX racute ecaron -37
+KPX racute ecircumflex -37
+KPX racute edieresis -37
+KPX racute edotaccent -37
+KPX racute egrave -37
+KPX racute emacron -37
+KPX racute eogonek -37
+KPX racute g -37
+KPX racute gbreve -37
+KPX racute gcommaaccent -37
+KPX racute hyphen -20
+KPX racute o -45
+KPX racute oacute -45
+KPX racute ocircumflex -45
+KPX racute odieresis -45
+KPX racute ograve -45
+KPX racute ohungarumlaut -45
+KPX racute omacron -45
+KPX racute oslash -45
+KPX racute otilde -45
+KPX racute period -111
+KPX racute q -37
+KPX racute s -10
+KPX racute sacute -10
+KPX racute scaron -10
+KPX racute scedilla -10
+KPX racute scommaaccent -10
+KPX rcaron a -15
+KPX rcaron aacute -15
+KPX rcaron abreve -15
+KPX rcaron acircumflex -15
+KPX rcaron adieresis -15
+KPX rcaron agrave -15
+KPX rcaron amacron -15
+KPX rcaron aogonek -15
+KPX rcaron aring -15
+KPX rcaron atilde -15
+KPX rcaron c -37
+KPX rcaron cacute -37
+KPX rcaron ccaron -37
+KPX rcaron ccedilla -37
+KPX rcaron comma -111
+KPX rcaron d -37
+KPX rcaron dcroat -37
+KPX rcaron e -37
+KPX rcaron eacute -37
+KPX rcaron ecaron -37
+KPX rcaron ecircumflex -37
+KPX rcaron edieresis -37
+KPX rcaron edotaccent -37
+KPX rcaron egrave -37
+KPX rcaron emacron -37
+KPX rcaron eogonek -37
+KPX rcaron g -37
+KPX rcaron gbreve -37
+KPX rcaron gcommaaccent -37
+KPX rcaron hyphen -20
+KPX rcaron o -45
+KPX rcaron oacute -45
+KPX rcaron ocircumflex -45
+KPX rcaron odieresis -45
+KPX rcaron ograve -45
+KPX rcaron ohungarumlaut -45
+KPX rcaron omacron -45
+KPX rcaron oslash -45
+KPX rcaron otilde -45
+KPX rcaron period -111
+KPX rcaron q -37
+KPX rcaron s -10
+KPX rcaron sacute -10
+KPX rcaron scaron -10
+KPX rcaron scedilla -10
+KPX rcaron scommaaccent -10
+KPX rcommaaccent a -15
+KPX rcommaaccent aacute -15
+KPX rcommaaccent abreve -15
+KPX rcommaaccent acircumflex -15
+KPX rcommaaccent adieresis -15
+KPX rcommaaccent agrave -15
+KPX rcommaaccent amacron -15
+KPX rcommaaccent aogonek -15
+KPX rcommaaccent aring -15
+KPX rcommaaccent atilde -15
+KPX rcommaaccent c -37
+KPX rcommaaccent cacute -37
+KPX rcommaaccent ccaron -37
+KPX rcommaaccent ccedilla -37
+KPX rcommaaccent comma -111
+KPX rcommaaccent d -37
+KPX rcommaaccent dcroat -37
+KPX rcommaaccent e -37
+KPX rcommaaccent eacute -37
+KPX rcommaaccent ecaron -37
+KPX rcommaaccent ecircumflex -37
+KPX rcommaaccent edieresis -37
+KPX rcommaaccent edotaccent -37
+KPX rcommaaccent egrave -37
+KPX rcommaaccent emacron -37
+KPX rcommaaccent eogonek -37
+KPX rcommaaccent g -37
+KPX rcommaaccent gbreve -37
+KPX rcommaaccent gcommaaccent -37
+KPX rcommaaccent hyphen -20
+KPX rcommaaccent o -45
+KPX rcommaaccent oacute -45
+KPX rcommaaccent ocircumflex -45
+KPX rcommaaccent odieresis -45
+KPX rcommaaccent ograve -45
+KPX rcommaaccent ohungarumlaut -45
+KPX rcommaaccent omacron -45
+KPX rcommaaccent oslash -45
+KPX rcommaaccent otilde -45
+KPX rcommaaccent period -111
+KPX rcommaaccent q -37
+KPX rcommaaccent s -10
+KPX rcommaaccent sacute -10
+KPX rcommaaccent scaron -10
+KPX rcommaaccent scedilla -10
+KPX rcommaaccent scommaaccent -10
+KPX space A -18
+KPX space Aacute -18
+KPX space Abreve -18
+KPX space Acircumflex -18
+KPX space Adieresis -18
+KPX space Agrave -18
+KPX space Amacron -18
+KPX space Aogonek -18
+KPX space Aring -18
+KPX space Atilde -18
+KPX space T -18
+KPX space Tcaron -18
+KPX space Tcommaaccent -18
+KPX space V -35
+KPX space W -40
+KPX space Y -75
+KPX space Yacute -75
+KPX space Ydieresis -75
+KPX v comma -74
+KPX v period -74
+KPX w comma -74
+KPX w period -74
+KPX y comma -55
+KPX y period -55
+KPX yacute comma -55
+KPX yacute period -55
+KPX ydieresis comma -55
+KPX ydieresis period -55
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/Times-Roman.afm b/iTechSharp/iTextSharp/text/pdf/fonts/Times-Roman.afm
new file mode 100644
index 0000000..354775b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/Times-Roman.afm
@@ -0,0 +1,2419 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 12:49:17 1997
+Comment UniqueID 43068
+Comment VMusage 43909 54934
+FontName Times-Roman
+FullName Times Roman
+FamilyName Times
+Weight Roman
+ItalicAngle 0
+IsFixedPitch false
+CharacterSet ExtendedRoman
+FontBBox -168 -218 1000 898
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 662
+XHeight 450
+Ascender 683
+Descender -217
+StdHW 28
+StdVW 84
+StartCharMetrics 315
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ;
+C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ;
+C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ;
+C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ;
+C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ;
+C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ;
+C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ;
+C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ;
+C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ;
+C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ;
+C 43 ; WX 564 ; N plus ; B 30 0 534 506 ;
+C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ;
+C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ;
+C 46 ; WX 250 ; N period ; B 70 -11 181 100 ;
+C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ;
+C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ;
+C 49 ; WX 500 ; N one ; B 111 0 394 676 ;
+C 50 ; WX 500 ; N two ; B 30 0 475 676 ;
+C 51 ; WX 500 ; N three ; B 43 -14 431 676 ;
+C 52 ; WX 500 ; N four ; B 12 0 472 676 ;
+C 53 ; WX 500 ; N five ; B 32 -14 438 688 ;
+C 54 ; WX 500 ; N six ; B 34 -14 468 684 ;
+C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ;
+C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ;
+C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ;
+C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ;
+C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ;
+C 60 ; WX 564 ; N less ; B 28 -8 536 514 ;
+C 61 ; WX 564 ; N equal ; B 30 120 534 386 ;
+C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ;
+C 63 ; WX 444 ; N question ; B 68 -8 414 676 ;
+C 64 ; WX 921 ; N at ; B 116 -14 809 676 ;
+C 65 ; WX 722 ; N A ; B 15 0 706 674 ;
+C 66 ; WX 667 ; N B ; B 17 0 593 662 ;
+C 67 ; WX 667 ; N C ; B 28 -14 633 676 ;
+C 68 ; WX 722 ; N D ; B 16 0 685 662 ;
+C 69 ; WX 611 ; N E ; B 12 0 597 662 ;
+C 70 ; WX 556 ; N F ; B 12 0 546 662 ;
+C 71 ; WX 722 ; N G ; B 32 -14 709 676 ;
+C 72 ; WX 722 ; N H ; B 19 0 702 662 ;
+C 73 ; WX 333 ; N I ; B 18 0 315 662 ;
+C 74 ; WX 389 ; N J ; B 10 -14 370 662 ;
+C 75 ; WX 722 ; N K ; B 34 0 723 662 ;
+C 76 ; WX 611 ; N L ; B 12 0 598 662 ;
+C 77 ; WX 889 ; N M ; B 12 0 863 662 ;
+C 78 ; WX 722 ; N N ; B 12 -11 707 662 ;
+C 79 ; WX 722 ; N O ; B 34 -14 688 676 ;
+C 80 ; WX 556 ; N P ; B 16 0 542 662 ;
+C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ;
+C 82 ; WX 667 ; N R ; B 17 0 659 662 ;
+C 83 ; WX 556 ; N S ; B 42 -14 491 676 ;
+C 84 ; WX 611 ; N T ; B 17 0 593 662 ;
+C 85 ; WX 722 ; N U ; B 14 -14 705 662 ;
+C 86 ; WX 722 ; N V ; B 16 -11 697 662 ;
+C 87 ; WX 944 ; N W ; B 5 -11 932 662 ;
+C 88 ; WX 722 ; N X ; B 10 0 704 662 ;
+C 89 ; WX 722 ; N Y ; B 22 0 703 662 ;
+C 90 ; WX 611 ; N Z ; B 9 0 597 662 ;
+C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ;
+C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ;
+C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ;
+C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ;
+C 97 ; WX 444 ; N a ; B 37 -10 442 460 ;
+C 98 ; WX 500 ; N b ; B 3 -10 468 683 ;
+C 99 ; WX 444 ; N c ; B 25 -10 412 460 ;
+C 100 ; WX 500 ; N d ; B 27 -10 491 683 ;
+C 101 ; WX 444 ; N e ; B 25 -10 424 460 ;
+C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 28 -218 470 460 ;
+C 104 ; WX 500 ; N h ; B 9 0 487 683 ;
+C 105 ; WX 278 ; N i ; B 16 0 253 683 ;
+C 106 ; WX 278 ; N j ; B -70 -218 194 683 ;
+C 107 ; WX 500 ; N k ; B 7 0 505 683 ;
+C 108 ; WX 278 ; N l ; B 19 0 257 683 ;
+C 109 ; WX 778 ; N m ; B 16 0 775 460 ;
+C 110 ; WX 500 ; N n ; B 16 0 485 460 ;
+C 111 ; WX 500 ; N o ; B 29 -10 470 460 ;
+C 112 ; WX 500 ; N p ; B 5 -217 470 460 ;
+C 113 ; WX 500 ; N q ; B 24 -217 488 460 ;
+C 114 ; WX 333 ; N r ; B 5 0 335 460 ;
+C 115 ; WX 389 ; N s ; B 51 -10 348 460 ;
+C 116 ; WX 278 ; N t ; B 13 -10 279 579 ;
+C 117 ; WX 500 ; N u ; B 9 -10 479 450 ;
+C 118 ; WX 500 ; N v ; B 19 -14 477 450 ;
+C 119 ; WX 722 ; N w ; B 21 -14 694 450 ;
+C 120 ; WX 500 ; N x ; B 17 0 479 450 ;
+C 121 ; WX 500 ; N y ; B 14 -218 475 450 ;
+C 122 ; WX 444 ; N z ; B 27 0 418 450 ;
+C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ;
+C 124 ; WX 200 ; N bar ; B 67 -218 133 782 ;
+C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ;
+C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
+C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ;
+C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ;
+C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ;
+C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ;
+C 165 ; WX 500 ; N yen ; B -53 0 512 662 ;
+C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ;
+C 167 ; WX 500 ; N section ; B 70 -148 426 676 ;
+C 168 ; WX 500 ; N currency ; B -22 58 522 602 ;
+C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ;
+C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ;
+C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ;
+C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ;
+C 174 ; WX 556 ; N fi ; B 31 0 521 683 ;
+C 175 ; WX 556 ; N fl ; B 32 0 521 683 ;
+C 177 ; WX 500 ; N endash ; B 0 201 500 250 ;
+C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ;
+C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ;
+C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
+C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ;
+C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ;
+C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ;
+C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ;
+C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ;
+C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ;
+C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ;
+C 193 ; WX 333 ; N grave ; B 19 507 242 678 ;
+C 194 ; WX 333 ; N acute ; B 93 507 317 678 ;
+C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ;
+C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ;
+C 197 ; WX 333 ; N macron ; B 11 547 322 601 ;
+C 198 ; WX 333 ; N breve ; B 26 507 307 664 ;
+C 199 ; WX 333 ; N dotaccent ; B 118 581 216 681 ;
+C 200 ; WX 333 ; N dieresis ; B 18 581 315 681 ;
+C 202 ; WX 333 ; N ring ; B 67 512 266 711 ;
+C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ;
+C 206 ; WX 333 ; N ogonek ; B 62 -165 243 0 ;
+C 207 ; WX 333 ; N caron ; B 11 507 322 674 ;
+C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ;
+C 225 ; WX 889 ; N AE ; B 0 0 863 662 ;
+C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ;
+C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ;
+C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ;
+C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ;
+C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ;
+C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ;
+C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ;
+C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ;
+C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ;
+C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ;
+C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ;
+C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ;
+C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ;
+C -1 ; WX 444 ; N abreve ; B 37 -10 442 664 ;
+C -1 ; WX 500 ; N uhungarumlaut ; B 9 -10 501 678 ;
+C -1 ; WX 444 ; N ecaron ; B 25 -10 424 674 ;
+C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ;
+C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ;
+C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ;
+C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ;
+C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ;
+C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ;
+C -1 ; WX 389 ; N scommaaccent ; B 51 -218 348 460 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ;
+C -1 ; WX 722 ; N Uring ; B 14 -14 705 898 ;
+C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ;
+C -1 ; WX 444 ; N aogonek ; B 37 -165 469 460 ;
+C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ;
+C -1 ; WX 500 ; N uogonek ; B 9 -155 487 450 ;
+C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ;
+C -1 ; WX 722 ; N Dcroat ; B 16 0 685 662 ;
+C -1 ; WX 250 ; N commaaccent ; B 59 -218 184 -50 ;
+C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ;
+C -1 ; WX 611 ; N Emacron ; B 12 0 597 813 ;
+C -1 ; WX 444 ; N ccaron ; B 25 -10 412 674 ;
+C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ;
+C -1 ; WX 722 ; N Ncommaaccent ; B 12 -198 707 662 ;
+C -1 ; WX 278 ; N lacute ; B 19 0 290 890 ;
+C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ;
+C -1 ; WX 611 ; N Tcommaaccent ; B 17 -218 593 662 ;
+C -1 ; WX 667 ; N Cacute ; B 28 -14 633 890 ;
+C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ;
+C -1 ; WX 611 ; N Edotaccent ; B 12 0 597 835 ;
+C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ;
+C -1 ; WX 389 ; N scedilla ; B 51 -215 348 460 ;
+C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ;
+C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ;
+C -1 ; WX 667 ; N Rcaron ; B 17 0 659 886 ;
+C -1 ; WX 722 ; N Gcommaaccent ; B 32 -218 709 676 ;
+C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ;
+C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ;
+C -1 ; WX 722 ; N Amacron ; B 15 0 706 813 ;
+C -1 ; WX 333 ; N rcaron ; B 5 0 335 674 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ;
+C -1 ; WX 611 ; N Zdotaccent ; B 9 0 597 835 ;
+C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ;
+C -1 ; WX 722 ; N Omacron ; B 34 -14 688 813 ;
+C -1 ; WX 667 ; N Racute ; B 17 0 659 890 ;
+C -1 ; WX 556 ; N Sacute ; B 42 -14 491 890 ;
+C -1 ; WX 588 ; N dcaron ; B 27 -10 589 695 ;
+C -1 ; WX 722 ; N Umacron ; B 14 -14 705 813 ;
+C -1 ; WX 500 ; N uring ; B 9 -10 479 711 ;
+C -1 ; WX 300 ; N threebaseior ; B 15 262 291 676 ;
+C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ;
+C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ;
+C -1 ; WX 722 ; N Abreve ; B 15 0 706 876 ;
+C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ;
+C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ;
+C -1 ; WX 611 ; N Tcaron ; B 17 0 593 886 ;
+C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ;
+C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ;
+C -1 ; WX 722 ; N Nacute ; B 12 -11 707 890 ;
+C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ;
+C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ;
+C -1 ; WX 444 ; N cacute ; B 25 -10 413 678 ;
+C -1 ; WX 500 ; N nacute ; B 16 0 485 678 ;
+C -1 ; WX 500 ; N umacron ; B 9 -10 479 601 ;
+C -1 ; WX 722 ; N Ncaron ; B 12 -11 707 886 ;
+C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ;
+C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ;
+C -1 ; WX 200 ; N brokenbar ; B 67 -143 133 707 ;
+C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ;
+C -1 ; WX 722 ; N Gbreve ; B 32 -14 709 876 ;
+C -1 ; WX 333 ; N Idotaccent ; B 18 0 315 835 ;
+C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ;
+C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ;
+C -1 ; WX 333 ; N racute ; B 5 0 335 678 ;
+C -1 ; WX 500 ; N omacron ; B 29 -10 470 601 ;
+C -1 ; WX 611 ; N Zacute ; B 9 0 597 890 ;
+C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ;
+C -1 ; WX 549 ; N greaterequal ; B 26 0 523 666 ;
+C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ;
+C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ;
+C -1 ; WX 278 ; N lcommaaccent ; B 19 -218 257 683 ;
+C -1 ; WX 326 ; N tcaron ; B 13 -10 318 722 ;
+C -1 ; WX 444 ; N eogonek ; B 25 -165 424 460 ;
+C -1 ; WX 722 ; N Uogonek ; B 14 -165 705 662 ;
+C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ;
+C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ;
+C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ;
+C -1 ; WX 444 ; N zacute ; B 27 0 418 678 ;
+C -1 ; WX 278 ; N iogonek ; B 16 -165 265 683 ;
+C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ;
+C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ;
+C -1 ; WX 444 ; N amacron ; B 37 -10 442 601 ;
+C -1 ; WX 389 ; N sacute ; B 51 -10 348 678 ;
+C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ;
+C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ;
+C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ;
+C -1 ; WX 300 ; N twobaseior ; B 1 270 296 676 ;
+C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ;
+C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ;
+C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ;
+C -1 ; WX 500 ; N ohungarumlaut ; B 29 -10 491 678 ;
+C -1 ; WX 611 ; N Eogonek ; B 12 -165 597 662 ;
+C -1 ; WX 500 ; N dcroat ; B 27 -10 500 683 ;
+C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ;
+C -1 ; WX 556 ; N Scedilla ; B 42 -215 491 676 ;
+C -1 ; WX 344 ; N lcaron ; B 19 0 347 695 ;
+C -1 ; WX 722 ; N Kcommaaccent ; B 34 -198 723 662 ;
+C -1 ; WX 611 ; N Lacute ; B 12 0 598 890 ;
+C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ;
+C -1 ; WX 444 ; N edotaccent ; B 25 -10 424 623 ;
+C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ;
+C -1 ; WX 333 ; N Imacron ; B 11 0 322 813 ;
+C -1 ; WX 611 ; N Lcaron ; B 12 0 598 676 ;
+C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ;
+C -1 ; WX 549 ; N lessequal ; B 26 0 523 666 ;
+C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ;
+C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ;
+C -1 ; WX 722 ; N Uhungarumlaut ; B 14 -14 705 890 ;
+C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ;
+C -1 ; WX 444 ; N emacron ; B 25 -10 424 601 ;
+C -1 ; WX 500 ; N gbreve ; B 28 -218 470 664 ;
+C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ;
+C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ;
+C -1 ; WX 556 ; N Scommaaccent ; B 42 -218 491 676 ;
+C -1 ; WX 722 ; N Ohungarumlaut ; B 34 -14 688 890 ;
+C -1 ; WX 400 ; N degree ; B 57 390 343 676 ;
+C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ;
+C -1 ; WX 667 ; N Ccaron ; B 28 -14 633 886 ;
+C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ;
+C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ;
+C -1 ; WX 722 ; N Dcaron ; B 16 0 685 886 ;
+C -1 ; WX 333 ; N rcommaaccent ; B 5 -218 335 460 ;
+C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ;
+C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ;
+C -1 ; WX 667 ; N Rcommaaccent ; B 17 -198 659 662 ;
+C -1 ; WX 611 ; N Lcommaaccent ; B 12 -218 598 662 ;
+C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ;
+C -1 ; WX 722 ; N Aogonek ; B 15 -165 738 674 ;
+C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ;
+C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ;
+C -1 ; WX 444 ; N zdotaccent ; B 27 0 418 623 ;
+C -1 ; WX 611 ; N Ecaron ; B 12 0 597 886 ;
+C -1 ; WX 333 ; N Iogonek ; B 18 -165 315 662 ;
+C -1 ; WX 500 ; N kcommaaccent ; B 7 -218 505 683 ;
+C -1 ; WX 564 ; N minus ; B 30 220 534 286 ;
+C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ;
+C -1 ; WX 500 ; N ncaron ; B 16 0 485 674 ;
+C -1 ; WX 278 ; N tcommaaccent ; B 13 -218 279 579 ;
+C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ;
+C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ;
+C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ;
+C -1 ; WX 549 ; N notequal ; B 12 -31 537 547 ;
+C -1 ; WX 500 ; N gcommaaccent ; B 28 -218 470 749 ;
+C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ;
+C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ;
+C -1 ; WX 500 ; N ncommaaccent ; B 16 -218 485 460 ;
+C -1 ; WX 300 ; N onebaseior ; B 57 270 248 676 ;
+C -1 ; WX 278 ; N imacron ; B 6 0 271 601 ;
+C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 2073
+KPX A C -40
+KPX A Cacute -40
+KPX A Ccaron -40
+KPX A Ccedilla -40
+KPX A G -40
+KPX A Gbreve -40
+KPX A Gcommaaccent -40
+KPX A O -55
+KPX A Oacute -55
+KPX A Ocircumflex -55
+KPX A Odieresis -55
+KPX A Ograve -55
+KPX A Ohungarumlaut -55
+KPX A Omacron -55
+KPX A Oslash -55
+KPX A Otilde -55
+KPX A Q -55
+KPX A T -111
+KPX A Tcaron -111
+KPX A Tcommaaccent -111
+KPX A U -55
+KPX A Uacute -55
+KPX A Ucircumflex -55
+KPX A Udieresis -55
+KPX A Ugrave -55
+KPX A Uhungarumlaut -55
+KPX A Umacron -55
+KPX A Uogonek -55
+KPX A Uring -55
+KPX A V -135
+KPX A W -90
+KPX A Y -105
+KPX A Yacute -105
+KPX A Ydieresis -105
+KPX A quoteright -111
+KPX A v -74
+KPX A w -92
+KPX A y -92
+KPX A yacute -92
+KPX A ydieresis -92
+KPX Aacute C -40
+KPX Aacute Cacute -40
+KPX Aacute Ccaron -40
+KPX Aacute Ccedilla -40
+KPX Aacute G -40
+KPX Aacute Gbreve -40
+KPX Aacute Gcommaaccent -40
+KPX Aacute O -55
+KPX Aacute Oacute -55
+KPX Aacute Ocircumflex -55
+KPX Aacute Odieresis -55
+KPX Aacute Ograve -55
+KPX Aacute Ohungarumlaut -55
+KPX Aacute Omacron -55
+KPX Aacute Oslash -55
+KPX Aacute Otilde -55
+KPX Aacute Q -55
+KPX Aacute T -111
+KPX Aacute Tcaron -111
+KPX Aacute Tcommaaccent -111
+KPX Aacute U -55
+KPX Aacute Uacute -55
+KPX Aacute Ucircumflex -55
+KPX Aacute Udieresis -55
+KPX Aacute Ugrave -55
+KPX Aacute Uhungarumlaut -55
+KPX Aacute Umacron -55
+KPX Aacute Uogonek -55
+KPX Aacute Uring -55
+KPX Aacute V -135
+KPX Aacute W -90
+KPX Aacute Y -105
+KPX Aacute Yacute -105
+KPX Aacute Ydieresis -105
+KPX Aacute quoteright -111
+KPX Aacute v -74
+KPX Aacute w -92
+KPX Aacute y -92
+KPX Aacute yacute -92
+KPX Aacute ydieresis -92
+KPX Abreve C -40
+KPX Abreve Cacute -40
+KPX Abreve Ccaron -40
+KPX Abreve Ccedilla -40
+KPX Abreve G -40
+KPX Abreve Gbreve -40
+KPX Abreve Gcommaaccent -40
+KPX Abreve O -55
+KPX Abreve Oacute -55
+KPX Abreve Ocircumflex -55
+KPX Abreve Odieresis -55
+KPX Abreve Ograve -55
+KPX Abreve Ohungarumlaut -55
+KPX Abreve Omacron -55
+KPX Abreve Oslash -55
+KPX Abreve Otilde -55
+KPX Abreve Q -55
+KPX Abreve T -111
+KPX Abreve Tcaron -111
+KPX Abreve Tcommaaccent -111
+KPX Abreve U -55
+KPX Abreve Uacute -55
+KPX Abreve Ucircumflex -55
+KPX Abreve Udieresis -55
+KPX Abreve Ugrave -55
+KPX Abreve Uhungarumlaut -55
+KPX Abreve Umacron -55
+KPX Abreve Uogonek -55
+KPX Abreve Uring -55
+KPX Abreve V -135
+KPX Abreve W -90
+KPX Abreve Y -105
+KPX Abreve Yacute -105
+KPX Abreve Ydieresis -105
+KPX Abreve quoteright -111
+KPX Abreve v -74
+KPX Abreve w -92
+KPX Abreve y -92
+KPX Abreve yacute -92
+KPX Abreve ydieresis -92
+KPX Acircumflex C -40
+KPX Acircumflex Cacute -40
+KPX Acircumflex Ccaron -40
+KPX Acircumflex Ccedilla -40
+KPX Acircumflex G -40
+KPX Acircumflex Gbreve -40
+KPX Acircumflex Gcommaaccent -40
+KPX Acircumflex O -55
+KPX Acircumflex Oacute -55
+KPX Acircumflex Ocircumflex -55
+KPX Acircumflex Odieresis -55
+KPX Acircumflex Ograve -55
+KPX Acircumflex Ohungarumlaut -55
+KPX Acircumflex Omacron -55
+KPX Acircumflex Oslash -55
+KPX Acircumflex Otilde -55
+KPX Acircumflex Q -55
+KPX Acircumflex T -111
+KPX Acircumflex Tcaron -111
+KPX Acircumflex Tcommaaccent -111
+KPX Acircumflex U -55
+KPX Acircumflex Uacute -55
+KPX Acircumflex Ucircumflex -55
+KPX Acircumflex Udieresis -55
+KPX Acircumflex Ugrave -55
+KPX Acircumflex Uhungarumlaut -55
+KPX Acircumflex Umacron -55
+KPX Acircumflex Uogonek -55
+KPX Acircumflex Uring -55
+KPX Acircumflex V -135
+KPX Acircumflex W -90
+KPX Acircumflex Y -105
+KPX Acircumflex Yacute -105
+KPX Acircumflex Ydieresis -105
+KPX Acircumflex quoteright -111
+KPX Acircumflex v -74
+KPX Acircumflex w -92
+KPX Acircumflex y -92
+KPX Acircumflex yacute -92
+KPX Acircumflex ydieresis -92
+KPX Adieresis C -40
+KPX Adieresis Cacute -40
+KPX Adieresis Ccaron -40
+KPX Adieresis Ccedilla -40
+KPX Adieresis G -40
+KPX Adieresis Gbreve -40
+KPX Adieresis Gcommaaccent -40
+KPX Adieresis O -55
+KPX Adieresis Oacute -55
+KPX Adieresis Ocircumflex -55
+KPX Adieresis Odieresis -55
+KPX Adieresis Ograve -55
+KPX Adieresis Ohungarumlaut -55
+KPX Adieresis Omacron -55
+KPX Adieresis Oslash -55
+KPX Adieresis Otilde -55
+KPX Adieresis Q -55
+KPX Adieresis T -111
+KPX Adieresis Tcaron -111
+KPX Adieresis Tcommaaccent -111
+KPX Adieresis U -55
+KPX Adieresis Uacute -55
+KPX Adieresis Ucircumflex -55
+KPX Adieresis Udieresis -55
+KPX Adieresis Ugrave -55
+KPX Adieresis Uhungarumlaut -55
+KPX Adieresis Umacron -55
+KPX Adieresis Uogonek -55
+KPX Adieresis Uring -55
+KPX Adieresis V -135
+KPX Adieresis W -90
+KPX Adieresis Y -105
+KPX Adieresis Yacute -105
+KPX Adieresis Ydieresis -105
+KPX Adieresis quoteright -111
+KPX Adieresis v -74
+KPX Adieresis w -92
+KPX Adieresis y -92
+KPX Adieresis yacute -92
+KPX Adieresis ydieresis -92
+KPX Agrave C -40
+KPX Agrave Cacute -40
+KPX Agrave Ccaron -40
+KPX Agrave Ccedilla -40
+KPX Agrave G -40
+KPX Agrave Gbreve -40
+KPX Agrave Gcommaaccent -40
+KPX Agrave O -55
+KPX Agrave Oacute -55
+KPX Agrave Ocircumflex -55
+KPX Agrave Odieresis -55
+KPX Agrave Ograve -55
+KPX Agrave Ohungarumlaut -55
+KPX Agrave Omacron -55
+KPX Agrave Oslash -55
+KPX Agrave Otilde -55
+KPX Agrave Q -55
+KPX Agrave T -111
+KPX Agrave Tcaron -111
+KPX Agrave Tcommaaccent -111
+KPX Agrave U -55
+KPX Agrave Uacute -55
+KPX Agrave Ucircumflex -55
+KPX Agrave Udieresis -55
+KPX Agrave Ugrave -55
+KPX Agrave Uhungarumlaut -55
+KPX Agrave Umacron -55
+KPX Agrave Uogonek -55
+KPX Agrave Uring -55
+KPX Agrave V -135
+KPX Agrave W -90
+KPX Agrave Y -105
+KPX Agrave Yacute -105
+KPX Agrave Ydieresis -105
+KPX Agrave quoteright -111
+KPX Agrave v -74
+KPX Agrave w -92
+KPX Agrave y -92
+KPX Agrave yacute -92
+KPX Agrave ydieresis -92
+KPX Amacron C -40
+KPX Amacron Cacute -40
+KPX Amacron Ccaron -40
+KPX Amacron Ccedilla -40
+KPX Amacron G -40
+KPX Amacron Gbreve -40
+KPX Amacron Gcommaaccent -40
+KPX Amacron O -55
+KPX Amacron Oacute -55
+KPX Amacron Ocircumflex -55
+KPX Amacron Odieresis -55
+KPX Amacron Ograve -55
+KPX Amacron Ohungarumlaut -55
+KPX Amacron Omacron -55
+KPX Amacron Oslash -55
+KPX Amacron Otilde -55
+KPX Amacron Q -55
+KPX Amacron T -111
+KPX Amacron Tcaron -111
+KPX Amacron Tcommaaccent -111
+KPX Amacron U -55
+KPX Amacron Uacute -55
+KPX Amacron Ucircumflex -55
+KPX Amacron Udieresis -55
+KPX Amacron Ugrave -55
+KPX Amacron Uhungarumlaut -55
+KPX Amacron Umacron -55
+KPX Amacron Uogonek -55
+KPX Amacron Uring -55
+KPX Amacron V -135
+KPX Amacron W -90
+KPX Amacron Y -105
+KPX Amacron Yacute -105
+KPX Amacron Ydieresis -105
+KPX Amacron quoteright -111
+KPX Amacron v -74
+KPX Amacron w -92
+KPX Amacron y -92
+KPX Amacron yacute -92
+KPX Amacron ydieresis -92
+KPX Aogonek C -40
+KPX Aogonek Cacute -40
+KPX Aogonek Ccaron -40
+KPX Aogonek Ccedilla -40
+KPX Aogonek G -40
+KPX Aogonek Gbreve -40
+KPX Aogonek Gcommaaccent -40
+KPX Aogonek O -55
+KPX Aogonek Oacute -55
+KPX Aogonek Ocircumflex -55
+KPX Aogonek Odieresis -55
+KPX Aogonek Ograve -55
+KPX Aogonek Ohungarumlaut -55
+KPX Aogonek Omacron -55
+KPX Aogonek Oslash -55
+KPX Aogonek Otilde -55
+KPX Aogonek Q -55
+KPX Aogonek T -111
+KPX Aogonek Tcaron -111
+KPX Aogonek Tcommaaccent -111
+KPX Aogonek U -55
+KPX Aogonek Uacute -55
+KPX Aogonek Ucircumflex -55
+KPX Aogonek Udieresis -55
+KPX Aogonek Ugrave -55
+KPX Aogonek Uhungarumlaut -55
+KPX Aogonek Umacron -55
+KPX Aogonek Uogonek -55
+KPX Aogonek Uring -55
+KPX Aogonek V -135
+KPX Aogonek W -90
+KPX Aogonek Y -105
+KPX Aogonek Yacute -105
+KPX Aogonek Ydieresis -105
+KPX Aogonek quoteright -111
+KPX Aogonek v -74
+KPX Aogonek w -52
+KPX Aogonek y -52
+KPX Aogonek yacute -52
+KPX Aogonek ydieresis -52
+KPX Aring C -40
+KPX Aring Cacute -40
+KPX Aring Ccaron -40
+KPX Aring Ccedilla -40
+KPX Aring G -40
+KPX Aring Gbreve -40
+KPX Aring Gcommaaccent -40
+KPX Aring O -55
+KPX Aring Oacute -55
+KPX Aring Ocircumflex -55
+KPX Aring Odieresis -55
+KPX Aring Ograve -55
+KPX Aring Ohungarumlaut -55
+KPX Aring Omacron -55
+KPX Aring Oslash -55
+KPX Aring Otilde -55
+KPX Aring Q -55
+KPX Aring T -111
+KPX Aring Tcaron -111
+KPX Aring Tcommaaccent -111
+KPX Aring U -55
+KPX Aring Uacute -55
+KPX Aring Ucircumflex -55
+KPX Aring Udieresis -55
+KPX Aring Ugrave -55
+KPX Aring Uhungarumlaut -55
+KPX Aring Umacron -55
+KPX Aring Uogonek -55
+KPX Aring Uring -55
+KPX Aring V -135
+KPX Aring W -90
+KPX Aring Y -105
+KPX Aring Yacute -105
+KPX Aring Ydieresis -105
+KPX Aring quoteright -111
+KPX Aring v -74
+KPX Aring w -92
+KPX Aring y -92
+KPX Aring yacute -92
+KPX Aring ydieresis -92
+KPX Atilde C -40
+KPX Atilde Cacute -40
+KPX Atilde Ccaron -40
+KPX Atilde Ccedilla -40
+KPX Atilde G -40
+KPX Atilde Gbreve -40
+KPX Atilde Gcommaaccent -40
+KPX Atilde O -55
+KPX Atilde Oacute -55
+KPX Atilde Ocircumflex -55
+KPX Atilde Odieresis -55
+KPX Atilde Ograve -55
+KPX Atilde Ohungarumlaut -55
+KPX Atilde Omacron -55
+KPX Atilde Oslash -55
+KPX Atilde Otilde -55
+KPX Atilde Q -55
+KPX Atilde T -111
+KPX Atilde Tcaron -111
+KPX Atilde Tcommaaccent -111
+KPX Atilde U -55
+KPX Atilde Uacute -55
+KPX Atilde Ucircumflex -55
+KPX Atilde Udieresis -55
+KPX Atilde Ugrave -55
+KPX Atilde Uhungarumlaut -55
+KPX Atilde Umacron -55
+KPX Atilde Uogonek -55
+KPX Atilde Uring -55
+KPX Atilde V -135
+KPX Atilde W -90
+KPX Atilde Y -105
+KPX Atilde Yacute -105
+KPX Atilde Ydieresis -105
+KPX Atilde quoteright -111
+KPX Atilde v -74
+KPX Atilde w -92
+KPX Atilde y -92
+KPX Atilde yacute -92
+KPX Atilde ydieresis -92
+KPX B A -35
+KPX B Aacute -35
+KPX B Abreve -35
+KPX B Acircumflex -35
+KPX B Adieresis -35
+KPX B Agrave -35
+KPX B Amacron -35
+KPX B Aogonek -35
+KPX B Aring -35
+KPX B Atilde -35
+KPX B U -10
+KPX B Uacute -10
+KPX B Ucircumflex -10
+KPX B Udieresis -10
+KPX B Ugrave -10
+KPX B Uhungarumlaut -10
+KPX B Umacron -10
+KPX B Uogonek -10
+KPX B Uring -10
+KPX D A -40
+KPX D Aacute -40
+KPX D Abreve -40
+KPX D Acircumflex -40
+KPX D Adieresis -40
+KPX D Agrave -40
+KPX D Amacron -40
+KPX D Aogonek -40
+KPX D Aring -40
+KPX D Atilde -40
+KPX D V -40
+KPX D W -30
+KPX D Y -55
+KPX D Yacute -55
+KPX D Ydieresis -55
+KPX Dcaron A -40
+KPX Dcaron Aacute -40
+KPX Dcaron Abreve -40
+KPX Dcaron Acircumflex -40
+KPX Dcaron Adieresis -40
+KPX Dcaron Agrave -40
+KPX Dcaron Amacron -40
+KPX Dcaron Aogonek -40
+KPX Dcaron Aring -40
+KPX Dcaron Atilde -40
+KPX Dcaron V -40
+KPX Dcaron W -30
+KPX Dcaron Y -55
+KPX Dcaron Yacute -55
+KPX Dcaron Ydieresis -55
+KPX Dcroat A -40
+KPX Dcroat Aacute -40
+KPX Dcroat Abreve -40
+KPX Dcroat Acircumflex -40
+KPX Dcroat Adieresis -40
+KPX Dcroat Agrave -40
+KPX Dcroat Amacron -40
+KPX Dcroat Aogonek -40
+KPX Dcroat Aring -40
+KPX Dcroat Atilde -40
+KPX Dcroat V -40
+KPX Dcroat W -30
+KPX Dcroat Y -55
+KPX Dcroat Yacute -55
+KPX Dcroat Ydieresis -55
+KPX F A -74
+KPX F Aacute -74
+KPX F Abreve -74
+KPX F Acircumflex -74
+KPX F Adieresis -74
+KPX F Agrave -74
+KPX F Amacron -74
+KPX F Aogonek -74
+KPX F Aring -74
+KPX F Atilde -74
+KPX F a -15
+KPX F aacute -15
+KPX F abreve -15
+KPX F acircumflex -15
+KPX F adieresis -15
+KPX F agrave -15
+KPX F amacron -15
+KPX F aogonek -15
+KPX F aring -15
+KPX F atilde -15
+KPX F comma -80
+KPX F o -15
+KPX F oacute -15
+KPX F ocircumflex -15
+KPX F odieresis -15
+KPX F ograve -15
+KPX F ohungarumlaut -15
+KPX F omacron -15
+KPX F oslash -15
+KPX F otilde -15
+KPX F period -80
+KPX J A -60
+KPX J Aacute -60
+KPX J Abreve -60
+KPX J Acircumflex -60
+KPX J Adieresis -60
+KPX J Agrave -60
+KPX J Amacron -60
+KPX J Aogonek -60
+KPX J Aring -60
+KPX J Atilde -60
+KPX K O -30
+KPX K Oacute -30
+KPX K Ocircumflex -30
+KPX K Odieresis -30
+KPX K Ograve -30
+KPX K Ohungarumlaut -30
+KPX K Omacron -30
+KPX K Oslash -30
+KPX K Otilde -30
+KPX K e -25
+KPX K eacute -25
+KPX K ecaron -25
+KPX K ecircumflex -25
+KPX K edieresis -25
+KPX K edotaccent -25
+KPX K egrave -25
+KPX K emacron -25
+KPX K eogonek -25
+KPX K o -35
+KPX K oacute -35
+KPX K ocircumflex -35
+KPX K odieresis -35
+KPX K ograve -35
+KPX K ohungarumlaut -35
+KPX K omacron -35
+KPX K oslash -35
+KPX K otilde -35
+KPX K u -15
+KPX K uacute -15
+KPX K ucircumflex -15
+KPX K udieresis -15
+KPX K ugrave -15
+KPX K uhungarumlaut -15
+KPX K umacron -15
+KPX K uogonek -15
+KPX K uring -15
+KPX K y -25
+KPX K yacute -25
+KPX K ydieresis -25
+KPX Kcommaaccent O -30
+KPX Kcommaaccent Oacute -30
+KPX Kcommaaccent Ocircumflex -30
+KPX Kcommaaccent Odieresis -30
+KPX Kcommaaccent Ograve -30
+KPX Kcommaaccent Ohungarumlaut -30
+KPX Kcommaaccent Omacron -30
+KPX Kcommaaccent Oslash -30
+KPX Kcommaaccent Otilde -30
+KPX Kcommaaccent e -25
+KPX Kcommaaccent eacute -25
+KPX Kcommaaccent ecaron -25
+KPX Kcommaaccent ecircumflex -25
+KPX Kcommaaccent edieresis -25
+KPX Kcommaaccent edotaccent -25
+KPX Kcommaaccent egrave -25
+KPX Kcommaaccent emacron -25
+KPX Kcommaaccent eogonek -25
+KPX Kcommaaccent o -35
+KPX Kcommaaccent oacute -35
+KPX Kcommaaccent ocircumflex -35
+KPX Kcommaaccent odieresis -35
+KPX Kcommaaccent ograve -35
+KPX Kcommaaccent ohungarumlaut -35
+KPX Kcommaaccent omacron -35
+KPX Kcommaaccent oslash -35
+KPX Kcommaaccent otilde -35
+KPX Kcommaaccent u -15
+KPX Kcommaaccent uacute -15
+KPX Kcommaaccent ucircumflex -15
+KPX Kcommaaccent udieresis -15
+KPX Kcommaaccent ugrave -15
+KPX Kcommaaccent uhungarumlaut -15
+KPX Kcommaaccent umacron -15
+KPX Kcommaaccent uogonek -15
+KPX Kcommaaccent uring -15
+KPX Kcommaaccent y -25
+KPX Kcommaaccent yacute -25
+KPX Kcommaaccent ydieresis -25
+KPX L T -92
+KPX L Tcaron -92
+KPX L Tcommaaccent -92
+KPX L V -100
+KPX L W -74
+KPX L Y -100
+KPX L Yacute -100
+KPX L Ydieresis -100
+KPX L quoteright -92
+KPX L y -55
+KPX L yacute -55
+KPX L ydieresis -55
+KPX Lacute T -92
+KPX Lacute Tcaron -92
+KPX Lacute Tcommaaccent -92
+KPX Lacute V -100
+KPX Lacute W -74
+KPX Lacute Y -100
+KPX Lacute Yacute -100
+KPX Lacute Ydieresis -100
+KPX Lacute quoteright -92
+KPX Lacute y -55
+KPX Lacute yacute -55
+KPX Lacute ydieresis -55
+KPX Lcaron quoteright -92
+KPX Lcaron y -55
+KPX Lcaron yacute -55
+KPX Lcaron ydieresis -55
+KPX Lcommaaccent T -92
+KPX Lcommaaccent Tcaron -92
+KPX Lcommaaccent Tcommaaccent -92
+KPX Lcommaaccent V -100
+KPX Lcommaaccent W -74
+KPX Lcommaaccent Y -100
+KPX Lcommaaccent Yacute -100
+KPX Lcommaaccent Ydieresis -100
+KPX Lcommaaccent quoteright -92
+KPX Lcommaaccent y -55
+KPX Lcommaaccent yacute -55
+KPX Lcommaaccent ydieresis -55
+KPX Lslash T -92
+KPX Lslash Tcaron -92
+KPX Lslash Tcommaaccent -92
+KPX Lslash V -100
+KPX Lslash W -74
+KPX Lslash Y -100
+KPX Lslash Yacute -100
+KPX Lslash Ydieresis -100
+KPX Lslash quoteright -92
+KPX Lslash y -55
+KPX Lslash yacute -55
+KPX Lslash ydieresis -55
+KPX N A -35
+KPX N Aacute -35
+KPX N Abreve -35
+KPX N Acircumflex -35
+KPX N Adieresis -35
+KPX N Agrave -35
+KPX N Amacron -35
+KPX N Aogonek -35
+KPX N Aring -35
+KPX N Atilde -35
+KPX Nacute A -35
+KPX Nacute Aacute -35
+KPX Nacute Abreve -35
+KPX Nacute Acircumflex -35
+KPX Nacute Adieresis -35
+KPX Nacute Agrave -35
+KPX Nacute Amacron -35
+KPX Nacute Aogonek -35
+KPX Nacute Aring -35
+KPX Nacute Atilde -35
+KPX Ncaron A -35
+KPX Ncaron Aacute -35
+KPX Ncaron Abreve -35
+KPX Ncaron Acircumflex -35
+KPX Ncaron Adieresis -35
+KPX Ncaron Agrave -35
+KPX Ncaron Amacron -35
+KPX Ncaron Aogonek -35
+KPX Ncaron Aring -35
+KPX Ncaron Atilde -35
+KPX Ncommaaccent A -35
+KPX Ncommaaccent Aacute -35
+KPX Ncommaaccent Abreve -35
+KPX Ncommaaccent Acircumflex -35
+KPX Ncommaaccent Adieresis -35
+KPX Ncommaaccent Agrave -35
+KPX Ncommaaccent Amacron -35
+KPX Ncommaaccent Aogonek -35
+KPX Ncommaaccent Aring -35
+KPX Ncommaaccent Atilde -35
+KPX Ntilde A -35
+KPX Ntilde Aacute -35
+KPX Ntilde Abreve -35
+KPX Ntilde Acircumflex -35
+KPX Ntilde Adieresis -35
+KPX Ntilde Agrave -35
+KPX Ntilde Amacron -35
+KPX Ntilde Aogonek -35
+KPX Ntilde Aring -35
+KPX Ntilde Atilde -35
+KPX O A -35
+KPX O Aacute -35
+KPX O Abreve -35
+KPX O Acircumflex -35
+KPX O Adieresis -35
+KPX O Agrave -35
+KPX O Amacron -35
+KPX O Aogonek -35
+KPX O Aring -35
+KPX O Atilde -35
+KPX O T -40
+KPX O Tcaron -40
+KPX O Tcommaaccent -40
+KPX O V -50
+KPX O W -35
+KPX O X -40
+KPX O Y -50
+KPX O Yacute -50
+KPX O Ydieresis -50
+KPX Oacute A -35
+KPX Oacute Aacute -35
+KPX Oacute Abreve -35
+KPX Oacute Acircumflex -35
+KPX Oacute Adieresis -35
+KPX Oacute Agrave -35
+KPX Oacute Amacron -35
+KPX Oacute Aogonek -35
+KPX Oacute Aring -35
+KPX Oacute Atilde -35
+KPX Oacute T -40
+KPX Oacute Tcaron -40
+KPX Oacute Tcommaaccent -40
+KPX Oacute V -50
+KPX Oacute W -35
+KPX Oacute X -40
+KPX Oacute Y -50
+KPX Oacute Yacute -50
+KPX Oacute Ydieresis -50
+KPX Ocircumflex A -35
+KPX Ocircumflex Aacute -35
+KPX Ocircumflex Abreve -35
+KPX Ocircumflex Acircumflex -35
+KPX Ocircumflex Adieresis -35
+KPX Ocircumflex Agrave -35
+KPX Ocircumflex Amacron -35
+KPX Ocircumflex Aogonek -35
+KPX Ocircumflex Aring -35
+KPX Ocircumflex Atilde -35
+KPX Ocircumflex T -40
+KPX Ocircumflex Tcaron -40
+KPX Ocircumflex Tcommaaccent -40
+KPX Ocircumflex V -50
+KPX Ocircumflex W -35
+KPX Ocircumflex X -40
+KPX Ocircumflex Y -50
+KPX Ocircumflex Yacute -50
+KPX Ocircumflex Ydieresis -50
+KPX Odieresis A -35
+KPX Odieresis Aacute -35
+KPX Odieresis Abreve -35
+KPX Odieresis Acircumflex -35
+KPX Odieresis Adieresis -35
+KPX Odieresis Agrave -35
+KPX Odieresis Amacron -35
+KPX Odieresis Aogonek -35
+KPX Odieresis Aring -35
+KPX Odieresis Atilde -35
+KPX Odieresis T -40
+KPX Odieresis Tcaron -40
+KPX Odieresis Tcommaaccent -40
+KPX Odieresis V -50
+KPX Odieresis W -35
+KPX Odieresis X -40
+KPX Odieresis Y -50
+KPX Odieresis Yacute -50
+KPX Odieresis Ydieresis -50
+KPX Ograve A -35
+KPX Ograve Aacute -35
+KPX Ograve Abreve -35
+KPX Ograve Acircumflex -35
+KPX Ograve Adieresis -35
+KPX Ograve Agrave -35
+KPX Ograve Amacron -35
+KPX Ograve Aogonek -35
+KPX Ograve Aring -35
+KPX Ograve Atilde -35
+KPX Ograve T -40
+KPX Ograve Tcaron -40
+KPX Ograve Tcommaaccent -40
+KPX Ograve V -50
+KPX Ograve W -35
+KPX Ograve X -40
+KPX Ograve Y -50
+KPX Ograve Yacute -50
+KPX Ograve Ydieresis -50
+KPX Ohungarumlaut A -35
+KPX Ohungarumlaut Aacute -35
+KPX Ohungarumlaut Abreve -35
+KPX Ohungarumlaut Acircumflex -35
+KPX Ohungarumlaut Adieresis -35
+KPX Ohungarumlaut Agrave -35
+KPX Ohungarumlaut Amacron -35
+KPX Ohungarumlaut Aogonek -35
+KPX Ohungarumlaut Aring -35
+KPX Ohungarumlaut Atilde -35
+KPX Ohungarumlaut T -40
+KPX Ohungarumlaut Tcaron -40
+KPX Ohungarumlaut Tcommaaccent -40
+KPX Ohungarumlaut V -50
+KPX Ohungarumlaut W -35
+KPX Ohungarumlaut X -40
+KPX Ohungarumlaut Y -50
+KPX Ohungarumlaut Yacute -50
+KPX Ohungarumlaut Ydieresis -50
+KPX Omacron A -35
+KPX Omacron Aacute -35
+KPX Omacron Abreve -35
+KPX Omacron Acircumflex -35
+KPX Omacron Adieresis -35
+KPX Omacron Agrave -35
+KPX Omacron Amacron -35
+KPX Omacron Aogonek -35
+KPX Omacron Aring -35
+KPX Omacron Atilde -35
+KPX Omacron T -40
+KPX Omacron Tcaron -40
+KPX Omacron Tcommaaccent -40
+KPX Omacron V -50
+KPX Omacron W -35
+KPX Omacron X -40
+KPX Omacron Y -50
+KPX Omacron Yacute -50
+KPX Omacron Ydieresis -50
+KPX Oslash A -35
+KPX Oslash Aacute -35
+KPX Oslash Abreve -35
+KPX Oslash Acircumflex -35
+KPX Oslash Adieresis -35
+KPX Oslash Agrave -35
+KPX Oslash Amacron -35
+KPX Oslash Aogonek -35
+KPX Oslash Aring -35
+KPX Oslash Atilde -35
+KPX Oslash T -40
+KPX Oslash Tcaron -40
+KPX Oslash Tcommaaccent -40
+KPX Oslash V -50
+KPX Oslash W -35
+KPX Oslash X -40
+KPX Oslash Y -50
+KPX Oslash Yacute -50
+KPX Oslash Ydieresis -50
+KPX Otilde A -35
+KPX Otilde Aacute -35
+KPX Otilde Abreve -35
+KPX Otilde Acircumflex -35
+KPX Otilde Adieresis -35
+KPX Otilde Agrave -35
+KPX Otilde Amacron -35
+KPX Otilde Aogonek -35
+KPX Otilde Aring -35
+KPX Otilde Atilde -35
+KPX Otilde T -40
+KPX Otilde Tcaron -40
+KPX Otilde Tcommaaccent -40
+KPX Otilde V -50
+KPX Otilde W -35
+KPX Otilde X -40
+KPX Otilde Y -50
+KPX Otilde Yacute -50
+KPX Otilde Ydieresis -50
+KPX P A -92
+KPX P Aacute -92
+KPX P Abreve -92
+KPX P Acircumflex -92
+KPX P Adieresis -92
+KPX P Agrave -92
+KPX P Amacron -92
+KPX P Aogonek -92
+KPX P Aring -92
+KPX P Atilde -92
+KPX P a -15
+KPX P aacute -15
+KPX P abreve -15
+KPX P acircumflex -15
+KPX P adieresis -15
+KPX P agrave -15
+KPX P amacron -15
+KPX P aogonek -15
+KPX P aring -15
+KPX P atilde -15
+KPX P comma -111
+KPX P period -111
+KPX Q U -10
+KPX Q Uacute -10
+KPX Q Ucircumflex -10
+KPX Q Udieresis -10
+KPX Q Ugrave -10
+KPX Q Uhungarumlaut -10
+KPX Q Umacron -10
+KPX Q Uogonek -10
+KPX Q Uring -10
+KPX R O -40
+KPX R Oacute -40
+KPX R Ocircumflex -40
+KPX R Odieresis -40
+KPX R Ograve -40
+KPX R Ohungarumlaut -40
+KPX R Omacron -40
+KPX R Oslash -40
+KPX R Otilde -40
+KPX R T -60
+KPX R Tcaron -60
+KPX R Tcommaaccent -60
+KPX R U -40
+KPX R Uacute -40
+KPX R Ucircumflex -40
+KPX R Udieresis -40
+KPX R Ugrave -40
+KPX R Uhungarumlaut -40
+KPX R Umacron -40
+KPX R Uogonek -40
+KPX R Uring -40
+KPX R V -80
+KPX R W -55
+KPX R Y -65
+KPX R Yacute -65
+KPX R Ydieresis -65
+KPX Racute O -40
+KPX Racute Oacute -40
+KPX Racute Ocircumflex -40
+KPX Racute Odieresis -40
+KPX Racute Ograve -40
+KPX Racute Ohungarumlaut -40
+KPX Racute Omacron -40
+KPX Racute Oslash -40
+KPX Racute Otilde -40
+KPX Racute T -60
+KPX Racute Tcaron -60
+KPX Racute Tcommaaccent -60
+KPX Racute U -40
+KPX Racute Uacute -40
+KPX Racute Ucircumflex -40
+KPX Racute Udieresis -40
+KPX Racute Ugrave -40
+KPX Racute Uhungarumlaut -40
+KPX Racute Umacron -40
+KPX Racute Uogonek -40
+KPX Racute Uring -40
+KPX Racute V -80
+KPX Racute W -55
+KPX Racute Y -65
+KPX Racute Yacute -65
+KPX Racute Ydieresis -65
+KPX Rcaron O -40
+KPX Rcaron Oacute -40
+KPX Rcaron Ocircumflex -40
+KPX Rcaron Odieresis -40
+KPX Rcaron Ograve -40
+KPX Rcaron Ohungarumlaut -40
+KPX Rcaron Omacron -40
+KPX Rcaron Oslash -40
+KPX Rcaron Otilde -40
+KPX Rcaron T -60
+KPX Rcaron Tcaron -60
+KPX Rcaron Tcommaaccent -60
+KPX Rcaron U -40
+KPX Rcaron Uacute -40
+KPX Rcaron Ucircumflex -40
+KPX Rcaron Udieresis -40
+KPX Rcaron Ugrave -40
+KPX Rcaron Uhungarumlaut -40
+KPX Rcaron Umacron -40
+KPX Rcaron Uogonek -40
+KPX Rcaron Uring -40
+KPX Rcaron V -80
+KPX Rcaron W -55
+KPX Rcaron Y -65
+KPX Rcaron Yacute -65
+KPX Rcaron Ydieresis -65
+KPX Rcommaaccent O -40
+KPX Rcommaaccent Oacute -40
+KPX Rcommaaccent Ocircumflex -40
+KPX Rcommaaccent Odieresis -40
+KPX Rcommaaccent Ograve -40
+KPX Rcommaaccent Ohungarumlaut -40
+KPX Rcommaaccent Omacron -40
+KPX Rcommaaccent Oslash -40
+KPX Rcommaaccent Otilde -40
+KPX Rcommaaccent T -60
+KPX Rcommaaccent Tcaron -60
+KPX Rcommaaccent Tcommaaccent -60
+KPX Rcommaaccent U -40
+KPX Rcommaaccent Uacute -40
+KPX Rcommaaccent Ucircumflex -40
+KPX Rcommaaccent Udieresis -40
+KPX Rcommaaccent Ugrave -40
+KPX Rcommaaccent Uhungarumlaut -40
+KPX Rcommaaccent Umacron -40
+KPX Rcommaaccent Uogonek -40
+KPX Rcommaaccent Uring -40
+KPX Rcommaaccent V -80
+KPX Rcommaaccent W -55
+KPX Rcommaaccent Y -65
+KPX Rcommaaccent Yacute -65
+KPX Rcommaaccent Ydieresis -65
+KPX T A -93
+KPX T Aacute -93
+KPX T Abreve -93
+KPX T Acircumflex -93
+KPX T Adieresis -93
+KPX T Agrave -93
+KPX T Amacron -93
+KPX T Aogonek -93
+KPX T Aring -93
+KPX T Atilde -93
+KPX T O -18
+KPX T Oacute -18
+KPX T Ocircumflex -18
+KPX T Odieresis -18
+KPX T Ograve -18
+KPX T Ohungarumlaut -18
+KPX T Omacron -18
+KPX T Oslash -18
+KPX T Otilde -18
+KPX T a -80
+KPX T aacute -80
+KPX T abreve -80
+KPX T acircumflex -80
+KPX T adieresis -40
+KPX T agrave -40
+KPX T amacron -40
+KPX T aogonek -80
+KPX T aring -80
+KPX T atilde -40
+KPX T colon -50
+KPX T comma -74
+KPX T e -70
+KPX T eacute -70
+KPX T ecaron -70
+KPX T ecircumflex -70
+KPX T edieresis -30
+KPX T edotaccent -70
+KPX T egrave -70
+KPX T emacron -30
+KPX T eogonek -70
+KPX T hyphen -92
+KPX T i -35
+KPX T iacute -35
+KPX T iogonek -35
+KPX T o -80
+KPX T oacute -80
+KPX T ocircumflex -80
+KPX T odieresis -80
+KPX T ograve -80
+KPX T ohungarumlaut -80
+KPX T omacron -80
+KPX T oslash -80
+KPX T otilde -80
+KPX T period -74
+KPX T r -35
+KPX T racute -35
+KPX T rcaron -35
+KPX T rcommaaccent -35
+KPX T semicolon -55
+KPX T u -45
+KPX T uacute -45
+KPX T ucircumflex -45
+KPX T udieresis -45
+KPX T ugrave -45
+KPX T uhungarumlaut -45
+KPX T umacron -45
+KPX T uogonek -45
+KPX T uring -45
+KPX T w -80
+KPX T y -80
+KPX T yacute -80
+KPX T ydieresis -80
+KPX Tcaron A -93
+KPX Tcaron Aacute -93
+KPX Tcaron Abreve -93
+KPX Tcaron Acircumflex -93
+KPX Tcaron Adieresis -93
+KPX Tcaron Agrave -93
+KPX Tcaron Amacron -93
+KPX Tcaron Aogonek -93
+KPX Tcaron Aring -93
+KPX Tcaron Atilde -93
+KPX Tcaron O -18
+KPX Tcaron Oacute -18
+KPX Tcaron Ocircumflex -18
+KPX Tcaron Odieresis -18
+KPX Tcaron Ograve -18
+KPX Tcaron Ohungarumlaut -18
+KPX Tcaron Omacron -18
+KPX Tcaron Oslash -18
+KPX Tcaron Otilde -18
+KPX Tcaron a -80
+KPX Tcaron aacute -80
+KPX Tcaron abreve -80
+KPX Tcaron acircumflex -80
+KPX Tcaron adieresis -40
+KPX Tcaron agrave -40
+KPX Tcaron amacron -40
+KPX Tcaron aogonek -80
+KPX Tcaron aring -80
+KPX Tcaron atilde -40
+KPX Tcaron colon -50
+KPX Tcaron comma -74
+KPX Tcaron e -70
+KPX Tcaron eacute -70
+KPX Tcaron ecaron -70
+KPX Tcaron ecircumflex -30
+KPX Tcaron edieresis -30
+KPX Tcaron edotaccent -70
+KPX Tcaron egrave -70
+KPX Tcaron emacron -30
+KPX Tcaron eogonek -70
+KPX Tcaron hyphen -92
+KPX Tcaron i -35
+KPX Tcaron iacute -35
+KPX Tcaron iogonek -35
+KPX Tcaron o -80
+KPX Tcaron oacute -80
+KPX Tcaron ocircumflex -80
+KPX Tcaron odieresis -80
+KPX Tcaron ograve -80
+KPX Tcaron ohungarumlaut -80
+KPX Tcaron omacron -80
+KPX Tcaron oslash -80
+KPX Tcaron otilde -80
+KPX Tcaron period -74
+KPX Tcaron r -35
+KPX Tcaron racute -35
+KPX Tcaron rcaron -35
+KPX Tcaron rcommaaccent -35
+KPX Tcaron semicolon -55
+KPX Tcaron u -45
+KPX Tcaron uacute -45
+KPX Tcaron ucircumflex -45
+KPX Tcaron udieresis -45
+KPX Tcaron ugrave -45
+KPX Tcaron uhungarumlaut -45
+KPX Tcaron umacron -45
+KPX Tcaron uogonek -45
+KPX Tcaron uring -45
+KPX Tcaron w -80
+KPX Tcaron y -80
+KPX Tcaron yacute -80
+KPX Tcaron ydieresis -80
+KPX Tcommaaccent A -93
+KPX Tcommaaccent Aacute -93
+KPX Tcommaaccent Abreve -93
+KPX Tcommaaccent Acircumflex -93
+KPX Tcommaaccent Adieresis -93
+KPX Tcommaaccent Agrave -93
+KPX Tcommaaccent Amacron -93
+KPX Tcommaaccent Aogonek -93
+KPX Tcommaaccent Aring -93
+KPX Tcommaaccent Atilde -93
+KPX Tcommaaccent O -18
+KPX Tcommaaccent Oacute -18
+KPX Tcommaaccent Ocircumflex -18
+KPX Tcommaaccent Odieresis -18
+KPX Tcommaaccent Ograve -18
+KPX Tcommaaccent Ohungarumlaut -18
+KPX Tcommaaccent Omacron -18
+KPX Tcommaaccent Oslash -18
+KPX Tcommaaccent Otilde -18
+KPX Tcommaaccent a -80
+KPX Tcommaaccent aacute -80
+KPX Tcommaaccent abreve -80
+KPX Tcommaaccent acircumflex -80
+KPX Tcommaaccent adieresis -40
+KPX Tcommaaccent agrave -40
+KPX Tcommaaccent amacron -40
+KPX Tcommaaccent aogonek -80
+KPX Tcommaaccent aring -80
+KPX Tcommaaccent atilde -40
+KPX Tcommaaccent colon -50
+KPX Tcommaaccent comma -74
+KPX Tcommaaccent e -70
+KPX Tcommaaccent eacute -70
+KPX Tcommaaccent ecaron -70
+KPX Tcommaaccent ecircumflex -30
+KPX Tcommaaccent edieresis -30
+KPX Tcommaaccent edotaccent -70
+KPX Tcommaaccent egrave -30
+KPX Tcommaaccent emacron -70
+KPX Tcommaaccent eogonek -70
+KPX Tcommaaccent hyphen -92
+KPX Tcommaaccent i -35
+KPX Tcommaaccent iacute -35
+KPX Tcommaaccent iogonek -35
+KPX Tcommaaccent o -80
+KPX Tcommaaccent oacute -80
+KPX Tcommaaccent ocircumflex -80
+KPX Tcommaaccent odieresis -80
+KPX Tcommaaccent ograve -80
+KPX Tcommaaccent ohungarumlaut -80
+KPX Tcommaaccent omacron -80
+KPX Tcommaaccent oslash -80
+KPX Tcommaaccent otilde -80
+KPX Tcommaaccent period -74
+KPX Tcommaaccent r -35
+KPX Tcommaaccent racute -35
+KPX Tcommaaccent rcaron -35
+KPX Tcommaaccent rcommaaccent -35
+KPX Tcommaaccent semicolon -55
+KPX Tcommaaccent u -45
+KPX Tcommaaccent uacute -45
+KPX Tcommaaccent ucircumflex -45
+KPX Tcommaaccent udieresis -45
+KPX Tcommaaccent ugrave -45
+KPX Tcommaaccent uhungarumlaut -45
+KPX Tcommaaccent umacron -45
+KPX Tcommaaccent uogonek -45
+KPX Tcommaaccent uring -45
+KPX Tcommaaccent w -80
+KPX Tcommaaccent y -80
+KPX Tcommaaccent yacute -80
+KPX Tcommaaccent ydieresis -80
+KPX U A -40
+KPX U Aacute -40
+KPX U Abreve -40
+KPX U Acircumflex -40
+KPX U Adieresis -40
+KPX U Agrave -40
+KPX U Amacron -40
+KPX U Aogonek -40
+KPX U Aring -40
+KPX U Atilde -40
+KPX Uacute A -40
+KPX Uacute Aacute -40
+KPX Uacute Abreve -40
+KPX Uacute Acircumflex -40
+KPX Uacute Adieresis -40
+KPX Uacute Agrave -40
+KPX Uacute Amacron -40
+KPX Uacute Aogonek -40
+KPX Uacute Aring -40
+KPX Uacute Atilde -40
+KPX Ucircumflex A -40
+KPX Ucircumflex Aacute -40
+KPX Ucircumflex Abreve -40
+KPX Ucircumflex Acircumflex -40
+KPX Ucircumflex Adieresis -40
+KPX Ucircumflex Agrave -40
+KPX Ucircumflex Amacron -40
+KPX Ucircumflex Aogonek -40
+KPX Ucircumflex Aring -40
+KPX Ucircumflex Atilde -40
+KPX Udieresis A -40
+KPX Udieresis Aacute -40
+KPX Udieresis Abreve -40
+KPX Udieresis Acircumflex -40
+KPX Udieresis Adieresis -40
+KPX Udieresis Agrave -40
+KPX Udieresis Amacron -40
+KPX Udieresis Aogonek -40
+KPX Udieresis Aring -40
+KPX Udieresis Atilde -40
+KPX Ugrave A -40
+KPX Ugrave Aacute -40
+KPX Ugrave Abreve -40
+KPX Ugrave Acircumflex -40
+KPX Ugrave Adieresis -40
+KPX Ugrave Agrave -40
+KPX Ugrave Amacron -40
+KPX Ugrave Aogonek -40
+KPX Ugrave Aring -40
+KPX Ugrave Atilde -40
+KPX Uhungarumlaut A -40
+KPX Uhungarumlaut Aacute -40
+KPX Uhungarumlaut Abreve -40
+KPX Uhungarumlaut Acircumflex -40
+KPX Uhungarumlaut Adieresis -40
+KPX Uhungarumlaut Agrave -40
+KPX Uhungarumlaut Amacron -40
+KPX Uhungarumlaut Aogonek -40
+KPX Uhungarumlaut Aring -40
+KPX Uhungarumlaut Atilde -40
+KPX Umacron A -40
+KPX Umacron Aacute -40
+KPX Umacron Abreve -40
+KPX Umacron Acircumflex -40
+KPX Umacron Adieresis -40
+KPX Umacron Agrave -40
+KPX Umacron Amacron -40
+KPX Umacron Aogonek -40
+KPX Umacron Aring -40
+KPX Umacron Atilde -40
+KPX Uogonek A -40
+KPX Uogonek Aacute -40
+KPX Uogonek Abreve -40
+KPX Uogonek Acircumflex -40
+KPX Uogonek Adieresis -40
+KPX Uogonek Agrave -40
+KPX Uogonek Amacron -40
+KPX Uogonek Aogonek -40
+KPX Uogonek Aring -40
+KPX Uogonek Atilde -40
+KPX Uring A -40
+KPX Uring Aacute -40
+KPX Uring Abreve -40
+KPX Uring Acircumflex -40
+KPX Uring Adieresis -40
+KPX Uring Agrave -40
+KPX Uring Amacron -40
+KPX Uring Aogonek -40
+KPX Uring Aring -40
+KPX Uring Atilde -40
+KPX V A -135
+KPX V Aacute -135
+KPX V Abreve -135
+KPX V Acircumflex -135
+KPX V Adieresis -135
+KPX V Agrave -135
+KPX V Amacron -135
+KPX V Aogonek -135
+KPX V Aring -135
+KPX V Atilde -135
+KPX V G -15
+KPX V Gbreve -15
+KPX V Gcommaaccent -15
+KPX V O -40
+KPX V Oacute -40
+KPX V Ocircumflex -40
+KPX V Odieresis -40
+KPX V Ograve -40
+KPX V Ohungarumlaut -40
+KPX V Omacron -40
+KPX V Oslash -40
+KPX V Otilde -40
+KPX V a -111
+KPX V aacute -111
+KPX V abreve -111
+KPX V acircumflex -71
+KPX V adieresis -71
+KPX V agrave -71
+KPX V amacron -71
+KPX V aogonek -111
+KPX V aring -111
+KPX V atilde -71
+KPX V colon -74
+KPX V comma -129
+KPX V e -111
+KPX V eacute -111
+KPX V ecaron -71
+KPX V ecircumflex -71
+KPX V edieresis -71
+KPX V edotaccent -111
+KPX V egrave -71
+KPX V emacron -71
+KPX V eogonek -111
+KPX V hyphen -100
+KPX V i -60
+KPX V iacute -60
+KPX V icircumflex -20
+KPX V idieresis -20
+KPX V igrave -20
+KPX V imacron -20
+KPX V iogonek -60
+KPX V o -129
+KPX V oacute -129
+KPX V ocircumflex -129
+KPX V odieresis -89
+KPX V ograve -89
+KPX V ohungarumlaut -129
+KPX V omacron -89
+KPX V oslash -129
+KPX V otilde -89
+KPX V period -129
+KPX V semicolon -74
+KPX V u -75
+KPX V uacute -75
+KPX V ucircumflex -75
+KPX V udieresis -75
+KPX V ugrave -75
+KPX V uhungarumlaut -75
+KPX V umacron -75
+KPX V uogonek -75
+KPX V uring -75
+KPX W A -120
+KPX W Aacute -120
+KPX W Abreve -120
+KPX W Acircumflex -120
+KPX W Adieresis -120
+KPX W Agrave -120
+KPX W Amacron -120
+KPX W Aogonek -120
+KPX W Aring -120
+KPX W Atilde -120
+KPX W O -10
+KPX W Oacute -10
+KPX W Ocircumflex -10
+KPX W Odieresis -10
+KPX W Ograve -10
+KPX W Ohungarumlaut -10
+KPX W Omacron -10
+KPX W Oslash -10
+KPX W Otilde -10
+KPX W a -80
+KPX W aacute -80
+KPX W abreve -80
+KPX W acircumflex -80
+KPX W adieresis -80
+KPX W agrave -80
+KPX W amacron -80
+KPX W aogonek -80
+KPX W aring -80
+KPX W atilde -80
+KPX W colon -37
+KPX W comma -92
+KPX W e -80
+KPX W eacute -80
+KPX W ecaron -80
+KPX W ecircumflex -80
+KPX W edieresis -40
+KPX W edotaccent -80
+KPX W egrave -40
+KPX W emacron -40
+KPX W eogonek -80
+KPX W hyphen -65
+KPX W i -40
+KPX W iacute -40
+KPX W iogonek -40
+KPX W o -80
+KPX W oacute -80
+KPX W ocircumflex -80
+KPX W odieresis -80
+KPX W ograve -80
+KPX W ohungarumlaut -80
+KPX W omacron -80
+KPX W oslash -80
+KPX W otilde -80
+KPX W period -92
+KPX W semicolon -37
+KPX W u -50
+KPX W uacute -50
+KPX W ucircumflex -50
+KPX W udieresis -50
+KPX W ugrave -50
+KPX W uhungarumlaut -50
+KPX W umacron -50
+KPX W uogonek -50
+KPX W uring -50
+KPX W y -73
+KPX W yacute -73
+KPX W ydieresis -73
+KPX Y A -120
+KPX Y Aacute -120
+KPX Y Abreve -120
+KPX Y Acircumflex -120
+KPX Y Adieresis -120
+KPX Y Agrave -120
+KPX Y Amacron -120
+KPX Y Aogonek -120
+KPX Y Aring -120
+KPX Y Atilde -120
+KPX Y O -30
+KPX Y Oacute -30
+KPX Y Ocircumflex -30
+KPX Y Odieresis -30
+KPX Y Ograve -30
+KPX Y Ohungarumlaut -30
+KPX Y Omacron -30
+KPX Y Oslash -30
+KPX Y Otilde -30
+KPX Y a -100
+KPX Y aacute -100
+KPX Y abreve -100
+KPX Y acircumflex -100
+KPX Y adieresis -60
+KPX Y agrave -60
+KPX Y amacron -60
+KPX Y aogonek -100
+KPX Y aring -100
+KPX Y atilde -60
+KPX Y colon -92
+KPX Y comma -129
+KPX Y e -100
+KPX Y eacute -100
+KPX Y ecaron -100
+KPX Y ecircumflex -100
+KPX Y edieresis -60
+KPX Y edotaccent -100
+KPX Y egrave -60
+KPX Y emacron -60
+KPX Y eogonek -100
+KPX Y hyphen -111
+KPX Y i -55
+KPX Y iacute -55
+KPX Y iogonek -55
+KPX Y o -110
+KPX Y oacute -110
+KPX Y ocircumflex -110
+KPX Y odieresis -70
+KPX Y ograve -70
+KPX Y ohungarumlaut -110
+KPX Y omacron -70
+KPX Y oslash -110
+KPX Y otilde -70
+KPX Y period -129
+KPX Y semicolon -92
+KPX Y u -111
+KPX Y uacute -111
+KPX Y ucircumflex -111
+KPX Y udieresis -71
+KPX Y ugrave -71
+KPX Y uhungarumlaut -111
+KPX Y umacron -71
+KPX Y uogonek -111
+KPX Y uring -111
+KPX Yacute A -120
+KPX Yacute Aacute -120
+KPX Yacute Abreve -120
+KPX Yacute Acircumflex -120
+KPX Yacute Adieresis -120
+KPX Yacute Agrave -120
+KPX Yacute Amacron -120
+KPX Yacute Aogonek -120
+KPX Yacute Aring -120
+KPX Yacute Atilde -120
+KPX Yacute O -30
+KPX Yacute Oacute -30
+KPX Yacute Ocircumflex -30
+KPX Yacute Odieresis -30
+KPX Yacute Ograve -30
+KPX Yacute Ohungarumlaut -30
+KPX Yacute Omacron -30
+KPX Yacute Oslash -30
+KPX Yacute Otilde -30
+KPX Yacute a -100
+KPX Yacute aacute -100
+KPX Yacute abreve -100
+KPX Yacute acircumflex -100
+KPX Yacute adieresis -60
+KPX Yacute agrave -60
+KPX Yacute amacron -60
+KPX Yacute aogonek -100
+KPX Yacute aring -100
+KPX Yacute atilde -60
+KPX Yacute colon -92
+KPX Yacute comma -129
+KPX Yacute e -100
+KPX Yacute eacute -100
+KPX Yacute ecaron -100
+KPX Yacute ecircumflex -100
+KPX Yacute edieresis -60
+KPX Yacute edotaccent -100
+KPX Yacute egrave -60
+KPX Yacute emacron -60
+KPX Yacute eogonek -100
+KPX Yacute hyphen -111
+KPX Yacute i -55
+KPX Yacute iacute -55
+KPX Yacute iogonek -55
+KPX Yacute o -110
+KPX Yacute oacute -110
+KPX Yacute ocircumflex -110
+KPX Yacute odieresis -70
+KPX Yacute ograve -70
+KPX Yacute ohungarumlaut -110
+KPX Yacute omacron -70
+KPX Yacute oslash -110
+KPX Yacute otilde -70
+KPX Yacute period -129
+KPX Yacute semicolon -92
+KPX Yacute u -111
+KPX Yacute uacute -111
+KPX Yacute ucircumflex -111
+KPX Yacute udieresis -71
+KPX Yacute ugrave -71
+KPX Yacute uhungarumlaut -111
+KPX Yacute umacron -71
+KPX Yacute uogonek -111
+KPX Yacute uring -111
+KPX Ydieresis A -120
+KPX Ydieresis Aacute -120
+KPX Ydieresis Abreve -120
+KPX Ydieresis Acircumflex -120
+KPX Ydieresis Adieresis -120
+KPX Ydieresis Agrave -120
+KPX Ydieresis Amacron -120
+KPX Ydieresis Aogonek -120
+KPX Ydieresis Aring -120
+KPX Ydieresis Atilde -120
+KPX Ydieresis O -30
+KPX Ydieresis Oacute -30
+KPX Ydieresis Ocircumflex -30
+KPX Ydieresis Odieresis -30
+KPX Ydieresis Ograve -30
+KPX Ydieresis Ohungarumlaut -30
+KPX Ydieresis Omacron -30
+KPX Ydieresis Oslash -30
+KPX Ydieresis Otilde -30
+KPX Ydieresis a -100
+KPX Ydieresis aacute -100
+KPX Ydieresis abreve -100
+KPX Ydieresis acircumflex -100
+KPX Ydieresis adieresis -60
+KPX Ydieresis agrave -60
+KPX Ydieresis amacron -60
+KPX Ydieresis aogonek -100
+KPX Ydieresis aring -100
+KPX Ydieresis atilde -100
+KPX Ydieresis colon -92
+KPX Ydieresis comma -129
+KPX Ydieresis e -100
+KPX Ydieresis eacute -100
+KPX Ydieresis ecaron -100
+KPX Ydieresis ecircumflex -100
+KPX Ydieresis edieresis -60
+KPX Ydieresis edotaccent -100
+KPX Ydieresis egrave -60
+KPX Ydieresis emacron -60
+KPX Ydieresis eogonek -100
+KPX Ydieresis hyphen -111
+KPX Ydieresis i -55
+KPX Ydieresis iacute -55
+KPX Ydieresis iogonek -55
+KPX Ydieresis o -110
+KPX Ydieresis oacute -110
+KPX Ydieresis ocircumflex -110
+KPX Ydieresis odieresis -70
+KPX Ydieresis ograve -70
+KPX Ydieresis ohungarumlaut -110
+KPX Ydieresis omacron -70
+KPX Ydieresis oslash -110
+KPX Ydieresis otilde -70
+KPX Ydieresis period -129
+KPX Ydieresis semicolon -92
+KPX Ydieresis u -111
+KPX Ydieresis uacute -111
+KPX Ydieresis ucircumflex -111
+KPX Ydieresis udieresis -71
+KPX Ydieresis ugrave -71
+KPX Ydieresis uhungarumlaut -111
+KPX Ydieresis umacron -71
+KPX Ydieresis uogonek -111
+KPX Ydieresis uring -111
+KPX a v -20
+KPX a w -15
+KPX aacute v -20
+KPX aacute w -15
+KPX abreve v -20
+KPX abreve w -15
+KPX acircumflex v -20
+KPX acircumflex w -15
+KPX adieresis v -20
+KPX adieresis w -15
+KPX agrave v -20
+KPX agrave w -15
+KPX amacron v -20
+KPX amacron w -15
+KPX aogonek v -20
+KPX aogonek w -15
+KPX aring v -20
+KPX aring w -15
+KPX atilde v -20
+KPX atilde w -15
+KPX b period -40
+KPX b u -20
+KPX b uacute -20
+KPX b ucircumflex -20
+KPX b udieresis -20
+KPX b ugrave -20
+KPX b uhungarumlaut -20
+KPX b umacron -20
+KPX b uogonek -20
+KPX b uring -20
+KPX b v -15
+KPX c y -15
+KPX c yacute -15
+KPX c ydieresis -15
+KPX cacute y -15
+KPX cacute yacute -15
+KPX cacute ydieresis -15
+KPX ccaron y -15
+KPX ccaron yacute -15
+KPX ccaron ydieresis -15
+KPX ccedilla y -15
+KPX ccedilla yacute -15
+KPX ccedilla ydieresis -15
+KPX comma quotedblright -70
+KPX comma quoteright -70
+KPX e g -15
+KPX e gbreve -15
+KPX e gcommaaccent -15
+KPX e v -25
+KPX e w -25
+KPX e x -15
+KPX e y -15
+KPX e yacute -15
+KPX e ydieresis -15
+KPX eacute g -15
+KPX eacute gbreve -15
+KPX eacute gcommaaccent -15
+KPX eacute v -25
+KPX eacute w -25
+KPX eacute x -15
+KPX eacute y -15
+KPX eacute yacute -15
+KPX eacute ydieresis -15
+KPX ecaron g -15
+KPX ecaron gbreve -15
+KPX ecaron gcommaaccent -15
+KPX ecaron v -25
+KPX ecaron w -25
+KPX ecaron x -15
+KPX ecaron y -15
+KPX ecaron yacute -15
+KPX ecaron ydieresis -15
+KPX ecircumflex g -15
+KPX ecircumflex gbreve -15
+KPX ecircumflex gcommaaccent -15
+KPX ecircumflex v -25
+KPX ecircumflex w -25
+KPX ecircumflex x -15
+KPX ecircumflex y -15
+KPX ecircumflex yacute -15
+KPX ecircumflex ydieresis -15
+KPX edieresis g -15
+KPX edieresis gbreve -15
+KPX edieresis gcommaaccent -15
+KPX edieresis v -25
+KPX edieresis w -25
+KPX edieresis x -15
+KPX edieresis y -15
+KPX edieresis yacute -15
+KPX edieresis ydieresis -15
+KPX edotaccent g -15
+KPX edotaccent gbreve -15
+KPX edotaccent gcommaaccent -15
+KPX edotaccent v -25
+KPX edotaccent w -25
+KPX edotaccent x -15
+KPX edotaccent y -15
+KPX edotaccent yacute -15
+KPX edotaccent ydieresis -15
+KPX egrave g -15
+KPX egrave gbreve -15
+KPX egrave gcommaaccent -15
+KPX egrave v -25
+KPX egrave w -25
+KPX egrave x -15
+KPX egrave y -15
+KPX egrave yacute -15
+KPX egrave ydieresis -15
+KPX emacron g -15
+KPX emacron gbreve -15
+KPX emacron gcommaaccent -15
+KPX emacron v -25
+KPX emacron w -25
+KPX emacron x -15
+KPX emacron y -15
+KPX emacron yacute -15
+KPX emacron ydieresis -15
+KPX eogonek g -15
+KPX eogonek gbreve -15
+KPX eogonek gcommaaccent -15
+KPX eogonek v -25
+KPX eogonek w -25
+KPX eogonek x -15
+KPX eogonek y -15
+KPX eogonek yacute -15
+KPX eogonek ydieresis -15
+KPX f a -10
+KPX f aacute -10
+KPX f abreve -10
+KPX f acircumflex -10
+KPX f adieresis -10
+KPX f agrave -10
+KPX f amacron -10
+KPX f aogonek -10
+KPX f aring -10
+KPX f atilde -10
+KPX f dotlessi -50
+KPX f f -25
+KPX f i -20
+KPX f iacute -20
+KPX f quoteright 55
+KPX g a -5
+KPX g aacute -5
+KPX g abreve -5
+KPX g acircumflex -5
+KPX g adieresis -5
+KPX g agrave -5
+KPX g amacron -5
+KPX g aogonek -5
+KPX g aring -5
+KPX g atilde -5
+KPX gbreve a -5
+KPX gbreve aacute -5
+KPX gbreve abreve -5
+KPX gbreve acircumflex -5
+KPX gbreve adieresis -5
+KPX gbreve agrave -5
+KPX gbreve amacron -5
+KPX gbreve aogonek -5
+KPX gbreve aring -5
+KPX gbreve atilde -5
+KPX gcommaaccent a -5
+KPX gcommaaccent aacute -5
+KPX gcommaaccent abreve -5
+KPX gcommaaccent acircumflex -5
+KPX gcommaaccent adieresis -5
+KPX gcommaaccent agrave -5
+KPX gcommaaccent amacron -5
+KPX gcommaaccent aogonek -5
+KPX gcommaaccent aring -5
+KPX gcommaaccent atilde -5
+KPX h y -5
+KPX h yacute -5
+KPX h ydieresis -5
+KPX i v -25
+KPX iacute v -25
+KPX icircumflex v -25
+KPX idieresis v -25
+KPX igrave v -25
+KPX imacron v -25
+KPX iogonek v -25
+KPX k e -10
+KPX k eacute -10
+KPX k ecaron -10
+KPX k ecircumflex -10
+KPX k edieresis -10
+KPX k edotaccent -10
+KPX k egrave -10
+KPX k emacron -10
+KPX k eogonek -10
+KPX k o -10
+KPX k oacute -10
+KPX k ocircumflex -10
+KPX k odieresis -10
+KPX k ograve -10
+KPX k ohungarumlaut -10
+KPX k omacron -10
+KPX k oslash -10
+KPX k otilde -10
+KPX k y -15
+KPX k yacute -15
+KPX k ydieresis -15
+KPX kcommaaccent e -10
+KPX kcommaaccent eacute -10
+KPX kcommaaccent ecaron -10
+KPX kcommaaccent ecircumflex -10
+KPX kcommaaccent edieresis -10
+KPX kcommaaccent edotaccent -10
+KPX kcommaaccent egrave -10
+KPX kcommaaccent emacron -10
+KPX kcommaaccent eogonek -10
+KPX kcommaaccent o -10
+KPX kcommaaccent oacute -10
+KPX kcommaaccent ocircumflex -10
+KPX kcommaaccent odieresis -10
+KPX kcommaaccent ograve -10
+KPX kcommaaccent ohungarumlaut -10
+KPX kcommaaccent omacron -10
+KPX kcommaaccent oslash -10
+KPX kcommaaccent otilde -10
+KPX kcommaaccent y -15
+KPX kcommaaccent yacute -15
+KPX kcommaaccent ydieresis -15
+KPX l w -10
+KPX lacute w -10
+KPX lcommaaccent w -10
+KPX lslash w -10
+KPX n v -40
+KPX n y -15
+KPX n yacute -15
+KPX n ydieresis -15
+KPX nacute v -40
+KPX nacute y -15
+KPX nacute yacute -15
+KPX nacute ydieresis -15
+KPX ncaron v -40
+KPX ncaron y -15
+KPX ncaron yacute -15
+KPX ncaron ydieresis -15
+KPX ncommaaccent v -40
+KPX ncommaaccent y -15
+KPX ncommaaccent yacute -15
+KPX ncommaaccent ydieresis -15
+KPX ntilde v -40
+KPX ntilde y -15
+KPX ntilde yacute -15
+KPX ntilde ydieresis -15
+KPX o v -15
+KPX o w -25
+KPX o y -10
+KPX o yacute -10
+KPX o ydieresis -10
+KPX oacute v -15
+KPX oacute w -25
+KPX oacute y -10
+KPX oacute yacute -10
+KPX oacute ydieresis -10
+KPX ocircumflex v -15
+KPX ocircumflex w -25
+KPX ocircumflex y -10
+KPX ocircumflex yacute -10
+KPX ocircumflex ydieresis -10
+KPX odieresis v -15
+KPX odieresis w -25
+KPX odieresis y -10
+KPX odieresis yacute -10
+KPX odieresis ydieresis -10
+KPX ograve v -15
+KPX ograve w -25
+KPX ograve y -10
+KPX ograve yacute -10
+KPX ograve ydieresis -10
+KPX ohungarumlaut v -15
+KPX ohungarumlaut w -25
+KPX ohungarumlaut y -10
+KPX ohungarumlaut yacute -10
+KPX ohungarumlaut ydieresis -10
+KPX omacron v -15
+KPX omacron w -25
+KPX omacron y -10
+KPX omacron yacute -10
+KPX omacron ydieresis -10
+KPX oslash v -15
+KPX oslash w -25
+KPX oslash y -10
+KPX oslash yacute -10
+KPX oslash ydieresis -10
+KPX otilde v -15
+KPX otilde w -25
+KPX otilde y -10
+KPX otilde yacute -10
+KPX otilde ydieresis -10
+KPX p y -10
+KPX p yacute -10
+KPX p ydieresis -10
+KPX period quotedblright -70
+KPX period quoteright -70
+KPX quotedblleft A -80
+KPX quotedblleft Aacute -80
+KPX quotedblleft Abreve -80
+KPX quotedblleft Acircumflex -80
+KPX quotedblleft Adieresis -80
+KPX quotedblleft Agrave -80
+KPX quotedblleft Amacron -80
+KPX quotedblleft Aogonek -80
+KPX quotedblleft Aring -80
+KPX quotedblleft Atilde -80
+KPX quoteleft A -80
+KPX quoteleft Aacute -80
+KPX quoteleft Abreve -80
+KPX quoteleft Acircumflex -80
+KPX quoteleft Adieresis -80
+KPX quoteleft Agrave -80
+KPX quoteleft Amacron -80
+KPX quoteleft Aogonek -80
+KPX quoteleft Aring -80
+KPX quoteleft Atilde -80
+KPX quoteleft quoteleft -74
+KPX quoteright d -50
+KPX quoteright dcroat -50
+KPX quoteright l -10
+KPX quoteright lacute -10
+KPX quoteright lcommaaccent -10
+KPX quoteright lslash -10
+KPX quoteright quoteright -74
+KPX quoteright r -50
+KPX quoteright racute -50
+KPX quoteright rcaron -50
+KPX quoteright rcommaaccent -50
+KPX quoteright s -55
+KPX quoteright sacute -55
+KPX quoteright scaron -55
+KPX quoteright scedilla -55
+KPX quoteright scommaaccent -55
+KPX quoteright space -74
+KPX quoteright t -18
+KPX quoteright tcommaaccent -18
+KPX quoteright v -50
+KPX r comma -40
+KPX r g -18
+KPX r gbreve -18
+KPX r gcommaaccent -18
+KPX r hyphen -20
+KPX r period -55
+KPX racute comma -40
+KPX racute g -18
+KPX racute gbreve -18
+KPX racute gcommaaccent -18
+KPX racute hyphen -20
+KPX racute period -55
+KPX rcaron comma -40
+KPX rcaron g -18
+KPX rcaron gbreve -18
+KPX rcaron gcommaaccent -18
+KPX rcaron hyphen -20
+KPX rcaron period -55
+KPX rcommaaccent comma -40
+KPX rcommaaccent g -18
+KPX rcommaaccent gbreve -18
+KPX rcommaaccent gcommaaccent -18
+KPX rcommaaccent hyphen -20
+KPX rcommaaccent period -55
+KPX space A -55
+KPX space Aacute -55
+KPX space Abreve -55
+KPX space Acircumflex -55
+KPX space Adieresis -55
+KPX space Agrave -55
+KPX space Amacron -55
+KPX space Aogonek -55
+KPX space Aring -55
+KPX space Atilde -55
+KPX space T -18
+KPX space Tcaron -18
+KPX space Tcommaaccent -18
+KPX space V -50
+KPX space W -30
+KPX space Y -90
+KPX space Yacute -90
+KPX space Ydieresis -90
+KPX v a -25
+KPX v aacute -25
+KPX v abreve -25
+KPX v acircumflex -25
+KPX v adieresis -25
+KPX v agrave -25
+KPX v amacron -25
+KPX v aogonek -25
+KPX v aring -25
+KPX v atilde -25
+KPX v comma -65
+KPX v e -15
+KPX v eacute -15
+KPX v ecaron -15
+KPX v ecircumflex -15
+KPX v edieresis -15
+KPX v edotaccent -15
+KPX v egrave -15
+KPX v emacron -15
+KPX v eogonek -15
+KPX v o -20
+KPX v oacute -20
+KPX v ocircumflex -20
+KPX v odieresis -20
+KPX v ograve -20
+KPX v ohungarumlaut -20
+KPX v omacron -20
+KPX v oslash -20
+KPX v otilde -20
+KPX v period -65
+KPX w a -10
+KPX w aacute -10
+KPX w abreve -10
+KPX w acircumflex -10
+KPX w adieresis -10
+KPX w agrave -10
+KPX w amacron -10
+KPX w aogonek -10
+KPX w aring -10
+KPX w atilde -10
+KPX w comma -65
+KPX w o -10
+KPX w oacute -10
+KPX w ocircumflex -10
+KPX w odieresis -10
+KPX w ograve -10
+KPX w ohungarumlaut -10
+KPX w omacron -10
+KPX w oslash -10
+KPX w otilde -10
+KPX w period -65
+KPX x e -15
+KPX x eacute -15
+KPX x ecaron -15
+KPX x ecircumflex -15
+KPX x edieresis -15
+KPX x edotaccent -15
+KPX x egrave -15
+KPX x emacron -15
+KPX x eogonek -15
+KPX y comma -65
+KPX y period -65
+KPX yacute comma -65
+KPX yacute period -65
+KPX ydieresis comma -65
+KPX ydieresis period -65
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/ZapfDingbats.afm b/iTechSharp/iTextSharp/text/pdf/fonts/ZapfDingbats.afm
new file mode 100644
index 0000000..b274505
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/ZapfDingbats.afm
@@ -0,0 +1,225 @@
+StartFontMetrics 4.1
+Comment Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.
+Comment Creation Date: Thu May 1 15:14:13 1997
+Comment UniqueID 43082
+Comment VMusage 45775 55535
+FontName ZapfDingbats
+FullName ITC Zapf Dingbats
+FamilyName ZapfDingbats
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+CharacterSet Special
+FontBBox -1 -143 981 820
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.000
+Notice Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation.
+EncodingScheme FontSpecific
+StdHW 28
+StdVW 90
+StartCharMetrics 202
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ;
+C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ;
+C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ;
+C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ;
+C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ;
+C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ;
+C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ;
+C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ;
+C 41 ; WX 690 ; N a117 ; B 34 138 655 553 ;
+C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ;
+C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ;
+C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ;
+C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ;
+C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ;
+C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ;
+C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ;
+C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ;
+C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ;
+C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ;
+C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ;
+C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ;
+C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ;
+C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ;
+C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ;
+C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ;
+C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ;
+C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ;
+C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ;
+C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ;
+C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ;
+C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ;
+C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ;
+C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ;
+C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ;
+C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ;
+C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ;
+C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ;
+C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ;
+C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ;
+C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ;
+C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ;
+C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ;
+C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ;
+C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ;
+C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ;
+C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ;
+C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ;
+C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ;
+C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ;
+C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ;
+C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ;
+C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ;
+C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ;
+C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ;
+C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ;
+C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ;
+C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ;
+C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ;
+C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ;
+C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ;
+C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ;
+C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ;
+C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ;
+C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ;
+C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ;
+C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ;
+C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ;
+C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ;
+C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ;
+C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ;
+C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ;
+C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ;
+C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ;
+C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ;
+C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ;
+C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ;
+C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ;
+C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ;
+C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ;
+C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ;
+C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ;
+C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ;
+C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ;
+C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ;
+C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ;
+C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ;
+C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ;
+C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ;
+C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ;
+C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ;
+C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ;
+C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ;
+C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ;
+C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ;
+C 128 ; WX 390 ; N a89 ; B 35 -14 356 705 ;
+C 129 ; WX 390 ; N a90 ; B 35 -14 355 705 ;
+C 130 ; WX 317 ; N a93 ; B 35 0 283 692 ;
+C 131 ; WX 317 ; N a94 ; B 35 0 283 692 ;
+C 132 ; WX 276 ; N a91 ; B 35 0 242 692 ;
+C 133 ; WX 276 ; N a92 ; B 35 0 242 692 ;
+C 134 ; WX 509 ; N a205 ; B 35 0 475 692 ;
+C 135 ; WX 509 ; N a85 ; B 35 0 475 692 ;
+C 136 ; WX 410 ; N a206 ; B 35 0 375 692 ;
+C 137 ; WX 410 ; N a86 ; B 35 0 375 692 ;
+C 138 ; WX 234 ; N a87 ; B 35 -14 199 705 ;
+C 139 ; WX 234 ; N a88 ; B 35 -14 199 705 ;
+C 140 ; WX 334 ; N a95 ; B 35 0 299 692 ;
+C 141 ; WX 334 ; N a96 ; B 35 0 299 692 ;
+C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ;
+C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ;
+C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ;
+C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ;
+C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ;
+C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ;
+C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ;
+C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ;
+C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ;
+C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ;
+C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ;
+C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ;
+C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ;
+C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ;
+C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ;
+C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ;
+C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ;
+C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ;
+C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ;
+C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ;
+C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ;
+C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ;
+C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ;
+C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ;
+C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ;
+C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ;
+C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ;
+C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ;
+C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ;
+C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ;
+C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ;
+C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ;
+C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ;
+C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ;
+C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ;
+C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ;
+C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ;
+C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ;
+C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ;
+C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ;
+C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ;
+C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ;
+C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ;
+C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ;
+C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ;
+C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ;
+C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ;
+C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ;
+C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ;
+C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ;
+C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ;
+C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ;
+C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ;
+C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ;
+C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ;
+C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ;
+C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ;
+C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ;
+C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ;
+C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ;
+C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ;
+C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ;
+C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ;
+C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ;
+C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ;
+C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ;
+C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ;
+C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ;
+C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ;
+C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ;
+C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ;
+C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ;
+C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ;
+C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ;
+C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ;
+C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ;
+C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ;
+C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ;
+C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ;
+C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ;
+C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ;
+C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ;
+C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ;
+C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ;
+C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ;
+C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ;
+C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ;
+C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ;
+C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ;
+C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ;
+C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ;
+C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ;
+C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/iTechSharp/iTextSharp/text/pdf/fonts/glyphlist.txt b/iTechSharp/iTextSharp/text/pdf/fonts/glyphlist.txt
new file mode 100644
index 0000000..6805d6e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/fonts/glyphlist.txt
@@ -0,0 +1,5430 @@
+# Name: Adobe Glyph List
+# Table version: 2.0
+# Date: September 20, 2002
+#
+# See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html
+#
+# Format: Semicolon-delimited fields:
+# (1) glyph name
+# (2) Unicode scalar value
+A;0041
+AE;00C6
+AEacute;01FC
+AEmacron;01E2
+AEsmall;F7E6
+Aacute;00C1
+Aacutesmall;F7E1
+Abreve;0102
+Abreveacute;1EAE
+Abrevecyrillic;04D0
+Abrevedotbelow;1EB6
+Abrevegrave;1EB0
+Abrevehookabove;1EB2
+Abrevetilde;1EB4
+Acaron;01CD
+Acircle;24B6
+Acircumflex;00C2
+Acircumflexacute;1EA4
+Acircumflexdotbelow;1EAC
+Acircumflexgrave;1EA6
+Acircumflexhookabove;1EA8
+Acircumflexsmall;F7E2
+Acircumflextilde;1EAA
+Acute;F6C9
+Acutesmall;F7B4
+Acyrillic;0410
+Adblgrave;0200
+Adieresis;00C4
+Adieresiscyrillic;04D2
+Adieresismacron;01DE
+Adieresissmall;F7E4
+Adotbelow;1EA0
+Adotmacron;01E0
+Agrave;00C0
+Agravesmall;F7E0
+Ahookabove;1EA2
+Aiecyrillic;04D4
+Ainvertedbreve;0202
+Alpha;0391
+Alphatonos;0386
+Amacron;0100
+Amonospace;FF21
+Aogonek;0104
+Aring;00C5
+Aringacute;01FA
+Aringbelow;1E00
+Aringsmall;F7E5
+Asmall;F761
+Atilde;00C3
+Atildesmall;F7E3
+Aybarmenian;0531
+B;0042
+Bcircle;24B7
+Bdotaccent;1E02
+Bdotbelow;1E04
+Becyrillic;0411
+Benarmenian;0532
+Beta;0392
+Bhook;0181
+Blinebelow;1E06
+Bmonospace;FF22
+Brevesmall;F6F4
+Bsmall;F762
+Btopbar;0182
+C;0043
+Caarmenian;053E
+Cacute;0106
+Caron;F6CA
+Caronsmall;F6F5
+Ccaron;010C
+Ccedilla;00C7
+Ccedillaacute;1E08
+Ccedillasmall;F7E7
+Ccircle;24B8
+Ccircumflex;0108
+Cdot;010A
+Cdotaccent;010A
+Cedillasmall;F7B8
+Chaarmenian;0549
+Cheabkhasiancyrillic;04BC
+Checyrillic;0427
+Chedescenderabkhasiancyrillic;04BE
+Chedescendercyrillic;04B6
+Chedieresiscyrillic;04F4
+Cheharmenian;0543
+Chekhakassiancyrillic;04CB
+Cheverticalstrokecyrillic;04B8
+Chi;03A7
+Chook;0187
+Circumflexsmall;F6F6
+Cmonospace;FF23
+Coarmenian;0551
+Csmall;F763
+D;0044
+DZ;01F1
+DZcaron;01C4
+Daarmenian;0534
+Dafrican;0189
+Dcaron;010E
+Dcedilla;1E10
+Dcircle;24B9
+Dcircumflexbelow;1E12
+Dcroat;0110
+Ddotaccent;1E0A
+Ddotbelow;1E0C
+Decyrillic;0414
+Deicoptic;03EE
+Delta;2206
+Deltagreek;0394
+Dhook;018A
+Dieresis;F6CB
+DieresisAcute;F6CC
+DieresisGrave;F6CD
+Dieresissmall;F7A8
+Digammagreek;03DC
+Djecyrillic;0402
+Dlinebelow;1E0E
+Dmonospace;FF24
+Dotaccentsmall;F6F7
+Dslash;0110
+Dsmall;F764
+Dtopbar;018B
+Dz;01F2
+Dzcaron;01C5
+Dzeabkhasiancyrillic;04E0
+Dzecyrillic;0405
+Dzhecyrillic;040F
+E;0045
+Eacute;00C9
+Eacutesmall;F7E9
+Ebreve;0114
+Ecaron;011A
+Ecedillabreve;1E1C
+Echarmenian;0535
+Ecircle;24BA
+Ecircumflex;00CA
+Ecircumflexacute;1EBE
+Ecircumflexbelow;1E18
+Ecircumflexdotbelow;1EC6
+Ecircumflexgrave;1EC0
+Ecircumflexhookabove;1EC2
+Ecircumflexsmall;F7EA
+Ecircumflextilde;1EC4
+Ecyrillic;0404
+Edblgrave;0204
+Edieresis;00CB
+Edieresissmall;F7EB
+Edot;0116
+Edotaccent;0116
+Edotbelow;1EB8
+Efcyrillic;0424
+Egrave;00C8
+Egravesmall;F7E8
+Eharmenian;0537
+Ehookabove;1EBA
+Eightroman;2167
+Einvertedbreve;0206
+Eiotifiedcyrillic;0464
+Elcyrillic;041B
+Elevenroman;216A
+Emacron;0112
+Emacronacute;1E16
+Emacrongrave;1E14
+Emcyrillic;041C
+Emonospace;FF25
+Encyrillic;041D
+Endescendercyrillic;04A2
+Eng;014A
+Enghecyrillic;04A4
+Enhookcyrillic;04C7
+Eogonek;0118
+Eopen;0190
+Epsilon;0395
+Epsilontonos;0388
+Ercyrillic;0420
+Ereversed;018E
+Ereversedcyrillic;042D
+Escyrillic;0421
+Esdescendercyrillic;04AA
+Esh;01A9
+Esmall;F765
+Eta;0397
+Etarmenian;0538
+Etatonos;0389
+Eth;00D0
+Ethsmall;F7F0
+Etilde;1EBC
+Etildebelow;1E1A
+Euro;20AC
+Ezh;01B7
+Ezhcaron;01EE
+Ezhreversed;01B8
+F;0046
+Fcircle;24BB
+Fdotaccent;1E1E
+Feharmenian;0556
+Feicoptic;03E4
+Fhook;0191
+Fitacyrillic;0472
+Fiveroman;2164
+Fmonospace;FF26
+Fourroman;2163
+Fsmall;F766
+G;0047
+GBsquare;3387
+Gacute;01F4
+Gamma;0393
+Gammaafrican;0194
+Gangiacoptic;03EA
+Gbreve;011E
+Gcaron;01E6
+Gcedilla;0122
+Gcircle;24BC
+Gcircumflex;011C
+Gcommaaccent;0122
+Gdot;0120
+Gdotaccent;0120
+Gecyrillic;0413
+Ghadarmenian;0542
+Ghemiddlehookcyrillic;0494
+Ghestrokecyrillic;0492
+Gheupturncyrillic;0490
+Ghook;0193
+Gimarmenian;0533
+Gjecyrillic;0403
+Gmacron;1E20
+Gmonospace;FF27
+Grave;F6CE
+Gravesmall;F760
+Gsmall;F767
+Gsmallhook;029B
+Gstroke;01E4
+H;0048
+H18533;25CF
+H18543;25AA
+H18551;25AB
+H22073;25A1
+HPsquare;33CB
+Haabkhasiancyrillic;04A8
+Hadescendercyrillic;04B2
+Hardsigncyrillic;042A
+Hbar;0126
+Hbrevebelow;1E2A
+Hcedilla;1E28
+Hcircle;24BD
+Hcircumflex;0124
+Hdieresis;1E26
+Hdotaccent;1E22
+Hdotbelow;1E24
+Hmonospace;FF28
+Hoarmenian;0540
+Horicoptic;03E8
+Hsmall;F768
+Hungarumlaut;F6CF
+Hungarumlautsmall;F6F8
+Hzsquare;3390
+I;0049
+IAcyrillic;042F
+IJ;0132
+IUcyrillic;042E
+Iacute;00CD
+Iacutesmall;F7ED
+Ibreve;012C
+Icaron;01CF
+Icircle;24BE
+Icircumflex;00CE
+Icircumflexsmall;F7EE
+Icyrillic;0406
+Idblgrave;0208
+Idieresis;00CF
+Idieresisacute;1E2E
+Idieresiscyrillic;04E4
+Idieresissmall;F7EF
+Idot;0130
+Idotaccent;0130
+Idotbelow;1ECA
+Iebrevecyrillic;04D6
+Iecyrillic;0415
+Ifraktur;2111
+Igrave;00CC
+Igravesmall;F7EC
+Ihookabove;1EC8
+Iicyrillic;0418
+Iinvertedbreve;020A
+Iishortcyrillic;0419
+Imacron;012A
+Imacroncyrillic;04E2
+Imonospace;FF29
+Iniarmenian;053B
+Iocyrillic;0401
+Iogonek;012E
+Iota;0399
+Iotaafrican;0196
+Iotadieresis;03AA
+Iotatonos;038A
+Ismall;F769
+Istroke;0197
+Itilde;0128
+Itildebelow;1E2C
+Izhitsacyrillic;0474
+Izhitsadblgravecyrillic;0476
+J;004A
+Jaarmenian;0541
+Jcircle;24BF
+Jcircumflex;0134
+Jecyrillic;0408
+Jheharmenian;054B
+Jmonospace;FF2A
+Jsmall;F76A
+K;004B
+KBsquare;3385
+KKsquare;33CD
+Kabashkircyrillic;04A0
+Kacute;1E30
+Kacyrillic;041A
+Kadescendercyrillic;049A
+Kahookcyrillic;04C3
+Kappa;039A
+Kastrokecyrillic;049E
+Kaverticalstrokecyrillic;049C
+Kcaron;01E8
+Kcedilla;0136
+Kcircle;24C0
+Kcommaaccent;0136
+Kdotbelow;1E32
+Keharmenian;0554
+Kenarmenian;053F
+Khacyrillic;0425
+Kheicoptic;03E6
+Khook;0198
+Kjecyrillic;040C
+Klinebelow;1E34
+Kmonospace;FF2B
+Koppacyrillic;0480
+Koppagreek;03DE
+Ksicyrillic;046E
+Ksmall;F76B
+L;004C
+LJ;01C7
+LL;F6BF
+Lacute;0139
+Lambda;039B
+Lcaron;013D
+Lcedilla;013B
+Lcircle;24C1
+Lcircumflexbelow;1E3C
+Lcommaaccent;013B
+Ldot;013F
+Ldotaccent;013F
+Ldotbelow;1E36
+Ldotbelowmacron;1E38
+Liwnarmenian;053C
+Lj;01C8
+Ljecyrillic;0409
+Llinebelow;1E3A
+Lmonospace;FF2C
+Lslash;0141
+Lslashsmall;F6F9
+Lsmall;F76C
+M;004D
+MBsquare;3386
+Macron;F6D0
+Macronsmall;F7AF
+Macute;1E3E
+Mcircle;24C2
+Mdotaccent;1E40
+Mdotbelow;1E42
+Menarmenian;0544
+Mmonospace;FF2D
+Msmall;F76D
+Mturned;019C
+Mu;039C
+N;004E
+NJ;01CA
+Nacute;0143
+Ncaron;0147
+Ncedilla;0145
+Ncircle;24C3
+Ncircumflexbelow;1E4A
+Ncommaaccent;0145
+Ndotaccent;1E44
+Ndotbelow;1E46
+Nhookleft;019D
+Nineroman;2168
+Nj;01CB
+Njecyrillic;040A
+Nlinebelow;1E48
+Nmonospace;FF2E
+Nowarmenian;0546
+Nsmall;F76E
+Ntilde;00D1
+Ntildesmall;F7F1
+Nu;039D
+O;004F
+OE;0152
+OEsmall;F6FA
+Oacute;00D3
+Oacutesmall;F7F3
+Obarredcyrillic;04E8
+Obarreddieresiscyrillic;04EA
+Obreve;014E
+Ocaron;01D1
+Ocenteredtilde;019F
+Ocircle;24C4
+Ocircumflex;00D4
+Ocircumflexacute;1ED0
+Ocircumflexdotbelow;1ED8
+Ocircumflexgrave;1ED2
+Ocircumflexhookabove;1ED4
+Ocircumflexsmall;F7F4
+Ocircumflextilde;1ED6
+Ocyrillic;041E
+Odblacute;0150
+Odblgrave;020C
+Odieresis;00D6
+Odieresiscyrillic;04E6
+Odieresissmall;F7F6
+Odotbelow;1ECC
+Ogoneksmall;F6FB
+Ograve;00D2
+Ogravesmall;F7F2
+Oharmenian;0555
+Ohm;2126
+Ohookabove;1ECE
+Ohorn;01A0
+Ohornacute;1EDA
+Ohorndotbelow;1EE2
+Ohorngrave;1EDC
+Ohornhookabove;1EDE
+Ohorntilde;1EE0
+Ohungarumlaut;0150
+Oi;01A2
+Oinvertedbreve;020E
+Omacron;014C
+Omacronacute;1E52
+Omacrongrave;1E50
+Omega;2126
+Omegacyrillic;0460
+Omegagreek;03A9
+Omegaroundcyrillic;047A
+Omegatitlocyrillic;047C
+Omegatonos;038F
+Omicron;039F
+Omicrontonos;038C
+Omonospace;FF2F
+Oneroman;2160
+Oogonek;01EA
+Oogonekmacron;01EC
+Oopen;0186
+Oslash;00D8
+Oslashacute;01FE
+Oslashsmall;F7F8
+Osmall;F76F
+Ostrokeacute;01FE
+Otcyrillic;047E
+Otilde;00D5
+Otildeacute;1E4C
+Otildedieresis;1E4E
+Otildesmall;F7F5
+P;0050
+Pacute;1E54
+Pcircle;24C5
+Pdotaccent;1E56
+Pecyrillic;041F
+Peharmenian;054A
+Pemiddlehookcyrillic;04A6
+Phi;03A6
+Phook;01A4
+Pi;03A0
+Piwrarmenian;0553
+Pmonospace;FF30
+Psi;03A8
+Psicyrillic;0470
+Psmall;F770
+Q;0051
+Qcircle;24C6
+Qmonospace;FF31
+Qsmall;F771
+R;0052
+Raarmenian;054C
+Racute;0154
+Rcaron;0158
+Rcedilla;0156
+Rcircle;24C7
+Rcommaaccent;0156
+Rdblgrave;0210
+Rdotaccent;1E58
+Rdotbelow;1E5A
+Rdotbelowmacron;1E5C
+Reharmenian;0550
+Rfraktur;211C
+Rho;03A1
+Ringsmall;F6FC
+Rinvertedbreve;0212
+Rlinebelow;1E5E
+Rmonospace;FF32
+Rsmall;F772
+Rsmallinverted;0281
+Rsmallinvertedsuperior;02B6
+S;0053
+SF010000;250C
+SF020000;2514
+SF030000;2510
+SF040000;2518
+SF050000;253C
+SF060000;252C
+SF070000;2534
+SF080000;251C
+SF090000;2524
+SF100000;2500
+SF110000;2502
+SF190000;2561
+SF200000;2562
+SF210000;2556
+SF220000;2555
+SF230000;2563
+SF240000;2551
+SF250000;2557
+SF260000;255D
+SF270000;255C
+SF280000;255B
+SF360000;255E
+SF370000;255F
+SF380000;255A
+SF390000;2554
+SF400000;2569
+SF410000;2566
+SF420000;2560
+SF430000;2550
+SF440000;256C
+SF450000;2567
+SF460000;2568
+SF470000;2564
+SF480000;2565
+SF490000;2559
+SF500000;2558
+SF510000;2552
+SF520000;2553
+SF530000;256B
+SF540000;256A
+Sacute;015A
+Sacutedotaccent;1E64
+Sampigreek;03E0
+Scaron;0160
+Scarondotaccent;1E66
+Scaronsmall;F6FD
+Scedilla;015E
+Schwa;018F
+Schwacyrillic;04D8
+Schwadieresiscyrillic;04DA
+Scircle;24C8
+Scircumflex;015C
+Scommaaccent;0218
+Sdotaccent;1E60
+Sdotbelow;1E62
+Sdotbelowdotaccent;1E68
+Seharmenian;054D
+Sevenroman;2166
+Shaarmenian;0547
+Shacyrillic;0428
+Shchacyrillic;0429
+Sheicoptic;03E2
+Shhacyrillic;04BA
+Shimacoptic;03EC
+Sigma;03A3
+Sixroman;2165
+Smonospace;FF33
+Softsigncyrillic;042C
+Ssmall;F773
+Stigmagreek;03DA
+T;0054
+Tau;03A4
+Tbar;0166
+Tcaron;0164
+Tcedilla;0162
+Tcircle;24C9
+Tcircumflexbelow;1E70
+Tcommaaccent;0162
+Tdotaccent;1E6A
+Tdotbelow;1E6C
+Tecyrillic;0422
+Tedescendercyrillic;04AC
+Tenroman;2169
+Tetsecyrillic;04B4
+Theta;0398
+Thook;01AC
+Thorn;00DE
+Thornsmall;F7FE
+Threeroman;2162
+Tildesmall;F6FE
+Tiwnarmenian;054F
+Tlinebelow;1E6E
+Tmonospace;FF34
+Toarmenian;0539
+Tonefive;01BC
+Tonesix;0184
+Tonetwo;01A7
+Tretroflexhook;01AE
+Tsecyrillic;0426
+Tshecyrillic;040B
+Tsmall;F774
+Twelveroman;216B
+Tworoman;2161
+U;0055
+Uacute;00DA
+Uacutesmall;F7FA
+Ubreve;016C
+Ucaron;01D3
+Ucircle;24CA
+Ucircumflex;00DB
+Ucircumflexbelow;1E76
+Ucircumflexsmall;F7FB
+Ucyrillic;0423
+Udblacute;0170
+Udblgrave;0214
+Udieresis;00DC
+Udieresisacute;01D7
+Udieresisbelow;1E72
+Udieresiscaron;01D9
+Udieresiscyrillic;04F0
+Udieresisgrave;01DB
+Udieresismacron;01D5
+Udieresissmall;F7FC
+Udotbelow;1EE4
+Ugrave;00D9
+Ugravesmall;F7F9
+Uhookabove;1EE6
+Uhorn;01AF
+Uhornacute;1EE8
+Uhorndotbelow;1EF0
+Uhorngrave;1EEA
+Uhornhookabove;1EEC
+Uhorntilde;1EEE
+Uhungarumlaut;0170
+Uhungarumlautcyrillic;04F2
+Uinvertedbreve;0216
+Ukcyrillic;0478
+Umacron;016A
+Umacroncyrillic;04EE
+Umacrondieresis;1E7A
+Umonospace;FF35
+Uogonek;0172
+Upsilon;03A5
+Upsilon1;03D2
+Upsilonacutehooksymbolgreek;03D3
+Upsilonafrican;01B1
+Upsilondieresis;03AB
+Upsilondieresishooksymbolgreek;03D4
+Upsilonhooksymbol;03D2
+Upsilontonos;038E
+Uring;016E
+Ushortcyrillic;040E
+Usmall;F775
+Ustraightcyrillic;04AE
+Ustraightstrokecyrillic;04B0
+Utilde;0168
+Utildeacute;1E78
+Utildebelow;1E74
+V;0056
+Vcircle;24CB
+Vdotbelow;1E7E
+Vecyrillic;0412
+Vewarmenian;054E
+Vhook;01B2
+Vmonospace;FF36
+Voarmenian;0548
+Vsmall;F776
+Vtilde;1E7C
+W;0057
+Wacute;1E82
+Wcircle;24CC
+Wcircumflex;0174
+Wdieresis;1E84
+Wdotaccent;1E86
+Wdotbelow;1E88
+Wgrave;1E80
+Wmonospace;FF37
+Wsmall;F777
+X;0058
+Xcircle;24CD
+Xdieresis;1E8C
+Xdotaccent;1E8A
+Xeharmenian;053D
+Xi;039E
+Xmonospace;FF38
+Xsmall;F778
+Y;0059
+Yacute;00DD
+Yacutesmall;F7FD
+Yatcyrillic;0462
+Ycircle;24CE
+Ycircumflex;0176
+Ydieresis;0178
+Ydieresissmall;F7FF
+Ydotaccent;1E8E
+Ydotbelow;1EF4
+Yericyrillic;042B
+Yerudieresiscyrillic;04F8
+Ygrave;1EF2
+Yhook;01B3
+Yhookabove;1EF6
+Yiarmenian;0545
+Yicyrillic;0407
+Yiwnarmenian;0552
+Ymonospace;FF39
+Ysmall;F779
+Ytilde;1EF8
+Yusbigcyrillic;046A
+Yusbigiotifiedcyrillic;046C
+Yuslittlecyrillic;0466
+Yuslittleiotifiedcyrillic;0468
+Z;005A
+Zaarmenian;0536
+Zacute;0179
+Zcaron;017D
+Zcaronsmall;F6FF
+Zcircle;24CF
+Zcircumflex;1E90
+Zdot;017B
+Zdotaccent;017B
+Zdotbelow;1E92
+Zecyrillic;0417
+Zedescendercyrillic;0498
+Zedieresiscyrillic;04DE
+Zeta;0396
+Zhearmenian;053A
+Zhebrevecyrillic;04C1
+Zhecyrillic;0416
+Zhedescendercyrillic;0496
+Zhedieresiscyrillic;04DC
+Zlinebelow;1E94
+Zmonospace;FF3A
+Zsmall;F77A
+Zstroke;01B5
+a;0061
+aabengali;0986
+aacute;00E1
+aadeva;0906
+aagujarati;0A86
+aagurmukhi;0A06
+aamatragurmukhi;0A3E
+aarusquare;3303
+aavowelsignbengali;09BE
+aavowelsigndeva;093E
+aavowelsigngujarati;0ABE
+abbreviationmarkarmenian;055F
+abbreviationsigndeva;0970
+abengali;0985
+abopomofo;311A
+abreve;0103
+abreveacute;1EAF
+abrevecyrillic;04D1
+abrevedotbelow;1EB7
+abrevegrave;1EB1
+abrevehookabove;1EB3
+abrevetilde;1EB5
+acaron;01CE
+acircle;24D0
+acircumflex;00E2
+acircumflexacute;1EA5
+acircumflexdotbelow;1EAD
+acircumflexgrave;1EA7
+acircumflexhookabove;1EA9
+acircumflextilde;1EAB
+acute;00B4
+acutebelowcmb;0317
+acutecmb;0301
+acutecomb;0301
+acutedeva;0954
+acutelowmod;02CF
+acutetonecmb;0341
+acyrillic;0430
+adblgrave;0201
+addakgurmukhi;0A71
+adeva;0905
+adieresis;00E4
+adieresiscyrillic;04D3
+adieresismacron;01DF
+adotbelow;1EA1
+adotmacron;01E1
+ae;00E6
+aeacute;01FD
+aekorean;3150
+aemacron;01E3
+afii00208;2015
+afii08941;20A4
+afii10017;0410
+afii10018;0411
+afii10019;0412
+afii10020;0413
+afii10021;0414
+afii10022;0415
+afii10023;0401
+afii10024;0416
+afii10025;0417
+afii10026;0418
+afii10027;0419
+afii10028;041A
+afii10029;041B
+afii10030;041C
+afii10031;041D
+afii10032;041E
+afii10033;041F
+afii10034;0420
+afii10035;0421
+afii10036;0422
+afii10037;0423
+afii10038;0424
+afii10039;0425
+afii10040;0426
+afii10041;0427
+afii10042;0428
+afii10043;0429
+afii10044;042A
+afii10045;042B
+afii10046;042C
+afii10047;042D
+afii10048;042E
+afii10049;042F
+afii10050;0490
+afii10051;0402
+afii10052;0403
+afii10053;0404
+afii10054;0405
+afii10055;0406
+afii10056;0407
+afii10057;0408
+afii10058;0409
+afii10059;040A
+afii10060;040B
+afii10061;040C
+afii10062;040E
+afii10063;F6C4
+afii10064;F6C5
+afii10065;0430
+afii10066;0431
+afii10067;0432
+afii10068;0433
+afii10069;0434
+afii10070;0435
+afii10071;0451
+afii10072;0436
+afii10073;0437
+afii10074;0438
+afii10075;0439
+afii10076;043A
+afii10077;043B
+afii10078;043C
+afii10079;043D
+afii10080;043E
+afii10081;043F
+afii10082;0440
+afii10083;0441
+afii10084;0442
+afii10085;0443
+afii10086;0444
+afii10087;0445
+afii10088;0446
+afii10089;0447
+afii10090;0448
+afii10091;0449
+afii10092;044A
+afii10093;044B
+afii10094;044C
+afii10095;044D
+afii10096;044E
+afii10097;044F
+afii10098;0491
+afii10099;0452
+afii10100;0453
+afii10101;0454
+afii10102;0455
+afii10103;0456
+afii10104;0457
+afii10105;0458
+afii10106;0459
+afii10107;045A
+afii10108;045B
+afii10109;045C
+afii10110;045E
+afii10145;040F
+afii10146;0462
+afii10147;0472
+afii10148;0474
+afii10192;F6C6
+afii10193;045F
+afii10194;0463
+afii10195;0473
+afii10196;0475
+afii10831;F6C7
+afii10832;F6C8
+afii10846;04D9
+afii299;200E
+afii300;200F
+afii301;200D
+afii57381;066A
+afii57388;060C
+afii57392;0660
+afii57393;0661
+afii57394;0662
+afii57395;0663
+afii57396;0664
+afii57397;0665
+afii57398;0666
+afii57399;0667
+afii57400;0668
+afii57401;0669
+afii57403;061B
+afii57407;061F
+afii57409;0621
+afii57410;0622
+afii57411;0623
+afii57412;0624
+afii57413;0625
+afii57414;0626
+afii57415;0627
+afii57416;0628
+afii57417;0629
+afii57418;062A
+afii57419;062B
+afii57420;062C
+afii57421;062D
+afii57422;062E
+afii57423;062F
+afii57424;0630
+afii57425;0631
+afii57426;0632
+afii57427;0633
+afii57428;0634
+afii57429;0635
+afii57430;0636
+afii57431;0637
+afii57432;0638
+afii57433;0639
+afii57434;063A
+afii57440;0640
+afii57441;0641
+afii57442;0642
+afii57443;0643
+afii57444;0644
+afii57445;0645
+afii57446;0646
+afii57448;0648
+afii57449;0649
+afii57450;064A
+afii57451;064B
+afii57452;064C
+afii57453;064D
+afii57454;064E
+afii57455;064F
+afii57456;0650
+afii57457;0651
+afii57458;0652
+afii57470;0647
+afii57505;06A4
+afii57506;067E
+afii57507;0686
+afii57508;0698
+afii57509;06AF
+afii57511;0679
+afii57512;0688
+afii57513;0691
+afii57514;06BA
+afii57519;06D2
+afii57534;06D5
+afii57636;20AA
+afii57645;05BE
+afii57658;05C3
+afii57664;05D0
+afii57665;05D1
+afii57666;05D2
+afii57667;05D3
+afii57668;05D4
+afii57669;05D5
+afii57670;05D6
+afii57671;05D7
+afii57672;05D8
+afii57673;05D9
+afii57674;05DA
+afii57675;05DB
+afii57676;05DC
+afii57677;05DD
+afii57678;05DE
+afii57679;05DF
+afii57680;05E0
+afii57681;05E1
+afii57682;05E2
+afii57683;05E3
+afii57684;05E4
+afii57685;05E5
+afii57686;05E6
+afii57687;05E7
+afii57688;05E8
+afii57689;05E9
+afii57690;05EA
+afii57694;FB2A
+afii57695;FB2B
+afii57700;FB4B
+afii57705;FB1F
+afii57716;05F0
+afii57717;05F1
+afii57718;05F2
+afii57723;FB35
+afii57793;05B4
+afii57794;05B5
+afii57795;05B6
+afii57796;05BB
+afii57797;05B8
+afii57798;05B7
+afii57799;05B0
+afii57800;05B2
+afii57801;05B1
+afii57802;05B3
+afii57803;05C2
+afii57804;05C1
+afii57806;05B9
+afii57807;05BC
+afii57839;05BD
+afii57841;05BF
+afii57842;05C0
+afii57929;02BC
+afii61248;2105
+afii61289;2113
+afii61352;2116
+afii61573;202C
+afii61574;202D
+afii61575;202E
+afii61664;200C
+afii63167;066D
+afii64937;02BD
+agrave;00E0
+agujarati;0A85
+agurmukhi;0A05
+ahiragana;3042
+ahookabove;1EA3
+aibengali;0990
+aibopomofo;311E
+aideva;0910
+aiecyrillic;04D5
+aigujarati;0A90
+aigurmukhi;0A10
+aimatragurmukhi;0A48
+ainarabic;0639
+ainfinalarabic;FECA
+aininitialarabic;FECB
+ainmedialarabic;FECC
+ainvertedbreve;0203
+aivowelsignbengali;09C8
+aivowelsigndeva;0948
+aivowelsigngujarati;0AC8
+akatakana;30A2
+akatakanahalfwidth;FF71
+akorean;314F
+alef;05D0
+alefarabic;0627
+alefdageshhebrew;FB30
+aleffinalarabic;FE8E
+alefhamzaabovearabic;0623
+alefhamzaabovefinalarabic;FE84
+alefhamzabelowarabic;0625
+alefhamzabelowfinalarabic;FE88
+alefhebrew;05D0
+aleflamedhebrew;FB4F
+alefmaddaabovearabic;0622
+alefmaddaabovefinalarabic;FE82
+alefmaksuraarabic;0649
+alefmaksurafinalarabic;FEF0
+alefmaksurainitialarabic;FEF3
+alefmaksuramedialarabic;FEF4
+alefpatahhebrew;FB2E
+alefqamatshebrew;FB2F
+aleph;2135
+allequal;224C
+alpha;03B1
+alphatonos;03AC
+amacron;0101
+amonospace;FF41
+ampersand;0026
+ampersandmonospace;FF06
+ampersandsmall;F726
+amsquare;33C2
+anbopomofo;3122
+angbopomofo;3124
+angkhankhuthai;0E5A
+angle;2220
+anglebracketleft;3008
+anglebracketleftvertical;FE3F
+anglebracketright;3009
+anglebracketrightvertical;FE40
+angleleft;2329
+angleright;232A
+angstrom;212B
+anoteleia;0387
+anudattadeva;0952
+anusvarabengali;0982
+anusvaradeva;0902
+anusvaragujarati;0A82
+aogonek;0105
+apaatosquare;3300
+aparen;249C
+apostrophearmenian;055A
+apostrophemod;02BC
+apple;F8FF
+approaches;2250
+approxequal;2248
+approxequalorimage;2252
+approximatelyequal;2245
+araeaekorean;318E
+araeakorean;318D
+arc;2312
+arighthalfring;1E9A
+aring;00E5
+aringacute;01FB
+aringbelow;1E01
+arrowboth;2194
+arrowdashdown;21E3
+arrowdashleft;21E0
+arrowdashright;21E2
+arrowdashup;21E1
+arrowdblboth;21D4
+arrowdbldown;21D3
+arrowdblleft;21D0
+arrowdblright;21D2
+arrowdblup;21D1
+arrowdown;2193
+arrowdownleft;2199
+arrowdownright;2198
+arrowdownwhite;21E9
+arrowheaddownmod;02C5
+arrowheadleftmod;02C2
+arrowheadrightmod;02C3
+arrowheadupmod;02C4
+arrowhorizex;F8E7
+arrowleft;2190
+arrowleftdbl;21D0
+arrowleftdblstroke;21CD
+arrowleftoverright;21C6
+arrowleftwhite;21E6
+arrowright;2192
+arrowrightdblstroke;21CF
+arrowrightheavy;279E
+arrowrightoverleft;21C4
+arrowrightwhite;21E8
+arrowtableft;21E4
+arrowtabright;21E5
+arrowup;2191
+arrowupdn;2195
+arrowupdnbse;21A8
+arrowupdownbase;21A8
+arrowupleft;2196
+arrowupleftofdown;21C5
+arrowupright;2197
+arrowupwhite;21E7
+arrowvertex;F8E6
+asciicircum;005E
+asciicircummonospace;FF3E
+asciitilde;007E
+asciitildemonospace;FF5E
+ascript;0251
+ascriptturned;0252
+asmallhiragana;3041
+asmallkatakana;30A1
+asmallkatakanahalfwidth;FF67
+asterisk;002A
+asteriskaltonearabic;066D
+asteriskarabic;066D
+asteriskmath;2217
+asteriskmonospace;FF0A
+asterisksmall;FE61
+asterism;2042
+asuperior;F6E9
+asymptoticallyequal;2243
+at;0040
+atilde;00E3
+atmonospace;FF20
+atsmall;FE6B
+aturned;0250
+aubengali;0994
+aubopomofo;3120
+audeva;0914
+augujarati;0A94
+augurmukhi;0A14
+aulengthmarkbengali;09D7
+aumatragurmukhi;0A4C
+auvowelsignbengali;09CC
+auvowelsigndeva;094C
+auvowelsigngujarati;0ACC
+avagrahadeva;093D
+aybarmenian;0561
+ayin;05E2
+ayinaltonehebrew;FB20
+ayinhebrew;05E2
+b;0062
+babengali;09AC
+backslash;005C
+backslashmonospace;FF3C
+badeva;092C
+bagujarati;0AAC
+bagurmukhi;0A2C
+bahiragana;3070
+bahtthai;0E3F
+bakatakana;30D0
+bar;007C
+barmonospace;FF5C
+bbopomofo;3105
+bcircle;24D1
+bdotaccent;1E03
+bdotbelow;1E05
+beamedsixteenthnotes;266C
+because;2235
+becyrillic;0431
+beharabic;0628
+behfinalarabic;FE90
+behinitialarabic;FE91
+behiragana;3079
+behmedialarabic;FE92
+behmeeminitialarabic;FC9F
+behmeemisolatedarabic;FC08
+behnoonfinalarabic;FC6D
+bekatakana;30D9
+benarmenian;0562
+bet;05D1
+beta;03B2
+betasymbolgreek;03D0
+betdagesh;FB31
+betdageshhebrew;FB31
+bethebrew;05D1
+betrafehebrew;FB4C
+bhabengali;09AD
+bhadeva;092D
+bhagujarati;0AAD
+bhagurmukhi;0A2D
+bhook;0253
+bihiragana;3073
+bikatakana;30D3
+bilabialclick;0298
+bindigurmukhi;0A02
+birusquare;3331
+blackcircle;25CF
+blackdiamond;25C6
+blackdownpointingtriangle;25BC
+blackleftpointingpointer;25C4
+blackleftpointingtriangle;25C0
+blacklenticularbracketleft;3010
+blacklenticularbracketleftvertical;FE3B
+blacklenticularbracketright;3011
+blacklenticularbracketrightvertical;FE3C
+blacklowerlefttriangle;25E3
+blacklowerrighttriangle;25E2
+blackrectangle;25AC
+blackrightpointingpointer;25BA
+blackrightpointingtriangle;25B6
+blacksmallsquare;25AA
+blacksmilingface;263B
+blacksquare;25A0
+blackstar;2605
+blackupperlefttriangle;25E4
+blackupperrighttriangle;25E5
+blackuppointingsmalltriangle;25B4
+blackuppointingtriangle;25B2
+blank;2423
+blinebelow;1E07
+block;2588
+bmonospace;FF42
+bobaimaithai;0E1A
+bohiragana;307C
+bokatakana;30DC
+bparen;249D
+bqsquare;33C3
+braceex;F8F4
+braceleft;007B
+braceleftbt;F8F3
+braceleftmid;F8F2
+braceleftmonospace;FF5B
+braceleftsmall;FE5B
+bracelefttp;F8F1
+braceleftvertical;FE37
+braceright;007D
+bracerightbt;F8FE
+bracerightmid;F8FD
+bracerightmonospace;FF5D
+bracerightsmall;FE5C
+bracerighttp;F8FC
+bracerightvertical;FE38
+bracketleft;005B
+bracketleftbt;F8F0
+bracketleftex;F8EF
+bracketleftmonospace;FF3B
+bracketlefttp;F8EE
+bracketright;005D
+bracketrightbt;F8FB
+bracketrightex;F8FA
+bracketrightmonospace;FF3D
+bracketrighttp;F8F9
+breve;02D8
+brevebelowcmb;032E
+brevecmb;0306
+breveinvertedbelowcmb;032F
+breveinvertedcmb;0311
+breveinverteddoublecmb;0361
+bridgebelowcmb;032A
+bridgeinvertedbelowcmb;033A
+brokenbar;00A6
+bstroke;0180
+bsuperior;F6EA
+btopbar;0183
+buhiragana;3076
+bukatakana;30D6
+bullet;2022
+bulletinverse;25D8
+bulletoperator;2219
+bullseye;25CE
+c;0063
+caarmenian;056E
+cabengali;099A
+cacute;0107
+cadeva;091A
+cagujarati;0A9A
+cagurmukhi;0A1A
+calsquare;3388
+candrabindubengali;0981
+candrabinducmb;0310
+candrabindudeva;0901
+candrabindugujarati;0A81
+capslock;21EA
+careof;2105
+caron;02C7
+caronbelowcmb;032C
+caroncmb;030C
+carriagereturn;21B5
+cbopomofo;3118
+ccaron;010D
+ccedilla;00E7
+ccedillaacute;1E09
+ccircle;24D2
+ccircumflex;0109
+ccurl;0255
+cdot;010B
+cdotaccent;010B
+cdsquare;33C5
+cedilla;00B8
+cedillacmb;0327
+cent;00A2
+centigrade;2103
+centinferior;F6DF
+centmonospace;FFE0
+centoldstyle;F7A2
+centsuperior;F6E0
+chaarmenian;0579
+chabengali;099B
+chadeva;091B
+chagujarati;0A9B
+chagurmukhi;0A1B
+chbopomofo;3114
+cheabkhasiancyrillic;04BD
+checkmark;2713
+checyrillic;0447
+chedescenderabkhasiancyrillic;04BF
+chedescendercyrillic;04B7
+chedieresiscyrillic;04F5
+cheharmenian;0573
+chekhakassiancyrillic;04CC
+cheverticalstrokecyrillic;04B9
+chi;03C7
+chieuchacirclekorean;3277
+chieuchaparenkorean;3217
+chieuchcirclekorean;3269
+chieuchkorean;314A
+chieuchparenkorean;3209
+chochangthai;0E0A
+chochanthai;0E08
+chochingthai;0E09
+chochoethai;0E0C
+chook;0188
+cieucacirclekorean;3276
+cieucaparenkorean;3216
+cieuccirclekorean;3268
+cieuckorean;3148
+cieucparenkorean;3208
+cieucuparenkorean;321C
+circle;25CB
+circlemultiply;2297
+circleot;2299
+circleplus;2295
+circlepostalmark;3036
+circlewithlefthalfblack;25D0
+circlewithrighthalfblack;25D1
+circumflex;02C6
+circumflexbelowcmb;032D
+circumflexcmb;0302
+clear;2327
+clickalveolar;01C2
+clickdental;01C0
+clicklateral;01C1
+clickretroflex;01C3
+club;2663
+clubsuitblack;2663
+clubsuitwhite;2667
+cmcubedsquare;33A4
+cmonospace;FF43
+cmsquaredsquare;33A0
+coarmenian;0581
+colon;003A
+colonmonetary;20A1
+colonmonospace;FF1A
+colonsign;20A1
+colonsmall;FE55
+colontriangularhalfmod;02D1
+colontriangularmod;02D0
+comma;002C
+commaabovecmb;0313
+commaaboverightcmb;0315
+commaaccent;F6C3
+commaarabic;060C
+commaarmenian;055D
+commainferior;F6E1
+commamonospace;FF0C
+commareversedabovecmb;0314
+commareversedmod;02BD
+commasmall;FE50
+commasuperior;F6E2
+commaturnedabovecmb;0312
+commaturnedmod;02BB
+compass;263C
+congruent;2245
+contourintegral;222E
+control;2303
+controlACK;0006
+controlBEL;0007
+controlBS;0008
+controlCAN;0018
+controlCR;000D
+controlDC1;0011
+controlDC2;0012
+controlDC3;0013
+controlDC4;0014
+controlDEL;007F
+controlDLE;0010
+controlEM;0019
+controlENQ;0005
+controlEOT;0004
+controlESC;001B
+controlETB;0017
+controlETX;0003
+controlFF;000C
+controlFS;001C
+controlGS;001D
+controlHT;0009
+controlLF;000A
+controlNAK;0015
+controlRS;001E
+controlSI;000F
+controlSO;000E
+controlSOT;0002
+controlSTX;0001
+controlSUB;001A
+controlSYN;0016
+controlUS;001F
+controlVT;000B
+copyright;00A9
+copyrightsans;F8E9
+copyrightserif;F6D9
+cornerbracketleft;300C
+cornerbracketlefthalfwidth;FF62
+cornerbracketleftvertical;FE41
+cornerbracketright;300D
+cornerbracketrighthalfwidth;FF63
+cornerbracketrightvertical;FE42
+corporationsquare;337F
+cosquare;33C7
+coverkgsquare;33C6
+cparen;249E
+cruzeiro;20A2
+cstretched;0297
+curlyand;22CF
+curlyor;22CE
+currency;00A4
+cyrBreve;F6D1
+cyrFlex;F6D2
+cyrbreve;F6D4
+cyrflex;F6D5
+d;0064
+daarmenian;0564
+dabengali;09A6
+dadarabic;0636
+dadeva;0926
+dadfinalarabic;FEBE
+dadinitialarabic;FEBF
+dadmedialarabic;FEC0
+dagesh;05BC
+dageshhebrew;05BC
+dagger;2020
+daggerdbl;2021
+dagujarati;0AA6
+dagurmukhi;0A26
+dahiragana;3060
+dakatakana;30C0
+dalarabic;062F
+dalet;05D3
+daletdagesh;FB33
+daletdageshhebrew;FB33
+dalethatafpatah;05D3 05B2
+dalethatafpatahhebrew;05D3 05B2
+dalethatafsegol;05D3 05B1
+dalethatafsegolhebrew;05D3 05B1
+dalethebrew;05D3
+dalethiriq;05D3 05B4
+dalethiriqhebrew;05D3 05B4
+daletholam;05D3 05B9
+daletholamhebrew;05D3 05B9
+daletpatah;05D3 05B7
+daletpatahhebrew;05D3 05B7
+daletqamats;05D3 05B8
+daletqamatshebrew;05D3 05B8
+daletqubuts;05D3 05BB
+daletqubutshebrew;05D3 05BB
+daletsegol;05D3 05B6
+daletsegolhebrew;05D3 05B6
+daletsheva;05D3 05B0
+daletshevahebrew;05D3 05B0
+dalettsere;05D3 05B5
+dalettserehebrew;05D3 05B5
+dalfinalarabic;FEAA
+dammaarabic;064F
+dammalowarabic;064F
+dammatanaltonearabic;064C
+dammatanarabic;064C
+danda;0964
+dargahebrew;05A7
+dargalefthebrew;05A7
+dasiapneumatacyrilliccmb;0485
+dblGrave;F6D3
+dblanglebracketleft;300A
+dblanglebracketleftvertical;FE3D
+dblanglebracketright;300B
+dblanglebracketrightvertical;FE3E
+dblarchinvertedbelowcmb;032B
+dblarrowleft;21D4
+dblarrowright;21D2
+dbldanda;0965
+dblgrave;F6D6
+dblgravecmb;030F
+dblintegral;222C
+dbllowline;2017
+dbllowlinecmb;0333
+dbloverlinecmb;033F
+dblprimemod;02BA
+dblverticalbar;2016
+dblverticallineabovecmb;030E
+dbopomofo;3109
+dbsquare;33C8
+dcaron;010F
+dcedilla;1E11
+dcircle;24D3
+dcircumflexbelow;1E13
+dcroat;0111
+ddabengali;09A1
+ddadeva;0921
+ddagujarati;0AA1
+ddagurmukhi;0A21
+ddalarabic;0688
+ddalfinalarabic;FB89
+dddhadeva;095C
+ddhabengali;09A2
+ddhadeva;0922
+ddhagujarati;0AA2
+ddhagurmukhi;0A22
+ddotaccent;1E0B
+ddotbelow;1E0D
+decimalseparatorarabic;066B
+decimalseparatorpersian;066B
+decyrillic;0434
+degree;00B0
+dehihebrew;05AD
+dehiragana;3067
+deicoptic;03EF
+dekatakana;30C7
+deleteleft;232B
+deleteright;2326
+delta;03B4
+deltaturned;018D
+denominatorminusonenumeratorbengali;09F8
+dezh;02A4
+dhabengali;09A7
+dhadeva;0927
+dhagujarati;0AA7
+dhagurmukhi;0A27
+dhook;0257
+dialytikatonos;0385
+dialytikatonoscmb;0344
+diamond;2666
+diamondsuitwhite;2662
+dieresis;00A8
+dieresisacute;F6D7
+dieresisbelowcmb;0324
+dieresiscmb;0308
+dieresisgrave;F6D8
+dieresistonos;0385
+dihiragana;3062
+dikatakana;30C2
+dittomark;3003
+divide;00F7
+divides;2223
+divisionslash;2215
+djecyrillic;0452
+dkshade;2593
+dlinebelow;1E0F
+dlsquare;3397
+dmacron;0111
+dmonospace;FF44
+dnblock;2584
+dochadathai;0E0E
+dodekthai;0E14
+dohiragana;3069
+dokatakana;30C9
+dollar;0024
+dollarinferior;F6E3
+dollarmonospace;FF04
+dollaroldstyle;F724
+dollarsmall;FE69
+dollarsuperior;F6E4
+dong;20AB
+dorusquare;3326
+dotaccent;02D9
+dotaccentcmb;0307
+dotbelowcmb;0323
+dotbelowcomb;0323
+dotkatakana;30FB
+dotlessi;0131
+dotlessj;F6BE
+dotlessjstrokehook;0284
+dotmath;22C5
+dottedcircle;25CC
+doubleyodpatah;FB1F
+doubleyodpatahhebrew;FB1F
+downtackbelowcmb;031E
+downtackmod;02D5
+dparen;249F
+dsuperior;F6EB
+dtail;0256
+dtopbar;018C
+duhiragana;3065
+dukatakana;30C5
+dz;01F3
+dzaltone;02A3
+dzcaron;01C6
+dzcurl;02A5
+dzeabkhasiancyrillic;04E1
+dzecyrillic;0455
+dzhecyrillic;045F
+e;0065
+eacute;00E9
+earth;2641
+ebengali;098F
+ebopomofo;311C
+ebreve;0115
+ecandradeva;090D
+ecandragujarati;0A8D
+ecandravowelsigndeva;0945
+ecandravowelsigngujarati;0AC5
+ecaron;011B
+ecedillabreve;1E1D
+echarmenian;0565
+echyiwnarmenian;0587
+ecircle;24D4
+ecircumflex;00EA
+ecircumflexacute;1EBF
+ecircumflexbelow;1E19
+ecircumflexdotbelow;1EC7
+ecircumflexgrave;1EC1
+ecircumflexhookabove;1EC3
+ecircumflextilde;1EC5
+ecyrillic;0454
+edblgrave;0205
+edeva;090F
+edieresis;00EB
+edot;0117
+edotaccent;0117
+edotbelow;1EB9
+eegurmukhi;0A0F
+eematragurmukhi;0A47
+efcyrillic;0444
+egrave;00E8
+egujarati;0A8F
+eharmenian;0567
+ehbopomofo;311D
+ehiragana;3048
+ehookabove;1EBB
+eibopomofo;311F
+eight;0038
+eightarabic;0668
+eightbengali;09EE
+eightcircle;2467
+eightcircleinversesansserif;2791
+eightdeva;096E
+eighteencircle;2471
+eighteenparen;2485
+eighteenperiod;2499
+eightgujarati;0AEE
+eightgurmukhi;0A6E
+eighthackarabic;0668
+eighthangzhou;3028
+eighthnotebeamed;266B
+eightideographicparen;3227
+eightinferior;2088
+eightmonospace;FF18
+eightoldstyle;F738
+eightparen;247B
+eightperiod;248F
+eightpersian;06F8
+eightroman;2177
+eightsuperior;2078
+eightthai;0E58
+einvertedbreve;0207
+eiotifiedcyrillic;0465
+ekatakana;30A8
+ekatakanahalfwidth;FF74
+ekonkargurmukhi;0A74
+ekorean;3154
+elcyrillic;043B
+element;2208
+elevencircle;246A
+elevenparen;247E
+elevenperiod;2492
+elevenroman;217A
+ellipsis;2026
+ellipsisvertical;22EE
+emacron;0113
+emacronacute;1E17
+emacrongrave;1E15
+emcyrillic;043C
+emdash;2014
+emdashvertical;FE31
+emonospace;FF45
+emphasismarkarmenian;055B
+emptyset;2205
+enbopomofo;3123
+encyrillic;043D
+endash;2013
+endashvertical;FE32
+endescendercyrillic;04A3
+eng;014B
+engbopomofo;3125
+enghecyrillic;04A5
+enhookcyrillic;04C8
+enspace;2002
+eogonek;0119
+eokorean;3153
+eopen;025B
+eopenclosed;029A
+eopenreversed;025C
+eopenreversedclosed;025E
+eopenreversedhook;025D
+eparen;24A0
+epsilon;03B5
+epsilontonos;03AD
+equal;003D
+equalmonospace;FF1D
+equalsmall;FE66
+equalsuperior;207C
+equivalence;2261
+erbopomofo;3126
+ercyrillic;0440
+ereversed;0258
+ereversedcyrillic;044D
+escyrillic;0441
+esdescendercyrillic;04AB
+esh;0283
+eshcurl;0286
+eshortdeva;090E
+eshortvowelsigndeva;0946
+eshreversedloop;01AA
+eshsquatreversed;0285
+esmallhiragana;3047
+esmallkatakana;30A7
+esmallkatakanahalfwidth;FF6A
+estimated;212E
+esuperior;F6EC
+eta;03B7
+etarmenian;0568
+etatonos;03AE
+eth;00F0
+etilde;1EBD
+etildebelow;1E1B
+etnahtafoukhhebrew;0591
+etnahtafoukhlefthebrew;0591
+etnahtahebrew;0591
+etnahtalefthebrew;0591
+eturned;01DD
+eukorean;3161
+euro;20AC
+evowelsignbengali;09C7
+evowelsigndeva;0947
+evowelsigngujarati;0AC7
+exclam;0021
+exclamarmenian;055C
+exclamdbl;203C
+exclamdown;00A1
+exclamdownsmall;F7A1
+exclammonospace;FF01
+exclamsmall;F721
+existential;2203
+ezh;0292
+ezhcaron;01EF
+ezhcurl;0293
+ezhreversed;01B9
+ezhtail;01BA
+f;0066
+fadeva;095E
+fagurmukhi;0A5E
+fahrenheit;2109
+fathaarabic;064E
+fathalowarabic;064E
+fathatanarabic;064B
+fbopomofo;3108
+fcircle;24D5
+fdotaccent;1E1F
+feharabic;0641
+feharmenian;0586
+fehfinalarabic;FED2
+fehinitialarabic;FED3
+fehmedialarabic;FED4
+feicoptic;03E5
+female;2640
+ff;FB00
+ffi;FB03
+ffl;FB04
+fi;FB01
+fifteencircle;246E
+fifteenparen;2482
+fifteenperiod;2496
+figuredash;2012
+filledbox;25A0
+filledrect;25AC
+finalkaf;05DA
+finalkafdagesh;FB3A
+finalkafdageshhebrew;FB3A
+finalkafhebrew;05DA
+finalkafqamats;05DA 05B8
+finalkafqamatshebrew;05DA 05B8
+finalkafsheva;05DA 05B0
+finalkafshevahebrew;05DA 05B0
+finalmem;05DD
+finalmemhebrew;05DD
+finalnun;05DF
+finalnunhebrew;05DF
+finalpe;05E3
+finalpehebrew;05E3
+finaltsadi;05E5
+finaltsadihebrew;05E5
+firsttonechinese;02C9
+fisheye;25C9
+fitacyrillic;0473
+five;0035
+fivearabic;0665
+fivebengali;09EB
+fivecircle;2464
+fivecircleinversesansserif;278E
+fivedeva;096B
+fiveeighths;215D
+fivegujarati;0AEB
+fivegurmukhi;0A6B
+fivehackarabic;0665
+fivehangzhou;3025
+fiveideographicparen;3224
+fiveinferior;2085
+fivemonospace;FF15
+fiveoldstyle;F735
+fiveparen;2478
+fiveperiod;248C
+fivepersian;06F5
+fiveroman;2174
+fivesuperior;2075
+fivethai;0E55
+fl;FB02
+florin;0192
+fmonospace;FF46
+fmsquare;3399
+fofanthai;0E1F
+fofathai;0E1D
+fongmanthai;0E4F
+forall;2200
+four;0034
+fourarabic;0664
+fourbengali;09EA
+fourcircle;2463
+fourcircleinversesansserif;278D
+fourdeva;096A
+fourgujarati;0AEA
+fourgurmukhi;0A6A
+fourhackarabic;0664
+fourhangzhou;3024
+fourideographicparen;3223
+fourinferior;2084
+fourmonospace;FF14
+fournumeratorbengali;09F7
+fouroldstyle;F734
+fourparen;2477
+fourperiod;248B
+fourpersian;06F4
+fourroman;2173
+foursuperior;2074
+fourteencircle;246D
+fourteenparen;2481
+fourteenperiod;2495
+fourthai;0E54
+fourthtonechinese;02CB
+fparen;24A1
+fraction;2044
+franc;20A3
+g;0067
+gabengali;0997
+gacute;01F5
+gadeva;0917
+gafarabic;06AF
+gaffinalarabic;FB93
+gafinitialarabic;FB94
+gafmedialarabic;FB95
+gagujarati;0A97
+gagurmukhi;0A17
+gahiragana;304C
+gakatakana;30AC
+gamma;03B3
+gammalatinsmall;0263
+gammasuperior;02E0
+gangiacoptic;03EB
+gbopomofo;310D
+gbreve;011F
+gcaron;01E7
+gcedilla;0123
+gcircle;24D6
+gcircumflex;011D
+gcommaaccent;0123
+gdot;0121
+gdotaccent;0121
+gecyrillic;0433
+gehiragana;3052
+gekatakana;30B2
+geometricallyequal;2251
+gereshaccenthebrew;059C
+gereshhebrew;05F3
+gereshmuqdamhebrew;059D
+germandbls;00DF
+gershayimaccenthebrew;059E
+gershayimhebrew;05F4
+getamark;3013
+ghabengali;0998
+ghadarmenian;0572
+ghadeva;0918
+ghagujarati;0A98
+ghagurmukhi;0A18
+ghainarabic;063A
+ghainfinalarabic;FECE
+ghaininitialarabic;FECF
+ghainmedialarabic;FED0
+ghemiddlehookcyrillic;0495
+ghestrokecyrillic;0493
+gheupturncyrillic;0491
+ghhadeva;095A
+ghhagurmukhi;0A5A
+ghook;0260
+ghzsquare;3393
+gihiragana;304E
+gikatakana;30AE
+gimarmenian;0563
+gimel;05D2
+gimeldagesh;FB32
+gimeldageshhebrew;FB32
+gimelhebrew;05D2
+gjecyrillic;0453
+glottalinvertedstroke;01BE
+glottalstop;0294
+glottalstopinverted;0296
+glottalstopmod;02C0
+glottalstopreversed;0295
+glottalstopreversedmod;02C1
+glottalstopreversedsuperior;02E4
+glottalstopstroke;02A1
+glottalstopstrokereversed;02A2
+gmacron;1E21
+gmonospace;FF47
+gohiragana;3054
+gokatakana;30B4
+gparen;24A2
+gpasquare;33AC
+gradient;2207
+grave;0060
+gravebelowcmb;0316
+gravecmb;0300
+gravecomb;0300
+gravedeva;0953
+gravelowmod;02CE
+gravemonospace;FF40
+gravetonecmb;0340
+greater;003E
+greaterequal;2265
+greaterequalorless;22DB
+greatermonospace;FF1E
+greaterorequivalent;2273
+greaterorless;2277
+greateroverequal;2267
+greatersmall;FE65
+gscript;0261
+gstroke;01E5
+guhiragana;3050
+guillemotleft;00AB
+guillemotright;00BB
+guilsinglleft;2039
+guilsinglright;203A
+gukatakana;30B0
+guramusquare;3318
+gysquare;33C9
+h;0068
+haabkhasiancyrillic;04A9
+haaltonearabic;06C1
+habengali;09B9
+hadescendercyrillic;04B3
+hadeva;0939
+hagujarati;0AB9
+hagurmukhi;0A39
+haharabic;062D
+hahfinalarabic;FEA2
+hahinitialarabic;FEA3
+hahiragana;306F
+hahmedialarabic;FEA4
+haitusquare;332A
+hakatakana;30CF
+hakatakanahalfwidth;FF8A
+halantgurmukhi;0A4D
+hamzaarabic;0621
+hamzadammaarabic;0621 064F
+hamzadammatanarabic;0621 064C
+hamzafathaarabic;0621 064E
+hamzafathatanarabic;0621 064B
+hamzalowarabic;0621
+hamzalowkasraarabic;0621 0650
+hamzalowkasratanarabic;0621 064D
+hamzasukunarabic;0621 0652
+hangulfiller;3164
+hardsigncyrillic;044A
+harpoonleftbarbup;21BC
+harpoonrightbarbup;21C0
+hasquare;33CA
+hatafpatah;05B2
+hatafpatah16;05B2
+hatafpatah23;05B2
+hatafpatah2f;05B2
+hatafpatahhebrew;05B2
+hatafpatahnarrowhebrew;05B2
+hatafpatahquarterhebrew;05B2
+hatafpatahwidehebrew;05B2
+hatafqamats;05B3
+hatafqamats1b;05B3
+hatafqamats28;05B3
+hatafqamats34;05B3
+hatafqamatshebrew;05B3
+hatafqamatsnarrowhebrew;05B3
+hatafqamatsquarterhebrew;05B3
+hatafqamatswidehebrew;05B3
+hatafsegol;05B1
+hatafsegol17;05B1
+hatafsegol24;05B1
+hatafsegol30;05B1
+hatafsegolhebrew;05B1
+hatafsegolnarrowhebrew;05B1
+hatafsegolquarterhebrew;05B1
+hatafsegolwidehebrew;05B1
+hbar;0127
+hbopomofo;310F
+hbrevebelow;1E2B
+hcedilla;1E29
+hcircle;24D7
+hcircumflex;0125
+hdieresis;1E27
+hdotaccent;1E23
+hdotbelow;1E25
+he;05D4
+heart;2665
+heartsuitblack;2665
+heartsuitwhite;2661
+hedagesh;FB34
+hedageshhebrew;FB34
+hehaltonearabic;06C1
+heharabic;0647
+hehebrew;05D4
+hehfinalaltonearabic;FBA7
+hehfinalalttwoarabic;FEEA
+hehfinalarabic;FEEA
+hehhamzaabovefinalarabic;FBA5
+hehhamzaaboveisolatedarabic;FBA4
+hehinitialaltonearabic;FBA8
+hehinitialarabic;FEEB
+hehiragana;3078
+hehmedialaltonearabic;FBA9
+hehmedialarabic;FEEC
+heiseierasquare;337B
+hekatakana;30D8
+hekatakanahalfwidth;FF8D
+hekutaarusquare;3336
+henghook;0267
+herutusquare;3339
+het;05D7
+hethebrew;05D7
+hhook;0266
+hhooksuperior;02B1
+hieuhacirclekorean;327B
+hieuhaparenkorean;321B
+hieuhcirclekorean;326D
+hieuhkorean;314E
+hieuhparenkorean;320D
+hihiragana;3072
+hikatakana;30D2
+hikatakanahalfwidth;FF8B
+hiriq;05B4
+hiriq14;05B4
+hiriq21;05B4
+hiriq2d;05B4
+hiriqhebrew;05B4
+hiriqnarrowhebrew;05B4
+hiriqquarterhebrew;05B4
+hiriqwidehebrew;05B4
+hlinebelow;1E96
+hmonospace;FF48
+hoarmenian;0570
+hohipthai;0E2B
+hohiragana;307B
+hokatakana;30DB
+hokatakanahalfwidth;FF8E
+holam;05B9
+holam19;05B9
+holam26;05B9
+holam32;05B9
+holamhebrew;05B9
+holamnarrowhebrew;05B9
+holamquarterhebrew;05B9
+holamwidehebrew;05B9
+honokhukthai;0E2E
+hookabovecomb;0309
+hookcmb;0309
+hookpalatalizedbelowcmb;0321
+hookretroflexbelowcmb;0322
+hoonsquare;3342
+horicoptic;03E9
+horizontalbar;2015
+horncmb;031B
+hotsprings;2668
+house;2302
+hparen;24A3
+hsuperior;02B0
+hturned;0265
+huhiragana;3075
+huiitosquare;3333
+hukatakana;30D5
+hukatakanahalfwidth;FF8C
+hungarumlaut;02DD
+hungarumlautcmb;030B
+hv;0195
+hyphen;002D
+hypheninferior;F6E5
+hyphenmonospace;FF0D
+hyphensmall;FE63
+hyphensuperior;F6E6
+hyphentwo;2010
+i;0069
+iacute;00ED
+iacyrillic;044F
+ibengali;0987
+ibopomofo;3127
+ibreve;012D
+icaron;01D0
+icircle;24D8
+icircumflex;00EE
+icyrillic;0456
+idblgrave;0209
+ideographearthcircle;328F
+ideographfirecircle;328B
+ideographicallianceparen;323F
+ideographiccallparen;323A
+ideographiccentrecircle;32A5
+ideographicclose;3006
+ideographiccomma;3001
+ideographiccommaleft;FF64
+ideographiccongratulationparen;3237
+ideographiccorrectcircle;32A3
+ideographicearthparen;322F
+ideographicenterpriseparen;323D
+ideographicexcellentcircle;329D
+ideographicfestivalparen;3240
+ideographicfinancialcircle;3296
+ideographicfinancialparen;3236
+ideographicfireparen;322B
+ideographichaveparen;3232
+ideographichighcircle;32A4
+ideographiciterationmark;3005
+ideographiclaborcircle;3298
+ideographiclaborparen;3238
+ideographicleftcircle;32A7
+ideographiclowcircle;32A6
+ideographicmedicinecircle;32A9
+ideographicmetalparen;322E
+ideographicmoonparen;322A
+ideographicnameparen;3234
+ideographicperiod;3002
+ideographicprintcircle;329E
+ideographicreachparen;3243
+ideographicrepresentparen;3239
+ideographicresourceparen;323E
+ideographicrightcircle;32A8
+ideographicsecretcircle;3299
+ideographicselfparen;3242
+ideographicsocietyparen;3233
+ideographicspace;3000
+ideographicspecialparen;3235
+ideographicstockparen;3231
+ideographicstudyparen;323B
+ideographicsunparen;3230
+ideographicsuperviseparen;323C
+ideographicwaterparen;322C
+ideographicwoodparen;322D
+ideographiczero;3007
+ideographmetalcircle;328E
+ideographmooncircle;328A
+ideographnamecircle;3294
+ideographsuncircle;3290
+ideographwatercircle;328C
+ideographwoodcircle;328D
+ideva;0907
+idieresis;00EF
+idieresisacute;1E2F
+idieresiscyrillic;04E5
+idotbelow;1ECB
+iebrevecyrillic;04D7
+iecyrillic;0435
+ieungacirclekorean;3275
+ieungaparenkorean;3215
+ieungcirclekorean;3267
+ieungkorean;3147
+ieungparenkorean;3207
+igrave;00EC
+igujarati;0A87
+igurmukhi;0A07
+ihiragana;3044
+ihookabove;1EC9
+iibengali;0988
+iicyrillic;0438
+iideva;0908
+iigujarati;0A88
+iigurmukhi;0A08
+iimatragurmukhi;0A40
+iinvertedbreve;020B
+iishortcyrillic;0439
+iivowelsignbengali;09C0
+iivowelsigndeva;0940
+iivowelsigngujarati;0AC0
+ij;0133
+ikatakana;30A4
+ikatakanahalfwidth;FF72
+ikorean;3163
+ilde;02DC
+iluyhebrew;05AC
+imacron;012B
+imacroncyrillic;04E3
+imageorapproximatelyequal;2253
+imatragurmukhi;0A3F
+imonospace;FF49
+increment;2206
+infinity;221E
+iniarmenian;056B
+integral;222B
+integralbottom;2321
+integralbt;2321
+integralex;F8F5
+integraltop;2320
+integraltp;2320
+intersection;2229
+intisquare;3305
+invbullet;25D8
+invcircle;25D9
+invsmileface;263B
+iocyrillic;0451
+iogonek;012F
+iota;03B9
+iotadieresis;03CA
+iotadieresistonos;0390
+iotalatin;0269
+iotatonos;03AF
+iparen;24A4
+irigurmukhi;0A72
+ismallhiragana;3043
+ismallkatakana;30A3
+ismallkatakanahalfwidth;FF68
+issharbengali;09FA
+istroke;0268
+isuperior;F6ED
+iterationhiragana;309D
+iterationkatakana;30FD
+itilde;0129
+itildebelow;1E2D
+iubopomofo;3129
+iucyrillic;044E
+ivowelsignbengali;09BF
+ivowelsigndeva;093F
+ivowelsigngujarati;0ABF
+izhitsacyrillic;0475
+izhitsadblgravecyrillic;0477
+j;006A
+jaarmenian;0571
+jabengali;099C
+jadeva;091C
+jagujarati;0A9C
+jagurmukhi;0A1C
+jbopomofo;3110
+jcaron;01F0
+jcircle;24D9
+jcircumflex;0135
+jcrossedtail;029D
+jdotlessstroke;025F
+jecyrillic;0458
+jeemarabic;062C
+jeemfinalarabic;FE9E
+jeeminitialarabic;FE9F
+jeemmedialarabic;FEA0
+jeharabic;0698
+jehfinalarabic;FB8B
+jhabengali;099D
+jhadeva;091D
+jhagujarati;0A9D
+jhagurmukhi;0A1D
+jheharmenian;057B
+jis;3004
+jmonospace;FF4A
+jparen;24A5
+jsuperior;02B2
+k;006B
+kabashkircyrillic;04A1
+kabengali;0995
+kacute;1E31
+kacyrillic;043A
+kadescendercyrillic;049B
+kadeva;0915
+kaf;05DB
+kafarabic;0643
+kafdagesh;FB3B
+kafdageshhebrew;FB3B
+kaffinalarabic;FEDA
+kafhebrew;05DB
+kafinitialarabic;FEDB
+kafmedialarabic;FEDC
+kafrafehebrew;FB4D
+kagujarati;0A95
+kagurmukhi;0A15
+kahiragana;304B
+kahookcyrillic;04C4
+kakatakana;30AB
+kakatakanahalfwidth;FF76
+kappa;03BA
+kappasymbolgreek;03F0
+kapyeounmieumkorean;3171
+kapyeounphieuphkorean;3184
+kapyeounpieupkorean;3178
+kapyeounssangpieupkorean;3179
+karoriisquare;330D
+kashidaautoarabic;0640
+kashidaautonosidebearingarabic;0640
+kasmallkatakana;30F5
+kasquare;3384
+kasraarabic;0650
+kasratanarabic;064D
+kastrokecyrillic;049F
+katahiraprolongmarkhalfwidth;FF70
+kaverticalstrokecyrillic;049D
+kbopomofo;310E
+kcalsquare;3389
+kcaron;01E9
+kcedilla;0137
+kcircle;24DA
+kcommaaccent;0137
+kdotbelow;1E33
+keharmenian;0584
+kehiragana;3051
+kekatakana;30B1
+kekatakanahalfwidth;FF79
+kenarmenian;056F
+kesmallkatakana;30F6
+kgreenlandic;0138
+khabengali;0996
+khacyrillic;0445
+khadeva;0916
+khagujarati;0A96
+khagurmukhi;0A16
+khaharabic;062E
+khahfinalarabic;FEA6
+khahinitialarabic;FEA7
+khahmedialarabic;FEA8
+kheicoptic;03E7
+khhadeva;0959
+khhagurmukhi;0A59
+khieukhacirclekorean;3278
+khieukhaparenkorean;3218
+khieukhcirclekorean;326A
+khieukhkorean;314B
+khieukhparenkorean;320A
+khokhaithai;0E02
+khokhonthai;0E05
+khokhuatthai;0E03
+khokhwaithai;0E04
+khomutthai;0E5B
+khook;0199
+khorakhangthai;0E06
+khzsquare;3391
+kihiragana;304D
+kikatakana;30AD
+kikatakanahalfwidth;FF77
+kiroguramusquare;3315
+kiromeetorusquare;3316
+kirosquare;3314
+kiyeokacirclekorean;326E
+kiyeokaparenkorean;320E
+kiyeokcirclekorean;3260
+kiyeokkorean;3131
+kiyeokparenkorean;3200
+kiyeoksioskorean;3133
+kjecyrillic;045C
+klinebelow;1E35
+klsquare;3398
+kmcubedsquare;33A6
+kmonospace;FF4B
+kmsquaredsquare;33A2
+kohiragana;3053
+kohmsquare;33C0
+kokaithai;0E01
+kokatakana;30B3
+kokatakanahalfwidth;FF7A
+kooposquare;331E
+koppacyrillic;0481
+koreanstandardsymbol;327F
+koroniscmb;0343
+kparen;24A6
+kpasquare;33AA
+ksicyrillic;046F
+ktsquare;33CF
+kturned;029E
+kuhiragana;304F
+kukatakana;30AF
+kukatakanahalfwidth;FF78
+kvsquare;33B8
+kwsquare;33BE
+l;006C
+labengali;09B2
+lacute;013A
+ladeva;0932
+lagujarati;0AB2
+lagurmukhi;0A32
+lakkhangyaothai;0E45
+lamaleffinalarabic;FEFC
+lamalefhamzaabovefinalarabic;FEF8
+lamalefhamzaaboveisolatedarabic;FEF7
+lamalefhamzabelowfinalarabic;FEFA
+lamalefhamzabelowisolatedarabic;FEF9
+lamalefisolatedarabic;FEFB
+lamalefmaddaabovefinalarabic;FEF6
+lamalefmaddaaboveisolatedarabic;FEF5
+lamarabic;0644
+lambda;03BB
+lambdastroke;019B
+lamed;05DC
+lameddagesh;FB3C
+lameddageshhebrew;FB3C
+lamedhebrew;05DC
+lamedholam;05DC 05B9
+lamedholamdagesh;05DC 05B9 05BC
+lamedholamdageshhebrew;05DC 05B9 05BC
+lamedholamhebrew;05DC 05B9
+lamfinalarabic;FEDE
+lamhahinitialarabic;FCCA
+laminitialarabic;FEDF
+lamjeeminitialarabic;FCC9
+lamkhahinitialarabic;FCCB
+lamlamhehisolatedarabic;FDF2
+lammedialarabic;FEE0
+lammeemhahinitialarabic;FD88
+lammeeminitialarabic;FCCC
+lammeemjeeminitialarabic;FEDF FEE4 FEA0
+lammeemkhahinitialarabic;FEDF FEE4 FEA8
+largecircle;25EF
+lbar;019A
+lbelt;026C
+lbopomofo;310C
+lcaron;013E
+lcedilla;013C
+lcircle;24DB
+lcircumflexbelow;1E3D
+lcommaaccent;013C
+ldot;0140
+ldotaccent;0140
+ldotbelow;1E37
+ldotbelowmacron;1E39
+leftangleabovecmb;031A
+lefttackbelowcmb;0318
+less;003C
+lessequal;2264
+lessequalorgreater;22DA
+lessmonospace;FF1C
+lessorequivalent;2272
+lessorgreater;2276
+lessoverequal;2266
+lesssmall;FE64
+lezh;026E
+lfblock;258C
+lhookretroflex;026D
+lira;20A4
+liwnarmenian;056C
+lj;01C9
+ljecyrillic;0459
+ll;F6C0
+lladeva;0933
+llagujarati;0AB3
+llinebelow;1E3B
+llladeva;0934
+llvocalicbengali;09E1
+llvocalicdeva;0961
+llvocalicvowelsignbengali;09E3
+llvocalicvowelsigndeva;0963
+lmiddletilde;026B
+lmonospace;FF4C
+lmsquare;33D0
+lochulathai;0E2C
+logicaland;2227
+logicalnot;00AC
+logicalnotreversed;2310
+logicalor;2228
+lolingthai;0E25
+longs;017F
+lowlinecenterline;FE4E
+lowlinecmb;0332
+lowlinedashed;FE4D
+lozenge;25CA
+lparen;24A7
+lslash;0142
+lsquare;2113
+lsuperior;F6EE
+ltshade;2591
+luthai;0E26
+lvocalicbengali;098C
+lvocalicdeva;090C
+lvocalicvowelsignbengali;09E2
+lvocalicvowelsigndeva;0962
+lxsquare;33D3
+m;006D
+mabengali;09AE
+macron;00AF
+macronbelowcmb;0331
+macroncmb;0304
+macronlowmod;02CD
+macronmonospace;FFE3
+macute;1E3F
+madeva;092E
+magujarati;0AAE
+magurmukhi;0A2E
+mahapakhhebrew;05A4
+mahapakhlefthebrew;05A4
+mahiragana;307E
+maichattawalowleftthai;F895
+maichattawalowrightthai;F894
+maichattawathai;0E4B
+maichattawaupperleftthai;F893
+maieklowleftthai;F88C
+maieklowrightthai;F88B
+maiekthai;0E48
+maiekupperleftthai;F88A
+maihanakatleftthai;F884
+maihanakatthai;0E31
+maitaikhuleftthai;F889
+maitaikhuthai;0E47
+maitholowleftthai;F88F
+maitholowrightthai;F88E
+maithothai;0E49
+maithoupperleftthai;F88D
+maitrilowleftthai;F892
+maitrilowrightthai;F891
+maitrithai;0E4A
+maitriupperleftthai;F890
+maiyamokthai;0E46
+makatakana;30DE
+makatakanahalfwidth;FF8F
+male;2642
+mansyonsquare;3347
+maqafhebrew;05BE
+mars;2642
+masoracirclehebrew;05AF
+masquare;3383
+mbopomofo;3107
+mbsquare;33D4
+mcircle;24DC
+mcubedsquare;33A5
+mdotaccent;1E41
+mdotbelow;1E43
+meemarabic;0645
+meemfinalarabic;FEE2
+meeminitialarabic;FEE3
+meemmedialarabic;FEE4
+meemmeeminitialarabic;FCD1
+meemmeemisolatedarabic;FC48
+meetorusquare;334D
+mehiragana;3081
+meizierasquare;337E
+mekatakana;30E1
+mekatakanahalfwidth;FF92
+mem;05DE
+memdagesh;FB3E
+memdageshhebrew;FB3E
+memhebrew;05DE
+menarmenian;0574
+merkhahebrew;05A5
+merkhakefulahebrew;05A6
+merkhakefulalefthebrew;05A6
+merkhalefthebrew;05A5
+mhook;0271
+mhzsquare;3392
+middledotkatakanahalfwidth;FF65
+middot;00B7
+mieumacirclekorean;3272
+mieumaparenkorean;3212
+mieumcirclekorean;3264
+mieumkorean;3141
+mieumpansioskorean;3170
+mieumparenkorean;3204
+mieumpieupkorean;316E
+mieumsioskorean;316F
+mihiragana;307F
+mikatakana;30DF
+mikatakanahalfwidth;FF90
+minus;2212
+minusbelowcmb;0320
+minuscircle;2296
+minusmod;02D7
+minusplus;2213
+minute;2032
+miribaarusquare;334A
+mirisquare;3349
+mlonglegturned;0270
+mlsquare;3396
+mmcubedsquare;33A3
+mmonospace;FF4D
+mmsquaredsquare;339F
+mohiragana;3082
+mohmsquare;33C1
+mokatakana;30E2
+mokatakanahalfwidth;FF93
+molsquare;33D6
+momathai;0E21
+moverssquare;33A7
+moverssquaredsquare;33A8
+mparen;24A8
+mpasquare;33AB
+mssquare;33B3
+msuperior;F6EF
+mturned;026F
+mu;00B5
+mu1;00B5
+muasquare;3382
+muchgreater;226B
+muchless;226A
+mufsquare;338C
+mugreek;03BC
+mugsquare;338D
+muhiragana;3080
+mukatakana;30E0
+mukatakanahalfwidth;FF91
+mulsquare;3395
+multiply;00D7
+mumsquare;339B
+munahhebrew;05A3
+munahlefthebrew;05A3
+musicalnote;266A
+musicalnotedbl;266B
+musicflatsign;266D
+musicsharpsign;266F
+mussquare;33B2
+muvsquare;33B6
+muwsquare;33BC
+mvmegasquare;33B9
+mvsquare;33B7
+mwmegasquare;33BF
+mwsquare;33BD
+n;006E
+nabengali;09A8
+nabla;2207
+nacute;0144
+nadeva;0928
+nagujarati;0AA8
+nagurmukhi;0A28
+nahiragana;306A
+nakatakana;30CA
+nakatakanahalfwidth;FF85
+napostrophe;0149
+nasquare;3381
+nbopomofo;310B
+nbspace;00A0
+ncaron;0148
+ncedilla;0146
+ncircle;24DD
+ncircumflexbelow;1E4B
+ncommaaccent;0146
+ndotaccent;1E45
+ndotbelow;1E47
+nehiragana;306D
+nekatakana;30CD
+nekatakanahalfwidth;FF88
+newsheqelsign;20AA
+nfsquare;338B
+ngabengali;0999
+ngadeva;0919
+ngagujarati;0A99
+ngagurmukhi;0A19
+ngonguthai;0E07
+nhiragana;3093
+nhookleft;0272
+nhookretroflex;0273
+nieunacirclekorean;326F
+nieunaparenkorean;320F
+nieuncieuckorean;3135
+nieuncirclekorean;3261
+nieunhieuhkorean;3136
+nieunkorean;3134
+nieunpansioskorean;3168
+nieunparenkorean;3201
+nieunsioskorean;3167
+nieuntikeutkorean;3166
+nihiragana;306B
+nikatakana;30CB
+nikatakanahalfwidth;FF86
+nikhahitleftthai;F899
+nikhahitthai;0E4D
+nine;0039
+ninearabic;0669
+ninebengali;09EF
+ninecircle;2468
+ninecircleinversesansserif;2792
+ninedeva;096F
+ninegujarati;0AEF
+ninegurmukhi;0A6F
+ninehackarabic;0669
+ninehangzhou;3029
+nineideographicparen;3228
+nineinferior;2089
+ninemonospace;FF19
+nineoldstyle;F739
+nineparen;247C
+nineperiod;2490
+ninepersian;06F9
+nineroman;2178
+ninesuperior;2079
+nineteencircle;2472
+nineteenparen;2486
+nineteenperiod;249A
+ninethai;0E59
+nj;01CC
+njecyrillic;045A
+nkatakana;30F3
+nkatakanahalfwidth;FF9D
+nlegrightlong;019E
+nlinebelow;1E49
+nmonospace;FF4E
+nmsquare;339A
+nnabengali;09A3
+nnadeva;0923
+nnagujarati;0AA3
+nnagurmukhi;0A23
+nnnadeva;0929
+nohiragana;306E
+nokatakana;30CE
+nokatakanahalfwidth;FF89
+nonbreakingspace;00A0
+nonenthai;0E13
+nonuthai;0E19
+noonarabic;0646
+noonfinalarabic;FEE6
+noonghunnaarabic;06BA
+noonghunnafinalarabic;FB9F
+noonhehinitialarabic;FEE7 FEEC
+nooninitialarabic;FEE7
+noonjeeminitialarabic;FCD2
+noonjeemisolatedarabic;FC4B
+noonmedialarabic;FEE8
+noonmeeminitialarabic;FCD5
+noonmeemisolatedarabic;FC4E
+noonnoonfinalarabic;FC8D
+notcontains;220C
+notelement;2209
+notelementof;2209
+notequal;2260
+notgreater;226F
+notgreaternorequal;2271
+notgreaternorless;2279
+notidentical;2262
+notless;226E
+notlessnorequal;2270
+notparallel;2226
+notprecedes;2280
+notsubset;2284
+notsucceeds;2281
+notsuperset;2285
+nowarmenian;0576
+nparen;24A9
+nssquare;33B1
+nsuperior;207F
+ntilde;00F1
+nu;03BD
+nuhiragana;306C
+nukatakana;30CC
+nukatakanahalfwidth;FF87
+nuktabengali;09BC
+nuktadeva;093C
+nuktagujarati;0ABC
+nuktagurmukhi;0A3C
+numbersign;0023
+numbersignmonospace;FF03
+numbersignsmall;FE5F
+numeralsigngreek;0374
+numeralsignlowergreek;0375
+numero;2116
+nun;05E0
+nundagesh;FB40
+nundageshhebrew;FB40
+nunhebrew;05E0
+nvsquare;33B5
+nwsquare;33BB
+nyabengali;099E
+nyadeva;091E
+nyagujarati;0A9E
+nyagurmukhi;0A1E
+o;006F
+oacute;00F3
+oangthai;0E2D
+obarred;0275
+obarredcyrillic;04E9
+obarreddieresiscyrillic;04EB
+obengali;0993
+obopomofo;311B
+obreve;014F
+ocandradeva;0911
+ocandragujarati;0A91
+ocandravowelsigndeva;0949
+ocandravowelsigngujarati;0AC9
+ocaron;01D2
+ocircle;24DE
+ocircumflex;00F4
+ocircumflexacute;1ED1
+ocircumflexdotbelow;1ED9
+ocircumflexgrave;1ED3
+ocircumflexhookabove;1ED5
+ocircumflextilde;1ED7
+ocyrillic;043E
+odblacute;0151
+odblgrave;020D
+odeva;0913
+odieresis;00F6
+odieresiscyrillic;04E7
+odotbelow;1ECD
+oe;0153
+oekorean;315A
+ogonek;02DB
+ogonekcmb;0328
+ograve;00F2
+ogujarati;0A93
+oharmenian;0585
+ohiragana;304A
+ohookabove;1ECF
+ohorn;01A1
+ohornacute;1EDB
+ohorndotbelow;1EE3
+ohorngrave;1EDD
+ohornhookabove;1EDF
+ohorntilde;1EE1
+ohungarumlaut;0151
+oi;01A3
+oinvertedbreve;020F
+okatakana;30AA
+okatakanahalfwidth;FF75
+okorean;3157
+olehebrew;05AB
+omacron;014D
+omacronacute;1E53
+omacrongrave;1E51
+omdeva;0950
+omega;03C9
+omega1;03D6
+omegacyrillic;0461
+omegalatinclosed;0277
+omegaroundcyrillic;047B
+omegatitlocyrillic;047D
+omegatonos;03CE
+omgujarati;0AD0
+omicron;03BF
+omicrontonos;03CC
+omonospace;FF4F
+one;0031
+onearabic;0661
+onebengali;09E7
+onecircle;2460
+onecircleinversesansserif;278A
+onedeva;0967
+onedotenleader;2024
+oneeighth;215B
+onefitted;F6DC
+onegujarati;0AE7
+onegurmukhi;0A67
+onehackarabic;0661
+onehalf;00BD
+onehangzhou;3021
+oneideographicparen;3220
+oneinferior;2081
+onemonospace;FF11
+onenumeratorbengali;09F4
+oneoldstyle;F731
+oneparen;2474
+oneperiod;2488
+onepersian;06F1
+onequarter;00BC
+oneroman;2170
+onesuperior;00B9
+onethai;0E51
+onethird;2153
+oogonek;01EB
+oogonekmacron;01ED
+oogurmukhi;0A13
+oomatragurmukhi;0A4B
+oopen;0254
+oparen;24AA
+openbullet;25E6
+option;2325
+ordfeminine;00AA
+ordmasculine;00BA
+orthogonal;221F
+oshortdeva;0912
+oshortvowelsigndeva;094A
+oslash;00F8
+oslashacute;01FF
+osmallhiragana;3049
+osmallkatakana;30A9
+osmallkatakanahalfwidth;FF6B
+ostrokeacute;01FF
+osuperior;F6F0
+otcyrillic;047F
+otilde;00F5
+otildeacute;1E4D
+otildedieresis;1E4F
+oubopomofo;3121
+overline;203E
+overlinecenterline;FE4A
+overlinecmb;0305
+overlinedashed;FE49
+overlinedblwavy;FE4C
+overlinewavy;FE4B
+overscore;00AF
+ovowelsignbengali;09CB
+ovowelsigndeva;094B
+ovowelsigngujarati;0ACB
+p;0070
+paampssquare;3380
+paasentosquare;332B
+pabengali;09AA
+pacute;1E55
+padeva;092A
+pagedown;21DF
+pageup;21DE
+pagujarati;0AAA
+pagurmukhi;0A2A
+pahiragana;3071
+paiyannoithai;0E2F
+pakatakana;30D1
+palatalizationcyrilliccmb;0484
+palochkacyrillic;04C0
+pansioskorean;317F
+paragraph;00B6
+parallel;2225
+parenleft;0028
+parenleftaltonearabic;FD3E
+parenleftbt;F8ED
+parenleftex;F8EC
+parenleftinferior;208D
+parenleftmonospace;FF08
+parenleftsmall;FE59
+parenleftsuperior;207D
+parenlefttp;F8EB
+parenleftvertical;FE35
+parenright;0029
+parenrightaltonearabic;FD3F
+parenrightbt;F8F8
+parenrightex;F8F7
+parenrightinferior;208E
+parenrightmonospace;FF09
+parenrightsmall;FE5A
+parenrightsuperior;207E
+parenrighttp;F8F6
+parenrightvertical;FE36
+partialdiff;2202
+paseqhebrew;05C0
+pashtahebrew;0599
+pasquare;33A9
+patah;05B7
+patah11;05B7
+patah1d;05B7
+patah2a;05B7
+patahhebrew;05B7
+patahnarrowhebrew;05B7
+patahquarterhebrew;05B7
+patahwidehebrew;05B7
+pazerhebrew;05A1
+pbopomofo;3106
+pcircle;24DF
+pdotaccent;1E57
+pe;05E4
+pecyrillic;043F
+pedagesh;FB44
+pedageshhebrew;FB44
+peezisquare;333B
+pefinaldageshhebrew;FB43
+peharabic;067E
+peharmenian;057A
+pehebrew;05E4
+pehfinalarabic;FB57
+pehinitialarabic;FB58
+pehiragana;307A
+pehmedialarabic;FB59
+pekatakana;30DA
+pemiddlehookcyrillic;04A7
+perafehebrew;FB4E
+percent;0025
+percentarabic;066A
+percentmonospace;FF05
+percentsmall;FE6A
+period;002E
+periodarmenian;0589
+periodcentered;00B7
+periodhalfwidth;FF61
+periodinferior;F6E7
+periodmonospace;FF0E
+periodsmall;FE52
+periodsuperior;F6E8
+perispomenigreekcmb;0342
+perpendicular;22A5
+perthousand;2030
+peseta;20A7
+pfsquare;338A
+phabengali;09AB
+phadeva;092B
+phagujarati;0AAB
+phagurmukhi;0A2B
+phi;03C6
+phi1;03D5
+phieuphacirclekorean;327A
+phieuphaparenkorean;321A
+phieuphcirclekorean;326C
+phieuphkorean;314D
+phieuphparenkorean;320C
+philatin;0278
+phinthuthai;0E3A
+phisymbolgreek;03D5
+phook;01A5
+phophanthai;0E1E
+phophungthai;0E1C
+phosamphaothai;0E20
+pi;03C0
+pieupacirclekorean;3273
+pieupaparenkorean;3213
+pieupcieuckorean;3176
+pieupcirclekorean;3265
+pieupkiyeokkorean;3172
+pieupkorean;3142
+pieupparenkorean;3205
+pieupsioskiyeokkorean;3174
+pieupsioskorean;3144
+pieupsiostikeutkorean;3175
+pieupthieuthkorean;3177
+pieuptikeutkorean;3173
+pihiragana;3074
+pikatakana;30D4
+pisymbolgreek;03D6
+piwrarmenian;0583
+plus;002B
+plusbelowcmb;031F
+pluscircle;2295
+plusminus;00B1
+plusmod;02D6
+plusmonospace;FF0B
+plussmall;FE62
+plussuperior;207A
+pmonospace;FF50
+pmsquare;33D8
+pohiragana;307D
+pointingindexdownwhite;261F
+pointingindexleftwhite;261C
+pointingindexrightwhite;261E
+pointingindexupwhite;261D
+pokatakana;30DD
+poplathai;0E1B
+postalmark;3012
+postalmarkface;3020
+pparen;24AB
+precedes;227A
+prescription;211E
+primemod;02B9
+primereversed;2035
+product;220F
+projective;2305
+prolongedkana;30FC
+propellor;2318
+propersubset;2282
+propersuperset;2283
+proportion;2237
+proportional;221D
+psi;03C8
+psicyrillic;0471
+psilipneumatacyrilliccmb;0486
+pssquare;33B0
+puhiragana;3077
+pukatakana;30D7
+pvsquare;33B4
+pwsquare;33BA
+q;0071
+qadeva;0958
+qadmahebrew;05A8
+qafarabic;0642
+qaffinalarabic;FED6
+qafinitialarabic;FED7
+qafmedialarabic;FED8
+qamats;05B8
+qamats10;05B8
+qamats1a;05B8
+qamats1c;05B8
+qamats27;05B8
+qamats29;05B8
+qamats33;05B8
+qamatsde;05B8
+qamatshebrew;05B8
+qamatsnarrowhebrew;05B8
+qamatsqatanhebrew;05B8
+qamatsqatannarrowhebrew;05B8
+qamatsqatanquarterhebrew;05B8
+qamatsqatanwidehebrew;05B8
+qamatsquarterhebrew;05B8
+qamatswidehebrew;05B8
+qarneyparahebrew;059F
+qbopomofo;3111
+qcircle;24E0
+qhook;02A0
+qmonospace;FF51
+qof;05E7
+qofdagesh;FB47
+qofdageshhebrew;FB47
+qofhatafpatah;05E7 05B2
+qofhatafpatahhebrew;05E7 05B2
+qofhatafsegol;05E7 05B1
+qofhatafsegolhebrew;05E7 05B1
+qofhebrew;05E7
+qofhiriq;05E7 05B4
+qofhiriqhebrew;05E7 05B4
+qofholam;05E7 05B9
+qofholamhebrew;05E7 05B9
+qofpatah;05E7 05B7
+qofpatahhebrew;05E7 05B7
+qofqamats;05E7 05B8
+qofqamatshebrew;05E7 05B8
+qofqubuts;05E7 05BB
+qofqubutshebrew;05E7 05BB
+qofsegol;05E7 05B6
+qofsegolhebrew;05E7 05B6
+qofsheva;05E7 05B0
+qofshevahebrew;05E7 05B0
+qoftsere;05E7 05B5
+qoftserehebrew;05E7 05B5
+qparen;24AC
+quarternote;2669
+qubuts;05BB
+qubuts18;05BB
+qubuts25;05BB
+qubuts31;05BB
+qubutshebrew;05BB
+qubutsnarrowhebrew;05BB
+qubutsquarterhebrew;05BB
+qubutswidehebrew;05BB
+question;003F
+questionarabic;061F
+questionarmenian;055E
+questiondown;00BF
+questiondownsmall;F7BF
+questiongreek;037E
+questionmonospace;FF1F
+questionsmall;F73F
+quotedbl;0022
+quotedblbase;201E
+quotedblleft;201C
+quotedblmonospace;FF02
+quotedblprime;301E
+quotedblprimereversed;301D
+quotedblright;201D
+quoteleft;2018
+quoteleftreversed;201B
+quotereversed;201B
+quoteright;2019
+quoterightn;0149
+quotesinglbase;201A
+quotesingle;0027
+quotesinglemonospace;FF07
+r;0072
+raarmenian;057C
+rabengali;09B0
+racute;0155
+radeva;0930
+radical;221A
+radicalex;F8E5
+radoverssquare;33AE
+radoverssquaredsquare;33AF
+radsquare;33AD
+rafe;05BF
+rafehebrew;05BF
+ragujarati;0AB0
+ragurmukhi;0A30
+rahiragana;3089
+rakatakana;30E9
+rakatakanahalfwidth;FF97
+ralowerdiagonalbengali;09F1
+ramiddlediagonalbengali;09F0
+ramshorn;0264
+ratio;2236
+rbopomofo;3116
+rcaron;0159
+rcedilla;0157
+rcircle;24E1
+rcommaaccent;0157
+rdblgrave;0211
+rdotaccent;1E59
+rdotbelow;1E5B
+rdotbelowmacron;1E5D
+referencemark;203B
+reflexsubset;2286
+reflexsuperset;2287
+registered;00AE
+registersans;F8E8
+registerserif;F6DA
+reharabic;0631
+reharmenian;0580
+rehfinalarabic;FEAE
+rehiragana;308C
+rehyehaleflamarabic;0631 FEF3 FE8E 0644
+rekatakana;30EC
+rekatakanahalfwidth;FF9A
+resh;05E8
+reshdageshhebrew;FB48
+reshhatafpatah;05E8 05B2
+reshhatafpatahhebrew;05E8 05B2
+reshhatafsegol;05E8 05B1
+reshhatafsegolhebrew;05E8 05B1
+reshhebrew;05E8
+reshhiriq;05E8 05B4
+reshhiriqhebrew;05E8 05B4
+reshholam;05E8 05B9
+reshholamhebrew;05E8 05B9
+reshpatah;05E8 05B7
+reshpatahhebrew;05E8 05B7
+reshqamats;05E8 05B8
+reshqamatshebrew;05E8 05B8
+reshqubuts;05E8 05BB
+reshqubutshebrew;05E8 05BB
+reshsegol;05E8 05B6
+reshsegolhebrew;05E8 05B6
+reshsheva;05E8 05B0
+reshshevahebrew;05E8 05B0
+reshtsere;05E8 05B5
+reshtserehebrew;05E8 05B5
+reversedtilde;223D
+reviahebrew;0597
+reviamugrashhebrew;0597
+revlogicalnot;2310
+rfishhook;027E
+rfishhookreversed;027F
+rhabengali;09DD
+rhadeva;095D
+rho;03C1
+rhook;027D
+rhookturned;027B
+rhookturnedsuperior;02B5
+rhosymbolgreek;03F1
+rhotichookmod;02DE
+rieulacirclekorean;3271
+rieulaparenkorean;3211
+rieulcirclekorean;3263
+rieulhieuhkorean;3140
+rieulkiyeokkorean;313A
+rieulkiyeoksioskorean;3169
+rieulkorean;3139
+rieulmieumkorean;313B
+rieulpansioskorean;316C
+rieulparenkorean;3203
+rieulphieuphkorean;313F
+rieulpieupkorean;313C
+rieulpieupsioskorean;316B
+rieulsioskorean;313D
+rieulthieuthkorean;313E
+rieultikeutkorean;316A
+rieulyeorinhieuhkorean;316D
+rightangle;221F
+righttackbelowcmb;0319
+righttriangle;22BF
+rihiragana;308A
+rikatakana;30EA
+rikatakanahalfwidth;FF98
+ring;02DA
+ringbelowcmb;0325
+ringcmb;030A
+ringhalfleft;02BF
+ringhalfleftarmenian;0559
+ringhalfleftbelowcmb;031C
+ringhalfleftcentered;02D3
+ringhalfright;02BE
+ringhalfrightbelowcmb;0339
+ringhalfrightcentered;02D2
+rinvertedbreve;0213
+rittorusquare;3351
+rlinebelow;1E5F
+rlongleg;027C
+rlonglegturned;027A
+rmonospace;FF52
+rohiragana;308D
+rokatakana;30ED
+rokatakanahalfwidth;FF9B
+roruathai;0E23
+rparen;24AD
+rrabengali;09DC
+rradeva;0931
+rragurmukhi;0A5C
+rreharabic;0691
+rrehfinalarabic;FB8D
+rrvocalicbengali;09E0
+rrvocalicdeva;0960
+rrvocalicgujarati;0AE0
+rrvocalicvowelsignbengali;09C4
+rrvocalicvowelsigndeva;0944
+rrvocalicvowelsigngujarati;0AC4
+rsuperior;F6F1
+rtblock;2590
+rturned;0279
+rturnedsuperior;02B4
+ruhiragana;308B
+rukatakana;30EB
+rukatakanahalfwidth;FF99
+rupeemarkbengali;09F2
+rupeesignbengali;09F3
+rupiah;F6DD
+ruthai;0E24
+rvocalicbengali;098B
+rvocalicdeva;090B
+rvocalicgujarati;0A8B
+rvocalicvowelsignbengali;09C3
+rvocalicvowelsigndeva;0943
+rvocalicvowelsigngujarati;0AC3
+s;0073
+sabengali;09B8
+sacute;015B
+sacutedotaccent;1E65
+sadarabic;0635
+sadeva;0938
+sadfinalarabic;FEBA
+sadinitialarabic;FEBB
+sadmedialarabic;FEBC
+sagujarati;0AB8
+sagurmukhi;0A38
+sahiragana;3055
+sakatakana;30B5
+sakatakanahalfwidth;FF7B
+sallallahoualayhewasallamarabic;FDFA
+samekh;05E1
+samekhdagesh;FB41
+samekhdageshhebrew;FB41
+samekhhebrew;05E1
+saraaathai;0E32
+saraaethai;0E41
+saraaimaimalaithai;0E44
+saraaimaimuanthai;0E43
+saraamthai;0E33
+saraathai;0E30
+saraethai;0E40
+saraiileftthai;F886
+saraiithai;0E35
+saraileftthai;F885
+saraithai;0E34
+saraothai;0E42
+saraueeleftthai;F888
+saraueethai;0E37
+saraueleftthai;F887
+sarauethai;0E36
+sarauthai;0E38
+sarauuthai;0E39
+sbopomofo;3119
+scaron;0161
+scarondotaccent;1E67
+scedilla;015F
+schwa;0259
+schwacyrillic;04D9
+schwadieresiscyrillic;04DB
+schwahook;025A
+scircle;24E2
+scircumflex;015D
+scommaaccent;0219
+sdotaccent;1E61
+sdotbelow;1E63
+sdotbelowdotaccent;1E69
+seagullbelowcmb;033C
+second;2033
+secondtonechinese;02CA
+section;00A7
+seenarabic;0633
+seenfinalarabic;FEB2
+seeninitialarabic;FEB3
+seenmedialarabic;FEB4
+segol;05B6
+segol13;05B6
+segol1f;05B6
+segol2c;05B6
+segolhebrew;05B6
+segolnarrowhebrew;05B6
+segolquarterhebrew;05B6
+segoltahebrew;0592
+segolwidehebrew;05B6
+seharmenian;057D
+sehiragana;305B
+sekatakana;30BB
+sekatakanahalfwidth;FF7E
+semicolon;003B
+semicolonarabic;061B
+semicolonmonospace;FF1B
+semicolonsmall;FE54
+semivoicedmarkkana;309C
+semivoicedmarkkanahalfwidth;FF9F
+sentisquare;3322
+sentosquare;3323
+seven;0037
+sevenarabic;0667
+sevenbengali;09ED
+sevencircle;2466
+sevencircleinversesansserif;2790
+sevendeva;096D
+seveneighths;215E
+sevengujarati;0AED
+sevengurmukhi;0A6D
+sevenhackarabic;0667
+sevenhangzhou;3027
+sevenideographicparen;3226
+seveninferior;2087
+sevenmonospace;FF17
+sevenoldstyle;F737
+sevenparen;247A
+sevenperiod;248E
+sevenpersian;06F7
+sevenroman;2176
+sevensuperior;2077
+seventeencircle;2470
+seventeenparen;2484
+seventeenperiod;2498
+seventhai;0E57
+sfthyphen;00AD
+shaarmenian;0577
+shabengali;09B6
+shacyrillic;0448
+shaddaarabic;0651
+shaddadammaarabic;FC61
+shaddadammatanarabic;FC5E
+shaddafathaarabic;FC60
+shaddafathatanarabic;0651 064B
+shaddakasraarabic;FC62
+shaddakasratanarabic;FC5F
+shade;2592
+shadedark;2593
+shadelight;2591
+shademedium;2592
+shadeva;0936
+shagujarati;0AB6
+shagurmukhi;0A36
+shalshelethebrew;0593
+shbopomofo;3115
+shchacyrillic;0449
+sheenarabic;0634
+sheenfinalarabic;FEB6
+sheeninitialarabic;FEB7
+sheenmedialarabic;FEB8
+sheicoptic;03E3
+sheqel;20AA
+sheqelhebrew;20AA
+sheva;05B0
+sheva115;05B0
+sheva15;05B0
+sheva22;05B0
+sheva2e;05B0
+shevahebrew;05B0
+shevanarrowhebrew;05B0
+shevaquarterhebrew;05B0
+shevawidehebrew;05B0
+shhacyrillic;04BB
+shimacoptic;03ED
+shin;05E9
+shindagesh;FB49
+shindageshhebrew;FB49
+shindageshshindot;FB2C
+shindageshshindothebrew;FB2C
+shindageshsindot;FB2D
+shindageshsindothebrew;FB2D
+shindothebrew;05C1
+shinhebrew;05E9
+shinshindot;FB2A
+shinshindothebrew;FB2A
+shinsindot;FB2B
+shinsindothebrew;FB2B
+shook;0282
+sigma;03C3
+sigma1;03C2
+sigmafinal;03C2
+sigmalunatesymbolgreek;03F2
+sihiragana;3057
+sikatakana;30B7
+sikatakanahalfwidth;FF7C
+siluqhebrew;05BD
+siluqlefthebrew;05BD
+similar;223C
+sindothebrew;05C2
+siosacirclekorean;3274
+siosaparenkorean;3214
+sioscieuckorean;317E
+sioscirclekorean;3266
+sioskiyeokkorean;317A
+sioskorean;3145
+siosnieunkorean;317B
+siosparenkorean;3206
+siospieupkorean;317D
+siostikeutkorean;317C
+six;0036
+sixarabic;0666
+sixbengali;09EC
+sixcircle;2465
+sixcircleinversesansserif;278F
+sixdeva;096C
+sixgujarati;0AEC
+sixgurmukhi;0A6C
+sixhackarabic;0666
+sixhangzhou;3026
+sixideographicparen;3225
+sixinferior;2086
+sixmonospace;FF16
+sixoldstyle;F736
+sixparen;2479
+sixperiod;248D
+sixpersian;06F6
+sixroman;2175
+sixsuperior;2076
+sixteencircle;246F
+sixteencurrencydenominatorbengali;09F9
+sixteenparen;2483
+sixteenperiod;2497
+sixthai;0E56
+slash;002F
+slashmonospace;FF0F
+slong;017F
+slongdotaccent;1E9B
+smileface;263A
+smonospace;FF53
+sofpasuqhebrew;05C3
+softhyphen;00AD
+softsigncyrillic;044C
+sohiragana;305D
+sokatakana;30BD
+sokatakanahalfwidth;FF7F
+soliduslongoverlaycmb;0338
+solidusshortoverlaycmb;0337
+sorusithai;0E29
+sosalathai;0E28
+sosothai;0E0B
+sosuathai;0E2A
+space;0020
+spacehackarabic;0020
+spade;2660
+spadesuitblack;2660
+spadesuitwhite;2664
+sparen;24AE
+squarebelowcmb;033B
+squarecc;33C4
+squarecm;339D
+squarediagonalcrosshatchfill;25A9
+squarehorizontalfill;25A4
+squarekg;338F
+squarekm;339E
+squarekmcapital;33CE
+squareln;33D1
+squarelog;33D2
+squaremg;338E
+squaremil;33D5
+squaremm;339C
+squaremsquared;33A1
+squareorthogonalcrosshatchfill;25A6
+squareupperlefttolowerrightfill;25A7
+squareupperrighttolowerleftfill;25A8
+squareverticalfill;25A5
+squarewhitewithsmallblack;25A3
+srsquare;33DB
+ssabengali;09B7
+ssadeva;0937
+ssagujarati;0AB7
+ssangcieuckorean;3149
+ssanghieuhkorean;3185
+ssangieungkorean;3180
+ssangkiyeokkorean;3132
+ssangnieunkorean;3165
+ssangpieupkorean;3143
+ssangsioskorean;3146
+ssangtikeutkorean;3138
+ssuperior;F6F2
+sterling;00A3
+sterlingmonospace;FFE1
+strokelongoverlaycmb;0336
+strokeshortoverlaycmb;0335
+subset;2282
+subsetnotequal;228A
+subsetorequal;2286
+succeeds;227B
+suchthat;220B
+suhiragana;3059
+sukatakana;30B9
+sukatakanahalfwidth;FF7D
+sukunarabic;0652
+summation;2211
+sun;263C
+superset;2283
+supersetnotequal;228B
+supersetorequal;2287
+svsquare;33DC
+syouwaerasquare;337C
+t;0074
+tabengali;09A4
+tackdown;22A4
+tackleft;22A3
+tadeva;0924
+tagujarati;0AA4
+tagurmukhi;0A24
+taharabic;0637
+tahfinalarabic;FEC2
+tahinitialarabic;FEC3
+tahiragana;305F
+tahmedialarabic;FEC4
+taisyouerasquare;337D
+takatakana;30BF
+takatakanahalfwidth;FF80
+tatweelarabic;0640
+tau;03C4
+tav;05EA
+tavdages;FB4A
+tavdagesh;FB4A
+tavdageshhebrew;FB4A
+tavhebrew;05EA
+tbar;0167
+tbopomofo;310A
+tcaron;0165
+tccurl;02A8
+tcedilla;0163
+tcheharabic;0686
+tchehfinalarabic;FB7B
+tchehinitialarabic;FB7C
+tchehmedialarabic;FB7D
+tchehmeeminitialarabic;FB7C FEE4
+tcircle;24E3
+tcircumflexbelow;1E71
+tcommaaccent;0163
+tdieresis;1E97
+tdotaccent;1E6B
+tdotbelow;1E6D
+tecyrillic;0442
+tedescendercyrillic;04AD
+teharabic;062A
+tehfinalarabic;FE96
+tehhahinitialarabic;FCA2
+tehhahisolatedarabic;FC0C
+tehinitialarabic;FE97
+tehiragana;3066
+tehjeeminitialarabic;FCA1
+tehjeemisolatedarabic;FC0B
+tehmarbutaarabic;0629
+tehmarbutafinalarabic;FE94
+tehmedialarabic;FE98
+tehmeeminitialarabic;FCA4
+tehmeemisolatedarabic;FC0E
+tehnoonfinalarabic;FC73
+tekatakana;30C6
+tekatakanahalfwidth;FF83
+telephone;2121
+telephoneblack;260E
+telishagedolahebrew;05A0
+telishaqetanahebrew;05A9
+tencircle;2469
+tenideographicparen;3229
+tenparen;247D
+tenperiod;2491
+tenroman;2179
+tesh;02A7
+tet;05D8
+tetdagesh;FB38
+tetdageshhebrew;FB38
+tethebrew;05D8
+tetsecyrillic;04B5
+tevirhebrew;059B
+tevirlefthebrew;059B
+thabengali;09A5
+thadeva;0925
+thagujarati;0AA5
+thagurmukhi;0A25
+thalarabic;0630
+thalfinalarabic;FEAC
+thanthakhatlowleftthai;F898
+thanthakhatlowrightthai;F897
+thanthakhatthai;0E4C
+thanthakhatupperleftthai;F896
+theharabic;062B
+thehfinalarabic;FE9A
+thehinitialarabic;FE9B
+thehmedialarabic;FE9C
+thereexists;2203
+therefore;2234
+theta;03B8
+theta1;03D1
+thetasymbolgreek;03D1
+thieuthacirclekorean;3279
+thieuthaparenkorean;3219
+thieuthcirclekorean;326B
+thieuthkorean;314C
+thieuthparenkorean;320B
+thirteencircle;246C
+thirteenparen;2480
+thirteenperiod;2494
+thonangmonthothai;0E11
+thook;01AD
+thophuthaothai;0E12
+thorn;00FE
+thothahanthai;0E17
+thothanthai;0E10
+thothongthai;0E18
+thothungthai;0E16
+thousandcyrillic;0482
+thousandsseparatorarabic;066C
+thousandsseparatorpersian;066C
+three;0033
+threearabic;0663
+threebengali;09E9
+threecircle;2462
+threecircleinversesansserif;278C
+threedeva;0969
+threeeighths;215C
+threegujarati;0AE9
+threegurmukhi;0A69
+threehackarabic;0663
+threehangzhou;3023
+threeideographicparen;3222
+threeinferior;2083
+threemonospace;FF13
+threenumeratorbengali;09F6
+threeoldstyle;F733
+threeparen;2476
+threeperiod;248A
+threepersian;06F3
+threequarters;00BE
+threequartersemdash;F6DE
+threeroman;2172
+threesuperior;00B3
+threethai;0E53
+thzsquare;3394
+tihiragana;3061
+tikatakana;30C1
+tikatakanahalfwidth;FF81
+tikeutacirclekorean;3270
+tikeutaparenkorean;3210
+tikeutcirclekorean;3262
+tikeutkorean;3137
+tikeutparenkorean;3202
+tilde;02DC
+tildebelowcmb;0330
+tildecmb;0303
+tildecomb;0303
+tildedoublecmb;0360
+tildeoperator;223C
+tildeoverlaycmb;0334
+tildeverticalcmb;033E
+timescircle;2297
+tipehahebrew;0596
+tipehalefthebrew;0596
+tippigurmukhi;0A70
+titlocyrilliccmb;0483
+tiwnarmenian;057F
+tlinebelow;1E6F
+tmonospace;FF54
+toarmenian;0569
+tohiragana;3068
+tokatakana;30C8
+tokatakanahalfwidth;FF84
+tonebarextrahighmod;02E5
+tonebarextralowmod;02E9
+tonebarhighmod;02E6
+tonebarlowmod;02E8
+tonebarmidmod;02E7
+tonefive;01BD
+tonesix;0185
+tonetwo;01A8
+tonos;0384
+tonsquare;3327
+topatakthai;0E0F
+tortoiseshellbracketleft;3014
+tortoiseshellbracketleftsmall;FE5D
+tortoiseshellbracketleftvertical;FE39
+tortoiseshellbracketright;3015
+tortoiseshellbracketrightsmall;FE5E
+tortoiseshellbracketrightvertical;FE3A
+totaothai;0E15
+tpalatalhook;01AB
+tparen;24AF
+trademark;2122
+trademarksans;F8EA
+trademarkserif;F6DB
+tretroflexhook;0288
+triagdn;25BC
+triaglf;25C4
+triagrt;25BA
+triagup;25B2
+ts;02A6
+tsadi;05E6
+tsadidagesh;FB46
+tsadidageshhebrew;FB46
+tsadihebrew;05E6
+tsecyrillic;0446
+tsere;05B5
+tsere12;05B5
+tsere1e;05B5
+tsere2b;05B5
+tserehebrew;05B5
+tserenarrowhebrew;05B5
+tserequarterhebrew;05B5
+tserewidehebrew;05B5
+tshecyrillic;045B
+tsuperior;F6F3
+ttabengali;099F
+ttadeva;091F
+ttagujarati;0A9F
+ttagurmukhi;0A1F
+tteharabic;0679
+ttehfinalarabic;FB67
+ttehinitialarabic;FB68
+ttehmedialarabic;FB69
+tthabengali;09A0
+tthadeva;0920
+tthagujarati;0AA0
+tthagurmukhi;0A20
+tturned;0287
+tuhiragana;3064
+tukatakana;30C4
+tukatakanahalfwidth;FF82
+tusmallhiragana;3063
+tusmallkatakana;30C3
+tusmallkatakanahalfwidth;FF6F
+twelvecircle;246B
+twelveparen;247F
+twelveperiod;2493
+twelveroman;217B
+twentycircle;2473
+twentyhangzhou;5344
+twentyparen;2487
+twentyperiod;249B
+two;0032
+twoarabic;0662
+twobengali;09E8
+twocircle;2461
+twocircleinversesansserif;278B
+twodeva;0968
+twodotenleader;2025
+twodotleader;2025
+twodotleadervertical;FE30
+twogujarati;0AE8
+twogurmukhi;0A68
+twohackarabic;0662
+twohangzhou;3022
+twoideographicparen;3221
+twoinferior;2082
+twomonospace;FF12
+twonumeratorbengali;09F5
+twooldstyle;F732
+twoparen;2475
+twoperiod;2489
+twopersian;06F2
+tworoman;2171
+twostroke;01BB
+twosuperior;00B2
+twothai;0E52
+twothirds;2154
+u;0075
+uacute;00FA
+ubar;0289
+ubengali;0989
+ubopomofo;3128
+ubreve;016D
+ucaron;01D4
+ucircle;24E4
+ucircumflex;00FB
+ucircumflexbelow;1E77
+ucyrillic;0443
+udattadeva;0951
+udblacute;0171
+udblgrave;0215
+udeva;0909
+udieresis;00FC
+udieresisacute;01D8
+udieresisbelow;1E73
+udieresiscaron;01DA
+udieresiscyrillic;04F1
+udieresisgrave;01DC
+udieresismacron;01D6
+udotbelow;1EE5
+ugrave;00F9
+ugujarati;0A89
+ugurmukhi;0A09
+uhiragana;3046
+uhookabove;1EE7
+uhorn;01B0
+uhornacute;1EE9
+uhorndotbelow;1EF1
+uhorngrave;1EEB
+uhornhookabove;1EED
+uhorntilde;1EEF
+uhungarumlaut;0171
+uhungarumlautcyrillic;04F3
+uinvertedbreve;0217
+ukatakana;30A6
+ukatakanahalfwidth;FF73
+ukcyrillic;0479
+ukorean;315C
+umacron;016B
+umacroncyrillic;04EF
+umacrondieresis;1E7B
+umatragurmukhi;0A41
+umonospace;FF55
+underscore;005F
+underscoredbl;2017
+underscoremonospace;FF3F
+underscorevertical;FE33
+underscorewavy;FE4F
+union;222A
+universal;2200
+uogonek;0173
+uparen;24B0
+upblock;2580
+upperdothebrew;05C4
+upsilon;03C5
+upsilondieresis;03CB
+upsilondieresistonos;03B0
+upsilonlatin;028A
+upsilontonos;03CD
+uptackbelowcmb;031D
+uptackmod;02D4
+uragurmukhi;0A73
+uring;016F
+ushortcyrillic;045E
+usmallhiragana;3045
+usmallkatakana;30A5
+usmallkatakanahalfwidth;FF69
+ustraightcyrillic;04AF
+ustraightstrokecyrillic;04B1
+utilde;0169
+utildeacute;1E79
+utildebelow;1E75
+uubengali;098A
+uudeva;090A
+uugujarati;0A8A
+uugurmukhi;0A0A
+uumatragurmukhi;0A42
+uuvowelsignbengali;09C2
+uuvowelsigndeva;0942
+uuvowelsigngujarati;0AC2
+uvowelsignbengali;09C1
+uvowelsigndeva;0941
+uvowelsigngujarati;0AC1
+v;0076
+vadeva;0935
+vagujarati;0AB5
+vagurmukhi;0A35
+vakatakana;30F7
+vav;05D5
+vavdagesh;FB35
+vavdagesh65;FB35
+vavdageshhebrew;FB35
+vavhebrew;05D5
+vavholam;FB4B
+vavholamhebrew;FB4B
+vavvavhebrew;05F0
+vavyodhebrew;05F1
+vcircle;24E5
+vdotbelow;1E7F
+vecyrillic;0432
+veharabic;06A4
+vehfinalarabic;FB6B
+vehinitialarabic;FB6C
+vehmedialarabic;FB6D
+vekatakana;30F9
+venus;2640
+verticalbar;007C
+verticallineabovecmb;030D
+verticallinebelowcmb;0329
+verticallinelowmod;02CC
+verticallinemod;02C8
+vewarmenian;057E
+vhook;028B
+vikatakana;30F8
+viramabengali;09CD
+viramadeva;094D
+viramagujarati;0ACD
+visargabengali;0983
+visargadeva;0903
+visargagujarati;0A83
+vmonospace;FF56
+voarmenian;0578
+voicediterationhiragana;309E
+voicediterationkatakana;30FE
+voicedmarkkana;309B
+voicedmarkkanahalfwidth;FF9E
+vokatakana;30FA
+vparen;24B1
+vtilde;1E7D
+vturned;028C
+vuhiragana;3094
+vukatakana;30F4
+w;0077
+wacute;1E83
+waekorean;3159
+wahiragana;308F
+wakatakana;30EF
+wakatakanahalfwidth;FF9C
+wakorean;3158
+wasmallhiragana;308E
+wasmallkatakana;30EE
+wattosquare;3357
+wavedash;301C
+wavyunderscorevertical;FE34
+wawarabic;0648
+wawfinalarabic;FEEE
+wawhamzaabovearabic;0624
+wawhamzaabovefinalarabic;FE86
+wbsquare;33DD
+wcircle;24E6
+wcircumflex;0175
+wdieresis;1E85
+wdotaccent;1E87
+wdotbelow;1E89
+wehiragana;3091
+weierstrass;2118
+wekatakana;30F1
+wekorean;315E
+weokorean;315D
+wgrave;1E81
+whitebullet;25E6
+whitecircle;25CB
+whitecircleinverse;25D9
+whitecornerbracketleft;300E
+whitecornerbracketleftvertical;FE43
+whitecornerbracketright;300F
+whitecornerbracketrightvertical;FE44
+whitediamond;25C7
+whitediamondcontainingblacksmalldiamond;25C8
+whitedownpointingsmalltriangle;25BF
+whitedownpointingtriangle;25BD
+whiteleftpointingsmalltriangle;25C3
+whiteleftpointingtriangle;25C1
+whitelenticularbracketleft;3016
+whitelenticularbracketright;3017
+whiterightpointingsmalltriangle;25B9
+whiterightpointingtriangle;25B7
+whitesmallsquare;25AB
+whitesmilingface;263A
+whitesquare;25A1
+whitestar;2606
+whitetelephone;260F
+whitetortoiseshellbracketleft;3018
+whitetortoiseshellbracketright;3019
+whiteuppointingsmalltriangle;25B5
+whiteuppointingtriangle;25B3
+wihiragana;3090
+wikatakana;30F0
+wikorean;315F
+wmonospace;FF57
+wohiragana;3092
+wokatakana;30F2
+wokatakanahalfwidth;FF66
+won;20A9
+wonmonospace;FFE6
+wowaenthai;0E27
+wparen;24B2
+wring;1E98
+wsuperior;02B7
+wturned;028D
+wynn;01BF
+x;0078
+xabovecmb;033D
+xbopomofo;3112
+xcircle;24E7
+xdieresis;1E8D
+xdotaccent;1E8B
+xeharmenian;056D
+xi;03BE
+xmonospace;FF58
+xparen;24B3
+xsuperior;02E3
+y;0079
+yaadosquare;334E
+yabengali;09AF
+yacute;00FD
+yadeva;092F
+yaekorean;3152
+yagujarati;0AAF
+yagurmukhi;0A2F
+yahiragana;3084
+yakatakana;30E4
+yakatakanahalfwidth;FF94
+yakorean;3151
+yamakkanthai;0E4E
+yasmallhiragana;3083
+yasmallkatakana;30E3
+yasmallkatakanahalfwidth;FF6C
+yatcyrillic;0463
+ycircle;24E8
+ycircumflex;0177
+ydieresis;00FF
+ydotaccent;1E8F
+ydotbelow;1EF5
+yeharabic;064A
+yehbarreearabic;06D2
+yehbarreefinalarabic;FBAF
+yehfinalarabic;FEF2
+yehhamzaabovearabic;0626
+yehhamzaabovefinalarabic;FE8A
+yehhamzaaboveinitialarabic;FE8B
+yehhamzaabovemedialarabic;FE8C
+yehinitialarabic;FEF3
+yehmedialarabic;FEF4
+yehmeeminitialarabic;FCDD
+yehmeemisolatedarabic;FC58
+yehnoonfinalarabic;FC94
+yehthreedotsbelowarabic;06D1
+yekorean;3156
+yen;00A5
+yenmonospace;FFE5
+yeokorean;3155
+yeorinhieuhkorean;3186
+yerahbenyomohebrew;05AA
+yerahbenyomolefthebrew;05AA
+yericyrillic;044B
+yerudieresiscyrillic;04F9
+yesieungkorean;3181
+yesieungpansioskorean;3183
+yesieungsioskorean;3182
+yetivhebrew;059A
+ygrave;1EF3
+yhook;01B4
+yhookabove;1EF7
+yiarmenian;0575
+yicyrillic;0457
+yikorean;3162
+yinyang;262F
+yiwnarmenian;0582
+ymonospace;FF59
+yod;05D9
+yoddagesh;FB39
+yoddageshhebrew;FB39
+yodhebrew;05D9
+yodyodhebrew;05F2
+yodyodpatahhebrew;FB1F
+yohiragana;3088
+yoikorean;3189
+yokatakana;30E8
+yokatakanahalfwidth;FF96
+yokorean;315B
+yosmallhiragana;3087
+yosmallkatakana;30E7
+yosmallkatakanahalfwidth;FF6E
+yotgreek;03F3
+yoyaekorean;3188
+yoyakorean;3187
+yoyakthai;0E22
+yoyingthai;0E0D
+yparen;24B4
+ypogegrammeni;037A
+ypogegrammenigreekcmb;0345
+yr;01A6
+yring;1E99
+ysuperior;02B8
+ytilde;1EF9
+yturned;028E
+yuhiragana;3086
+yuikorean;318C
+yukatakana;30E6
+yukatakanahalfwidth;FF95
+yukorean;3160
+yusbigcyrillic;046B
+yusbigiotifiedcyrillic;046D
+yuslittlecyrillic;0467
+yuslittleiotifiedcyrillic;0469
+yusmallhiragana;3085
+yusmallkatakana;30E5
+yusmallkatakanahalfwidth;FF6D
+yuyekorean;318B
+yuyeokorean;318A
+yyabengali;09DF
+yyadeva;095F
+z;007A
+zaarmenian;0566
+zacute;017A
+zadeva;095B
+zagurmukhi;0A5B
+zaharabic;0638
+zahfinalarabic;FEC6
+zahinitialarabic;FEC7
+zahiragana;3056
+zahmedialarabic;FEC8
+zainarabic;0632
+zainfinalarabic;FEB0
+zakatakana;30B6
+zaqefgadolhebrew;0595
+zaqefqatanhebrew;0594
+zarqahebrew;0598
+zayin;05D6
+zayindagesh;FB36
+zayindageshhebrew;FB36
+zayinhebrew;05D6
+zbopomofo;3117
+zcaron;017E
+zcircle;24E9
+zcircumflex;1E91
+zcurl;0291
+zdot;017C
+zdotaccent;017C
+zdotbelow;1E93
+zecyrillic;0437
+zedescendercyrillic;0499
+zedieresiscyrillic;04DF
+zehiragana;305C
+zekatakana;30BC
+zero;0030
+zeroarabic;0660
+zerobengali;09E6
+zerodeva;0966
+zerogujarati;0AE6
+zerogurmukhi;0A66
+zerohackarabic;0660
+zeroinferior;2080
+zeromonospace;FF10
+zerooldstyle;F730
+zeropersian;06F0
+zerosuperior;2070
+zerothai;0E50
+zerowidthjoiner;FEFF
+zerowidthnonjoiner;200C
+zerowidthspace;200B
+zeta;03B6
+zhbopomofo;3113
+zhearmenian;056A
+zhebrevecyrillic;04C2
+zhecyrillic;0436
+zhedescendercyrillic;0497
+zhedieresiscyrillic;04DD
+zihiragana;3058
+zikatakana;30B8
+zinorhebrew;05AE
+zlinebelow;1E95
+zmonospace;FF5A
+zohiragana;305E
+zokatakana;30BE
+zparen;24B5
+zretroflexhook;0290
+zstroke;01B6
+zuhiragana;305A
+zukatakana;30BA
+#--end
+#
+# Name: Adobe Glyph List
+# Table version: 1.2
+# Date: 22 Oct 1998
+#
+# Description:
+#
+# The Adobe Glyph List (AGL) list relates Unicode values (UVs) to glyph
+# names, and should be used only as described in the document "Unicode and
+# Glyph Names," at
+# http://partners.adobe.com/asn/developer/typeforum/unicodegn.html .
+#
+# The glyph name to UV relation is one to many. 12 glyph names are mapped to
+# two UVs each; each UV has a separate entry. All other glyph names are
+# mapped to one UV each.
+#
+# The Unicode Standard version 2.1 is used for all UVs outside of the Private
+# Use area, except for 4 entries (see Revision History for 1.2 below).
+#
+# There are 1051 entries in this list, 171 of which are in the Corporate Use
+# subarea (CUS). Refer to the document "Unicode Corporate Use Subarea as used
+# by Adobe Systems," at
+# http://partners.adobe.com/asn/developer/typeforum/corporateuse.txt
+# for compatibility decompositions for these characters, and to the document
+# "Unicode and Glyph Names" for more information the CUS.
+#
+# Format: Semicolon-delimited fields:
+#
+# (1) Standard UV or CUS UV. (4 uppercase hexadecimal digits)
+#
+# (2) Glyph name. (upper- and lowercase letters, digits)
+#
+# (3) Character names: Unicode character names for standard UVs, and
+# descriptive names for CUS UVs. (uppercase letters, hyphen, space)
+#
+# (4) [optional] Comment. A comment of "Duplicate" indicates one of two
+# UVs of a double-mapping. It is the UV that may be given a uni
+# override, or the UV that is in the CUS, as described in the document
+# "Unicode and Glyph Names."
+#
+# The entries are sorted by glyph name in increasing ASCII order; entries
+# with the same glyph name are sorted in decreasing priority order.
+#
+# Lines starting with "#" are comments; blank lines should be ignored.
+#
+# Revision History:
+#
+# 1.2 [22 Oct 1998]
+#
+# Some Central European glyph names were remapped and the glyph "dotlessj"
+# was added. Some entries in the table below have not changed but are
+# included to provide a complete context for other glyphs that have been
+# remapped or double-mapped. "-" means that the entry for that UV does not
+# exist in the AGL.
+#
+# -------- ---------------------- ---------------- --------------
+# UV Character name AGL 1.1 AGL 1.2
+# (shortened) glyph name glyph name
+# -------- ---------------------- ---------------- --------------
+# 015E/F S/s with cedilla S/scommaaccent S/scedilla
+# 0162/3 T/t with cedilla T/tcommaaccent T/tcommaaccent
+# 0218/9 S/s with comma below - S/scommaaccent
+# 021A/B T/t with comma below - T/tcommaaccent
+# 1E9E/F S/s with comma below S/scedilla -
+# F6C1/2 S/s with cedilla S/scedilla S/scedilla
+# F6BE dotless j - dotlessj
+# -------- ---------------------- ---------------- --------------
+#
+# The characters at U+1E9E/F in AGL 1.1, LATIN CAPITAL/SMALL LETTER S WITH
+# COMMA BELOW, which are proposed new characters (see (b) in the notes for
+# AGL 1.1 below), have since been reassigned by the Unicode Standard to new
+# proposed values of U+0218/9. These characters, as well as U+021A/B, LATIN
+# CAPITAL/SMALL LETTER T WITH COMMA BELOW, are not in the Unicode Standard
+# 2.1.
+#
+# Entries with the same glyph name are now sorted in decreasing priority
+# order instead of in increasing UV order.
+#
+# 1.1 [24 Nov 1997]
+#
+# a. The "Euro" glyph's UV assignment is changed from U+20A0 (EURO-CURRENCY
+# SIGN) to U+20AC (EURO SIGN). While U+20AC is not defined in the
+# Unicode Standard 2.0, it has been accepted by the Unicode Technical
+# Committee for the next version of the Standard; it has not yet passed
+# the ISO approval process as of 7 November '97.
+#
+# b. Glyphs "Scedilla" and "scedilla", which were assigned in the Corporate
+# Use Subarea in AGL 1.0, are now additionally mapped to U+1E9E and
+# U+1E9F respectively. These two UVs share the same Unicode approval
+# status as the Euro glyph (see a. above).
+#
+# c. The "fraction" glyph is now additionally mapped to U+2215, to match
+# Windows Glyph List 4.
+#
+# d. The descriptive name for glyph "onefitted", in the Corporate Use
+# subarea, is changed from "TABULAR DIGIT ONE" to "PROPORTIONAL DIGIT
+# ONE".
+#
+# 1.0 [17 Jul 1997] Original version
+#
+A;0041
+AE;00C6
+AEacute;01FC
+AEsmall;F7E6
+Aacute;00C1
+Aacutesmall;F7E1
+Abreve;0102
+Acircumflex;00C2
+Acircumflexsmall;F7E2
+Acute;F6C9
+Acutesmall;F7B4
+Adieresis;00C4
+Adieresissmall;F7E4
+Agrave;00C0
+Agravesmall;F7E0
+Alpha;0391
+Alphatonos;0386
+Amacron;0100
+Aogonek;0104
+Aring;00C5
+Aringacute;01FA
+Aringsmall;F7E5
+Asmall;F761
+Atilde;00C3
+Atildesmall;F7E3
+B;0042
+Beta;0392
+Brevesmall;F6F4
+Bsmall;F762
+C;0043
+Cacute;0106
+Caron;F6CA
+Caronsmall;F6F5
+Ccaron;010C
+Ccedilla;00C7
+Ccedillasmall;F7E7
+Ccircumflex;0108
+Cdotaccent;010A
+Cedillasmall;F7B8
+Chi;03A7
+Circumflexsmall;F6F6
+Csmall;F763
+D;0044
+Dcaron;010E
+Dcroat;0110
+Delta;0394
+Dieresis;F6CB
+DieresisAcute;F6CC
+DieresisGrave;F6CD
+Dieresissmall;F7A8
+Dotaccentsmall;F6F7
+Dsmall;F764
+E;0045
+Eacute;00C9
+Eacutesmall;F7E9
+Ebreve;0114
+Ecaron;011A
+Ecircumflex;00CA
+Ecircumflexsmall;F7EA
+Edieresis;00CB
+Edieresissmall;F7EB
+Edotaccent;0116
+Egrave;00C8
+Egravesmall;F7E8
+Emacron;0112
+Eng;014A
+Eogonek;0118
+Epsilon;0395
+Epsilontonos;0388
+Esmall;F765
+Eta;0397
+Etatonos;0389
+Eth;00D0
+Ethsmall;F7F0
+Euro;20AC
+F;0046
+Fsmall;F766
+G;0047
+Gamma;0393
+Gbreve;011E
+Gcaron;01E6
+Gcircumflex;011C
+Gcommaaccent;0122
+Gdotaccent;0120
+Grave;F6CE
+Gravesmall;F760
+Gsmall;F767
+H;0048
+H18533;25CF
+H18543;25AA
+H18551;25AB
+H22073;25A1
+Hbar;0126
+Hcircumflex;0124
+Hsmall;F768
+Hungarumlaut;F6CF
+Hungarumlautsmall;F6F8
+I;0049
+IJ;0132
+Iacute;00CD
+Iacutesmall;F7ED
+Ibreve;012C
+Icircumflex;00CE
+Icircumflexsmall;F7EE
+Idieresis;00CF
+Idieresissmall;F7EF
+Idotaccent;0130
+Ifraktur;2111
+Igrave;00CC
+Igravesmall;F7EC
+Imacron;012A
+Iogonek;012E
+Iota;0399
+Iotadieresis;03AA
+Iotatonos;038A
+Ismall;F769
+Itilde;0128
+J;004A
+Jcircumflex;0134
+Jsmall;F76A
+K;004B
+Kappa;039A
+Kcommaaccent;0136
+Ksmall;F76B
+L;004C
+LL;F6BF
+Lacute;0139
+Lambda;039B
+Lcaron;013D
+Lcommaaccent;013B
+Ldot;013F
+Lslash;0141
+Lslashsmall;F6F9
+Lsmall;F76C
+M;004D
+Macron;F6D0
+Macronsmall;F7AF
+Msmall;F76D
+Mu;039C
+N;004E
+Nacute;0143
+Ncaron;0147
+Ncommaaccent;0145
+Nsmall;F76E
+Ntilde;00D1
+Ntildesmall;F7F1
+Nu;039D
+O;004F
+OE;0152
+OEsmall;F6FA
+Oacute;00D3
+Oacutesmall;F7F3
+Obreve;014E
+Ocircumflex;00D4
+Ocircumflexsmall;F7F4
+Odieresis;00D6
+Odieresissmall;F7F6
+Ogoneksmall;F6FB
+Ograve;00D2
+Ogravesmall;F7F2
+Ohorn;01A0
+Ohungarumlaut;0150
+Omacron;014C
+Omega;03A9
+Omegatonos;038F
+Omicron;039F
+Omicrontonos;038C
+Oslash;00D8
+Oslashacute;01FE
+Oslashsmall;F7F8
+Osmall;F76F
+Otilde;00D5
+Otildesmall;F7F5
+P;0050
+Phi;03A6
+Pi;03A0
+Psi;03A8
+Psmall;F770
+Q;0051
+Qsmall;F771
+R;0052
+Racute;0154
+Rcaron;0158
+Rcommaaccent;0156
+Rfraktur;211C
+Rho;03A1
+Ringsmall;F6FC
+Rsmall;F772
+S;0053
+SF010000;250C
+SF020000;2514
+SF030000;2510
+SF040000;2518
+SF050000;253C
+SF060000;252C
+SF070000;2534
+SF080000;251C
+SF090000;2524
+SF100000;2500
+SF110000;2502
+SF190000;2561
+SF200000;2562
+SF210000;2556
+SF220000;2555
+SF230000;2563
+SF240000;2551
+SF250000;2557
+SF260000;255D
+SF270000;255C
+SF280000;255B
+SF360000;255E
+SF370000;255F
+SF380000;255A
+SF390000;2554
+SF400000;2569
+SF410000;2566
+SF420000;2560
+SF430000;2550
+SF440000;256C
+SF450000;2567
+SF460000;2568
+SF470000;2564
+SF480000;2565
+SF490000;2559
+SF500000;2558
+SF510000;2552
+SF520000;2553
+SF530000;256B
+SF540000;256A
+Sacute;015A
+Scaron;0160
+Scaronsmall;F6FD
+Scedilla;015E
+Scircumflex;015C
+Scommaaccent;0218
+Sigma;03A3
+Ssmall;F773
+T;0054
+Tau;03A4
+Tbar;0166
+Tcaron;0164
+Tcommaaccent;0162
+Theta;0398
+Thorn;00DE
+Thornsmall;F7FE
+Tildesmall;F6FE
+Tsmall;F774
+U;0055
+Uacute;00DA
+Uacutesmall;F7FA
+Ubreve;016C
+Ucircumflex;00DB
+Ucircumflexsmall;F7FB
+Udieresis;00DC
+Udieresissmall;F7FC
+Ugrave;00D9
+Ugravesmall;F7F9
+Uhorn;01AF
+Uhungarumlaut;0170
+Umacron;016A
+Uogonek;0172
+Upsilon;03A5
+Upsilon1;03D2
+Upsilondieresis;03AB
+Upsilontonos;038E
+Uring;016E
+Usmall;F775
+Utilde;0168
+V;0056
+Vsmall;F776
+W;0057
+Wacute;1E82
+Wcircumflex;0174
+Wdieresis;1E84
+Wgrave;1E80
+Wsmall;F777
+X;0058
+Xi;039E
+Xsmall;F778
+Y;0059
+Yacute;00DD
+Yacutesmall;F7FD
+Ycircumflex;0176
+Ydieresis;0178
+Ydieresissmall;F7FF
+Ygrave;1EF2
+Ysmall;F779
+Z;005A
+Zacute;0179
+Zcaron;017D
+Zcaronsmall;F6FF
+Zdotaccent;017B
+Zeta;0396
+Zsmall;F77A
+a;0061
+aacute;00E1
+abreve;0103
+acircumflex;00E2
+acute;00B4
+acutecomb;0301
+adieresis;00E4
+ae;00E6
+aeacute;01FD
+afii00208;2015
+afii10017;0410
+afii10018;0411
+afii10019;0412
+afii10020;0413
+afii10021;0414
+afii10022;0415
+afii10023;0401
+afii10024;0416
+afii10025;0417
+afii10026;0418
+afii10027;0419
+afii10028;041A
+afii10029;041B
+afii10030;041C
+afii10031;041D
+afii10032;041E
+afii10033;041F
+afii10034;0420
+afii10035;0421
+afii10036;0422
+afii10037;0423
+afii10038;0424
+afii10039;0425
+afii10040;0426
+afii10041;0427
+afii10042;0428
+afii10043;0429
+afii10044;042A
+afii10045;042B
+afii10046;042C
+afii10047;042D
+afii10048;042E
+afii10049;042F
+afii10050;0490
+afii10051;0402
+afii10052;0403
+afii10053;0404
+afii10054;0405
+afii10055;0406
+afii10056;0407
+afii10057;0408
+afii10058;0409
+afii10059;040A
+afii10060;040B
+afii10061;040C
+afii10062;040E
+afii10063;F6C4
+afii10064;F6C5
+afii10065;0430
+afii10066;0431
+afii10067;0432
+afii10068;0433
+afii10069;0434
+afii10070;0435
+afii10071;0451
+afii10072;0436
+afii10073;0437
+afii10074;0438
+afii10075;0439
+afii10076;043A
+afii10077;043B
+afii10078;043C
+afii10079;043D
+afii10080;043E
+afii10081;043F
+afii10082;0440
+afii10083;0441
+afii10084;0442
+afii10085;0443
+afii10086;0444
+afii10087;0445
+afii10088;0446
+afii10089;0447
+afii10090;0448
+afii10091;0449
+afii10092;044A
+afii10093;044B
+afii10094;044C
+afii10095;044D
+afii10096;044E
+afii10097;044F
+afii10098;0491
+afii10099;0452
+afii10100;0453
+afii10101;0454
+afii10102;0455
+afii10103;0456
+afii10104;0457
+afii10105;0458
+afii10106;0459
+afii10107;045A
+afii10108;045B
+afii10109;045C
+afii10110;045E
+afii10145;040F
+afii10146;0462
+afii10147;0472
+afii10148;0474
+afii10192;F6C6
+afii10193;045F
+afii10194;0463
+afii10195;0473
+afii10196;0475
+afii10831;F6C7
+afii10832;F6C8
+afii10846;04D9
+afii299;200E
+afii300;200F
+afii301;200D
+afii57381;066A
+afii57388;060C
+afii57392;0660
+afii57393;0661
+afii57394;0662
+afii57395;0663
+afii57396;0664
+afii57397;0665
+afii57398;0666
+afii57399;0667
+afii57400;0668
+afii57401;0669
+afii57403;061B
+afii57407;061F
+afii57409;0621
+afii57410;0622
+afii57411;0623
+afii57412;0624
+afii57413;0625
+afii57414;0626
+afii57415;0627
+afii57416;0628
+afii57417;0629
+afii57418;062A
+afii57419;062B
+afii57420;062C
+afii57421;062D
+afii57422;062E
+afii57423;062F
+afii57424;0630
+afii57425;0631
+afii57426;0632
+afii57427;0633
+afii57428;0634
+afii57429;0635
+afii57430;0636
+afii57431;0637
+afii57432;0638
+afii57433;0639
+afii57434;063A
+afii57440;0640
+afii57441;0641
+afii57442;0642
+afii57443;0643
+afii57444;0644
+afii57445;0645
+afii57446;0646
+afii57448;0648
+afii57449;0649
+afii57450;064A
+afii57451;064B
+afii57452;064C
+afii57453;064D
+afii57454;064E
+afii57455;064F
+afii57456;0650
+afii57457;0651
+afii57458;0652
+afii57470;0647
+afii57505;06A4
+afii57506;067E
+afii57507;0686
+afii57508;0698
+afii57509;06AF
+afii57511;0679
+afii57512;0688
+afii57513;0691
+afii57514;06BA
+afii57519;06D2
+afii57534;06D5
+afii57636;20AA
+afii57645;05BE
+afii57658;05C3
+afii57664;05D0
+afii57665;05D1
+afii57666;05D2
+afii57667;05D3
+afii57668;05D4
+afii57669;05D5
+afii57670;05D6
+afii57671;05D7
+afii57672;05D8
+afii57673;05D9
+afii57674;05DA
+afii57675;05DB
+afii57676;05DC
+afii57677;05DD
+afii57678;05DE
+afii57679;05DF
+afii57680;05E0
+afii57681;05E1
+afii57682;05E2
+afii57683;05E3
+afii57684;05E4
+afii57685;05E5
+afii57686;05E6
+afii57687;05E7
+afii57688;05E8
+afii57689;05E9
+afii57690;05EA
+afii57694;FB2A
+afii57695;FB2B
+afii57700;FB4B
+afii57705;FB1F
+afii57716;05F0
+afii57717;05F1
+afii57718;05F2
+afii57723;FB35
+afii57793;05B4
+afii57794;05B5
+afii57795;05B6
+afii57796;05BB
+afii57797;05B8
+afii57798;05B7
+afii57799;05B0
+afii57800;05B2
+afii57801;05B1
+afii57802;05B3
+afii57803;05C2
+afii57804;05C1
+afii57806;05B9
+afii57807;05BC
+afii57839;05BD
+afii57841;05BF
+afii57842;05C0
+afii57929;02BC
+afii61248;2105
+afii61289;2113
+afii61352;2116
+afii61573;202C
+afii61574;202D
+afii61575;202E
+afii61664;200C
+afii63167;066D
+afii64937;02BD
+agrave;00E0
+aleph;2135
+alpha;03B1
+alphatonos;03AC
+amacron;0101
+ampersand;0026
+ampersandsmall;F726
+angle;2220
+angleleft;2329
+angleright;232A
+anoteleia;0387
+aogonek;0105
+approxequal;2248
+aring;00E5
+aringacute;01FB
+arrowboth;2194
+arrowdblboth;21D4
+arrowdbldown;21D3
+arrowdblleft;21D0
+arrowdblright;21D2
+arrowdblup;21D1
+arrowdown;2193
+arrowhorizex;F8E7
+arrowleft;2190
+arrowright;2192
+arrowup;2191
+arrowupdn;2195
+arrowupdnbse;21A8
+arrowvertex;F8E6
+asciicircum;005E
+asciitilde;007E
+asterisk;002A
+asteriskmath;2217
+asuperior;F6E9
+at;0040
+atilde;00E3
+b;0062
+backslash;005C
+bar;007C
+beta;03B2
+block;2588
+braceex;F8F4
+braceleft;007B
+braceleftbt;F8F3
+braceleftmid;F8F2
+bracelefttp;F8F1
+braceright;007D
+bracerightbt;F8FE
+bracerightmid;F8FD
+bracerighttp;F8FC
+bracketleft;005B
+bracketleftbt;F8F0
+bracketleftex;F8EF
+bracketlefttp;F8EE
+bracketright;005D
+bracketrightbt;F8FB
+bracketrightex;F8FA
+bracketrighttp;F8F9
+breve;02D8
+brokenbar;00A6
+bsuperior;F6EA
+bullet;2022
+c;0063
+cacute;0107
+caron;02C7
+carriagereturn;21B5
+ccaron;010D
+ccedilla;00E7
+ccircumflex;0109
+cdotaccent;010B
+cedilla;00B8
+cent;00A2
+centinferior;F6DF
+centoldstyle;F7A2
+centsuperior;F6E0
+chi;03C7
+circle;25CB
+circlemultiply;2297
+circleplus;2295
+circumflex;02C6
+club;2663
+colon;003A
+colonmonetary;20A1
+comma;002C
+commaaccent;F6C3
+commainferior;F6E1
+commasuperior;F6E2
+congruent;2245
+copyright;00A9
+copyrightsans;F8E9
+copyrightserif;F6D9
+currency;00A4
+cyrBreve;F6D1
+cyrFlex;F6D2
+cyrbreve;F6D4
+cyrflex;F6D5
+d;0064
+dagger;2020
+daggerdbl;2021
+dblGrave;F6D3
+dblgrave;F6D6
+dcaron;010F
+dcroat;0111
+degree;00B0
+delta;03B4
+diamond;2666
+dieresis;00A8
+dieresisacute;F6D7
+dieresisgrave;F6D8
+dieresistonos;0385
+divide;00F7
+dkshade;2593
+dnblock;2584
+dollar;0024
+dollarinferior;F6E3
+dollaroldstyle;F724
+dollarsuperior;F6E4
+dong;20AB
+dotaccent;02D9
+dotbelowcomb;0323
+dotlessi;0131
+dotlessj;F6BE
+dotmath;22C5
+dsuperior;F6EB
+e;0065
+eacute;00E9
+ebreve;0115
+ecaron;011B
+ecircumflex;00EA
+edieresis;00EB
+edotaccent;0117
+egrave;00E8
+eight;0038
+eightinferior;2088
+eightoldstyle;F738
+eightsuperior;2078
+element;2208
+ellipsis;2026
+emacron;0113
+emdash;2014
+emptyset;2205
+endash;2013
+eng;014B
+eogonek;0119
+epsilon;03B5
+epsilontonos;03AD
+equal;003D
+equivalence;2261
+estimated;212E
+esuperior;F6EC
+eta;03B7
+etatonos;03AE
+eth;00F0
+exclam;0021
+exclamdbl;203C
+exclamdown;00A1
+exclamdownsmall;F7A1
+exclamsmall;F721
+existential;2203
+f;0066
+female;2640
+ff;FB00
+ffi;FB03
+ffl;FB04
+fi;FB01
+figuredash;2012
+filledbox;25A0
+filledrect;25AC
+five;0035
+fiveeighths;215D
+fiveinferior;2085
+fiveoldstyle;F735
+fivesuperior;2075
+fl;FB02
+florin;0192
+four;0034
+fourinferior;2084
+fouroldstyle;F734
+foursuperior;2074
+fraction;2044
+franc;20A3
+g;0067
+gamma;03B3
+gbreve;011F
+gcaron;01E7
+gcircumflex;011D
+gcommaaccent;0123
+gdotaccent;0121
+germandbls;00DF
+gradient;2207
+grave;0060
+gravecomb;0300
+greater;003E
+greaterequal;2265
+guillemotleft;00AB
+guillemotright;00BB
+guilsinglleft;2039
+guilsinglright;203A
+h;0068
+hbar;0127
+hcircumflex;0125
+heart;2665
+hookabovecomb;0309
+house;2302
+hungarumlaut;02DD
+hyphen;002D
+hypheninferior;F6E5
+hyphensuperior;F6E6
+i;0069
+iacute;00ED
+ibreve;012D
+icircumflex;00EE
+idieresis;00EF
+igrave;00EC
+ij;0133
+imacron;012B
+infinity;221E
+integral;222B
+integralbt;2321
+integralex;F8F5
+integraltp;2320
+intersection;2229
+invbullet;25D8
+invcircle;25D9
+invsmileface;263B
+iogonek;012F
+iota;03B9
+iotadieresis;03CA
+iotadieresistonos;0390
+iotatonos;03AF
+isuperior;F6ED
+itilde;0129
+j;006A
+jcircumflex;0135
+k;006B
+kappa;03BA
+kcommaaccent;0137
+kgreenlandic;0138
+l;006C
+lacute;013A
+lambda;03BB
+lcaron;013E
+lcommaaccent;013C
+ldot;0140
+less;003C
+lessequal;2264
+lfblock;258C
+lira;20A4
+ll;F6C0
+logicaland;2227
+logicalnot;00AC
+logicalor;2228
+longs;017F
+lozenge;25CA
+lslash;0142
+lsuperior;F6EE
+ltshade;2591
+m;006D
+macron;00AF
+male;2642
+minus;2212
+minute;2032
+msuperior;F6EF
+mu;03BC
+multiply;00D7
+musicalnote;266A
+musicalnotedbl;266B
+n;006E
+nacute;0144
+napostrophe;0149
+ncaron;0148
+ncommaaccent;0146
+nine;0039
+nineinferior;2089
+nineoldstyle;F739
+ninesuperior;2079
+notelement;2209
+notequal;2260
+notsubset;2284
+nsuperior;207F
+ntilde;00F1
+nu;03BD
+numbersign;0023
+o;006F
+oacute;00F3
+obreve;014F
+ocircumflex;00F4
+odieresis;00F6
+oe;0153
+ogonek;02DB
+ograve;00F2
+ohorn;01A1
+ohungarumlaut;0151
+omacron;014D
+omega;03C9
+omega1;03D6
+omegatonos;03CE
+omicron;03BF
+omicrontonos;03CC
+one;0031
+onedotenleader;2024
+oneeighth;215B
+onefitted;F6DC
+onehalf;00BD
+oneinferior;2081
+oneoldstyle;F731
+onequarter;00BC
+onesuperior;00B9
+onethird;2153
+openbullet;25E6
+ordfeminine;00AA
+ordmasculine;00BA
+orthogonal;221F
+oslash;00F8
+oslashacute;01FF
+osuperior;F6F0
+otilde;00F5
+p;0070
+paragraph;00B6
+parenleft;0028
+parenleftbt;F8ED
+parenleftex;F8EC
+parenleftinferior;208D
+parenleftsuperior;207D
+parenlefttp;F8EB
+parenright;0029
+parenrightbt;F8F8
+parenrightex;F8F7
+parenrightinferior;208E
+parenrightsuperior;207E
+parenrighttp;F8F6
+partialdiff;2202
+percent;0025
+period;002E
+periodcentered;00B7
+periodinferior;F6E7
+periodsuperior;F6E8
+perpendicular;22A5
+perthousand;2030
+peseta;20A7
+phi;03C6
+phi1;03D5
+pi;03C0
+plus;002B
+plusminus;00B1
+prescription;211E
+product;220F
+propersubset;2282
+propersuperset;2283
+proportional;221D
+psi;03C8
+q;0071
+question;003F
+questiondown;00BF
+questiondownsmall;F7BF
+questionsmall;F73F
+quotedbl;0022
+quotedblbase;201E
+quotedblleft;201C
+quotedblright;201D
+quoteleft;2018
+quotereversed;201B
+quoteright;2019
+quotesinglbase;201A
+quotesingle;0027
+r;0072
+racute;0155
+radical;221A
+radicalex;F8E5
+rcaron;0159
+rcommaaccent;0157
+reflexsubset;2286
+reflexsuperset;2287
+registered;00AE
+registersans;F8E8
+registerserif;F6DA
+revlogicalnot;2310
+rho;03C1
+ring;02DA
+rsuperior;F6F1
+rtblock;2590
+rupiah;F6DD
+s;0073
+sacute;015B
+scaron;0161
+scedilla;015F
+scircumflex;015D
+scommaaccent;0219
+second;2033
+section;00A7
+semicolon;003B
+seven;0037
+seveneighths;215E
+seveninferior;2087
+sevenoldstyle;F737
+sevensuperior;2077
+shade;2592
+sigma;03C3
+sigma1;03C2
+similar;223C
+six;0036
+sixinferior;2086
+sixoldstyle;F736
+sixsuperior;2076
+slash;002F
+smileface;263A
+space;0020
+spade;2660
+ssuperior;F6F2
+sterling;00A3
+suchthat;220B
+summation;2211
+sun;263C
+t;0074
+tau;03C4
+tbar;0167
+tcaron;0165
+tcommaaccent;0163
+therefore;2234
+theta;03B8
+theta1;03D1
+thorn;00FE
+three;0033
+threeeighths;215C
+threeinferior;2083
+threeoldstyle;F733
+threequarters;00BE
+threequartersemdash;F6DE
+threesuperior;00B3
+tilde;02DC
+tildecomb;0303
+tonos;0384
+trademark;2122
+trademarksans;F8EA
+trademarkserif;F6DB
+triagdn;25BC
+triaglf;25C4
+triagrt;25BA
+triagup;25B2
+tsuperior;F6F3
+two;0032
+twodotenleader;2025
+twoinferior;2082
+twooldstyle;F732
+twosuperior;00B2
+twothirds;2154
+u;0075
+uacute;00FA
+ubreve;016D
+ucircumflex;00FB
+udieresis;00FC
+ugrave;00F9
+uhorn;01B0
+uhungarumlaut;0171
+umacron;016B
+underscore;005F
+underscoredbl;2017
+union;222A
+universal;2200
+uogonek;0173
+upblock;2580
+upsilon;03C5
+upsilondieresis;03CB
+upsilondieresistonos;03B0
+upsilontonos;03CD
+uring;016F
+utilde;0169
+v;0076
+w;0077
+wacute;1E83
+wcircumflex;0175
+wdieresis;1E85
+weierstrass;2118
+wgrave;1E81
+x;0078
+xi;03BE
+y;0079
+yacute;00FD
+ycircumflex;0177
+ydieresis;00FF
+yen;00A5
+ygrave;1EF3
+z;007A
+zacute;017A
+zcaron;017E
+zdotaccent;017C
+zero;0030
+zeroinferior;2080
+zerooldstyle;F730
+zerosuperior;2070
+zeta;03B6
diff --git a/iTechSharp/iTextSharp/text/pdf/hyphenation/ByteVector.cs b/iTechSharp/iTextSharp/text/pdf/hyphenation/ByteVector.cs
new file mode 100644
index 0000000..05687f2
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/hyphenation/ByteVector.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections;
+
+/*
+ * $Id: ByteVector.cs,v 1.2 2005/06/18 08:17:05 psoares33 Exp $
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+namespace iTextSharp.text.pdf.hyphenation {
+ /**
+ * This class implements a simple byte vector with access to the
+ * underlying array.
+ *
+ * @author Carlos Villegas
+ * for (i=0; i
or a Ternary Search Tree
+ *
+ *
+ * PdfFormField
+ * to the document. Only the top parent of a PdfFormField
+ * needs to be added.
+ * @param annot the PdfAnnotation
or the PdfFormField
to add
+ */
+ void AddAnnotation(PdfAnnotation annot);
+
+ /**
+ * Use this method to adds the PdfAnnotation
+ * to the calculation order array.
+ * @param annot the PdfAnnotation
to be added
+ */
+ void AddCalculationOrder(PdfFormField annot);
+
+ /**
+ * Use this method to set the signature flags.
+ * @param f the flags. This flags are ORed with current ones
+ */
+ int SigFlags {
+ set;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfDocumentActions.cs b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfDocumentActions.cs
new file mode 100644
index 0000000..f13f947
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfDocumentActions.cs
@@ -0,0 +1,87 @@
+using System;
+using iTextSharp.text.pdf;
+/*
+ * $Id: IPdfDocumentActions.cs,v 1.1 2007/02/09 15:34:40 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.interfaces {
+
+ /**
+ * A PDF document can have an open action and other additional actions.
+ */
+
+ public interface IPdfDocumentActions {
+ /**
+ * When the document opens it will jump to the destination with
+ * this name.
+ * @param name the name of the destination to jump to
+ */
+ void SetOpenAction(String name);
+
+ /**
+ * When the document opens this action
will be
+ * invoked.
+ * @param action the action to be invoked
+ */
+ void SetOpenAction(PdfAction action);
+
+ /**
+ * Additional-actions defining the actions to be taken in
+ * response to various trigger events affecting the document
+ * as a whole. The actions types allowed are: DOCUMENT_CLOSE
,
+ * WILL_SAVE
, DID_SAVE
, WILL_PRINT
+ * and DID_PRINT
.
+ *
+ * @param actionType the action type
+ * @param action the action to execute in response to the trigger
+ * @throws DocumentException on invalid action type
+ */
+ void SetAdditionalAction(PdfName actionType, PdfAction action);
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfEncryptionSettings.cs b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfEncryptionSettings.cs
new file mode 100644
index 0000000..8250d59
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfEncryptionSettings.cs
@@ -0,0 +1,96 @@
+using System;
+using Org.BouncyCastle.X509;
+/*
+ * $Id: IPdfEncryptionSettings.cs,v 1.2 2007/04/29 13:57:00 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.interfaces {
+
+ /**
+ * Encryption settings are described in section 3.5 (more specifically
+ * section 3.5.2) of the PDF Reference 1.7.
+ * They are explained in section 3.3.3 of the book 'iText in Action'.
+ * The values of the different preferences were originally stored
+ * in class PdfWriter, but they have been moved to this separate interface
+ * for reasons of convenience.
+ */
+
+ public interface IPdfEncryptionSettings {
+
+ /**
+ * Sets the encryption options for this document. The userPassword and the
+ * ownerPassword can be null or have zero length. In this case the ownerPassword
+ * is replaced by a random string. The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * @param userPassword the user password. Can be null or empty
+ * @param ownerPassword the owner password. Can be null or empty
+ * @param permissions the user permissions
+ * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @throws DocumentException if the document is already open
+ */
+ void SetEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType);
+
+ /**
+ * Sets the certificate encryption options for this document. An array of one or more public certificates
+ * must be provided together with an array of the same size for the permissions for each certificate.
+ * The open permissions for the document can be
+ * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
+ * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
+ * The permissions can be combined by ORing them.
+ * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext
+ * @param certs the public certificates to be used for the encryption
+ * @param permissions the user permissions for each of the certicates
+ * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128.
+ * @throws DocumentException if the document is already open
+ */
+ void SetEncryption(X509Certificate[] certs, int[] permissions, int encryptionType);
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfPageActions.cs b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfPageActions.cs
new file mode 100644
index 0000000..a1fd316
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfPageActions.cs
@@ -0,0 +1,85 @@
+using System;
+using iTextSharp.text;
+using iTextSharp.text.pdf;
+/*
+ * $Id: IPdfPageActions.cs,v 1.1 2007/02/09 15:34:40 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.interfaces {
+
+ /**
+ * A PDF page can have an open and/or close action.
+ */
+
+ public interface IPdfPageActions {
+ /**
+ * Sets the open and close page additional action.
+ * @param actionType the action type. It can be PdfWriter.PAGE_OPEN
+ * or PdfWriter.PAGE_CLOSE
+ * @param action the action to perform
+ * @throws DocumentException if the action type is invalid
+ */
+ void SetPageAction(PdfName actionType, PdfAction action);
+
+ /**
+ * Sets the display duration for the page (for presentations)
+ * @param seconds the number of seconds to display the page
+ */
+ int Duration {
+ set;
+ }
+
+ /**
+ * Sets the transition for the page
+ * @param transition the Transition object
+ */
+ PdfTransition Transition {
+ set;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfRunDirection.cs b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfRunDirection.cs
new file mode 100644
index 0000000..b3c563c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfRunDirection.cs
@@ -0,0 +1,63 @@
+using System;
+/*
+ * $Id: IPdfRunDirection.cs,v 1.1 2007/02/09 15:34:40 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.interfaces {
+
+ public interface IPdfRunDirection {
+ /** Sets the run direction. This is only used as a placeholder
+ * as it does not affect anything.
+ * @param runDirection the run direction
+ */
+ int RunDirection {
+ set;
+ get;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfVersion.cs b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfVersion.cs
new file mode 100644
index 0000000..6a55b14
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfVersion.cs
@@ -0,0 +1,94 @@
+using System;
+using iTextSharp.text;
+using iTextSharp.text.pdf;
+/*
+ * $Id: IPdfVersion.cs,v 1.1 2007/02/09 15:34:40 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.interfaces {
+
+ /**
+ * The PDF version is described in the PDF Reference 1.7 p92
+ * (about the PDF Header) and page 139 (the version entry in
+ * the Catalog). You'll also find info about setting the version
+ * in the book 'iText in Action' sections 2.1.3 (PDF Header)
+ * and 3.3 (Version history).
+ */
+
+ public interface IPdfVersion {
+
+ /**
+ * If the PDF Header hasn't been written yet,
+ * this changes the version as it will appear in the PDF Header.
+ * If the PDF header was already written to the Stream,
+ * this changes the version as it will appear in the Catalog.
+ * @param version a character representing the PDF version
+ */
+ char PdfVersion {
+ set;
+ }
+
+ /**
+ * If the PDF Header hasn't been written yet,
+ * this changes the version as it will appear in the PDF Header,
+ * but only if param refers to a higher version.
+ * If the PDF header was already written to the Stream,
+ * this changes the version as it will appear in the Catalog.
+ * @param version a character representing the PDF version
+ */
+ void SetAtLeastPdfVersion(char version);
+ /**
+ * Sets the PDF version as it will appear in the Catalog.
+ * Note that this only has effect if you use a later version
+ * than the one that appears in the header; this method
+ * ignores the parameter if you try to set a lower version.
+ * @param version the PDF name that will be used for the Version key in the catalog
+ */
+ void SetPdfVersion(PdfName version);
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfViewerPreferences.cs b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfViewerPreferences.cs
new file mode 100644
index 0000000..e5eb88f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfViewerPreferences.cs
@@ -0,0 +1,202 @@
+using System;
+using iTextSharp.text.pdf;
+/*
+ * $Id: IPdfViewerPreferences.cs,v 1.3 2008/05/02 15:58:08 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.interfaces {
+
+ /**
+ * Viewer preferences are described in section 3.6.1 and 8.1 of the
+ * PDF Reference 1.7 (Table 3.25 on p139-142 and Table 8.1 on p579-581).
+ * They are explained in section 13.1 of the book 'iText in Action'.
+ * The values of the different preferences were originally stored
+ * in class PdfWriter, but they have been moved to this separate interface
+ * for reasons of convenience.
+ */
+
+ public interface IPdfViewerPreferences {
+
+ /**
+ * Sets the page layout and page mode preferences by ORing one or two of these constants.
+ *
+ *
+ * For backward compatibility these values are also supported,
+ * but it's better to use method
+ *
+ *
+ *
+ * addViewerPreference(key, value)
+ * if you want to change the following preferences:
+ *
+ *
+ * @param preferences the viewer preferences
+ * @see PdfViewerPreferences#addViewerPreference
+ */
+ int ViewerPreferences {
+ set;
+ }
+
+ /**
+ * Adds a viewer preference.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * The value must be a of type PdfBoolean (true or false).
+ *
+ *
+ *
+ *
+ *
+ *
+ * The value must be one of these names:
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @param key the name of the viewer preference
+ * @param value the value of the viewer preference
+ * @see PdfViewerPreferences#setViewerPreferences
+ */
+ void AddViewerPreference(PdfName key, PdfObject value);
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfXConformance.cs b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfXConformance.cs
new file mode 100644
index 0000000..d347c37
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/interfaces/IPdfXConformance.cs
@@ -0,0 +1,71 @@
+using System;
+/*
+ * $Id: IPdfXConformance.cs,v 1.2 2007/06/05 15:00:43 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.interfaces {
+
+ public interface IPdfXConformance {
+ /**
+ * Sets the PDF/X conformance level.
+ * Allowed values are PDFX1A2001, PDFX32002, PDFA1A and PDFA1B.
+ * It must be called before opening the document.
+ * @param pdfxConformance the conformance level
+ */
+ int PDFXConformance{
+ set;
+ get;
+ }
+
+ /**
+ * Checks if the PDF/X Conformance is necessary.
+ * @return true if the PDF has to be in conformance with any of the PDF/X specifications
+ */
+ bool IsPdfX();
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/intern/PdfAnnotationsImp.cs b/iTechSharp/iTextSharp/text/pdf/intern/PdfAnnotationsImp.cs
new file mode 100644
index 0000000..c24b2e9
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/intern/PdfAnnotationsImp.cs
@@ -0,0 +1,230 @@
+using System;
+using System.Collections;
+using iTextSharp.text.pdf;
+using iTextSharp.text;
+/*
+ * $Id: PdfAnnotationsImp.cs,v 1.1 2007/02/09 15:34:40 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.intern {
+
+ public class PdfAnnotationsImp {
+
+ /**
+ * This is the AcroForm object for the complete document.
+ */
+ protected internal PdfAcroForm acroForm;
+
+ /**
+ * This is the array containing the references to annotations
+ * that were added to the document.
+ */
+ protected internal ArrayList annotations;
+
+ /**
+ * This is an array containg references to some delayed annotations
+ * (that were added for a page that doesn't exist yet).
+ */
+ protected internal ArrayList delayedAnnotations = new ArrayList();
+
+
+ public PdfAnnotationsImp(PdfWriter writer) {
+ acroForm = new PdfAcroForm(writer);
+ }
+
+ /**
+ * Checks if the AcroForm is valid.
+ */
+ public bool HasValidAcroForm() {
+ return acroForm.IsValid();
+ }
+
+ /**
+ * Gets the AcroForm object.
+ * @return the PdfAcroform object of the PdfDocument
+ */
+ public PdfAcroForm AcroForm {
+ get {
+ return acroForm;
+ }
+ }
+
+ public int SigFlags {
+ set {
+ acroForm.SigFlags = value;
+ }
+ }
+
+ public void AddCalculationOrder(PdfFormField formField) {
+ acroForm.AddCalculationOrder(formField);
+ }
+
+ public void AddAnnotation(PdfAnnotation annot) {
+ if (annot.IsForm()) {
+ PdfFormField field = (PdfFormField)annot;
+ if (field.Parent == null)
+ AddFormFieldRaw(field);
+ }
+ else
+ annotations.Add(annot);
+ }
+
+ public void AddPlainAnnotation(PdfAnnotation annot) {
+ annotations.Add(annot);
+ }
+
+ void AddFormFieldRaw(PdfFormField field) {
+ annotations.Add(field);
+ ArrayList kids = field.Kids;
+ if (kids != null) {
+ for (int k = 0; k < kids.Count; ++k)
+ AddFormFieldRaw((PdfFormField)kids[k]);
+ }
+ }
+
+ public bool HasUnusedAnnotations() {
+ return annotations.Count > 0;
+ }
+
+ public void ResetAnnotations() {
+ annotations = delayedAnnotations;
+ delayedAnnotations = new ArrayList();
+ }
+
+ public PdfArray RotateAnnotations(PdfWriter writer, Rectangle pageSize) {
+ PdfArray array = new PdfArray();
+ int rotation = pageSize.Rotation % 360;
+ int currentPage = writer.CurrentPageNumber;
+ for (int k = 0; k < annotations.Count; ++k) {
+ PdfAnnotation dic = (PdfAnnotation)annotations[k];
+ int page = dic.PlaceInPage;
+ if (page > currentPage) {
+ delayedAnnotations.Add(dic);
+ continue;
+ }
+ if (dic.IsForm()) {
+ if (!dic.IsUsed()) {
+ Hashtable templates = dic.Templates;
+ if (templates != null)
+ acroForm.AddFieldTemplates(templates);
+ }
+ PdfFormField field = (PdfFormField)dic;
+ if (field.Parent == null)
+ acroForm.AddDocumentField(field.IndirectReference);
+ }
+ if (dic.IsAnnotation()) {
+ array.Add(dic.IndirectReference);
+ if (!dic.IsUsed()) {
+ PdfRectangle rect = (PdfRectangle)dic.Get(PdfName.RECT);
+ if (rect != null) {
+ switch (rotation) {
+ case 90:
+ dic.Put(PdfName.RECT, new PdfRectangle(
+ pageSize.Top - rect.Bottom,
+ rect.Left,
+ pageSize.Top - rect.Top,
+ rect.Right));
+ break;
+ case 180:
+ dic.Put(PdfName.RECT, new PdfRectangle(
+ pageSize.Right - rect.Left,
+ pageSize.Top - rect.Bottom,
+ pageSize.Right - rect.Right,
+ pageSize.Top - rect.Top));
+ break;
+ case 270:
+ dic.Put(PdfName.RECT, new PdfRectangle(
+ rect.Bottom,
+ pageSize.Right - rect.Left,
+ rect.Top,
+ pageSize.Right - rect.Right));
+ break;
+ }
+ }
+ }
+ }
+ if (!dic.IsUsed()) {
+ dic.SetUsed();
+ writer.AddToBody(dic, dic.IndirectReference);
+ }
+ }
+ return array;
+ }
+
+ public static PdfAnnotation ConvertAnnotation(PdfWriter writer, Annotation annot, Rectangle defaultRect) {
+ switch (annot.AnnotationType) {
+ case Annotation.URL_NET:
+ return new PdfAnnotation(writer, annot.GetLlx(), annot.GetLly(), annot.GetUrx(), annot.GetUry(), new PdfAction((Uri) annot.Attributes[Annotation.URL]));
+ case Annotation.URL_AS_STRING:
+ return new PdfAnnotation(writer, annot.GetLlx(), annot.GetLly(), annot.GetUrx(), annot.GetUry(), new PdfAction((String) annot.Attributes[Annotation.FILE]));
+ case Annotation.FILE_DEST:
+ return new PdfAnnotation(writer, annot.GetLlx(), annot.GetLly(), annot.GetUrx(), annot.GetUry(), new PdfAction((String) annot.Attributes[Annotation.FILE], (String) annot.Attributes[Annotation.DESTINATION]));
+ case Annotation.SCREEN:
+ bool[] sparams = (bool[])annot.Attributes[Annotation.PARAMETERS];
+ String fname = (String) annot.Attributes[Annotation.FILE];
+ String mimetype = (String) annot.Attributes[Annotation.MIMETYPE];
+ PdfFileSpecification fs;
+ if (sparams[0])
+ fs = PdfFileSpecification.FileEmbedded(writer, fname, fname, null);
+ else
+ fs = PdfFileSpecification.FileExtern(writer, fname);
+ PdfAnnotation ann = PdfAnnotation.CreateScreen(writer, new Rectangle(annot.GetLlx(), annot.GetLly(), annot.GetUrx(), annot.GetUry()),
+ fname, fs, mimetype, sparams[1]);
+ return ann;
+ case Annotation.FILE_PAGE:
+ return new PdfAnnotation(writer, annot.GetLlx(), annot.GetLly(), annot.GetUrx(), annot.GetUry(), new PdfAction((String) annot.Attributes[Annotation.FILE], (int)annot.Attributes[Annotation.PAGE]));
+ case Annotation.NAMED_DEST:
+ return new PdfAnnotation(writer, annot.GetLlx(), annot.GetLly(), annot.GetUrx(), annot.GetUry(), new PdfAction((int) annot.Attributes[Annotation.NAMED]));
+ case Annotation.LAUNCH:
+ return new PdfAnnotation(writer, annot.GetLlx(), annot.GetLly(), annot.GetUrx(), annot.GetUry(), new PdfAction((String) annot.Attributes[Annotation.APPLICATION],(String) annot.Attributes[Annotation.PARAMETERS],(String) annot.Attributes[Annotation.OPERATION],(String) annot.Attributes[Annotation.DEFAULTDIR]));
+ default:
+ return new PdfAnnotation(writer, defaultRect.Left, defaultRect.Bottom, defaultRect.Right, defaultRect.Top, new PdfString(annot.Title, PdfObject.TEXT_UNICODE), new PdfString(annot.Content, PdfObject.TEXT_UNICODE));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/intern/PdfVersionImp.cs b/iTechSharp/iTextSharp/text/pdf/intern/PdfVersionImp.cs
new file mode 100644
index 0000000..121a74f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/intern/PdfVersionImp.cs
@@ -0,0 +1,172 @@
+using System;
+using iTextSharp.text.pdf;
+using iTextSharp.text;
+using iTextSharp.text.pdf.interfaces;
+/*
+ * $Id: PdfVersionImp.cs,v 1.1 2007/02/09 15:34:40 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.intern {
+
+ /**
+ * Stores the PDF version information,
+ * knows how to write a PDF Header,
+ * and how to add the version to the catalog (if necessary).
+ */
+
+ public class PdfVersionImp : IPdfVersion {
+
+ /** Contains different strings that are part of the header. */
+ public static readonly byte[][] HEADER = {
+ DocWriter.GetISOBytes("\n"),
+ DocWriter.GetISOBytes("%PDF-"),
+ DocWriter.GetISOBytes("\n%\u00e2\u00e3\u00cf\u00d3\n")
+ };
+ /** Indicates if the header was already written. */
+ protected bool headerWasWritten = false;
+ /** Indicates if we are working in append mode. */
+ protected bool appendmode = false;
+ /** The version that was or will be written to the header. */
+ protected char header_version = PdfWriter.VERSION_1_4;
+ /** The version that will be written to the catalog. */
+ protected PdfName catalog_version = null;
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(char)
+ */
+ public char PdfVersion {
+ set {
+ if (headerWasWritten || appendmode) {
+ SetPdfVersion(GetVersionAsName(value));
+ }
+ else {
+ this.header_version = value;
+ }
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfVersion#setAtLeastPdfVersion(char)
+ */
+ public void SetAtLeastPdfVersion(char version) {
+ if (version > header_version) {
+ PdfVersion = version;
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(com.lowagie.text.pdf.PdfName)
+ */
+ public void SetPdfVersion(PdfName version) {
+ if (catalog_version == null || catalog_version.CompareTo(version) < 0) {
+ this.catalog_version = version;
+ }
+ }
+
+ /**
+ * Sets the append mode.
+ */
+ public void SetAppendmode(bool appendmode) {
+ this.appendmode = appendmode;
+ }
+
+ /**
+ * Writes the header to the OutputStreamCounter.
+ * @throws IOException
+ */
+ public void WriteHeader(OutputStreamCounter os) {
+ if (appendmode) {
+ os.Write(HEADER[0], 0, HEADER[0].Length);
+ }
+ else {
+ os.Write(HEADER[1], 0, HEADER[1].Length);
+ os.Write(GetVersionAsByteArray(header_version), 0, GetVersionAsByteArray(header_version).Length);
+ os.Write(HEADER[2], 0, HEADER[2].Length);
+ headerWasWritten = true;
+ }
+ }
+
+ /**
+ * Returns the PDF version as a name.
+ * @param version the version character.
+ */
+ public PdfName GetVersionAsName(char version) {
+ switch (version) {
+ case PdfWriter.VERSION_1_2:
+ return PdfWriter.PDF_VERSION_1_2;
+ case PdfWriter.VERSION_1_3:
+ return PdfWriter.PDF_VERSION_1_3;
+ case PdfWriter.VERSION_1_4:
+ return PdfWriter.PDF_VERSION_1_4;
+ case PdfWriter.VERSION_1_5:
+ return PdfWriter.PDF_VERSION_1_5;
+ case PdfWriter.VERSION_1_6:
+ return PdfWriter.PDF_VERSION_1_6;
+ case PdfWriter.VERSION_1_7:
+ return PdfWriter.PDF_VERSION_1_7;
+ default:
+ return PdfWriter.PDF_VERSION_1_4;
+ }
+ }
+
+ /**
+ * Returns the version as a byte[].
+ * @param version the version character
+ */
+ public byte[] GetVersionAsByteArray(char version) {
+ return DocWriter.GetISOBytes(GetVersionAsName(version).ToString().Substring(1));
+ }
+
+ /** Adds the version to the Catalog dictionary. */
+ public void AddToCatalog(PdfDictionary catalog) {
+ if(catalog_version != null) {
+ catalog.Put(PdfName.VERSION, catalog_version);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/intern/PdfViewerPreferencesImp.cs b/iTechSharp/iTextSharp/text/pdf/intern/PdfViewerPreferencesImp.cs
new file mode 100644
index 0000000..f449467
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/intern/PdfViewerPreferencesImp.cs
@@ -0,0 +1,359 @@
+using System;
+using iTextSharp.text.pdf;
+using iTextSharp.text.pdf.interfaces;
+
+/*
+ * $Id: PdfViewerPreferencesImp.cs,v 1.7 2008/05/04 10:49:46 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.intern {
+
+ /**
+ * Stores the information concerning viewer preferences,
+ * and contains the business logic that allows you to set viewer preferences.
+ */
+ public class PdfViewerPreferencesImp : IPdfViewerPreferences {
+
+ public static readonly PdfName[] VIEWER_PREFERENCES = {
+ PdfName.HIDETOOLBAR, // 0
+ PdfName.HIDEMENUBAR, // 1
+ PdfName.HIDEWINDOWUI, // 2
+ PdfName.FITWINDOW, // 3
+ PdfName.CENTERWINDOW, // 4
+ PdfName.DISPLAYDOCTITLE, // 5
+ PdfName.NONFULLSCREENPAGEMODE, // 6
+ PdfName.DIRECTION, // 7
+ PdfName.VIEWAREA, // 8
+ PdfName.VIEWCLIP, // 9
+ PdfName.PRINTAREA, // 10
+ PdfName.PRINTCLIP, // 11
+ PdfName.PRINTSCALING, // 12
+ PdfName.DUPLEX, // 13
+ PdfName.PICKTRAYBYPDFSIZE, // 14
+ PdfName.PRINTPAGERANGE, // 15
+ PdfName.NUMCOPIES // 16
+ };
+
+
+ /** A series of viewer preferences. */
+ public static readonly PdfName[] NONFULLSCREENPAGEMODE_PREFERENCES = {
+ PdfName.USENONE, PdfName.USEOUTLINES, PdfName.USETHUMBS, PdfName.USEOC
+ };
+ /** A series of viewer preferences. */
+ public static readonly PdfName[] DIRECTION_PREFERENCES = {
+ PdfName.L2R, PdfName.R2L
+ };
+ /** A series of viewer preferences. */
+ public static readonly PdfName[] PAGE_BOUNDARIES = {
+ PdfName.MEDIABOX, PdfName.CROPBOX, PdfName.BLEEDBOX, PdfName.TRIMBOX, PdfName.ARTBOX
+ };
+ /** A series of viewer preferences */
+ public static readonly PdfName[] PRINTSCALING_PREFERENCES = {
+ PdfName.APPDEFAULT, PdfName.NONE
+ };
+ /** A series of viewer preferences. */
+ public static readonly PdfName[] DUPLEX_PREFERENCES = {
+ PdfName.SIMPLEX, PdfName.DUPLEXFLIPSHORTEDGE, PdfName.DUPLEXFLIPLONGEDGE
+ };
+ /** This value will hold the viewer preferences for the page layout and page mode. */
+ private int pageLayoutAndMode = 0;
+
+ /** This dictionary holds the viewer preferences (other than page layout and page mode). */
+ private PdfDictionary viewerPreferences = new PdfDictionary();
+
+ /** The mask to decide if a ViewerPreferences dictionary is needed */
+ private const int viewerPreferencesMask = 0xfff000;
+
+ /**
+ * Returns the page layout and page mode value.
+ */
+ public int PageLayoutAndMode {
+ get {
+ return pageLayoutAndMode;
+ }
+ }
+
+ /**
+ * Returns the viewer preferences.
+ */
+ public PdfDictionary GetViewerPreferences() {
+ return viewerPreferences;
+ }
+
+ /**
+ * Sets the viewer preferences as the sum of several constants.
+ *
+ * @param preferences
+ * the viewer preferences
+ * @see PdfWriter#setViewerPreferences
+ */
+ public int ViewerPreferences {
+ set {
+ int preferences = value;
+ this.pageLayoutAndMode |= preferences;
+ // for backwards compatibility, it is also possible
+ // to set the following viewer preferences with this method:
+ if ((preferences & viewerPreferencesMask) != 0) {
+ pageLayoutAndMode = ~viewerPreferencesMask & pageLayoutAndMode;
+ if ((preferences & PdfWriter.HideToolbar) != 0)
+ viewerPreferences.Put(PdfName.HIDETOOLBAR, PdfBoolean.PDFTRUE);
+ if ((preferences & PdfWriter.HideMenubar) != 0)
+ viewerPreferences.Put(PdfName.HIDEMENUBAR, PdfBoolean.PDFTRUE);
+ if ((preferences & PdfWriter.HideWindowUI) != 0)
+ viewerPreferences.Put(PdfName.HIDEWINDOWUI, PdfBoolean.PDFTRUE);
+ if ((preferences & PdfWriter.FitWindow) != 0)
+ viewerPreferences.Put(PdfName.FITWINDOW, PdfBoolean.PDFTRUE);
+ if ((preferences & PdfWriter.CenterWindow) != 0)
+ viewerPreferences.Put(PdfName.CENTERWINDOW, PdfBoolean.PDFTRUE);
+ if ((preferences & PdfWriter.DisplayDocTitle) != 0)
+ viewerPreferences.Put(PdfName.DISPLAYDOCTITLE, PdfBoolean.PDFTRUE);
+
+ if ((preferences & PdfWriter.NonFullScreenPageModeUseNone) != 0)
+ viewerPreferences.Put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USENONE);
+ else if ((preferences & PdfWriter.NonFullScreenPageModeUseOutlines) != 0)
+ viewerPreferences.Put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USEOUTLINES);
+ else if ((preferences & PdfWriter.NonFullScreenPageModeUseThumbs) != 0)
+ viewerPreferences.Put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USETHUMBS);
+ else if ((preferences & PdfWriter.NonFullScreenPageModeUseOC) != 0)
+ viewerPreferences.Put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USEOC);
+
+ if ((preferences & PdfWriter.DirectionL2R) != 0)
+ viewerPreferences.Put(PdfName.DIRECTION, PdfName.L2R);
+ else if ((preferences & PdfWriter.DirectionR2L) != 0)
+ viewerPreferences.Put(PdfName.DIRECTION, PdfName.R2L);
+
+ if ((preferences & PdfWriter.PrintScalingNone) != 0)
+ viewerPreferences.Put(PdfName.PRINTSCALING, PdfName.NONE);
+ }
+ }
+ }
+
+ /**
+ * Given a key for a viewer preference (a PdfName object),
+ * this method returns the index in the VIEWER_PREFERENCES array.
+ * @param key a PdfName referring to a viewer preference
+ * @return an index in the VIEWER_PREFERENCES array
+ */
+ private int GetIndex(PdfName key) {
+ for (int i = 0; i < VIEWER_PREFERENCES.Length; i++) {
+ if (VIEWER_PREFERENCES[i].Equals(key))
+ return i;
+ }
+ return -1;
+ }
+
+ /**
+ * Checks if some value is valid for a certain key.
+ */
+ private bool IsPossibleValue(PdfName value, PdfName[] accepted) {
+ for (int i = 0; i < accepted.Length; i++) {
+ if (accepted[i].Equals(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Sets the viewer preferences for printing.
+ */
+ public virtual void AddViewerPreference(PdfName key, PdfObject value) {
+ switch (GetIndex(key)) {
+ case 0: // HIDETOOLBAR
+ case 1: // HIDEMENUBAR
+ case 2: // HIDEWINDOWUI
+ case 3: // FITWINDOW
+ case 4: // CENTERWINDOW
+ case 5: // DISPLAYDOCTITLE
+ case 14: // PICKTRAYBYPDFSIZE
+ if (value is PdfBoolean) {
+ viewerPreferences.Put(key, value);
+ }
+ break;
+ case 6: // NONFULLSCREENPAGEMODE
+ if (value is PdfName
+ && IsPossibleValue((PdfName)value, NONFULLSCREENPAGEMODE_PREFERENCES)) {
+ viewerPreferences.Put(key, value);
+ }
+ break;
+ case 7: // DIRECTION
+ if (value is PdfName
+ && IsPossibleValue((PdfName)value, DIRECTION_PREFERENCES)) {
+ viewerPreferences.Put(key, value);
+ }
+ break;
+ case 8: // VIEWAREA
+ case 9: // VIEWCLIP
+ case 10: // PRINTAREA
+ case 11: // PRINTCLIP
+ if (value is PdfName
+ && IsPossibleValue((PdfName)value, PAGE_BOUNDARIES)) {
+ viewerPreferences.Put(key, value);
+ }
+ break;
+ case 12: // PRINTSCALING
+ if (value is PdfName
+ && IsPossibleValue((PdfName)value, PRINTSCALING_PREFERENCES)) {
+ viewerPreferences.Put(key, value);
+ }
+ break;
+ case 13: // DUPLEX
+ if (value is PdfName
+ && IsPossibleValue((PdfName)value, DUPLEX_PREFERENCES)) {
+ viewerPreferences.Put(key, value);
+ }
+ break;
+ case 15: // PRINTPAGERANGE
+ if (value is PdfArray) {
+ viewerPreferences.Put(key, value);
+ }
+ break;
+ case 16: // NUMCOPIES
+ if (value is PdfNumber) {
+ viewerPreferences.Put(key, value);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Adds the viewer preferences defined in the preferences parameter to a
+ * PdfDictionary (more specifically the root or catalog of a PDF file).
+ *
+ * @param catalog
+ */
+ public void AddToCatalog(PdfDictionary catalog) {
+ // Page Layout
+ catalog.Remove(PdfName.PAGELAYOUT);
+ if ((pageLayoutAndMode & PdfWriter.PageLayoutSinglePage) != 0)
+ catalog.Put(PdfName.PAGELAYOUT, PdfName.SINGLEPAGE);
+ else if ((pageLayoutAndMode & PdfWriter.PageLayoutOneColumn) != 0)
+ catalog.Put(PdfName.PAGELAYOUT, PdfName.ONECOLUMN);
+ else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoColumnLeft) != 0)
+ catalog.Put(PdfName.PAGELAYOUT, PdfName.TWOCOLUMNLEFT);
+ else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoColumnRight) != 0)
+ catalog.Put(PdfName.PAGELAYOUT, PdfName.TWOCOLUMNRIGHT);
+ else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoPageLeft) != 0)
+ catalog.Put(PdfName.PAGELAYOUT, PdfName.TWOPAGELEFT);
+ else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoPageRight) != 0)
+ catalog.Put(PdfName.PAGELAYOUT, PdfName.TWOPAGERIGHT);
+
+ // Page Mode
+ catalog.Remove(PdfName.PAGEMODE);
+ if ((pageLayoutAndMode & PdfWriter.PageModeUseNone) != 0)
+ catalog.Put(PdfName.PAGEMODE, PdfName.USENONE);
+ else if ((pageLayoutAndMode & PdfWriter.PageModeUseOutlines) != 0)
+ catalog.Put(PdfName.PAGEMODE, PdfName.USEOUTLINES);
+ else if ((pageLayoutAndMode & PdfWriter.PageModeUseThumbs) != 0)
+ catalog.Put(PdfName.PAGEMODE, PdfName.USETHUMBS);
+ else if ((pageLayoutAndMode & PdfWriter.PageModeFullScreen) != 0)
+ catalog.Put(PdfName.PAGEMODE, PdfName.FULLSCREEN);
+ else if ((pageLayoutAndMode & PdfWriter.PageModeUseOC) != 0)
+ catalog.Put(PdfName.PAGEMODE, PdfName.USEOC);
+ else if ((pageLayoutAndMode & PdfWriter.PageModeUseAttachments) != 0)
+ catalog.Put(PdfName.PAGEMODE, PdfName.USEATTACHMENTS);
+
+ // viewer preferences (Table 8.1 of the PDF Reference)
+ catalog.Remove(PdfName.VIEWERPREFERENCES);
+ if (viewerPreferences.Size > 0) {
+ catalog.Put(PdfName.VIEWERPREFERENCES, viewerPreferences);
+ }
+ }
+
+ public static PdfViewerPreferencesImp GetViewerPreferences(PdfDictionary catalog) {
+ PdfViewerPreferencesImp preferences = new PdfViewerPreferencesImp();
+ int prefs = 0;
+ PdfName name = null;
+ // page layout
+ PdfObject obj = PdfReader.GetPdfObjectRelease(catalog.Get(PdfName.PAGELAYOUT));
+ if (obj != null && obj.IsName()) {
+ name = (PdfName) obj;
+ if (name.Equals(PdfName.SINGLEPAGE))
+ prefs |= PdfWriter.PageLayoutSinglePage;
+ else if (name.Equals(PdfName.ONECOLUMN))
+ prefs |= PdfWriter.PageLayoutOneColumn;
+ else if (name.Equals(PdfName.TWOCOLUMNLEFT))
+ prefs |= PdfWriter.PageLayoutTwoColumnLeft;
+ else if (name.Equals(PdfName.TWOCOLUMNRIGHT))
+ prefs |= PdfWriter.PageLayoutTwoColumnRight;
+ else if (name.Equals(PdfName.TWOPAGELEFT))
+ prefs |= PdfWriter.PageLayoutTwoPageLeft;
+ else if (name.Equals(PdfName.TWOPAGERIGHT))
+ prefs |= PdfWriter.PageLayoutTwoPageRight;
+ }
+ // page mode
+ obj = PdfReader.GetPdfObjectRelease(catalog.Get(PdfName.PAGEMODE));
+ if (obj != null && obj.IsName()) {
+ name = (PdfName) obj;
+ if (name.Equals(PdfName.USENONE))
+ prefs |= PdfWriter.PageModeUseNone;
+ else if (name.Equals(PdfName.USEOUTLINES))
+ prefs |= PdfWriter.PageModeUseOutlines;
+ else if (name.Equals(PdfName.USETHUMBS))
+ prefs |= PdfWriter.PageModeUseThumbs;
+ else if (name.Equals(PdfName.USEOC))
+ prefs |= PdfWriter.PageModeUseOC;
+ else if (name.Equals(PdfName.USEATTACHMENTS))
+ prefs |= PdfWriter.PageModeUseAttachments;
+ }
+ // set page layout and page mode preferences
+ preferences.ViewerPreferences = prefs;
+ // other preferences
+ obj = PdfReader.GetPdfObjectRelease(catalog
+ .Get(PdfName.VIEWERPREFERENCES));
+ if (obj != null && obj.IsDictionary()) {
+ PdfDictionary vp = (PdfDictionary) obj;
+ for (int i = 0; i < VIEWER_PREFERENCES.Length; i++) {
+ obj = PdfReader.GetPdfObjectRelease(vp.Get(VIEWER_PREFERENCES[i]));
+ preferences.AddViewerPreference(VIEWER_PREFERENCES[i], obj);
+ }
+ }
+ return preferences;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/pdf/intern/PdfXConformanceImp.cs b/iTechSharp/iTextSharp/text/pdf/intern/PdfXConformanceImp.cs
new file mode 100644
index 0000000..296a053
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/pdf/intern/PdfXConformanceImp.cs
@@ -0,0 +1,256 @@
+using System;
+using System.Collections;
+using iTextSharp.text.pdf;
+using iTextSharp.text;
+using iTextSharp.text.pdf.interfaces;
+
+/*
+ * $Id: PdfXConformanceImp.cs,v 1.3 2007/06/05 15:00:44 psoares33 Exp $
+ *
+ * Copyright 2006 Bruno Lowagie (based on code by Paulo Soares)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.pdf.intern {
+
+ public class PdfXConformanceImp : IPdfXConformance {
+
+ /** A key for an aspect that can be checked for PDF/X Conformance. */
+ public const int PDFXKEY_COLOR = 1;
+ /** A key for an aspect that can be checked for PDF/X Conformance. */
+ public const int PDFXKEY_CMYK = 2;
+ /** A key for an aspect that can be checked for PDF/X Conformance. */
+ public const int PDFXKEY_RGB = 3;
+ /** A key for an aspect that can be checked for PDF/X Conformance. */
+ public const int PDFXKEY_FONT = 4;
+ /** A key for an aspect that can be checked for PDF/X Conformance. */
+ public const int PDFXKEY_IMAGE = 5;
+ /** A key for an aspect that can be checked for PDF/X Conformance. */
+ public const int PDFXKEY_GSTATE = 6;
+ /** A key for an aspect that can be checked for PDF/X Conformance. */
+ public const int PDFXKEY_LAYER = 7;
+
+ /**
+ * The value indicating if the PDF has to be in conformance with PDF/X.
+ */
+ protected internal int pdfxConformance = PdfWriter.PDFXNONE;
+
+ /**
+ * @see com.lowagie.text.pdf.interfaces.PdfXConformance#setPDFXConformance(int)
+ */
+ public int PDFXConformance {
+ set {
+ this.pdfxConformance = value;
+ }
+ get {
+ return pdfxConformance;
+ }
+ }
+
+ /**
+ * Checks if the PDF/X Conformance is necessary.
+ * @return true if the PDF has to be in conformance with any of the PDF/X specifications
+ */
+ public bool IsPdfX() {
+ return pdfxConformance != PdfWriter.PDFXNONE;
+ }
+ /**
+ * Checks if the PDF has to be in conformance with PDF/X-1a:2001
+ * @return true of the PDF has to be in conformance with PDF/X-1a:2001
+ */
+ public bool IsPdfX1A2001() {
+ return pdfxConformance == PdfWriter.PDFX1A2001;
+ }
+ /**
+ * Checks if the PDF has to be in conformance with PDF/X-3:2002
+ * @return true of the PDF has to be in conformance with PDF/X-3:2002
+ */
+ public bool IsPdfX32002() {
+ return pdfxConformance == PdfWriter.PDFX32002;
+ }
+
+ /**
+ * Checks if the PDF has to be in conformance with PDFA1
+ * @return true of the PDF has to be in conformance with PDFA1
+ */
+ public bool IsPdfA1() {
+ return pdfxConformance == PdfWriter.PDFA1A || pdfxConformance == PdfWriter.PDFA1B;
+ }
+
+ /**
+ * Checks if the PDF has to be in conformance with PDFA1A
+ * @return true of the PDF has to be in conformance with PDFA1A
+ */
+ public bool IsPdfA1A() {
+ return pdfxConformance == PdfWriter.PDFA1A;
+ }
+
+ public void CompleteInfoDictionary(PdfDictionary info) {
+ if (IsPdfX() && !IsPdfA1()) {
+ if (info.Get(PdfName.GTS_PDFXVERSION) == null) {
+ if (IsPdfX1A2001()) {
+ info.Put(PdfName.GTS_PDFXVERSION, new PdfString("PDF/X-1:2001"));
+ info.Put(new PdfName("GTS_PDFXConformance"), new PdfString("PDF/X-1a:2001"));
+ }
+ else if (IsPdfX32002())
+ info.Put(PdfName.GTS_PDFXVERSION, new PdfString("PDF/X-3:2002"));
+ }
+ if (info.Get(PdfName.TITLE) == null) {
+ info.Put(PdfName.TITLE, new PdfString("Pdf document"));
+ }
+ if (info.Get(PdfName.CREATOR) == null) {
+ info.Put(PdfName.CREATOR, new PdfString("Unknown"));
+ }
+ if (info.Get(PdfName.TRAPPED) == null) {
+ info.Put(PdfName.TRAPPED, new PdfName("False"));
+ }
+ }
+ }
+
+ public void CompleteExtraCatalog(PdfDictionary extraCatalog) {
+ if (IsPdfX() && !IsPdfA1()) {
+ if (extraCatalog.Get(PdfName.OUTPUTINTENTS) == null) {
+ PdfDictionary outp = new PdfDictionary(PdfName.OUTPUTINTENT);
+ outp.Put(PdfName.OUTPUTCONDITION, new PdfString("SWOP CGATS TR 001-1995"));
+ outp.Put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString("CGATS TR 001"));
+ outp.Put(PdfName.REGISTRYNAME, new PdfString("http://www.color.org"));
+ outp.Put(PdfName.INFO, new PdfString(""));
+ outp.Put(PdfName.S, PdfName.GTS_PDFX);
+ extraCatalog.Put(PdfName.OUTPUTINTENTS, new PdfArray(outp));
+ }
+ }
+ }
+
+ /**
+ * Business logic that checks if a certain object is in conformance with PDF/X.
+ * @param writer the writer that is supposed to write the PDF/X file
+ * @param key the type of PDF/X conformance that has to be checked
+ * @param obj1 the object that is checked for conformance
+ */
+ public static void CheckPDFXConformance(PdfWriter writer, int key, Object obj1) {
+ if (writer == null || !writer.IsPdfX())
+ return;
+ int conf = writer.PDFXConformance;
+ switch (key) {
+ case PDFXKEY_COLOR:
+ switch (conf) {
+ case PdfWriter.PDFX1A2001:
+ if (obj1 is ExtendedColor) {
+ ExtendedColor ec = (ExtendedColor)obj1;
+ switch (ec.Type) {
+ case ExtendedColor.TYPE_CMYK:
+ case ExtendedColor.TYPE_GRAY:
+ return;
+ case ExtendedColor.TYPE_RGB:
+ throw new PdfXConformanceException("Colorspace RGB is not allowed.");
+ case ExtendedColor.TYPE_SEPARATION:
+ SpotColor sc = (SpotColor)ec;
+ CheckPDFXConformance(writer, PDFXKEY_COLOR, sc.PdfSpotColor.AlternativeCS);
+ break;
+ case ExtendedColor.TYPE_SHADING:
+ ShadingColor xc = (ShadingColor)ec;
+ CheckPDFXConformance(writer, PDFXKEY_COLOR, xc.PdfShadingPattern.Shading.ColorSpace);
+ break;
+ case ExtendedColor.TYPE_PATTERN:
+ PatternColor pc = (PatternColor)ec;
+ CheckPDFXConformance(writer, PDFXKEY_COLOR, pc.Painter.DefaultColor);
+ break;
+ }
+ }
+ else if (obj1 is Color)
+ throw new PdfXConformanceException("Colorspace RGB is not allowed.");
+ break;
+ }
+ break;
+ case PDFXKEY_CMYK:
+ break;
+ case PDFXKEY_RGB:
+ if (conf == PdfWriter.PDFX1A2001)
+ throw new PdfXConformanceException("Colorspace RGB is not allowed.");
+ break;
+ case PDFXKEY_FONT:
+ if (!((BaseFont)obj1).IsEmbedded())
+ throw new PdfXConformanceException("All the fonts must be embedded.");
+ break;
+ case PDFXKEY_IMAGE:
+ PdfImage image = (PdfImage)obj1;
+ if (image.Get(PdfName.SMASK) != null)
+ throw new PdfXConformanceException("The /SMask key is not allowed in images.");
+ switch (conf) {
+ case PdfWriter.PDFX1A2001:
+ PdfObject cs = image.Get(PdfName.COLORSPACE);
+ if (cs == null)
+ return;
+ if (cs.IsName()) {
+ if (PdfName.DEVICERGB.Equals(cs))
+ throw new PdfXConformanceException("Colorspace RGB is not allowed.");
+ }
+ else if (cs.IsArray()) {
+ if (PdfName.CALRGB.Equals(((PdfArray)cs).ArrayList[0]))
+ throw new PdfXConformanceException("Colorspace CalRGB is not allowed.");
+ }
+ break;
+ }
+ break;
+ case PDFXKEY_GSTATE:
+ PdfDictionary gs = (PdfDictionary)obj1;
+ PdfObject obj = gs.Get(PdfName.BM);
+ if (obj != null && !PdfGState.BM_NORMAL.Equals(obj) && !PdfGState.BM_COMPATIBLE.Equals(obj))
+ throw new PdfXConformanceException("Blend mode " + obj.ToString() + " not allowed.");
+ obj = gs.Get(PdfName.CA);
+ double v = 0.0;
+ if (obj != null && (v = ((PdfNumber)obj).DoubleValue) != 1.0)
+ throw new PdfXConformanceException("Transparency is not allowed: /CA = " + v);
+ obj = gs.Get(PdfName.ca_);
+ v = 0.0;
+ if (obj != null && (v = ((PdfNumber)obj).DoubleValue) != 1.0)
+ throw new PdfXConformanceException("Transparency is not allowed: /ca = " + v);
+ break;
+ case PDFXKEY_LAYER:
+ throw new PdfXConformanceException("Layers are not allowed.");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/IEventListener.cs b/iTechSharp/iTextSharp/text/rtf/IEventListener.cs
new file mode 100644
index 0000000..61e1c4e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/IEventListener.cs
@@ -0,0 +1,6 @@
+using System;
+
+namespace iTextSharp.text.rtf {
+ public interface IEventListener {
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/IRtfBasicElement.cs b/iTechSharp/iTextSharp/text/rtf/IRtfBasicElement.cs
new file mode 100644
index 0000000..330ce19
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/IRtfBasicElement.cs
@@ -0,0 +1,87 @@
+using System;
+using System.IO;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text;
+/*
+ * $Id: IRtfBasicElement.cs,v 1.4 2008/05/13 11:25:42 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf {
+
+ public interface IRtfBasicElement : IRtfElementInterface {
+
+ /**
+ * Writes the element content to the given output stream.
+ *
+ * @param out The OutputStream
to write the content to
+ */
+ void WriteContent(Stream outp);
+
+ /**
+ * Sets the RtfDocument this RtfElement belongs to
+ *
+ * @param doc The @link{com.lowagie.text.rtf.document.RtfDocument} this RtfElement
belongs to
+ */
+ void SetRtfDocument(RtfDocument doc);
+
+ /**
+ * Sets whether this IRtfBasicElement is in a table
+ *
+ * @param inTable Whether this IRtfBasicElement is in a table
+ */
+ void SetInTable(bool inTable);
+
+ /**
+ * Sets whether this IRtfBasicElement is in a header
+ *
+ * @param inHeader Whether this IRtfBasicElement is in a header
+ */
+ void SetInHeader(bool inHeader);
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/IRtfExtendedElement.cs b/iTechSharp/iTextSharp/text/rtf/IRtfExtendedElement.cs
new file mode 100644
index 0000000..74c5ddd
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/IRtfExtendedElement.cs
@@ -0,0 +1,70 @@
+using System;
+using System.IO;
+
+/*
+ * $Id: IRtfExtendedElement.cs,v 1.5 2008/05/16 19:30:12 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf {
+
+ /**
+ * The RtfExtendedElement interface is to be used for elements that also
+ * write data into the definition part of the rtf document
+ * Version: $Id: IRtfExtendedElement.cs,v 1.5 2008/05/16 19:30:12 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public interface IRtfExtendedElement : IRtfBasicElement {
+ /**
+ * Write the definition part of the element
+ *
+ * @param doc The OutputStream
to write the element definition to
+ */
+ void WriteDefinition(Stream outp);
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/RtfAddableElement.cs b/iTechSharp/iTextSharp/text/rtf/RtfAddableElement.cs
new file mode 100644
index 0000000..89b9b4a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/RtfAddableElement.cs
@@ -0,0 +1,134 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfAddableElement.cs,v 1.6 2008/05/16 19:30:13 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are
+ * Copyright (C) 2006 by Mark Hall. All Rights Reserved
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf {
+
+ /**
+ * The RtfAddableElement is the superclass for all rtf specific elements
+ * that need to be added to an iText document. It is an extension of Chunk
+ * and it also implements RtfBasicElement. It is an abstract class thus it
+ * cannot be instantiated itself and has to be subclassed to be used.
+ *
+ * @version $Revision: 1.6 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public abstract class RtfAddableElement : Chunk, IRtfBasicElement {
+
+ /**
+ * The RtfDocument this RtfAddableElement belongs to.
+ */
+ protected RtfDocument doc = null;
+ /**
+ * Whether this RtfAddableElement is contained in a table.
+ */
+ protected bool inTable = false;
+ /**
+ * Whether this RtfAddableElement is contained in a header.
+ */
+ protected bool inHeader = false;
+
+ /**
+ * Constructs a new RtfAddableElement. The Chunk content is
+ * set to an empty string and the font to the default Font().
+ */
+ public RtfAddableElement() : base("", new Font()) {
+ }
+
+ /**
+ * Writes the element content to the given output stream.
+ */
+ public abstract void WriteContent(Stream outp);
+
+ /**
+ * Sets the RtfDocument this RtfAddableElement belongs to.
+ */
+ public void SetRtfDocument(RtfDocument doc) {
+ this.doc = doc;
+ }
+
+ /**
+ * Sets whether this RtfAddableElement is contained in a table.
+ */
+ public void SetInTable(bool inTable) {
+ this.inTable = inTable;
+ }
+
+ /**
+ * Sets whether this RtfAddableElement is contained in a header/footer.
+ */
+ public void SetInHeader(bool inHeader) {
+ this.inHeader = inHeader;
+ }
+
+ /**
+ * Transforms an integer into its String representation and then returns the bytes
+ * of that string.
+ *
+ * @param i The integer to convert
+ * @return A byte array representing the integer
+ */
+ public byte[] IntToByteArray(int i) {
+ return DocWriter.GetISOBytes(i.ToString());
+ }
+
+ /**
+ * RtfAddableElement subclasses are never assumed to be empty.
+ */
+ public override bool IsEmpty() {
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/RtfElement.cs b/iTechSharp/iTextSharp/text/rtf/RtfElement.cs
new file mode 100644
index 0000000..71cabe4
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/RtfElement.cs
@@ -0,0 +1,159 @@
+using System;
+using System.IO;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text;
+/*
+ * $Id: RtfElement.cs,v 1.5 2008/05/16 19:30:14 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf {
+
+ /**
+ * RtfElement is the base class for all RTF Element classes
+ *
+ * Version: $Id: RtfElement.cs,v 1.5 2008/05/16 19:30:14 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public abstract class RtfElement : IRtfBasicElement {
+ /**
+ * Constant for the beginning of a rtf group
+ */
+ public static byte[] OPEN_GROUP = {(byte)'{'};
+ /**
+ * Constant for the end of an rtf group
+ */
+ public static byte[] CLOSE_GROUP = {(byte)'}'};
+ /**
+ * Constant for a delimiter in rtf
+ */
+ public static byte[] DELIMITER = {(byte)' '};
+ /**
+ * Constant for a comma delimiter in rtf
+ */
+ public static byte[] COMMA_DELIMITER = {(byte)';'};
+ /**
+ * The factor to use for translating from iText to rtf measurments
+ */
+ public const double TWIPS_FACTOR = 20;
+
+ /**
+ * The RtfDocument this RtfElement belongs to
+ */
+ protected RtfDocument document = null;
+ /**
+ * Whether this RtfElement is in a table
+ */
+ protected bool inTable = false;
+ /**
+ * Whether this RtfElement is in a header
+ */
+ protected bool inHeader = false;
+
+ /**
+ * Constructs a RtfElement belonging to the specified RtfDocument.
+ *
+ * @param doc The RtfDocument this RtfElement belongs to
+ */
+ public RtfElement(RtfDocument doc) : base(){
+ this.document = doc;
+ }
+
+ /**
+ * Transforms an integer into its String representation and then returns the bytes
+ * of that string.
+ *
+ * @param i The integer to convert
+ * @return A byte array representing the integer
+ */
+ public byte[] IntToByteArray(int i) {
+ return DocWriter.GetISOBytes(i.ToString());
+ }
+
+ /**
+ * Writes the element content to the given output stream.
+ */
+ public abstract void WriteContent(Stream outp);
+
+ /**
+ * Sets the RtfDocument this RtfElement belongs to
+ *
+ * @param doc The RtfDocument to use
+ */
+ public virtual void SetRtfDocument(RtfDocument doc) {
+ this.document = doc;
+ }
+
+ /**
+ * Gets whether this RtfElement is in a table
+ *
+ * @return Whether this RtfElement is in a table
+ */
+ public virtual bool IsInTable() {
+ return inTable;
+ }
+
+ /**
+ * Sets whether this RtfElement is in a table
+ *
+ * @param inTable True
if this RtfElement is in a table, false
otherwise
+ */
+ public virtual void SetInTable(bool inTable) {
+ this.inTable = inTable;
+ }
+
+ /**
+ * Sets whether this RtfElement is in a header
+ *
+ * @param inHeader True
if this RtfElement is in a header, false
otherwise
+ */
+ public virtual void SetInHeader(bool inHeader) {
+ this.inHeader = inHeader;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/RtfMapper.cs b/iTechSharp/iTextSharp/text/rtf/RtfMapper.cs
new file mode 100644
index 0000000..ea4e103
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/RtfMapper.cs
@@ -0,0 +1,173 @@
+using System;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.field;
+using iTextSharp.text.rtf.graphic;
+using iTextSharp.text.rtf.list;
+using iTextSharp.text.rtf.table;
+using iTextSharp.text.rtf.text;
+/*
+ * $Id: RtfMapper.cs,v 1.4 2008/05/16 19:30:14 psoares33 Exp $
+ *
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf {
+
+ /**
+ * The RtfMapper provides mappings between com.lowagie.text.* classes
+ * and the corresponding com.lowagie.text.rtf.** classes.
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfMapper {
+
+ /**
+ * The RtfDocument this RtfMapper belongs to
+ */
+ RtfDocument rtfDoc;
+
+ /**
+ * Constructs a RtfMapper for a RtfDocument
+ *
+ * @param doc The RtfDocument this RtfMapper belongs to
+ */
+ public RtfMapper(RtfDocument doc) {
+ this.rtfDoc = doc;
+ }
+
+ /**
+ * Takes an Element subclass and returns an array of RtfBasicElement
+ * subclasses, that contained the mapped RTF equivalent to the Element
+ * passed in.
+ *
+ * @param element The Element to wrap
+ * @return An array of RtfBasicElement wrapping the Element
+ * @throws DocumentException
+ */
+ public IRtfBasicElement[] MapElement(IElement element) {
+ ArrayList rtfElements = new ArrayList();
+
+ if (element is IRtfBasicElement) {
+ IRtfBasicElement rtfElement = (IRtfBasicElement) element;
+ rtfElement.SetRtfDocument(this.rtfDoc);
+ return new IRtfBasicElement[]{rtfElement};
+ }
+ switch (element.Type) {
+ case Element.CHUNK:
+ Chunk chunk = (Chunk) element;
+ if (chunk.HasAttributes()) {
+ if (chunk.Attributes.ContainsKey(Chunk.IMAGE)) {
+ rtfElements.Add(new RtfImage(rtfDoc, (Image) chunk.Attributes[Chunk.IMAGE]));
+ } else if (chunk.Attributes.ContainsKey(Chunk.NEWPAGE)) {
+ rtfElements.Add(new RtfNewPage(rtfDoc));
+ } else if (chunk.Attributes.ContainsKey(Chunk.TAB)) {
+ float tabPos = (float) ((Object[]) chunk.Attributes[Chunk.TAB])[1];
+ RtfTab tab = new RtfTab(tabPos, RtfTab.TAB_LEFT_ALIGN);
+ tab.SetRtfDocument(rtfDoc);
+ rtfElements.Add(tab);
+ rtfElements.Add(new RtfChunk(rtfDoc, new Chunk("\t")));
+ } else {
+ rtfElements.Add(new RtfChunk(rtfDoc, (Chunk) element));
+ }
+ } else {
+ rtfElements.Add(new RtfChunk(rtfDoc, (Chunk) element));
+ }
+ break;
+ case Element.PHRASE:
+ rtfElements.Add(new RtfPhrase(rtfDoc, (Phrase) element));
+ break;
+ case Element.PARAGRAPH:
+ rtfElements.Add(new RtfParagraph(rtfDoc, (Paragraph) element));
+ break;
+ case Element.ANCHOR:
+ rtfElements.Add(new RtfAnchor(rtfDoc, (Anchor) element));
+ break;
+ case Element.ANNOTATION:
+ rtfElements.Add(new RtfAnnotation(rtfDoc, (Annotation) element));
+ break;
+ case Element.IMGRAW:
+ case Element.IMGTEMPLATE:
+ case Element.JPEG:
+ rtfElements.Add(new RtfImage(rtfDoc, (Image) element));
+ break;
+ case Element.AUTHOR:
+ case Element.SUBJECT:
+ case Element.KEYWORDS:
+ case Element.TITLE:
+ case Element.PRODUCER:
+ case Element.CREATIONDATE:
+ rtfElements.Add(new RtfInfoElement(rtfDoc, (Meta) element));
+ break;
+ case Element.LIST:
+ rtfElements.Add(new RtfList(rtfDoc, (List) element));
+ break;
+ case Element.LISTITEM:
+ rtfElements.Add(new RtfListItem(rtfDoc, (ListItem) element));
+ break;
+ case Element.SECTION:
+ rtfElements.Add(new RtfSection(rtfDoc, (Section) element));
+ break;
+ case Element.CHAPTER:
+ rtfElements.Add(new RtfChapter(rtfDoc, (Chapter) element));
+ break;
+ case Element.TABLE:
+ try {
+ rtfElements.Add(new RtfTable(rtfDoc, (Table) element));
+ }
+ catch (InvalidCastException) {
+ rtfElements.Add(new RtfTable(rtfDoc, ((SimpleTable) element).CreateTable()));
+ }
+ break;
+ }
+
+ return (IRtfBasicElement[]) rtfElements.ToArray(typeof(IRtfBasicElement));
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/RtfWriter2.cs b/iTechSharp/iTextSharp/text/rtf/RtfWriter2.cs
new file mode 100644
index 0000000..a663d45
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/RtfWriter2.cs
@@ -0,0 +1,334 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.text;
+using iTextSharp.text.rtf.parser;
+/*
+ * $Id: RtfWriter2.cs,v 1.11 2008/05/23 17:24:11 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf {
+
+ /**
+ * The RtfWriter allows the creation of rtf documents via the iText system
+ *
+ * Version: $Id: RtfWriter2.cs,v 1.11 2008/05/23 17:24:11 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfWriter2 : DocWriter {
+ /**
+ * The RtfDocument this RtfWriter is creating
+ */
+ private RtfDocument rtfDoc = null;
+
+ /**
+ * Constructs a new RtfWriter that listens to the specified Document and
+ * writes its output to the Stream.
+ *
+ * @param doc The Document that this RtfWriter listens to
+ * @param os The Stream to write to
+ */
+ protected RtfWriter2(Document doc, Stream os) : base(doc, os) {
+ doc.AddDocListener(this);
+ rtfDoc = new RtfDocument();
+ }
+
+ /**
+ * Static method to generate RtfWriters
+ *
+ * @param doc The Document that this RtfWriter listens to
+ * @param os The Stream to write to
+ * @return The new RtfWriter
+ */
+ public static RtfWriter2 GetInstance(Document doc, Stream os) {
+ return new RtfWriter2(doc, os);
+ }
+
+ /**
+ * Sets the header to use
+ *
+ * @param hf The HeaderFooter to use
+ */
+ public override HeaderFooter Header {
+ set {
+ this.rtfDoc.GetDocumentHeader().SetHeader(value);
+ }
+ }
+
+ /**
+ * Resets the header
+ */
+ public override void ResetHeader() {
+ this.rtfDoc.GetDocumentHeader().SetHeader(null);
+ }
+
+ /**
+ * Sets the footer to use
+ *
+ * @param hf The HeaderFooter to use
+ */
+ public override HeaderFooter Footer {
+ set {
+ this.rtfDoc.GetDocumentHeader().SetFooter(value);
+ }
+ }
+
+ /**
+ * Resets the footer
+ */
+ public override void ResetFooter() {
+ this.rtfDoc.GetDocumentHeader().SetFooter(null);
+ }
+
+ /**
+ * This method is not supported in the RtfWriter
+ * @param i Unused
+ */
+ public override int PageCount {
+ set {}
+ }
+
+ /**
+ * This method is not supported in the RtfWriter
+ */
+ public override void ResetPageCount() {
+ }
+
+ /**
+ * Opens the RtfDocument
+ */
+ public override void Open() {
+ base.Open();
+ this.rtfDoc.Open();
+ }
+
+ /**
+ * Closes the RtfDocument. This causes the document to be written
+ * to the specified Stream
+ */
+ public override void Close() {
+ if (open) {
+ rtfDoc.WriteDocument(os);
+ base.Close();
+ this.rtfDoc = new RtfDocument();
+ }
+ }
+
+ /**
+ * Adds an Element to the Document
+ *
+ * @param element The element to be added
+ * @return false
+ * @throws DocumentException
+ */
+ public override bool Add(IElement element) {
+ if (pause) {
+ return false;
+ }
+ IRtfBasicElement[] rtfElements = rtfDoc.GetMapper().MapElement(element);
+ if(rtfElements.Length != 0) {
+ for (int i = 0; i < rtfElements.Length; i++) {
+ if (rtfElements[i] != null) {
+ rtfDoc.Add(rtfElements[i]);
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Adds a page break
+ *
+ * @return false
+ */
+ public override bool NewPage() {
+ rtfDoc.Add(new RtfNewPage(rtfDoc));
+ return true;
+ }
+
+ /**
+ * Sets the page margins
+ *
+ * @param left The left margin
+ * @param right The right margin
+ * @param top The top margin
+ * @param bottom The bottom margin
+ * @return false
+ */
+ public override bool SetMargins(float left, float right, float top, float bottom) {
+ rtfDoc.GetDocumentHeader().GetPageSetting().SetMarginLeft((int) (left * RtfElement.TWIPS_FACTOR));
+ rtfDoc.GetDocumentHeader().GetPageSetting().SetMarginRight((int) (right * RtfElement.TWIPS_FACTOR));
+ rtfDoc.GetDocumentHeader().GetPageSetting().SetMarginTop((int) (top * RtfElement.TWIPS_FACTOR));
+ rtfDoc.GetDocumentHeader().GetPageSetting().SetMarginBottom((int) (bottom * RtfElement.TWIPS_FACTOR));
+ return true;
+ }
+
+ /**
+ * Sets the size of the page
+ *
+ * @param rect A Rectangle representing the page
+ * @return false
+ */
+ public override bool SetPageSize(Rectangle rect) {
+ rtfDoc.GetDocumentHeader().GetPageSetting().SetPageSize(rect);
+ return true;
+ }
+
+ /**
+ * Whether to automagically generate table of contents entries when
+ * adding Chapters or Sections.
+ *
+ * @param autogenerate Whether to automatically generate TOC entries
+ */
+ public void SetAutogenerateTOCEntries(bool autogenerate) {
+ this.rtfDoc.SetAutogenerateTOCEntries(autogenerate);
+ }
+
+ /**
+ * Gets the RtfDocumentSettings that specify how the rtf document is generated.
+ *
+ * @return The current RtfDocumentSettings.
+ */
+ public RtfDocumentSettings GetDocumentSettings() {
+ return this.rtfDoc.GetDocumentSettings();
+ }
+
+ /**
+ * Adds the complete RTF document to the current RTF document being generated.
+ * It will parse the font and color tables and correct the font and color references
+ * so that the imported RTF document retains its formattings.
+ *
+ * @param documentSource The Stream to read the RTF document from.
+ * @throws IOException On errors reading the RTF document.
+ * @throws DocumentException On errors adding to this RTF document.
+ */
+ public void ImportRtfDocument(Stream documentSource) {
+ ImportRtfDocument(documentSource, null);
+ }
+
+ /**
+ * Adds the complete RTF document to the current RTF document being generated.
+ * It will parse the font and color tables and correct the font and color references
+ * so that the imported RTF document retains its formattings.
+ * Uses new RtfParser object.
+ *
+ * @param documentSource The Stream to read the RTF document from.
+ * @param eventListeners The array of event listeners. May be null
+ * @throws IOException
+ * @throws DocumentException
+ *
+ * @see com.lowagie.text.rtf.parser.RtfParser
+ * @see com.lowagie.text.rtf.parser.RtfParser#importRtfDocument(Reader, RtfDocument)
+ * @since 2.0.8
+ * @author Howard Shank
+ */
+ public void ImportRtfDocument(Stream documentSource, IEventListener[] events ) {
+ if(!this.open) {
+ throw new DocumentException("The document must be open to import RTF documents.");
+ }
+ RtfParser rtfImport = new RtfParser();
+ if(events != null) {
+ for(int idx=0;idx
+ *
+ * For convenience the RtfDirectContent provides a DIRECT_SOFT_LINEBREAK
+ * constant that makes it possible to easily add soft line-breaks anywhere in
+ * the RTF document.
+ *
+ * @version $Revision: 1.6 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfDirectContent : RtfAddableElement {
+ /**
+ * Add the DIRECT_SOFT_LINEBREAK to the Document to insert
+ * a soft line-break at that position.
+ */
+ public static RtfDirectContent DIRECT_SOFT_LINEBREAK = new RtfDirectContent("\\line");
+
+ /**
+ * The direct content to add.
+ */
+ private String directContent = "";
+
+ /**
+ * Constructs a new RtfDirectContent with the content to add.
+ *
+ * @param directContent The content to add.
+ */
+ public RtfDirectContent(String directContent) {
+ this.directContent = directContent;
+ }
+
+ /**
+ * Writes the element content to the given output stream.
+ */
+ public override void WriteContent(Stream outp) {
+ byte[] contentBytes = DocWriter.GetISOBytes(this.directContent);
+ outp.Write(contentBytes, 0, contentBytes.Length);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfCodePage.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfCodePage.cs
new file mode 100644
index 0000000..408714c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfCodePage.cs
@@ -0,0 +1,99 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/*
+ * $Id: RtfCodePage.cs,v 1.5 2008/05/16 19:30:50 psoares33 Exp $
+ *
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document {
+
+ /**
+ * The RtfCodePage class allows different code pages to be used in the rtf document.
+ * Currently always ansi / ansicpg1252
+ *
+ * Version: $Id: RtfCodePage.cs,v 1.5 2008/05/16 19:30:50 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfCodePage : RtfElement, IRtfExtendedElement {
+ /**
+ * Constant for ansi encoded rtf documents
+ */
+ private static byte[] ANSI = DocWriter.GetISOBytes("\\ansi");
+ /**
+ * Constant for the ansi codepage
+ */
+ private static byte[] ANSI_CODEPAGE = DocWriter.GetISOBytes("\\ansicpg");
+
+ /**
+ * Construct an RtfCodePage
+ *
+ * @param doc The RtfDocument this RtfCodePage belongs to
+ */
+ public RtfCodePage(RtfDocument doc) : base(doc) {
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Writes the selected codepage
+ */
+ public virtual void WriteDefinition(Stream result) {
+ result.Write(ANSI, 0, ANSI.Length);
+ result.Write(ANSI_CODEPAGE, 0, ANSI_CODEPAGE.Length);
+ byte[] t = IntToByteArray(1252);
+ result.Write(t, 0, t.Length);
+ result.WriteByte((byte)'\n');
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfDocument.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfDocument.cs
new file mode 100644
index 0000000..efee2ec
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfDocument.cs
@@ -0,0 +1,347 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Text;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document.output;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.graphic;
+/*
+ * $Id: RtfDocument.cs,v 1.12 2008/05/16 19:30:50 psoares33 Exp $
+ *
+ *
+ * Copyright 2003, 2004, 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document {
+
+ /**
+ * The RtfDocument stores all document related data and also the main data stream.
+ * INTERNAL CLASS - NOT TO BE USED DIRECTLY
+ *
+ * Version: $Id: RtfDocument.cs,v 1.12 2008/05/16 19:30:50 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Todd Bush (Todd.Bush@canopysystems.com) [Tab support]
+ */
+ public class RtfDocument : RtfElement {
+ /**
+ * Stores the actual document data
+ */
+ private IRtfDataCache data = null;
+ /**
+ * The RtfMapper to use in this RtfDocument
+ */
+ private RtfMapper mapper = null;
+ /**
+ * The RtfDocumentHeader that handles all document header methods
+ */
+ private RtfDocumentHeader documentHeader = null;
+ /**
+ * Stores integers that have been generated as unique random numbers
+ */
+ private ArrayList previousRandomInts = null;
+ /**
+ * Whether to automatically generate TOC entries for Chapters and Sections. Defaults to false
+ */
+ private bool autogenerateTOCEntries = false;
+ /**
+ * The RtfDocumentSettings for this RtfDocument.
+ */
+ private RtfDocumentSettings documentSettings = null;
+
+ /**
+ * The last RtfBasicElement that was added directly to the RtfDocument.
+ */
+ private IRtfBasicElement lastElementWritten = null;
+
+ /**
+ * Constant for the Rtf document start
+ */
+ private static byte[] RTF_DOCUMENT = DocWriter.GetISOBytes("\\rtf1");
+ private static byte[] FSC_LINE = DocWriter.GetISOBytes("\\line ");
+ private static byte[] FSC_PAR = DocWriter.GetISOBytes("\\par ");
+ private static byte[] FSC_TAB = DocWriter.GetISOBytes("\\tab ");
+ private static byte[] FSC_PAGE_PAR = DocWriter.GetISOBytes("\\page\\par ");
+ private static byte[] FSC_NEWPAGE = DocWriter.GetISOBytes("$newpage$");
+ private static byte[] FSC_BACKSLASH = DocWriter.GetISOBytes("\\");
+ private static byte[] FSC_HEX_PREFIX = DocWriter.GetISOBytes("\\\'");
+ private static byte[] FSC_UNI_PREFIX = DocWriter.GetISOBytes("\\u");
+
+ private static Random random = new Random();
+
+ /**
+ * The default constructor for a RtfDocument
+ */
+ public RtfDocument() : base(null) {
+ this.data = new RtfMemoryCache();
+ this.mapper = new RtfMapper(this);
+ this.documentHeader = new RtfDocumentHeader(this);
+ this.documentHeader.Init();
+ this.previousRandomInts = new ArrayList();
+ this.documentSettings = new RtfDocumentSettings(this);
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Writes the document
+ *
+ * @param outs The Stream
to write the RTF document to.
+ */
+ public void WriteDocument(Stream outs) {
+ try {
+ outs.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ outs.Write(RtfDocument.RTF_DOCUMENT, 0, RtfDocument.RTF_DOCUMENT.Length);
+ this.documentHeader.WriteContent(outs);
+ this.data.WriteTo(outs);
+ outs.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ } catch (IOException) {
+ }
+ }
+
+ /**
+ * Opens the RtfDocument and initialises the data cache. If the data cache is
+ * set to CACHE_DISK, but the cache cannot be initialised then the memory cache
+ * is used.
+ */
+ public void Open() {
+ try {
+ switch (this.documentSettings.GetDataCacheStyle()) {
+ case RtfDataCache.CACHE_MEMORY_EFFICIENT:
+ this.data = new RtfEfficientMemoryCache();
+ break;
+ case RtfDataCache.CACHE_MEMORY:
+ this.data = new RtfMemoryCache();
+ break;
+ case RtfDataCache.CACHE_DISK:
+ this.data = new RtfDiskCache();
+ break;
+ default:
+ throw new ArgumentException("unknown");
+ }
+ } catch (IOException) {
+ this.data = new RtfMemoryCache();
+ }
+ }
+
+ /**
+ * Adds an element to the rtf document
+ *
+ * @param element The element to add
+ */
+ public void Add(IRtfBasicElement element) {
+ try {
+ if (element is RtfInfoElement) {
+ this.documentHeader.AddInfoElement((RtfInfoElement) element);
+ } else {
+ if (element is RtfImage) {
+ ((RtfImage) element).SetTopLevelElement(true);
+ }
+ element.WriteContent(this.data.GetOutputStream());
+ this.lastElementWritten = element;
+ }
+ } catch (IOException) {
+ }
+ }
+
+ /**
+ * Gets the RtfMapper object of this RtfDocument
+ *
+ * @return The RtfMapper
+ */
+ public RtfMapper GetMapper() {
+ return this.mapper;
+ }
+
+ /**
+ * Generates a random integer that is unique with respect to the document.
+ *
+ * @return A random int
+ */
+ public int GetRandomInt() {
+ int newInt;
+ do {
+ lock (random) {
+ newInt = random.Next(int.MaxValue - 2);
+ }
+ } while (this.previousRandomInts.Contains(newInt));
+ this.previousRandomInts.Add(newInt);
+ return newInt;
+ }
+
+ /**
+ * Gets the RtfDocumentHeader of this RtfDocument
+ *
+ * @return The RtfDocumentHeader of this RtfDocument
+ */
+ public RtfDocumentHeader GetDocumentHeader() {
+ return this.documentHeader;
+ }
+
+ /**
+ * Writes the given string to the given {@link Stream} encoding the string characters.
+ *
+ * @param outp destination Stream
+ * @param str string to write
+ * @param useHex if true
hex encoding characters is preferred to unicode encoding if possible
+ * @param softLineBreaks if true
return characters are written as soft line breaks
+ *
+ * @throws IOException
+ */
+ public void FilterSpecialChar(Stream outp, String str, bool useHex, bool softLineBreaks) {
+ if (outp == null) {
+ throw new ArgumentException("null OutpuStream");
+ }
+
+ bool alwaysUseUniCode = this.documentSettings.IsAlwaysUseUnicode();
+ if (str == null) {
+ return;
+ }
+ int len = str.Length;
+ if (len == 0) {
+ return;
+ }
+ byte[] t = null;
+ for (int k = 0; k < len; k++) {
+ char c = str[k];
+ if (c < 0x20) {
+ //allow return and tab only
+ if (c == '\n') {
+ outp.Write(t = softLineBreaks ? FSC_LINE : FSC_PAR, 0, t.Length);
+ } else if (c == '\t') {
+ outp.Write(FSC_TAB, 0, FSC_TAB.Length);
+ } else {
+ outp.WriteByte((byte)'?');
+ }
+ } else if ((c == '\\') || (c == '{') || (c == '}')) {
+ //escape
+ outp.Write(FSC_BACKSLASH, 0, FSC_BACKSLASH.Length);
+ outp.WriteByte((byte)c);
+ } else if ((c == '$') && (len-k >= FSC_NEWPAGE.Length) && SubMatch(str, k, FSC_NEWPAGE)) {
+ outp.Write(FSC_PAGE_PAR, 0, FSC_PAGE_PAR.Length);
+ k += FSC_NEWPAGE.Length-1;
+ } else {
+ if ((c > 0xff) || ((c > 'z') && alwaysUseUniCode)) {
+ if (useHex && (c <= 0xff)) {
+ //encode as 2 char hex string
+ outp.Write(FSC_HEX_PREFIX, 0, FSC_HEX_PREFIX.Length);
+ outp.Write(RtfImage.byte2charLUT, c*2, 2);
+ } else {
+ //encode as decimal, signed short value
+ outp.Write(FSC_UNI_PREFIX, 0, FSC_UNI_PREFIX.Length);
+ String s = ((short)c).ToString();
+ for (int x = 0; x < s.Length; x++) {
+ outp.WriteByte((byte)s[x]);
+ }
+ outp.WriteByte((byte)'?');
+ }
+ } else {
+ outp.WriteByte((byte)c);
+ }
+ }
+ }
+ }
+ /**
+ * Returns true
if m.length characters in str, starting at offset soff
+ * match the bytes in the given array m.
+ *
+ * @param str the string to search for a match
+ * @param soff the starting offset in str
+ * @param m the array to match
+ * @return true
if there is match
+ */
+ private static bool SubMatch(String str, int soff, byte[] m)
+ {
+ for (int k = 0; k < m.Length; k++) {
+ if (str[soff++] != (char)m[k]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Whether to automagically generate table of contents entries when
+ * adding Chapters or Sections.
+ *
+ * @param autogenerate Whether to automatically generate TOC entries
+ */
+ public void SetAutogenerateTOCEntries(bool autogenerate) {
+ this.autogenerateTOCEntries = autogenerate;
+ }
+
+ /**
+ * Get whether to autmatically generate table of contents entries
+ *
+ * @return Wheter to automatically generate TOC entries
+ */
+ public bool GetAutogenerateTOCEntries() {
+ return this.autogenerateTOCEntries;
+ }
+
+ /**
+ * Gets the RtfDocumentSettings that specify how the rtf document is generated.
+ *
+ * @return The current RtfDocumentSettings.
+ */
+ public RtfDocumentSettings GetDocumentSettings() {
+ return this.documentSettings;
+ }
+ /**
+ * Gets the last RtfBasicElement that was directly added to the RtfDocument.
+ *
+ * @return The last RtfBasicElement that was directly added to the RtfDocument.
+ */
+ public IRtfBasicElement GetLastElementWritten() {
+ return this.lastElementWritten;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfDocumentHeader.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfDocumentHeader.cs
new file mode 100644
index 0000000..d00b788
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfDocumentHeader.cs
@@ -0,0 +1,321 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document.output;
+using iTextSharp.text.rtf.list;
+using ST = iTextSharp.text.rtf.style;
+using iTextSharp.text.rtf.style;
+using HF = iTextSharp.text.rtf.headerfooter;
+using iTextSharp.text.rtf.headerfooter;
+//using iTextSharp.text.rtf;
+/*
+ * $Id: RtfDocumentHeader.cs,v 1.11 2008/05/16 19:30:51 psoares33 Exp $
+ *
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document {
+
+ /**
+ * The RtfDocumentHeader contains all classes required for the generation of
+ * the document header area.
+ *
+ * @version $Id: RtfDocumentHeader.cs,v 1.11 2008/05/16 19:30:51 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+ public class RtfDocumentHeader : RtfElement {
+ /**
+ * Constant for the title page
+ */
+ private static byte[] TITLE_PAGE = DocWriter.GetISOBytes("\\titlepg");
+ /**
+ * Constant for facing pages
+ */
+ private static byte[] FACING_PAGES = DocWriter.GetISOBytes("\\facingp");
+
+ /**
+ * The code page to use
+ */
+ private RtfCodePage codePage = null;
+ /**
+ * Stores all the colors used in the document
+ */
+ private RtfColorList colorList = null;
+ /**
+ * Stores all the fonts used in the document
+ */
+ private RtfFontList fontList = null;
+ /**
+ * Manages List tables
+ */
+ private RtfListTable listTable = null;
+ /**
+ * Stores all paragraph styles used in the document.
+ */
+ private RtfStylesheetList stylesheetList = null;
+ /**
+ * Generator string in document
+ */
+ private RtfGenerator generator = null;
+ /**
+ * The information group with author/subject/keywords/title/producer/creationdate data
+ */
+ private RtfInfoGroup infoGroup = null;
+ /**
+ * The protection settings
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ private RtfProtectionSetting protectionSetting = null;
+ /**
+ * The page settings
+ */
+ private RtfPageSetting pageSetting = null;
+ /**
+ * The current RtfHeaderFooterGroup for the header
+ */
+ private HeaderFooter header = null;
+ /**
+ * The current RtfHeaderFooterGroup for the footer
+ */
+ private HeaderFooter footer = null;
+
+ /**
+ * Constructs a RtfDocumentHeader for a RtfDocument
+ *
+ * @param doc The RtfDocument this RtfDocumentHeader belongs to
+ */
+ protected internal RtfDocumentHeader(RtfDocument doc) : base(doc) {
+ }
+
+ /**
+ * Initialises the RtfDocumentHeader.
+ */
+ protected internal void Init() {
+ this.codePage = new RtfCodePage(this.document);
+ this.colorList = new RtfColorList(this.document);
+ this.fontList = new RtfFontList(this.document);
+ this.listTable = new RtfListTable(this.document);
+ this.stylesheetList = new RtfStylesheetList(this.document);
+ this.infoGroup = new RtfInfoGroup(this.document);
+ this.protectionSetting = new RtfProtectionSetting(this.document);
+ this.pageSetting = new RtfPageSetting(this.document);
+ this.header = new RtfHeaderFooterGroup(this.document, HF.RtfHeaderFooter.TYPE_HEADER);
+ this.footer = new RtfHeaderFooterGroup(this.document, HF.RtfHeaderFooter.TYPE_FOOTER);
+ this.generator = new RtfGenerator(this.document);
+ }
+
+ /**
+ * Write the contents of the document header area.
+ */
+ public override void WriteContent(Stream result) {
+ try {
+ // This is so that all colour, font and similar information is processed once, before
+ // the header section is written.
+ WriteSectionDefinition(new RtfNilOutputStream());
+
+ this.codePage.WriteDefinition(result);
+ this.fontList.WriteDefinition(result);
+ this.colorList.WriteDefinition(result);
+ this.stylesheetList.WriteDefinition(result);
+ this.listTable.WriteDefinition(result);
+ this.generator.WriteContent(result);
+ this.infoGroup.WriteContent(result);
+ this.protectionSetting.WriteDefinition(result);
+ this.pageSetting.WriteDefinition(result);
+
+ WriteSectionDefinition(result);
+ } catch (IOException) {
+ }
+ }
+
+ /**
+ * Writes the section definition data
+ * @param result
+ */
+ public void WriteSectionDefinition(Stream result) {
+ try {
+ RtfHeaderFooterGroup header = ConvertHeaderFooter(this.header, HF.RtfHeaderFooter.TYPE_HEADER);
+ RtfHeaderFooterGroup footer = ConvertHeaderFooter(this.footer, HF.RtfHeaderFooter.TYPE_FOOTER);
+ if (header.HasTitlePage() || footer.HasTitlePage()) {
+ result.Write(TITLE_PAGE, 0, TITLE_PAGE.Length);
+ header.SetHasTitlePage();
+ footer.SetHasTitlePage();
+ }
+ if (header.HasFacingPages() || footer.HasFacingPages()) {
+ result.Write(FACING_PAGES, 0, FACING_PAGES.Length);
+ header.SetHasFacingPages();
+ footer.SetHasFacingPages();
+ }
+ footer.WriteContent(result);
+ header.WriteContent(result);
+ pageSetting.WriteSectionDefinition(result);
+ } catch (IOException) {
+ }
+ }
+
+ /**
+ * Gets the number of the specified RtfFont
+ *
+ * @param font The RtfFont for which to get the number
+ * @return The number of the font
+ */
+ public int GetFontNumber(ST.RtfFont font) {
+ return this.fontList.GetFontNumber(font);
+ }
+
+ /**
+ * Gets the number of the specified RtfColor
+ *
+ * @param color The RtfColor for which to get the number
+ * @return The number of the color
+ */
+ public int GetColorNumber(ST.RtfColor color) {
+ return this.colorList.GetColorNumber(color);
+ }
+
+ /**
+ * Gets the number of the specified RtfList
+ *
+ * @param list The RtfList for which to get the number
+ * @return The number of the list
+ */
+ public int GetListNumber(RtfList list) {
+ return this.listTable.GetListNumber(list);
+ }
+
+ /**
+ * Gets the RtfParagraphStyle with the given style name.
+ *
+ * @param styleName The style name of the RtfParagraphStyle to get.
+ * @return The RtfParagraphStyle with the given style name or null.
+ */
+ public RtfParagraphStyle GetRtfParagraphStyle(String styleName) {
+ return this.stylesheetList.GetRtfParagraphStyle(styleName);
+ }
+
+ /**
+ * Removes a RtfList from the list table
+ *
+ * @param list The RtfList to remove
+ */
+ public void FreeListNumber(RtfList list) {
+ this.listTable.FreeListNumber(list);
+ }
+
+ /**
+ * Gets the RtfPageSetting object of this RtfDocument
+ *
+ * @return The RtfPageSetting object
+ */
+ public RtfPageSetting GetPageSetting() {
+ return this.pageSetting;
+ }
+
+ /**
+ * Adds an RtfInfoElement to the list of RtfInfoElements
+ *
+ * @param rtfInfoElement The RtfInfoElement to add
+ */
+ public void AddInfoElement(RtfInfoElement rtfInfoElement) {
+ this.infoGroup.Add(rtfInfoElement);
+ }
+
+ /**
+ * Sets the current header to use
+ *
+ * @param header The HeaderFooter to use as header
+ */
+ public void SetHeader(HeaderFooter header) {
+ this.header = header;
+ }
+
+ /**
+ * Sets the current footer to use
+ *
+ * @param footer The HeaderFooter to use as footer
+ */
+ public void SetFooter(HeaderFooter footer) {
+ this.footer = footer;
+ }
+
+ /**
+ * Registers the RtfParagraphStyle for further use in the document.
+ *
+ * @param rtfParagraphStyle The RtfParagraphStyle to register.
+ */
+ public void RegisterParagraphStyle(RtfParagraphStyle rtfParagraphStyle) {
+ this.stylesheetList.RegisterParagraphStyle(rtfParagraphStyle);
+ }
+
+ /**
+ * Converts a HeaderFooter into a RtfHeaderFooterGroup. Depending on which class
+ * the HeaderFooter is, the correct RtfHeaderFooterGroup is created.
+ *
+ * @param hf The HeaderFooter to convert.
+ * @param type Whether the conversion is being done on a footer or header
+ * @return The converted RtfHeaderFooterGroup.
+ * @see com.lowagie.text.rtf.headerfooter.RtfHeaderFooter
+ * @see com.lowagie.text.rtf.headerfooter.RtfHeaderFooterGroup
+ */
+ private RtfHeaderFooterGroup ConvertHeaderFooter(HeaderFooter hf, int type) {
+ if (hf != null) {
+ if (hf is RtfHeaderFooterGroup) {
+ return new RtfHeaderFooterGroup(this.document, (RtfHeaderFooterGroup) hf, type);
+ } else if (hf is RtfHeaderFooter) {
+ return new RtfHeaderFooterGroup(this.document, (RtfHeaderFooter) hf, type);
+ } else {
+ return new RtfHeaderFooterGroup(this.document, hf, type);
+ }
+ } else {
+ return new RtfHeaderFooterGroup(this.document, type);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfDocumentSettings.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfDocumentSettings.cs
new file mode 100644
index 0000000..657e307
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfDocumentSettings.cs
@@ -0,0 +1,566 @@
+using System;
+using iTextSharp.text.rtf.style;
+using iTextSharp.text.rtf.document.output;
+
+/*
+ * $Id: RtfDocumentSettings.cs,v 1.10 2008/05/16 19:30:51 psoares33 Exp $
+ *
+ *
+ * Copyright 2003, 2004, 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document {
+
+ /**
+ * The RtfDocumentSettings contains output specific settings. These settings modify
+ * how the actual document is then generated and some settings may mean that some
+ * RTF readers can't read the document or render it wrongly.
+ *
+ * @version $Id: RtfDocumentSettings.cs,v 1.10 2008/05/16 19:30:51 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+ public class RtfDocumentSettings {
+
+ /**
+ * The RtfDocument this RtfDocumentSettings belongs to.
+ */
+ private RtfDocument document = null;
+ /**
+ * Whether to also output the table row definition after the cell content.
+ */
+ private bool outputTableRowDefinitionAfter = true;
+ /**
+ * Whether to output the line breaks that make the rtf document source more readable.
+ */
+ private bool outputDebugLineBreaks = true;
+ /**
+ * Whether to always generate soft linebreaks for \n in Chunks.
+ */
+ private bool alwaysGenerateSoftLinebreaks = false;
+ /**
+ * Whether to always translate characters past 'z' into unicode representations.
+ */
+ private bool alwaysUseUnicode = true;
+ /**
+ * How to cache the document during generation. Defaults to RtfDataCache.CACHE_MEMORY;
+ */
+ private int dataCacheStyle = RtfDataCache.CACHE_MEMORY;
+ /**
+ * Whether to write image scaling information. This is required for Word 2000, 97 and Word for Mac
+ */
+ private bool writeImageScalingInformation = false;
+ /**
+ * Whether images should be written in order to mimick the PDF output.
+ */
+ private bool imagePDFConformance = true;
+ /**
+ * Document protection level
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ private int protectionLevel = RtfProtection.LEVEL_NONE;
+ /**
+ * Document protection level password hash.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ private String protectionHash = null;
+ /**
+ * Document read password hash
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ //private String writereservhash = null; //\*\writereservhash - not implemented
+ /**
+ * Document recommended to be opened in read only mode.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ private bool readOnlyRecommended = false;
+ /**
+ * Images are written as binary data and not hex encoded.
+ * @since 2.1.1
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ private bool imageWrittenAsBinary = true;
+
+ /**
+ * Constructs a new RtfDocumentSettings object.
+ *
+ * @param document The RtfDocument this RtfDocumentSettings belong to.
+ */
+ public RtfDocumentSettings(RtfDocument document) {
+ this.document = document;
+ }
+
+ /**
+ * Gets whether to output the line breaks for increased rtf document readability.
+ *
+ * @return Whether to output line breaks.
+ */
+ public bool IsOutputDebugLineBreaks() {
+ return outputDebugLineBreaks;
+ }
+
+ /**
+ * Sets whether to output the line breaks for increased rtf document readability.
+ * Some line breaks may be added where the rtf specification demands it.
+ *
+ * @param outputDebugLineBreaks The outputDebugLineBreaks to set.
+ */
+ public void SetOutputDebugLineBreaks(bool outputDebugLineBreaks) {
+ this.outputDebugLineBreaks = outputDebugLineBreaks;
+ }
+
+ /**
+ * Gets whether the table row definition should also be written after the cell content.
+ *
+ * @return Returns the outputTableRowDefinitionAfter.
+ */
+ public bool IsOutputTableRowDefinitionAfter() {
+ return outputTableRowDefinitionAfter;
+ }
+
+ /**
+ * Sets whether the table row definition should also be written after the cell content.
+ * This is recommended to be set to true
if you need Word2000 compatiblity and
+ * false
if the document should be opened in OpenOffice.org Writer.
+ *
+ * @param outputTableRowDefinitionAfter The outputTableRowDefinitionAfter to set.
+ */
+ public void SetOutputTableRowDefinitionAfter(
+ bool outputTableRowDefinitionAfter) {
+ this.outputTableRowDefinitionAfter = outputTableRowDefinitionAfter;
+ }
+
+ /**
+ * Gets whether all linebreaks inside Chunks are generated as soft linebreaks.
+ *
+ * @return True
if soft linebreaks are generated, false
for hard linebreaks.
+ */
+ public bool IsAlwaysGenerateSoftLinebreaks() {
+ return this.alwaysGenerateSoftLinebreaks;
+ }
+
+ /**
+ * Sets whether to always generate soft linebreaks.
+ *
+ * @param alwaysGenerateSoftLinebreaks Whether to always generate soft linebreaks.
+ */
+ public void SetAlwaysGenerateSoftLinebreaks(bool alwaysGenerateSoftLinebreaks) {
+ this.alwaysGenerateSoftLinebreaks = alwaysGenerateSoftLinebreaks;
+ }
+
+ /**
+ * Gets whether all characters bigger than 'z' are represented as unicode.
+ *
+ * @return True
if unicode representation is used, false
otherwise.
+ */
+ public bool IsAlwaysUseUnicode() {
+ return this.alwaysUseUnicode;
+ }
+
+ /**
+ * Sets whether to represent all characters bigger than 'z' as unicode.
+ *
+ * @param alwaysUseUnicode True
to use unicode representation, false
otherwise.
+ */
+ public void SetAlwaysUseUnicode(bool alwaysUseUnicode) {
+ this.alwaysUseUnicode = alwaysUseUnicode;
+ }
+
+ /**
+ * Registers the RtfParagraphStyle for further use in the document. This does not need to be
+ * done for the default styles in the RtfParagraphStyle object. Those are added automatically.
+ *
+ * @param rtfParagraphStyle The RtfParagraphStyle to register.
+ */
+ public void RegisterParagraphStyle(RtfParagraphStyle rtfParagraphStyle) {
+ this.document.GetDocumentHeader().RegisterParagraphStyle(rtfParagraphStyle);
+ }
+
+ /**
+ * Sets the data cache style. This controls where the document is cached during
+ * generation. Two cache styles are supported:
+ *
+ *
+ *
+ * @param dataCacheStyle The data cache style to set. Valid constants can be found
+ * in RtfDataCache.
+ * @see com.lowagie.text.rtf.document.output.output.RtfDataCache.
+ */
+ public void SetDataCacheStyle(int dataCacheStyle) {
+ switch (dataCacheStyle) {
+ case RtfDataCache.CACHE_MEMORY_EFFICIENT:
+ this.dataCacheStyle = RtfDataCache.CACHE_MEMORY_EFFICIENT;
+ break;
+ case RtfDataCache.CACHE_DISK:
+ this.dataCacheStyle = RtfDataCache.CACHE_DISK;
+ break;
+ default:
+ //case RtfDataCache.CACHE_MEMORY:
+ this.dataCacheStyle = RtfDataCache.CACHE_MEMORY;
+ break;
+ }
+ }
+
+ /**
+ * Gets the current data cache style.
+ *
+ * @return The current data cache style.
+ */
+ public int GetDataCacheStyle() {
+ return this.dataCacheStyle;
+ }
+
+ /**
+ * Gets the current setting on image PDF conformance.
+ *
+ * @return The current image PDF conformance.
+ */
+ public bool IsImagePDFConformance() {
+ return this.imagePDFConformance;
+ }
+
+
+ /**
+ * Sets the image PDF conformance setting. By default images will be added
+ * as if they were displayed with 72dpi. Set this to false
+ * if images should be generated with the Word default DPI setting.
+ *
+ * @param imagePDFConformance True
if PDF equivalence is desired, false
+ * for the default Word display.
+ */
+ public void SetImagePDFConformance(bool imagePDFConformance) {
+ this.imagePDFConformance = imagePDFConformance;
+ }
+
+
+ /**
+ * Gets whether to write scaling information for images.
+ *
+ * @return Whether to write scaling information for images.
+ */
+ public bool IsWriteImageScalingInformation() {
+ return this.writeImageScalingInformation;
+ }
+
+
+ /**
+ * Sets whether image scaling information should be written. This needs to be set to true
+ * MS Word 2000, MS Word 97 and Word for Mac.
+ *
+ * @param writeImageScalingInformation Whether to write image scaling information.
+ */
+ public void SetWriteImageScalingInformation(bool writeImageScalingInformation) {
+ this.writeImageScalingInformation = writeImageScalingInformation;
+ }
+
+ /**
+ * Set the options required for RTF documents to display correctly in MS Word 2000
+ * and MS Word 97.
+ * Sets outputTableRowDefinitionAfter = true
and writeImageScalingInformation = true
.
+ */
+ public void SetOptionsForMSWord2000And97() {
+ this.SetOutputTableRowDefinitionAfter(true);
+ this.SetWriteImageScalingInformation(true);
+ }
+
+ /**
+ * Set the options required for RTF documents to display correctly in MS Word for Mac.
+ * Sets writeImageScalingInformation = true
.
+ */
+ public void SetOptionsForMSWordForMac() {
+ this.SetWriteImageScalingInformation(true);
+ }
+
+ /**
+ * Set the options required for RTF documents to display correctly in MS Word XP (2002).
+ * Sets writeImageScalingInformation = false
.
+ */
+ public void SetOptionsForMSWordXP() {
+ this.SetWriteImageScalingInformation(false);
+ }
+
+ /**
+ * Set the options required for RTF documents to display correctly in OpenOffice.Org
+ * Writer.
+ * Sets outputTableRowDefinitionAfter = false
.
+ */
+ public void SetOptionsForOpenOfficeOrg() {
+ this.SetOutputTableRowDefinitionAfter(false);
+ }
+
+ /**
+ * @param level Document protecton level
+ * @param pwd Document password - clear text
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public bool SetProtection(int level, String pwd) {
+ bool result = false;
+ if (this.protectionHash == null) {
+ if (!SetProtectionLevel(level)) {
+ result = false;
+ }
+ else
+ {
+ protectionHash = RtfProtection.GenerateHash(pwd);
+ result = true;
+ }
+ }
+ else {
+ if (this.protectionHash.Equals(RtfProtection.GenerateHash(pwd))) {
+ if (!SetProtectionLevel(level)) {
+ result = false;
+ }
+ else
+ {
+ protectionHash = RtfProtection.GenerateHash(pwd);
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param pwd Document password - clear text
+ * @return true if document unprotected, false if protection is not removed.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public bool UnprotectDocument(String pwd) {
+ bool result = false;
+ if (this.protectionHash.Equals(RtfProtection.GenerateHash(pwd))) {
+ this.protectionLevel = RtfProtection.LEVEL_NONE;
+ this.protectionHash = null;
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * @param level Document protection level
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public bool SetProtectionLevel(int level) {
+ bool result = false;
+ switch (level) {
+ case RtfProtection.LEVEL_NONE:
+ if (this.protectionHash == null) {
+ break;
+ }
+ goto case RtfProtection.LEVEL_ANNOTPROT;
+ case RtfProtection.LEVEL_ANNOTPROT:
+ case RtfProtection.LEVEL_FORMPROT:
+ case RtfProtection.LEVEL_REVPROT:
+ case RtfProtection.LEVEL_READPROT:
+ this.protectionLevel = level;
+ result = true;
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * This function is not intended for general use. Please see 'public bool SetProtection(int level, String pwd)'
+ * @param pwd Password HASH to set the document password hash to.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public void SetPasswordHash(String pwd) {
+ if (pwd != null && pwd.Length != 8) return;
+ this.protectionHash = pwd;
+ }
+
+ /**
+ * Converts protection level from internal bitmap value to protlevel output value
+ * @return
+ * 0 = Revision protection
+ * 1 = Annotation/Comment protection
+ * 2 = Form protection
+ * 3 = Read only protection
+ *
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ private int ConvertProtectionLevel() {
+ int level = 0;
+ switch (this.protectionLevel) {
+ case RtfProtection.LEVEL_NONE:
+ break;
+ case RtfProtection.LEVEL_REVPROT:
+ level = 0;
+ break;
+ case RtfProtection.LEVEL_ANNOTPROT:
+ level = 1;
+ break;
+ case RtfProtection.LEVEL_FORMPROT:
+ level = 2;
+ break;
+ case RtfProtection.LEVEL_READPROT:
+ level = 3;
+ break;
+ }
+ return level;
+
+ }
+
+ /**
+ * @return RTF document protection level
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public int GetProtectionLevelRaw() {
+ return this.protectionLevel;
+ }
+
+ /**
+ * @return RTF document protection level
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public int GetProtectionLevel() {
+ return ConvertProtectionLevel();
+ }
+
+ /**
+ * @return RTF document protection level as a byte array (byte[])
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public byte[] GetProtectionLevelBytes() {
+ return DocWriter.GetISOBytes(ConvertProtectionLevel().ToString());
+ }
+
+ /**
+ * @param oldPwd Old password - clear text
+ * @param newPwd New password - clear text
+ * @return true if password set, false if password not set
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public bool SetNewPassword(String oldPwd, String newPwd) {
+ bool result = false;
+ if (this.protectionHash.Equals(RtfProtection.GenerateHash(oldPwd))) {
+ this.protectionHash = RtfProtection.GenerateHash(newPwd);
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Set the RTF flag that recommends the document be opened in read only mode.
+ * @param value true if the flag is to be set, false if it is NOT to be set
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public void SetReadOnlyRecommended(bool value) {
+ this.readOnlyRecommended = value;
+ }
+
+ /**
+ * Get the RTF flag that recommends if the the document should be opened in read only mode.
+ * @return true if flag is set, false if it is not set
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public bool GetReadOnlyRecommended() {
+ return this.readOnlyRecommended;
+ }
+
+ /**
+ * Determine if document has protection enabled.
+ * @return true if protection is enabled, false if it is not enabled
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public bool IsDocumentProtected() {
+ return !(this.protectionHash == null);
+ }
+
+ /**
+ * Obtain the password has as a byte array.
+ * @return The bytes of the password hash as a byte array (byte[])
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public byte[] GetProtectionHashBytes() {
+ return DocWriter.GetISOBytes(this.protectionHash);
+ }
+
+ /**
+ * Set whether images are written as binary data or are hex encoded.
+ *
+ * @param imageWrittenAsBinary True
to write images as binary data, false
for hex encoding.
+ * @since 2.1.1
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public void SetImageWrittenAsBinary(bool imageWrittenAsBinary) {
+ this.imageWrittenAsBinary = imageWrittenAsBinary;
+ }
+
+ /**
+ * Gets whether images are written as binary data or are hex encoded. Defaults to true
.
+ *
+ * @since 2.1.1
+ * @return True
if images are written as binary data, false
if hex encoded.
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public bool IsImageWrittenAsBinary() {
+ return this.imageWrittenAsBinary;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfGenerator.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfGenerator.cs
new file mode 100644
index 0000000..a46f483
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfGenerator.cs
@@ -0,0 +1,92 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/*
+ * $Id: RtfGenerator.cs,v 1.3 2008/05/13 11:25:44 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+
+namespace iTextSharp.text.rtf.document {
+ /**
+ * The RtfGenerator creates the (\*\generator ...} element.
+ *
+ * @version $Id: RtfGenerator.cs,v 1.3 2008/05/13 11:25:44 psoares33 Exp $
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public class RtfGenerator : RtfElement {
+ /**
+ * Generator group starting tag
+ */
+ private static byte[] GENERATOR = DocWriter.GetISOBytes("\\*\\generator");
+
+ /**
+ * Constructs a RtfGenerator
belonging to a RtfDocument
+ *
+ * @param doc The RtfDocument
this RtfGenerator
belongs to
+ */
+ public RtfGenerator(RtfDocument doc) : base(doc) {
+ }
+
+
+ /**
+ * Writes the RTF generator group.
+ */
+ public override void WriteContent(Stream result) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(GENERATOR, 0, GENERATOR.Length);
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ byte[] t;
+ result.Write(t = DocWriter.GetISOBytes(Document.Version), 0, t.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfInfoElement.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfInfoElement.cs
new file mode 100644
index 0000000..242fc49
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfInfoElement.cs
@@ -0,0 +1,168 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/*
+ * $Id: RtfInfoElement.cs,v 1.6 2008/05/16 19:30:51 psoares33 Exp $
+ *
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document {
+
+ /**
+ * Stores one information group element. Valid elements are
+ * author, title, subject, keywords, producer and creationdate.
+ *
+ * @version $Id: RtfInfoElement.cs,v 1.6 2008/05/16 19:30:51 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+ public class RtfInfoElement : RtfElement {
+
+ /**
+ * Constant for the author element
+ */
+ private static byte[] INFO_AUTHOR = DocWriter.GetISOBytes("\\author");
+ /**
+ * Constant for the subject element
+ */
+ private static byte[] INFO_SUBJECT = DocWriter.GetISOBytes("\\subject");
+ /**
+ * Constant for the keywords element
+ */
+ private static byte[] INFO_KEYWORDS = DocWriter.GetISOBytes("\\keywords");
+ /**
+ * Constant for the title element
+ */
+ private static byte[] INFO_TITLE = DocWriter.GetISOBytes("\\title");
+ /**
+ * Constant for the producer element
+ */
+ private static byte[] INFO_PRODUCER = DocWriter.GetISOBytes("\\operator");
+ /**
+ * Constant for the creationdate element
+ */
+ private static byte[] INFO_CREATION_DATE = DocWriter.GetISOBytes("\\creationdate");
+
+ /**
+ * The type of this RtfInfoElement. The values from Element.INFO_ELEMENT_NAME are used.
+ */
+ private int infoType = -1;
+ /**
+ * The content of this RtfInfoElement
+ */
+ private String content = "";
+
+ /**
+ * Constructs a RtfInfoElement based on the given Meta object
+ *
+ * @param doc The RtfDocument this RtfInfoElement belongs to
+ * @param meta The Meta object this RtfInfoElement is based on
+ */
+ public RtfInfoElement(RtfDocument doc, Meta meta) : base(doc) {
+ infoType = meta.Type;
+ content = meta.Content;
+ }
+
+ /**
+ * Writes the content of one RTF information element.
+ */
+ public override void WriteContent(Stream result) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ switch (infoType) {
+ case Element.AUTHOR:
+ result.Write(INFO_AUTHOR, 0, INFO_AUTHOR.Length);
+ break;
+ case Element.SUBJECT:
+ result.Write(INFO_SUBJECT, 0, INFO_SUBJECT.Length);
+ break;
+ case Element.KEYWORDS:
+ result.Write(INFO_KEYWORDS, 0, INFO_KEYWORDS.Length);
+ break;
+ case Element.TITLE:
+ result.Write(INFO_TITLE, 0, INFO_TITLE.Length);
+ break;
+ case Element.PRODUCER:
+ result.Write(INFO_PRODUCER, 0, INFO_PRODUCER.Length);
+ break;
+ case Element.CREATIONDATE:
+ result.Write(INFO_CREATION_DATE, 0, INFO_CREATION_DATE.Length);
+ break;
+ default:
+ result.Write(INFO_AUTHOR, 0, INFO_AUTHOR.Length);
+ break;
+ }
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ byte[] t;
+ if (infoType == Element.CREATIONDATE) {
+ t = DocWriter.GetISOBytes(ConvertDate(content));
+ result.Write(t, 0, t.Length);
+ } else {
+ document.FilterSpecialChar(result, content, false, false);
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ }
+
+ /**
+ * Converts a date from the format used by iText to the format required by
+ * rtf.
iText: EEE MMM dd HH:mm:ss zzz yyyy - rtf: \\'yr'yyyy\\'mo'MM\\'dy'dd\\'hr'HH\\'min'mm\\'sec'ss
+ *
+ * @param date The date formated by iText
+ * @return The date formated for rtf
+ */
+ private String ConvertDate(String date) {
+ DateTime d;
+ try {
+ d = DateTime.Parse(date);
+ } catch {
+ d = DateTime.Now;
+ }
+ return d.ToString("'\\\\yr'yyyy'\\\\mo'MM'\\\\dy'dd'\\\\hr'HH'\\\\min'mm'\\\\sec'ss");
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfInfoGroup.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfInfoGroup.cs
new file mode 100644
index 0000000..7f41939
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfInfoGroup.cs
@@ -0,0 +1,125 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/*
+ * $Id: RtfInfoGroup.cs,v 1.6 2008/05/16 19:30:51 psoares33 Exp $
+ *
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document {
+
+ /**
+ * The RtfInfoGroup stores information group elements.
+ *
+ * @version $Id: RtfInfoGroup.cs,v 1.6 2008/05/16 19:30:51 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+ public class RtfInfoGroup : RtfElement {
+ /**
+ * Information group starting tag
+ */
+ private static byte[] INFO_GROUP = DocWriter.GetISOBytes("\\info");
+
+ /**
+ * Constant for the password element
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ private static byte[] INFO_PASSWORD = DocWriter.GetISOBytes("\\*\\password");
+
+ /**
+ * The RtfInfoElements that belong to this RtfInfoGroup
+ */
+ ArrayList infoElements = null;
+
+ /**
+ * Constructs a RtfInfoGroup belonging to a RtfDocument
+ *
+ * @param doc The RtfDocument this RtfInfoGroup belongs to
+ */
+ public RtfInfoGroup(RtfDocument doc) : base(doc) {
+ infoElements = new ArrayList();
+ }
+
+ /**
+ * Adds an RtfInfoElement to the RtfInfoGroup
+ *
+ * @param infoElement The RtfInfoElement to add
+ */
+ public void Add(RtfInfoElement infoElement) {
+ this.infoElements.Add(infoElement);
+ }
+
+ /**
+ * Writes the RTF information group and its elements.
+ */
+ public override void WriteContent(Stream result) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(INFO_GROUP, 0, INFO_GROUP.Length);
+ for (int i = 0; i < infoElements.Count; i++) {
+ RtfInfoElement infoElement = (RtfInfoElement) infoElements[i];
+ infoElement.WriteContent(result);
+ }
+
+ // handle document protection
+ if (document.GetDocumentSettings().IsDocumentProtected()) {
+ byte[] t;
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(INFO_PASSWORD, 0, INFO_PASSWORD.Length);
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ result.Write(t = document.GetDocumentSettings().GetProtectionHashBytes(), 0, t.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfPageSetting.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfPageSetting.cs
new file mode 100644
index 0000000..b058bd1
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfPageSetting.cs
@@ -0,0 +1,425 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/*
+ * $Id: RtfPageSetting.cs,v 1.5 2008/05/16 19:30:51 psoares33 Exp $
+ *
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document {
+
+ /**
+ * The RtfPageSetting stores the page size / page margins for a RtfDocument.
+ * INTERNAL CLASS - NOT TO BE USED DIRECTLY
+ *
+ * @version $Id: RtfPageSetting.cs,v 1.5 2008/05/16 19:30:51 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+ public class RtfPageSetting : RtfElement, IRtfExtendedElement {
+
+ /**
+ * Constant for the page height
+ */
+ private static byte[] PAGE_WIDTH = DocWriter.GetISOBytes("\\paperw");
+ /**
+ * Constant for the page width
+ */
+ private static byte[] PAGE_HEIGHT = DocWriter.GetISOBytes("\\paperh");
+ /**
+ * Constant for the left margin
+ */
+ private static byte[] MARGIN_LEFT = DocWriter.GetISOBytes("\\margl");
+ /**
+ * Constant for the right margin
+ */
+ private static byte[] MARGIN_RIGHT = DocWriter.GetISOBytes("\\margr");
+ /**
+ * Constant for the top margin
+ */
+ private static byte[] MARGIN_TOP = DocWriter.GetISOBytes("\\margt");
+ /**
+ * Constant for the bottom margin
+ */
+ private static byte[] MARGIN_BOTTOM = DocWriter.GetISOBytes("\\margb");
+ /**
+ * Constant for landscape
+ */
+ private static byte[] LANDSCAPE = DocWriter.GetISOBytes("\\lndscpsxn");
+ /**
+ * Constant for the section page width
+ */
+ private static byte[] SECTION_PAGE_WIDTH = DocWriter.GetISOBytes("\\pgwsxn");
+ /**
+ * Constant for the section page height
+ */
+ private static byte[] SECTION_PAGE_HEIGHT = DocWriter.GetISOBytes("\\pghsxn");
+ /**
+ * Constant for the section left margin
+ */
+ private static byte[] SECTION_MARGIN_LEFT = DocWriter.GetISOBytes("\\marglsxn");
+ /**
+ * Constant for the section right margin
+ */
+ private static byte[] SECTION_MARGIN_RIGHT = DocWriter.GetISOBytes("\\margrsxn");
+ /**
+ * Constant for the section top margin
+ */
+ private static byte[] SECTION_MARGIN_TOP = DocWriter.GetISOBytes("\\margtsxn");
+ /**
+ * Constant for the section bottom margin
+ */
+ private static byte[] SECTION_MARGIN_BOTTOM = DocWriter.GetISOBytes("\\margbsxn");
+
+ /**
+ * The page width to use
+ */
+ private int pageWidth = 11906;
+ /**
+ * The page height to use
+ */
+ private int pageHeight = 16840;
+ /**
+ * The left margin to use
+ */
+ private int marginLeft = 1800;
+ /**
+ * The right margin to use
+ */
+ private int marginRight = 1800;
+ /**
+ * The top margin to use
+ */
+ private int marginTop = 1440;
+ /**
+ * The bottom margin to use
+ */
+ private int marginBottom = 1440;
+ /**
+ * Whether the page is portrait or landscape
+ */
+ private bool landscape = false;
+
+ /**
+ * Constructs a new RtfPageSetting object belonging to a RtfDocument.
+ *
+ * @param doc The RtfDocument this RtfPageSetting belongs to
+ */
+ public RtfPageSetting(RtfDocument doc) : base(doc) {
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Writes the page size / page margin definition
+ */
+ public virtual void WriteDefinition(Stream result) {
+ byte[] t;
+ result.Write(PAGE_WIDTH, 0, PAGE_WIDTH.Length);
+ result.Write(t = IntToByteArray(pageWidth), 0, t.Length);
+ result.Write(PAGE_HEIGHT, 0, PAGE_HEIGHT.Length);
+ result.Write(t = IntToByteArray(pageHeight), 0, t.Length);
+ result.Write(MARGIN_LEFT, 0, MARGIN_LEFT.Length);
+ result.Write(t = IntToByteArray(marginLeft), 0, t.Length);
+ result.Write(MARGIN_RIGHT, 0, MARGIN_RIGHT.Length);
+ result.Write(t = IntToByteArray(marginRight), 0, t.Length);
+ result.Write(MARGIN_TOP, 0, MARGIN_TOP.Length);
+ result.Write(t = IntToByteArray(marginTop), 0, t.Length);
+ result.Write(MARGIN_BOTTOM, 0, MARGIN_BOTTOM.Length);
+ result.Write(t = IntToByteArray(marginBottom), 0, t.Length);
+ result.WriteByte((byte)'\n');
+ }
+
+ /**
+ * Writes the definition part for a new section
+ *
+ * @return A byte array containing the definition for a new section
+ */
+ public void WriteSectionDefinition(Stream result) {
+ byte[] t;
+ if (landscape) {
+ result.Write(LANDSCAPE, 0, LANDSCAPE.Length);
+ result.Write(SECTION_PAGE_WIDTH, 0, SECTION_PAGE_WIDTH.Length);
+ result.Write(t = IntToByteArray(pageWidth), 0, t.Length);
+ result.Write(SECTION_PAGE_HEIGHT, 0, SECTION_PAGE_HEIGHT.Length);
+ result.Write(t = IntToByteArray(pageHeight), 0, t.Length);
+ result.WriteByte((byte)'\n');
+ } else {
+ result.Write(SECTION_PAGE_WIDTH, 0, SECTION_PAGE_WIDTH.Length);
+ result.Write(t = IntToByteArray(pageWidth), 0, t.Length);
+ result.Write(SECTION_PAGE_HEIGHT, 0, SECTION_PAGE_HEIGHT.Length);
+ result.Write(t = IntToByteArray(pageHeight), 0, t.Length);
+ result.WriteByte((byte)'\n');
+ }
+ result.Write(SECTION_MARGIN_LEFT, 0, SECTION_MARGIN_LEFT.Length);
+ result.Write(t = IntToByteArray(marginLeft), 0, t.Length);
+ result.Write(SECTION_MARGIN_RIGHT, 0, SECTION_MARGIN_RIGHT.Length);
+ result.Write(t = IntToByteArray(marginRight), 0, t.Length);
+ result.Write(SECTION_MARGIN_TOP, 0, SECTION_MARGIN_TOP.Length);
+ result.Write(t = IntToByteArray(marginTop), 0, t.Length);
+ result.Write(SECTION_MARGIN_BOTTOM, 0, SECTION_MARGIN_BOTTOM.Length);
+ result.Write(t = IntToByteArray(marginBottom), 0, t.Length);
+ }
+
+ /**
+ * Gets the bottom margin
+ *
+ * @return Returns the bottom margin
+ */
+ public int GetMarginBottom() {
+ return marginBottom;
+ }
+
+ /**
+ * Sets the bottom margin
+ *
+ * @param marginBottom The bottom margin to use
+ */
+ public void SetMarginBottom(int marginBottom) {
+ this.marginBottom = marginBottom;
+ }
+
+ /**
+ * Gets the left margin
+ *
+ * @return Returns the left margin
+ */
+ public int GetMarginLeft() {
+ return marginLeft;
+ }
+
+ /**
+ * Sets the left margin to use
+ *
+ * @param marginLeft The left margin to use
+ */
+ public void SetMarginLeft(int marginLeft) {
+ this.marginLeft = marginLeft;
+ }
+
+ /**
+ * Gets the right margin
+ *
+ * @return Returns the right margin
+ */
+ public int GetMarginRight() {
+ return marginRight;
+ }
+
+ /**
+ * Sets the right margin to use
+ *
+ * @param marginRight The right margin to use
+ */
+ public void SetMarginRight(int marginRight) {
+ this.marginRight = marginRight;
+ }
+
+ /**
+ * Gets the top margin
+ *
+ * @return Returns the top margin
+ */
+ public int GetMarginTop() {
+ return marginTop;
+ }
+
+ /**
+ * Sets the top margin to use
+ *
+ * @param marginTop The top margin to use
+ */
+ public void SetMarginTop(int marginTop) {
+ this.marginTop = marginTop;
+ }
+
+ /**
+ * Gets the page height
+ *
+ * @return Returns the page height
+ */
+ public int GetPageHeight() {
+ return pageHeight;
+ }
+
+ /**
+ * Sets the page height to use
+ *
+ * @param pageHeight The page height to use
+ */
+ public void SetPageHeight(int pageHeight) {
+ this.pageHeight = pageHeight;
+ }
+
+ /**
+ * Gets the page width
+ *
+ * @return Returns the page width
+ */
+ public int GetPageWidth() {
+ return pageWidth;
+ }
+
+ /**
+ * Sets the page width to use
+ *
+ * @param pageWidth The page width to use
+ */
+ public void SetPageWidth(int pageWidth) {
+ this.pageWidth = pageWidth;
+ }
+
+ /**
+ * Set the page size to use. This method will use guessFormat to try to guess the correct
+ * page format. If no format could be guessed, the sizes from the pageSize are used and
+ * the landscape setting is determined by comparing width and height;
+ *
+ * @param pageSize The pageSize to use
+ */
+ public void SetPageSize(Rectangle pageSize) {
+ if (!GuessFormat(pageSize, false)) {
+ this.pageWidth = (int) (pageSize.Width * TWIPS_FACTOR);
+ this.pageHeight = (int) (pageSize.Height * TWIPS_FACTOR);
+ this.landscape = pageWidth > pageHeight;
+ }
+ }
+
+ /**
+ * This method tries to fit the Rectangle pageSize
to one of the predefined PageSize rectangles.
+ * If a match is found the pageWidth and pageHeight will be set according to values determined from files
+ * generated by MS Word2000 and OpenOffice 641. If no match is found the method will try to match the rotated
+ * Rectangle by calling itself with the parameter rotate set to true.
+ *
+ * @param pageSize the page size for which to guess the correct format
+ * @param rotate Whether we should try to rotate the size befor guessing the format
+ * @return True
if the format was guessed, false/
otherwise
+ */
+ private bool GuessFormat(Rectangle pageSize, bool rotate) {
+ if (rotate) {
+ pageSize = pageSize.Rotate();
+ }
+ if (RectEquals(pageSize, PageSize.A3)) {
+ pageWidth = 16837;
+ pageHeight = 23811;
+ landscape = rotate;
+ return true;
+ }
+ if (RectEquals(pageSize, PageSize.A4)) {
+ pageWidth = 11907;
+ pageHeight = 16840;
+ landscape = rotate;
+ return true;
+ }
+ if (RectEquals(pageSize, PageSize.A5)) {
+ pageWidth = 8391;
+ pageHeight = 11907;
+ landscape = rotate;
+ return true;
+ }
+ if (RectEquals(pageSize, PageSize.A6)) {
+ pageWidth = 5959;
+ pageHeight = 8420;
+ landscape = rotate;
+ return true;
+ }
+ if (RectEquals(pageSize, PageSize.B4)) {
+ pageWidth = 14570;
+ pageHeight = 20636;
+ landscape = rotate;
+ return true;
+ }
+ if (RectEquals(pageSize, PageSize.B5)) {
+ pageWidth = 10319;
+ pageHeight = 14572;
+ landscape = rotate;
+ return true;
+ }
+ if (RectEquals(pageSize, PageSize.HALFLETTER)) {
+ pageWidth = 7927;
+ pageHeight = 12247;
+ landscape = rotate;
+ return true;
+ }
+ if (RectEquals(pageSize, PageSize.LETTER)) {
+ pageWidth = 12242;
+ pageHeight = 15842;
+ landscape = rotate;
+ return true;
+ }
+ if (RectEquals(pageSize, PageSize.LEGAL)) {
+ pageWidth = 12252;
+ pageHeight = 20163;
+ landscape = rotate;
+ return true;
+ }
+ if (!rotate && GuessFormat(pageSize, true)) {
+ int x = pageWidth;
+ pageWidth = pageHeight;
+ pageHeight = x;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * This method compares to Rectangles. They are considered equal if width and height are the same
+ *
+ * @param rect1 The first Rectangle to compare
+ * @param rect2 The second Rectangle to compare
+ * @return
+ */
+ private long ctrlWordCount = 0;
+ /**
+ * Total { encountered as an open group token.
+ */
+ private long openGroupCount = 0;
+ /**
+ * Total } encountered as a close group token.
+ */
+ private long closeGroupCount = 0;
+ /**
+ * Total clear text characters processed.
+ */
+ private long characterCount = 0;
+ /**
+ * Total control words recognized.
+ */
+ private long ctrlWordHandledCount = 0;
+ /**
+ * Total control words not handled.
+ */
+ private long ctrlWordNotHandledCount = 0;
+ /**
+ * Total control words skipped.
+ */
+ private long ctrlWordSkippedCount = 0;
+ /**
+ * Total groups skipped. Includes { and } as a group.
+ */
+ private long groupSkippedCount = 0;
+ /**
+ * Start time as a long.
+ */
+ private long startTime = 0;
+ /**
+ * Stop time as a long.
+ */
+ private long endTime = 0;
+ /**
+ * Start date as a date.
+ */
+ private DateTime startDate;
+ /**
+ * End date as a date.
+ */
+ private DateTime endDate;
+ //////////////////////////////////// STATS VARIABLES ///////////////////
+ /**
+ * Last control word and parameter processed.
+ */
+ private RtfCtrlWordData lastCtrlWordParam = null;
+
+ /** The True
if the Rectangles equal, false
otherwise
+ */
+ private static bool RectEquals(Rectangle rect1, Rectangle rect2) {
+ return (rect1.Width == rect2.Width) && (rect1.Height == rect2.Height);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/RtfProtection.cs b/iTechSharp/iTextSharp/text/rtf/document/RtfProtection.cs
new file mode 100644
index 0000000..2e6e2bd
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/RtfProtection.cs
@@ -0,0 +1,273 @@
+using System;
+/*
+ * $Id: RtfProtection.cs,v 1.2 2008/05/13 11:25:50 psoares33 Exp $
+ *
+ *
+ * Copyright 2008 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document {
+
+ /**
+ * RtfProtection
+ *
+ * See ECMA Specification for WordprocessingML documentProtection element.
+ *
+ * Reference:
+ * Standard ECMA-376 1st Edition / December 2006
+ * Office Open XML File Formats
+ *
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public sealed class RtfProtection {
+ /**
+ * Default for protection level.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int LEVEL_NONE = 0x0000;
+ /**
+ * REVPROT
+ * Mutually exclusive
+ * This document is protected for revisions. The user can edit the document,
+ * but revision marking cannot be disabled.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int LEVEL_REVPROT = 0x0001; // protlevel0
+ /**
+ * ANNNOTPROT
+ * Mutually exclusive
+ * This document is protected for comments (annotations).
+ * The user cannot edit the document but can insert comments (annotations).
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int LEVEL_ANNOTPROT = 0x0002; // protlevel1
+ /**
+ * FORMPROT
+ * Mutually exclusive
+ * Document is protected for forms.
+ * see also \allprot (forms controlword)
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int LEVEL_FORMPROT = 0x0004; // protlevel2
+ /**
+ * READPROT
+ * Mutually exclusive but can be combined with ANNOTPROT for backward compatibility
+ * Document is protected for editing, except areas marked as exceptions by \protstart and\protend
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int LEVEL_READPROT = 0x0008; // protlevel3
+
+
+ /**
+ * STYLELOCK
+ *
+ * The document contains styles and formatting restrictions.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int STYLELOCK = 0x0001;
+ /**
+ * STYLELOCKENFORCED
+ *
+ * The styles and formatting restrictions are being enforced.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int STYLELOCKENFORCED = 0x0002;
+ /**
+ * STYLELOCKBACKCOMP
+ *
+ * Style lockdown backward compatibility flag, indicating we emitted protection
+ * keywords to get documents with styles and formatting restrictions to behave
+ * in a reasonable way when opened by older versions.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int STYLELOCKBACKCOMP = 0x0004;
+ /**
+ * STYLELOCKBACKCOMP
+ *
+ * Allow AutoFormat to override styles and formatting restrictions. When style
+ * protection is on, the user cannot add direct formatting. This setting allows
+ * AutoFormat actions to apply direct formatting when needed.
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public const int AUTOFMTOVERRIDE = 0x0008;
+
+
+ /**
+ * initialCodeArray
Table from ECMA-376 Specification
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ private static int[] initialCodeArray = {
+ 0xE1F0,
+ 0x1D0F,
+ 0xCC9C,
+ 0x84C0,
+ 0x110C,
+ 0x0E10,
+ 0xF1CE,
+ 0x313E,
+ 0x1872,
+ 0xE139,
+ 0xD40F,
+ 0x84F9,
+ 0x280C,
+ 0xA96A,
+ 0x4EC3
+ };
+
+ /**
+ * encryptionMatrix
Table from ECMA-376 Specification
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ private static int[][] encryptionMatrix = {
+ /* bit1 bit2 bit3 bit4 bit5 bit6 bit7 **bit8 is ignored** */
+ /* char 1 */ new int[]{0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4},
+ /* char 2 */ new int[]{0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC},
+ /* char 3 */ new int[]{0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD},
+ /* char 4 */ new int[]{0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C},
+ /* char 5 */ new int[]{0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168},
+ /* char 6 */ new int[]{0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10},
+ /* char 7 */ new int[]{0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC},
+ /* char 8 */ new int[]{0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0},
+ /* char 9 */ new int[]{0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9},
+ /* char 10 */ new int[]{0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A},
+ /* char 11 */ new int[]{0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5},
+ /* char 12 */ new int[]{0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40},
+ /* char 13 */ new int[]{0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0},
+ /* char 14 */ new int[]{0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF},
+ /* char 15 */ new int[]{0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09}
+ };
+
+ /**
+ * generateHash
generates the password hash from a clear text string.
+ *
+ * @param pwd Clear text string input
+ * @return hex encoded password hash
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.1
+ */
+ public static String GenerateHash(String pwd) {
+ String encryptedPwd="00000000";
+ String password = pwd;
+
+ // if there is no password or the length is 0, then skip this and return "00000000" as default
+ // otherwise process the password
+ if (password != null && password.Length > 0) {
+ int hi=0;
+ int lo=0;
+
+ // Truncate the password to 15 characters.
+ if (password.Length > 15) {
+ password = password.Substring(0,15);
+ }
+
+ // compute key's high-order word
+ // initialize to table value
+ hi = initialCodeArray[password.Length-1];
+
+ int fidx = 0;
+ int idxR = password.Length-1;
+ // process each character left to right.
+ // check each bit and if it is set, xor the hi word with
+ // the table entry for the position in password and bit position.
+ for (; fidxRtfProtectionSetting
belonging to a RtfDocument
+ *
+ * @param doc The RtfDocument
this RtfProtectionSetting
belongs to
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public RtfProtectionSetting(RtfDocument doc) : base(doc) {
+ }
+
+ /**
+ * Writes the RTF protection control words
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public override void WriteContent(Stream result) {
+ }
+
+ /**
+ * Writes the RTF protection control words
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public virtual void WriteDefinition(Stream result) {
+ if (document.GetDocumentSettings().IsDocumentProtected()) {
+ switch (document.GetDocumentSettings().GetProtectionLevelRaw()) {
+ case RtfProtection.LEVEL_FORMPROT:
+ result.Write(FORMPROT, 0, FORMPROT.Length);
+ break;
+ case RtfProtection.LEVEL_ANNOTPROT:
+ result.Write(ANNOTPROT, 0, ANNOTPROT.Length);
+ break;
+ case RtfProtection.LEVEL_REVPROT:
+ result.Write(REVPROT, 0, REVPROT.Length);
+ break;
+ case RtfProtection.LEVEL_READPROT:
+ result.Write(ANNOTPROT, 0, ANNOTPROT.Length);
+ result.Write(READPROT, 0, READPROT.Length);
+ break;
+ }
+ result.Write(ENFORCEPROT, 0, ENFORCEPROT.Length); // assumes one of the above protection keywords was output.
+ result.WriteByte((byte)'1');
+ result.Write(PROTLEVEL, 0, PROTLEVEL.Length);
+ byte[] t;
+ result.Write(t = document.GetDocumentSettings().GetProtectionLevelBytes(), 0, t.Length);
+ }
+
+ if (document.GetDocumentSettings().GetReadOnlyRecommended()) {
+ result.Write(READONLYRECOMMENDED, 0, READONLYRECOMMENDED.Length);
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/output/IRtfDataCache.cs b/iTechSharp/iTextSharp/text/rtf/document/output/IRtfDataCache.cs
new file mode 100644
index 0000000..6749eaf
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/output/IRtfDataCache.cs
@@ -0,0 +1,92 @@
+using System;
+using System.IO;
+/*
+ * $Id: IRtfDataCache.cs,v 1.4 2008/05/16 19:30:53 psoares33 Exp $
+ *
+ *
+ * Copyright 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document.output {
+
+ /**
+ * The RtfDataCache interface must be implemented by classes wishing to
+ * act as caches for the rtf document data.
+ *
+ * @version $Revision: 1.4 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public interface IRtfDataCache {
+ /**
+ * Get the OutputStream that the RtfDocument can write to.
+ *
+ * @return The OutputStream the RtfDocument can use.
+ */
+ Stream GetOutputStream();
+ /**
+ * Write the content of the cache into the OutputStream.
+ *
+ * @param target The OutputStream to write the content into.
+ * @throws IOException If an error occurs reading/writing.
+ */
+ void WriteTo(Stream target);
+ }
+
+ public class RtfDataCache {
+ /**
+ * Constant for caching efficently into memory.
+ */
+ public const int CACHE_MEMORY_EFFICIENT = 3;
+ /**
+ * Constant for caching into memory.
+ */
+ public const int CACHE_MEMORY = 2;
+ /**
+ * Constant for caching to the disk.
+ */
+ public const int CACHE_DISK = 1;
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/output/RtfByteArrayBuffer.cs b/iTechSharp/iTextSharp/text/rtf/document/output/RtfByteArrayBuffer.cs
new file mode 100644
index 0000000..b5b60d2
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/output/RtfByteArrayBuffer.cs
@@ -0,0 +1,306 @@
+using System;
+using System.IO;
+using System.Collections;
+/*
+ * Copyright 2007 Thomas Bickel
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document.output {
+
+ public class RtfByteArrayBuffer : Stream {
+ private ArrayList arrays = new ArrayList();
+ private byte[] buffer;
+ private int pos = 0;
+ private int size = 0;
+
+ public RtfByteArrayBuffer() : this(256) {
+ }
+
+ /**
+ * Creates a new buffer with the given initial size.
+ *
+ * @param bufferSize desired initial size in bytes
+ */
+ public RtfByteArrayBuffer(int bufferSize) {
+ if ((bufferSize <= 0) || (bufferSize > 1<<30)) throw(new ArgumentException("bufferSize "+bufferSize));
+
+ int n = 1<<5;
+ while(n < bufferSize) {
+ n <<= 1;
+ }
+ buffer = new byte[n];
+ }
+
+ public override bool CanRead {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanSeek {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanWrite {
+ get {
+ return true;
+ }
+ }
+
+ public override long Length {
+ get {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override long Position {
+ get {
+ throw new NotSupportedException();
+ }
+ set {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override void Close() {
+ }
+
+ public override void Flush() {
+ }
+
+ public override int Read(byte[] buffer, int offset, int count) {
+ throw new NotSupportedException();
+ }
+
+ public override long Seek(long offset, SeekOrigin origin) {
+ throw new NotSupportedException();
+ }
+
+ public override void SetLength(long value) {
+ throw new NotSupportedException();
+ }
+
+ public override void Write(byte[] src, int off, int len) {
+ if(src == null) throw(new ArgumentNullException());
+ if((off < 0) || (off > src.Length) || (len < 0) || ((off + len) > src.Length) || ((off + len) < 0)) throw new IndexOutOfRangeException();
+
+ WriteLoop(src, off, len);
+ }
+
+ private void WriteLoop(byte[] src, int off, int len) {
+ while(len > 0) {
+ int room = buffer.Length - pos;
+ int n = len > room ? room : len;
+ System.Array.Copy(src, off, buffer, pos, n);
+ len -= n;
+ off += n;
+ pos += n;
+ size += n;
+ if(pos == buffer.Length) FlushBuffer(len);
+ }
+ }
+
+ /**
+ * Writes all bytes available in the given inputstream to this buffer.
+ *
+ * @param in
+ * @return number of bytes written
+ * @throws IOException
+ */
+ public long Write(Stream inp) {
+ if (inp == null) throw(new ArgumentNullException());
+ long sizeStart = size;
+ while (true) {
+ int n = inp.Read(buffer, pos, buffer.Length - pos);
+ if (n <= 0) break;
+ pos += n;
+ size += n;
+ if(pos == buffer.Length) FlushBuffer();
+ }
+ return(size - sizeStart);
+ }
+
+ /**
+ * Appends the given array to this buffer without copying (if possible).
+ *
+ * @param a
+ */
+ public void Append(byte[] a) {
+ if(a == null) throw(new ArgumentNullException());
+ if(a.Length == 0) return;
+
+ if(a.Length <= 8) {
+ Write(a, 0, a.Length);
+ } else if((a.Length <= 16) && (pos > 0) && ((buffer.Length - pos) > a.Length)) {
+ Write(a, 0, a.Length);
+ } else {
+ FlushBuffer();
+ arrays.Add(a);
+ size += a.Length;
+ }
+ }
+ /**
+ * Appends all arrays to this buffer without copying (if possible).
+ *
+ * @param a
+ */
+ public void Append(byte[][] a) {
+ if(a == null) throw(new ArgumentNullException());
+
+ for(int k = 0; k < a.Length; k++) {
+ Append(a[k]);
+ }
+ }
+
+ /**
+ * Returns the internal list of byte array buffers without copying the buffer contents.
+ *
+ * @return an byte aray of buffers
+ */
+ public byte[][] ToArrayArray()
+ {
+ FlushBuffer();
+ byte[][] a = new byte[arrays.Count][];
+ arrays.CopyTo(a);
+ return a;
+ }
+
+ /**
+ * Allocates a new array and copies all data that has been written to this buffer to the newly allocated array.
+ *
+ * @return a new byte array
+ */
+ public byte[] ToArray()
+ {
+ byte[] r = new byte[size];
+ int off = 0;
+ int n = arrays.Count;
+ for(int k = 0; k < n; k++) {
+ byte[] src = (byte[])arrays[k];
+ System.Array.Copy(src, 0, r, off, src.Length);
+ off += src.Length;
+ }
+ if(pos > 0) System.Array.Copy(buffer, 0, r, off, pos);
+ return(r);
+ }
+
+ /**
+ * Writes all data that has been written to this buffer to the given output stream.
+ *
+ * @param out
+ * @throws IOException
+ */
+ public void WriteTo(Stream outp) {
+ if(outp == null) throw(new ArgumentNullException());
+
+ int n = arrays.Count;
+ for(int k = 0; k < n; k++) {
+ byte[] src = (byte[])arrays[k];
+ outp.Write(src, 0, src.Length);
+ }
+ if(pos > 0) outp.Write(buffer, 0, pos);
+ }
+
+ public override void WriteByte(byte value) {
+ buffer[pos] = value;
+ size++;
+ if(++pos == buffer.Length) FlushBuffer();
+ }
+
+ public override string ToString() {
+ return("RtfByteArrayBuffer: size="+Size()+" #arrays="+arrays.Count+" pos="+pos);
+ }
+
+ /**
+ * Resets this buffer.
+ */
+ public void Reset() {
+ arrays.Clear();
+ pos = 0;
+ size = 0;
+ }
+
+ /**
+ * Returns the number of bytes that have been written to this buffer so far.
+ *
+ * @return number of bytes written to this buffer
+ */
+ public long Size() {
+ return(size);
+ }
+
+ private void FlushBuffer() {
+ FlushBuffer(1);
+ }
+
+ private void FlushBuffer(int reqSize) {
+ if(reqSize < 0) throw(new ArgumentException());
+
+ if(pos == 0) return;
+
+ if(pos == buffer.Length) {
+ //add old buffer, alloc new (possibly larger) buffer
+ arrays.Add(buffer);
+ int newSize = buffer.Length;
+ buffer = null;
+ int MAX = Math.Max(1, size>>24) << 16;
+ while(newSize < MAX) {
+ newSize <<= 1;
+ if(newSize >= reqSize) break;
+ }
+ buffer = new byte[newSize];
+ } else {
+ //copy buffer contents to newly allocated buffer
+ byte[] c = new byte[pos];
+ System.Array.Copy(buffer, 0, c, 0, pos);
+ arrays.Add(c);
+ }
+ pos = 0;
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/rtf/document/output/RtfDiskCache.cs b/iTechSharp/iTextSharp/text/rtf/document/output/RtfDiskCache.cs
new file mode 100644
index 0000000..c81ad3a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/output/RtfDiskCache.cs
@@ -0,0 +1,107 @@
+using System;
+using System.IO;
+/*
+ * $Id: RtfDiskCache.cs,v 1.3 2008/05/16 19:30:53 psoares33 Exp $
+ *
+ *
+ * Copyright 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document.output {
+
+ /**
+ * The RtfFileCache is a RtfDataCache that uses a temporary file
+ * to store the rtf document data. Not so fast, but doesn't use any
+ * memory (just disk space).
+ *
+ * @version $Revision: 1.3 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfDiskCache : IRtfDataCache {
+
+ /**
+ * The BufferedOutputStream that stores the cache data.
+ */
+ private BufferedStream data = null;
+ /**
+ * The temporary file to store the data in.
+ */
+ private string tempFile = null;
+
+ /**
+ * Constructs a RtfFileCache. Creates the temp file.
+ *
+ * @throws IOException If the temporary file could not be created.
+ */
+ public RtfDiskCache() {
+ this.tempFile = Path.GetTempFileName();
+ this.data = new BufferedStream(new FileStream(tempFile, FileMode.Create));
+ }
+
+ /**
+ * Gets the BufferedOutputStream to write to.
+ */
+ public Stream GetOutputStream() {
+ return this.data;
+ }
+
+ /**
+ * Writes the content of the temporary file into the Stream.
+ */
+ public void WriteTo(Stream target) {
+ this.data.Close();
+ BufferedStream tempIn = new BufferedStream(new FileStream(this.tempFile, FileMode.Open));
+ byte[] buffer = new byte[8192];
+ int bytesRead = -1;
+ while ((bytesRead = tempIn.Read(buffer, 0, buffer.Length)) > 0) {
+ target.Write(buffer, 0, bytesRead);
+ }
+ tempIn.Close();
+ File.Delete(this.tempFile);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/output/RtfEfficientMemoryCache.cs b/iTechSharp/iTextSharp/text/rtf/document/output/RtfEfficientMemoryCache.cs
new file mode 100644
index 0000000..ea0b05e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/output/RtfEfficientMemoryCache.cs
@@ -0,0 +1,86 @@
+using System;
+using System.IO;
+/*
+ * Copyright 2007 by Thomas Bickel
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document.output {
+ /**
+ * The RtfEfficientMemoryCache is an RtfDataCache that keeps the whole rtf document
+ * data in memory.
+ * More efficient than {@link RtfMemoryCache}.
+ *
+ * @version $Id: RtfEfficientMemoryCache.cs,v 1.1 2007/05/26 20:44:49 psoares33 Exp $
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+ public class RtfEfficientMemoryCache : IRtfDataCache {
+ /**
+ * The buffer for the rtf document data.
+ */
+ private RtfByteArrayBuffer bab;
+
+ /**
+ * Constructs a RtfMemoryCache.
+ */
+ public RtfEfficientMemoryCache() {
+ bab = new RtfByteArrayBuffer();
+ }
+
+ /**
+ * Gets the OutputStream.
+ */
+ public virtual Stream GetOutputStream() {
+ return(bab);
+ }
+
+ /**
+ * Writes the content of the buffer into the OutputStream.
+ */
+ public virtual void WriteTo(Stream target) {
+ bab.WriteTo(target);
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/rtf/document/output/RtfMemoryCache.cs b/iTechSharp/iTextSharp/text/rtf/document/output/RtfMemoryCache.cs
new file mode 100644
index 0000000..b00e48c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/output/RtfMemoryCache.cs
@@ -0,0 +1,91 @@
+using System;
+using System.IO;
+/*
+ * $Id: RtfMemoryCache.cs,v 1.3 2008/05/16 19:30:53 psoares33 Exp $
+ *
+ *
+ * Copyright 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document.output {
+
+ /**
+ * The RtfMemoryCache is an RtfDataCache that keeps the whole rtf document
+ * data in memory. Fast but memory intensive.
+ *
+ * @version $Revision: 1.3 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfMemoryCache : IRtfDataCache {
+
+ /**
+ * The buffer for the rtf document data.
+ */
+ private MemoryStream data = null;
+
+ /**
+ * Constructs a RtfMemoryCache.
+ */
+ public RtfMemoryCache() {
+ this.data = new MemoryStream();
+ }
+
+ /**
+ * Gets the MemoryStream.
+ */
+ public Stream GetOutputStream() {
+ return this.data;
+ }
+
+ /**
+ * Writes the content of the MemoryStream into the Stream.
+ */
+ public void WriteTo(Stream target) {
+ this.data.WriteTo(target);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/document/output/RtfNilOutputStream.cs b/iTechSharp/iTextSharp/text/rtf/document/output/RtfNilOutputStream.cs
new file mode 100644
index 0000000..048c27a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/document/output/RtfNilOutputStream.cs
@@ -0,0 +1,139 @@
+using System;
+using System.IO;
+/*
+ * Copyright 2007 Thomas Bickel
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.document.output {
+
+ /**
+ * The RtfNilOutputStream is a dummy output stream that sends all
+ * bytes to the big byte bucket in the sky. It is used to improve
+ * speed in those situations where processing is required, but
+ * the results are not needed.
+ *
+ * @version $Id: RtfNilOutputStream.cs,v 1.2 2008/05/16 19:30:53 psoares33 Exp $
+ * @author Thomas Bickel (tmb99@inode.at)
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfNilOutputStream : Stream {
+ private long size = 0;
+
+ public RtfNilOutputStream() {
+ }
+
+ public override bool CanRead {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanSeek {
+ get {
+ return false;
+ }
+ }
+
+ public override bool CanWrite {
+ get {
+ return true;
+ }
+ }
+
+ public override long Length {
+ get {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override long Position {
+ get {
+ throw new NotSupportedException();
+ }
+ set {
+ throw new NotSupportedException();
+ }
+ }
+
+ public override void Close() {
+ }
+
+ public override void Flush() {
+ }
+
+ public override int Read(byte[] buffer, int offset, int count) {
+ throw new NotSupportedException();
+ }
+
+ public override long Seek(long offset, SeekOrigin origin) {
+ throw new NotSupportedException();
+ }
+
+ public override void SetLength(long value) {
+ throw new NotSupportedException();
+ }
+
+ public override void Write(byte[] src, int off, int len) {
+ if(src == null) throw(new ArgumentNullException());
+ if((off < 0) || (off > src.Length) || (len < 0) || ((off + len) > src.Length) || ((off + len) < 0)) throw new IndexOutOfRangeException();
+
+ size += len;
+ }
+
+ public override void WriteByte(byte value) {
+ ++size;
+ }
+
+ /**
+ * Returns the number of bytes that have been written to this buffer so far.
+ *
+ * @return number of bytes written to this buffer
+ */
+ public long GetSize() {
+ return(size);
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/rtf/field/RtfAnchor.cs b/iTechSharp/iTextSharp/text/rtf/field/RtfAnchor.cs
new file mode 100644
index 0000000..e81163a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/field/RtfAnchor.cs
@@ -0,0 +1,111 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf.text;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfAnchor.cs,v 1.7 2008/05/16 19:30:54 psoares33 Exp $
+ *
+ *
+ * Copyright 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.field {
+
+ /**
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfAnchor : RtfField {
+
+ /**
+ * Constant for a hyperlink
+ */
+ private static byte[] HYPERLINK = DocWriter.GetISOBytes("HYPERLINK");
+
+ /**
+ * The url of this RtfAnchor
+ */
+ private String url = "";
+ /**
+ * The RtfPhrase to display for the url
+ */
+ private new RtfPhrase content = null;
+
+ /**
+ * Constructs a RtfAnchor based on a RtfField
+ *
+ * @param doc The RtfDocument this RtfAnchor belongs to
+ * @param anchor The Anchor this RtfAnchor is based on
+ */
+ public RtfAnchor(RtfDocument doc, Anchor anchor) : base(doc) {
+ this.url = anchor.Reference;
+ this.content = new RtfPhrase(doc, anchor);
+ }
+
+ /**
+ * Write the field instructions for this RtfAnchor. Sets the field
+ * type to HYPERLINK and then writes the url.
+ *
+ * @return The field instructions for this RtfAnchor
+ * @throws IOException
+ */
+ protected override void WriteFieldInstContent(Stream result) {
+ result.Write(HYPERLINK, 0, HYPERLINK.Length);
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ this.document.FilterSpecialChar(result, url, true, true);
+ }
+
+ /**
+ * Write the field result for this RtfAnchor. Writes the content
+ * of the RtfPhrase.
+ */
+ protected override void WriteFieldResultContent(Stream outp) {
+ content.WriteContent(outp);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/field/RtfField.cs b/iTechSharp/iTextSharp/text/rtf/field/RtfField.cs
new file mode 100644
index 0000000..bb4c369
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/field/RtfField.cs
@@ -0,0 +1,427 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using ST = iTextSharp.text.rtf.style;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfField.cs,v 1.7 2008/05/16 19:30:54 psoares33 Exp $
+ *
+ *
+ * Copyright 2004 by Mark Hall
+ * Uses code Copyright 2002
+ * SMB
+ * Dirk.Weigenand@smb-tec.com
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.field {
+
+ /**
+ * The RtfField class is an abstract base class for all rtf field functionality.
+ * Subclasses only need to implement the two abstract methods writeFieldInstContent
+ * and writeFieldResultContent. All other field functionality is handled by the
+ * RtfField class.
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Dirk Weigenand
+ */
+ public abstract class RtfField : Chunk, iTextSharp.text.rtf.IRtfBasicElement {
+
+ /**
+ * Constant for the beginning of a rtf group
+ */
+ public static byte[] OPEN_GROUP = {(byte)'{'};
+ /**
+ * Constant for the end of an rtf group
+ */
+ public static byte[] CLOSE_GROUP = {(byte)'}'};
+ /**
+ * Constant for a delimiter in rtf
+ */
+ public static byte[] DELIMITER = {(byte)' '};
+ /**
+ * Constant for a comma delimiter in rtf
+ */
+ public static byte[] COMMA_DELIMITER = {(byte)';'};
+ /**
+ * The factor to use for translating from iText to rtf measurments
+ */
+ public const double TWIPS_FACTOR = 20;
+
+ /**
+ * Constant for a rtf field
+ */
+ private static byte[] FIELD = DocWriter.GetISOBytes("\\field");
+ /**
+ * Constant for a dirty field
+ */
+ private static byte[] FIELD_DIRTY = DocWriter.GetISOBytes("\\flddirty");
+ /**
+ * Constant for a private field
+ */
+ private static byte[] FIELD_PRIVATE = DocWriter.GetISOBytes("\\fldpriv");
+ /**
+ * Constant for a locked field
+ */
+ private static byte[] FIELD_LOCKED = DocWriter.GetISOBytes("\\fldlock");
+ /**
+ * Constant for a edited field
+ */
+ private static byte[] FIELD_EDIT = DocWriter.GetISOBytes("\\fldedit");
+ /**
+ * Constant for an alt field
+ */
+ private static byte[] FIELD_ALT = DocWriter.GetISOBytes("\\fldalt");
+ /**
+ * Constant for the field instructions
+ */
+ private static byte[] FIELD_INSTRUCTIONS = DocWriter.GetISOBytes("\\*\\fldinst");
+ /**
+ * Constant for the field result
+ */
+ private static byte[] FIELD_RESULT = DocWriter.GetISOBytes("\\fldrslt");
+
+ /**
+ * Is the field dirty
+ */
+ private bool fieldDirty = false;
+ /**
+ * Is the field edited
+ */
+ private bool fieldEdit = false;
+ /**
+ * Is the field locked
+ */
+ private bool fieldLocked = false;
+ /**
+ * Is the field private
+ */
+ private bool fieldPrivate = false;
+ /**
+ * Is it an alt field
+ */
+ private bool fieldAlt = false;
+ /**
+ * Whether this RtfField is in a table
+ */
+ private bool inTable = false;
+ /**
+ * Whether this RtfElement is in a header
+ */
+ private bool inHeader = false;
+ /**
+ * The RtfDocument this RtfField belongs to
+ */
+ protected RtfDocument document = null;
+ /**
+ * The RtfFont of this RtfField
+ */
+ private new ST.RtfFont font = null;
+
+ /**
+ * Constructs a RtfField for a RtfDocument. This is not very usefull,
+ * since the RtfField by itself does not do anything. Use one of the
+ * subclasses instead.
+ *
+ * @param doc The RtfDocument this RtfField belongs to.
+ */
+ protected RtfField(RtfDocument doc) : this(doc, new Font()) {
+ }
+
+ /**
+ * Constructs a RtfField for a RtfDocument. This is not very usefull,
+ * since the RtfField by itself does not do anything. Use one of the
+ * subclasses instead.
+ *
+ * @param doc The RtfDocument this RtfField belongs to.
+ * @param font The Font this RtfField should use
+ */
+ protected RtfField(RtfDocument doc, Font font) : base("", font) {
+ this.document = doc;
+ this.font = new ST.RtfFont(this.document, font);
+ }
+
+ /**
+ * Sets the RtfDocument this RtfElement belongs to
+ *
+ * @param doc The RtfDocument to use
+ */
+ public void SetRtfDocument(RtfDocument doc) {
+ this.document = doc;
+ this.font.SetRtfDocument(this.document);
+ }
+
+ /**
+ * Writes the field beginning. Also writes field properties.
+ *
+ * @return A byte array with the field beginning.
+ * @throws IOException
+ */
+ private void WriteFieldBegin(Stream result) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(FIELD, 0, FIELD.Length);
+ if (fieldDirty) result.Write(FIELD_DIRTY, 0, FIELD_DIRTY.Length);
+ if (fieldEdit) result.Write(FIELD_EDIT, 0, FIELD_EDIT.Length);
+ if (fieldLocked) result.Write(FIELD_LOCKED, 0, FIELD_LOCKED.Length);
+ if (fieldPrivate) result.Write(FIELD_PRIVATE, 0, FIELD_PRIVATE.Length);
+ }
+
+ /**
+ * Writes the beginning of the field instruction area.
+ *
+ * @return The beginning of the field instruction area
+ * @throws IOException
+ */
+ private void WriteFieldInstBegin(Stream result) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(FIELD_INSTRUCTIONS, 0, FIELD_INSTRUCTIONS.Length);
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ }
+
+ /**
+ * Writes the content of the field instruction area. Override this
+ * method in your subclasses.
+ */
+ protected abstract void WriteFieldInstContent(Stream oupt);
+
+ /**
+ * Writes the end of the field instruction area.
+ */
+ private void WriteFieldInstEnd(Stream result) {
+ if (fieldAlt) {
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ result.Write(FIELD_ALT, 0, FIELD_ALT.Length);
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ }
+
+ /**
+ * Writes the beginning of the field result area
+ */
+ private void WriteFieldResultBegin(Stream result) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(FIELD_RESULT, 0, FIELD_RESULT.Length);
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ }
+
+ /**
+ * Writes the content of the pre-calculated field result. Override this
+ * method in your subclasses.
+ */
+ protected abstract void WriteFieldResultContent(Stream oupt);
+
+ /**
+ * Writes the end of the field result area
+ */
+ private void WriteFieldResultEnd(Stream result) {
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ }
+
+ /**
+ * Writes the end of the field
+ */
+ private void WriteFieldEnd(Stream result) {
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ }
+
+
+ /**
+ * Writes the field to the OutputStream
.
+ */
+ public virtual void WriteContent(Stream result) {
+ font.WriteBegin(result);
+ WriteFieldBegin(result);
+ WriteFieldInstBegin(result);
+ WriteFieldInstContent(result);
+ WriteFieldInstEnd(result);
+ WriteFieldResultBegin(result);
+ WriteFieldResultContent(result);
+ WriteFieldResultEnd(result);
+ WriteFieldEnd(result);
+ font.WriteEnd(result);
+ }
+
+ /**
+ * Get whether this field is an alt field
+ *
+ * @return Returns whether this field is an alt field
+ */
+ public bool IsFieldAlt() {
+ return fieldAlt;
+ }
+
+ /**
+ * Set whether this field is an alt field
+ *
+ * @param fieldAlt The value to use
+ */
+ public void SetFieldAlt(bool fieldAlt) {
+ this.fieldAlt = fieldAlt;
+ }
+
+ /**
+ * Get whether this field is dirty
+ *
+ * @return Returns whether this field is dirty
+ */
+ public bool IsFieldDirty() {
+ return fieldDirty;
+ }
+
+ /**
+ * Set whether this field is dirty
+ *
+ * @param fieldDirty The value to use
+ */
+ public void SetFieldDirty(bool fieldDirty) {
+ this.fieldDirty = fieldDirty;
+ }
+
+ /**
+ * Get whether this field is edited
+ *
+ * @return Returns whether this field is edited
+ */
+ public bool IsFieldEdit() {
+ return fieldEdit;
+ }
+
+ /**
+ * Set whether this field is edited.
+ *
+ * @param fieldEdit The value to use
+ */
+ public void SetFieldEdit(bool fieldEdit) {
+ this.fieldEdit = fieldEdit;
+ }
+
+ /**
+ * Get whether this field is locked
+ *
+ * @return Returns the fieldLocked.
+ */
+ public bool IsFieldLocked() {
+ return fieldLocked;
+ }
+
+ /**
+ * Set whether this field is locked
+ * @param fieldLocked The value to use
+ */
+ public void SetFieldLocked(bool fieldLocked) {
+ this.fieldLocked = fieldLocked;
+ }
+
+ /**
+ * Get whether this field is private
+ *
+ * @return Returns the fieldPrivate.
+ */
+ public bool IsFieldPrivate() {
+ return fieldPrivate;
+ }
+
+ /**
+ * Set whether this field is private
+ *
+ * @param fieldPrivate The value to use
+ */
+ public void SetFieldPrivate(bool fieldPrivate) {
+ this.fieldPrivate = fieldPrivate;
+ }
+
+ /**
+ * Sets whether this RtfField is in a table
+ *
+ * @param inTable True
if this RtfField is in a table, false
otherwise
+ */
+ public void SetInTable(bool inTable) {
+ this.inTable = inTable;
+ }
+
+ /**
+ * Gets whether this RtfField
is in a table.
+ *
+ * @return True
if this RtfField
is in a table, false
otherwise
+ */
+ public bool IsInTable() {
+ return this.inTable;
+ }
+
+ /**
+ * Sets whether this RtfField is in a header
+ *
+ * @param inHeader True
if this RtfField is in a header, false
otherwise
+ */
+ public void SetInHeader(bool inHeader) {
+ this.inHeader = inHeader;
+ }
+
+ /**
+ * Gets whether this RtfField
is in a header.
+ *
+ * @return True
if this RtfField
is in a header, false
otherwise
+ */
+ public bool IsInHeader() {
+ return this.inHeader;
+ }
+
+ /**
+ * An RtfField is never empty.
+ */
+ public override bool IsEmpty() {
+ return false;
+ }
+
+ public override Font Font {
+ set {
+ base.Font = value;
+ font = new ST.RtfFont(document, value);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/field/RtfPageNumber.cs b/iTechSharp/iTextSharp/text/rtf/field/RtfPageNumber.cs
new file mode 100644
index 0000000..ea0ded7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/field/RtfPageNumber.cs
@@ -0,0 +1,75 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+/*
+ * Created on Aug 10, 2004
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+namespace iTextSharp.text.rtf.field {
+
+ /**
+ * The RtfPageNumber provides the page number field in rtf documents.
+ *
+ * @version $Revision: 1.4 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen.Stundzig@smb-tec.com
+ */
+ public class RtfPageNumber : RtfField {
+
+ /**
+ * Constant for the page number
+ */
+ private static byte[] PAGE_NUMBER = DocWriter.GetISOBytes("PAGE");
+
+ /**
+ * Constructs a RtfPageNumber. This can be added anywhere to add a page number field.
+ */
+ public RtfPageNumber() : base(null) {
+ }
+
+ /**
+ * Constructs a RtfPageNumber with a specified Font. This can be added anywhere to
+ * add a page number field.
+ * @param font
+ */
+ public RtfPageNumber(Font font) : base(null, font) {
+ }
+
+ /**
+ * Constructs a RtfPageNumber object.
+ *
+ * @param doc The RtfDocument this RtfPageNumber belongs to
+ */
+ public RtfPageNumber(RtfDocument doc) : base(doc) {
+ }
+
+ /**
+ * Constructs a RtfPageNumber object with a specific font.
+ *
+ * @param doc The RtfDocument this RtfPageNumber belongs to
+ * @param font The Font to use
+ */
+ public RtfPageNumber(RtfDocument doc, Font font) : base(doc, font) {
+ }
+
+ /**
+ * Writes the field instruction content
+ *
+ * @
+ */
+ protected override void WriteFieldInstContent(Stream oupt) {
+ oupt.Write(PAGE_NUMBER, 0, PAGE_NUMBER.Length);
+ }
+
+ /**
+ * Writes the field result content
+ *
+ * @
+ */
+ protected override void WriteFieldResultContent(Stream oupt) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/field/RtfTOCEntry.cs b/iTechSharp/iTextSharp/text/rtf/field/RtfTOCEntry.cs
new file mode 100644
index 0000000..3fac144
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/field/RtfTOCEntry.cs
@@ -0,0 +1,146 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+/*
+ * $Id: RtfTOCEntry.cs,v 1.6 2008/05/23 17:24:26 psoares33 Exp $
+ *
+ *
+ * Copyright 2004 by Mark Hall
+ * Uses code Copyright 2002
+ * Steffen.Stundzig@smb-tec.com
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.field {
+
+ /**
+ * The RtfTOCEntry is used together with the RtfTableOfContents to generate a table of
+ * contents. Add the RtfTOCEntry in those locations in the document where table of
+ * contents entries should link to
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen.Stundzig@smb-tec.com
+ */
+ public class RtfTOCEntry : RtfField {
+
+ /**
+ * Constant for the beginning of hidden text
+ */
+ private static byte[] TEXT_HIDDEN_ON = DocWriter.GetISOBytes("\\v");
+ /**
+ * Constant for the end of hidden text
+ */
+ private static byte[] TEXT_HIDDEN_OFF = DocWriter.GetISOBytes("\\v0");
+ /**
+ * Constant for a TOC entry with page numbers
+ */
+ private static byte[] TOC_ENTRY_PAGE_NUMBER = DocWriter.GetISOBytes("\\tc");
+ /**
+ * Constant for a TOC entry without page numbers
+ */
+ private static byte[] TOC_ENTRY_NO_PAGE_NUMBER = DocWriter.GetISOBytes("\\tcn");
+
+ /**
+ * The entry text of this RtfTOCEntry
+ */
+ private String entry = "";
+ /**
+ * Whether to show page numbers in the table of contents
+ */
+ private bool showPageNumber = true;
+
+ /**
+ * Constructs a RtfTOCEntry with a certain entry text.
+ *
+ * @param entry The entry text to display
+ * @param font The Font to use
+ */
+ public RtfTOCEntry(String entry) : base(null, new Font()) {
+ if (entry != null) {
+ this.entry = entry;
+ }
+ }
+
+ /**
+ * Writes the content of the RtfTOCEntry
+ */
+ public override void WriteContent(Stream result) {
+ result.Write(TEXT_HIDDEN_ON, 0, TEXT_HIDDEN_ON.Length);
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ if (this.showPageNumber) {
+ result.Write(TOC_ENTRY_PAGE_NUMBER, 0, TOC_ENTRY_PAGE_NUMBER.Length);
+ } else {
+ result.Write(TOC_ENTRY_NO_PAGE_NUMBER, 0, TOC_ENTRY_NO_PAGE_NUMBER.Length);
+ }
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ this.document.FilterSpecialChar(result, this.entry, true, false);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.Write(TEXT_HIDDEN_OFF, 0, TEXT_HIDDEN_OFF.Length);
+ }
+
+ /**
+ * Sets whether to display a page number in the table of contents, or not
+ *
+ * @param showPageNumber Whether to display a page number or not
+ */
+ public void SetShowPageNumber(bool showPageNumber) {
+ this.showPageNumber = showPageNumber;
+ }
+
+ /**
+ * unused
+ */
+ protected override void WriteFieldInstContent(Stream outp) {
+ }
+
+ /*
+ * unused
+ * @see com.lowagie.text.rtf.field.RtfField#writeFieldResultContent(java.io.OutputStream)
+ */
+ protected override void WriteFieldResultContent(Stream outp) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/field/RtfTableOfContents.cs b/iTechSharp/iTextSharp/text/rtf/field/RtfTableOfContents.cs
new file mode 100644
index 0000000..94181e5
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/field/RtfTableOfContents.cs
@@ -0,0 +1,105 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+/*
+ * $Id: RtfTableOfContents.cs,v 1.7 2008/05/23 17:24:26 psoares33 Exp $
+ *
+ *
+ * Copyright 2004 by Mark Hall
+ * Uses code Copyright 2002
+ * Steffen.Stundzig@smb-tec.com
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.field {
+
+ /**
+ * The RtfTableOfContents together with multiple RtfTOCEntry objects generates a table
+ * of contents. The table of contents will display no entries in the viewing program
+ * and the user will have to update it first. A text to inform the user of this is
+ * displayed instead.
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen.Stundzig@smb-tec.com
+ */
+ public class RtfTableOfContents : RtfField {
+
+ /**
+ * field inst content
+ */
+ private const String FIELD_INST = "TOC \\\\f \\\\h \\\\u \\\\o \"1-5\" ";
+ /**
+ * The default text to display
+ */
+ private String defaultText = "Table of Contents - Click to update";
+
+ /**
+ * Constructs a RtfTableOfContents. The default text is the text that is displayed
+ * before the user updates the table of contents
+ *
+ * @param defaultText The default text to display
+ * @param font The Font to use
+ */
+ public RtfTableOfContents(String defaultText) : base(null, new Font()) {
+ this.defaultText = defaultText;
+ }
+
+ /**
+ * Writes the field instruction content
+ */
+ protected override void WriteFieldInstContent(Stream outp) {
+ byte[] t = DocWriter.GetISOBytes(FIELD_INST);
+ outp.Write(t, 0, t.Length);
+ }
+
+ /**
+ * Writes the field result content
+ */
+ protected override void WriteFieldResultContent(Stream outp) {
+ document.FilterSpecialChar(outp, defaultText, true, true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/field/RtfTotalPageNumber.cs b/iTechSharp/iTextSharp/text/rtf/field/RtfTotalPageNumber.cs
new file mode 100644
index 0000000..a38b300
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/field/RtfTotalPageNumber.cs
@@ -0,0 +1,118 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfTotalPageNumber.cs,v 1.5 2008/05/23 17:24:26 psoares33 Exp $
+ *
+ *
+ * Copyright 2005 Jose Hurtado jose.hurtado@gft.com
+ * Parts Copyright 2005 Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.field {
+
+ /**
+ * The RtfTotalPageNumber provides the total number of pages field in rtf documents.
+ *
+ * @version $Version:$
+ * @author Jose Hurtado (jose.hurtado@gft.com)
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfTotalPageNumber : RtfField {
+
+ /**
+ * Constant for arabic total page numbers.
+ */
+ private static byte[] ARABIC_TOTAL_PAGES = DocWriter.GetISOBytes("NUMPAGES \\\\* Arabic");
+
+ /**
+ * Constructs a RtfTotalPageNumber. This can be added anywhere to add a total number of pages field.
+ */
+ public RtfTotalPageNumber() : base(null) {
+ }
+
+ /**
+ * Constructs a RtfTotalPageNumber with a specified Font. This can be added anywhere
+ * to add a total number of pages field.
+ * @param font
+ */
+ public RtfTotalPageNumber(Font font) : base(null, font) {
+ }
+
+ /**
+ * Constructs a RtfTotalPageNumber object.
+ *
+ * @param doc The RtfDocument this RtfTotalPageNumber belongs to
+ */
+ public RtfTotalPageNumber(RtfDocument doc) : base(doc) {
+ }
+
+ /**
+ * Constructs a RtfTotalPageNumber object with a specific font.
+ *
+ * @param doc The RtfDocument this RtfTotalPageNumber belongs to
+ * @param font The Font to use
+ */
+ public RtfTotalPageNumber(RtfDocument doc, Font font) : base(doc, font) {
+ }
+
+ /**
+ * Writes the field NUMPAGES instruction with Arabic format: "NUMPAGES \\\\* Arabic".
+ */
+ protected override void WriteFieldInstContent(Stream outp) {
+ outp.Write(ARABIC_TOTAL_PAGES, 0, ARABIC_TOTAL_PAGES.Length);
+ }
+
+ /**
+ * Writes the field result content "1"
+ */
+ protected override void WriteFieldResultContent(Stream outp) {
+ byte[] t = new byte[]{(byte)'1'};
+ outp.Write(t, 0, t.Length);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/graphic/RtfImage.cs b/iTechSharp/iTextSharp/text/rtf/graphic/RtfImage.cs
new file mode 100644
index 0000000..ec2edf4
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/graphic/RtfImage.cs
@@ -0,0 +1,384 @@
+using System;
+using System.IO;
+using System.Net;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.document.output;
+using iTextSharp.text.rtf.text;
+using iTextSharp.text.rtf.style;
+using iTextSharp.text.pdf.codec.wmf;
+/*
+ * $Id: RtfImage.cs,v 1.11 2008/05/16 19:30:59 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.graphic {
+
+ /**
+ * The RtfImage contains one image. Supported image types are jpeg, png, wmf, bmp.
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Paulo Soares
+ */
+ public class RtfImage : RtfElement {
+
+ /**
+ * Constant for the shape/picture group
+ */
+ private static byte[] PICTURE_GROUP = DocWriter.GetISOBytes("\\*\\shppict");
+ /**
+ * Constant for a picture
+ */
+ private static byte[] PICTURE = DocWriter.GetISOBytes("\\pict");
+ /**
+ * Constant for a jpeg image
+ */
+ private static byte[] PICTURE_JPEG = DocWriter.GetISOBytes("\\jpegblip");
+ /**
+ * Constant for a png image
+ */
+ private static byte[] PICTURE_PNG = DocWriter.GetISOBytes("\\pngblip");
+ /**
+ * Constant for a wmf image
+ */
+ private static byte[] PICTURE_WMF = DocWriter.GetISOBytes("\\wmetafile8");
+ /**
+ * Constant for the picture width
+ */
+ private static byte[] PICTURE_WIDTH = DocWriter.GetISOBytes("\\picw");
+ /**
+ * Constant for the picture height
+ */
+ private static byte[] PICTURE_HEIGHT = DocWriter.GetISOBytes("\\pich");
+ /**
+ * Constant for the picture width scale
+ */
+ private static byte[] PICTURE_SCALED_WIDTH = DocWriter.GetISOBytes("\\picwgoal");
+ /**
+ * Constant for the picture height scale
+ */
+ private static byte[] PICTURE_SCALED_HEIGHT = DocWriter.GetISOBytes("\\pichgoal");
+ /**
+ * Constant for horizontal picture scaling
+ */
+ private static byte[] PICTURE_SCALE_X = DocWriter.GetISOBytes("\\picscalex");
+ /**
+ * Constant for vertical picture scaling
+ */
+ private static byte[] PICTURE_SCALE_Y = DocWriter.GetISOBytes("\\picscaley");
+ /**
+ * "\bin" constant
+ */
+ private static byte[] PICTURE_BINARY_DATA = DocWriter.GetISOBytes("\\bin");
+ /**
+ * Constant for converting pixels to twips
+ */
+ private const int PIXEL_TWIPS_FACTOR = 15;
+
+ /**
+ * The type of image this is.
+ */
+ private int imageType;
+ /**
+ * Binary image data.
+ */
+ private byte[][] imageData;
+ /**
+ * The alignment of this picture
+ */
+ private int alignment = Element.ALIGN_LEFT;
+ /**
+ * The width of this picture
+ */
+ private float width = 0;
+ /**
+ * The height of this picutre
+ */
+ private float height = 0;
+ /**
+ * The intended display width of this picture
+ */
+ private float plainWidth = 0;
+ /**
+ * The intended display height of this picture
+ */
+ private float plainHeight = 0;
+ /**
+ * Whether this RtfImage is a top level element and should
+ * be an extra paragraph.
+ */
+ private bool topLevelElement = false;
+
+ /**
+ * Constructs a RtfImage for an Image.
+ *
+ * @param doc The RtfDocument this RtfImage belongs to
+ * @param image The Image that this RtfImage wraps
+ * @throws DocumentException If an error occured accessing the image content
+ */
+ public RtfImage(RtfDocument doc, Image image) : base(doc) {
+ imageType = image.OriginalType;
+ if (!(imageType == Image.ORIGINAL_JPEG || imageType == Image.ORIGINAL_BMP
+ || imageType == Image.ORIGINAL_PNG || imageType == Image.ORIGINAL_WMF || imageType == Image.ORIGINAL_GIF)) {
+ throw new DocumentException("Only BMP, PNG, WMF, GIF and JPEG images are supported by the RTF Writer");
+ }
+ alignment = image.Alignment;
+ width = image.Width;
+ height = image.Height;
+ plainWidth = image.PlainWidth;
+ plainHeight = image.PlainHeight;
+ this.imageData = GetImageData(image);
+ }
+
+ /**
+ * Extracts the image data from the Image.
+ *
+ * @param image The image for which to extract the content
+ * @return The raw image data, not formated
+ * @throws DocumentException If an error occurs accessing the image content
+ */
+ private byte[][] GetImageData(Image image) {
+ int WMF_PLACEABLE_HEADER_SIZE = 22;
+ RtfByteArrayBuffer bab = new RtfByteArrayBuffer();
+
+ try {
+ if (imageType == Image.ORIGINAL_BMP) {
+ bab.Append(MetaDo.WrapBMP(image));
+ } else {
+ byte[] iod = image.OriginalData;
+ if (iod == null) {
+ Stream imageIn = WebRequest.Create(image.Url).GetResponse().GetResponseStream();
+ if (imageType == Image.ORIGINAL_WMF) { //remove the placeable header first
+ for (int k = 0; k < WMF_PLACEABLE_HEADER_SIZE; k++) {
+ if (imageIn.ReadByte() < 0) throw (new IOException("while removing wmf placeable header"));
+ }
+ }
+ bab.Write(imageIn);
+ imageIn.Close();
+
+ } else {
+
+ if (imageType == Image.ORIGINAL_WMF) {
+ //remove the placeable header
+ bab.Write(iod, WMF_PLACEABLE_HEADER_SIZE, iod.Length - WMF_PLACEABLE_HEADER_SIZE);
+ } else {
+ bab.Append(iod);
+ }
+
+ }
+ }
+ return bab.ToArrayArray();
+ } catch (IOException ioe) {
+ throw new DocumentException(ioe.Message);
+ }
+ }
+
+
+ /**
+ * lookup table used for converting bytes to hex chars.
+ * TODO Should probably be refactored into a helper class
+ */
+ public static byte[] byte2charLUT = new byte[512]; //'0001020304050607 ... fafbfcfdfeff'
+ static RtfImage() {
+ char c = '0';
+ for (int k = 0; k < 16; k++) {
+ for (int x = 0; x < 16; x++) {
+ byte2charLUT[((k*16)+x)*2] = byte2charLUT[(((x*16)+k)*2)+1] = (byte)c;
+ }
+ if (++c == ':') c = 'a';
+ }
+ }
+ /**
+ * Writes the image data to the given buffer as hex encoded text.
+ *
+ * @param binary
+ * @param bab
+ * @
+ */
+ private void WriteImageDataHexEncoded(Stream bab) {
+ int cnt = 0;
+ for (int k = 0; k < imageData.Length; k++) {
+ byte[] chunk = imageData[k];
+ for (int x = 0; x < chunk.Length; x++) {
+ bab.Write(byte2charLUT, (chunk[x]&0xff)*2, 2);
+ if (++cnt == 64) {
+ bab.WriteByte((byte)'\n');
+ cnt = 0;
+ }
+ }
+ }
+ if (cnt > 0) bab.WriteByte((byte)'\n');
+ }
+ /**
+ * Returns the image raw data size in bytes.
+ *
+ * @return
+ */
+ private int ImageDataSize() {
+ int size = 0;
+ for (int k = 0; k < imageData.Length; k++) {
+ size += imageData[k].Length;
+ }
+ return size;
+ }
+
+ /**
+ * Writes the RtfImage content
+ */
+ public override void WriteContent(Stream result)
+ {
+ byte[] t;
+ if (this.topLevelElement) {
+ result.Write(RtfParagraph.PARAGRAPH_DEFAULTS, 0, RtfParagraph.PARAGRAPH_DEFAULTS.Length);
+ switch (alignment) {
+ case Element.ALIGN_LEFT:
+ result.Write(RtfParagraphStyle.ALIGN_LEFT, 0, RtfParagraphStyle.ALIGN_LEFT.Length);
+ break;
+ case Element.ALIGN_RIGHT:
+ result.Write(RtfParagraphStyle.ALIGN_RIGHT, 0, RtfParagraphStyle.ALIGN_RIGHT.Length);
+ break;
+ case Element.ALIGN_CENTER:
+ result.Write(RtfParagraphStyle.ALIGN_CENTER, 0, RtfParagraphStyle.ALIGN_CENTER.Length);
+ break;
+ case Element.ALIGN_JUSTIFIED:
+ result.Write(RtfParagraphStyle.ALIGN_JUSTIFY, 0, RtfParagraphStyle.ALIGN_JUSTIFY.Length);
+ break;
+ }
+ }
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(PICTURE_GROUP, 0, PICTURE_GROUP.Length);
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(PICTURE, 0, PICTURE.Length);
+ switch (imageType) {
+ case Image.ORIGINAL_JPEG:
+ result.Write(PICTURE_JPEG, 0, PICTURE_JPEG.Length);
+ break;
+ case Image.ORIGINAL_PNG:
+ case Image.ORIGINAL_GIF:
+ result.Write(PICTURE_PNG, 0, PICTURE_PNG.Length);
+ break;
+ case Image.ORIGINAL_WMF:
+ case Image.ORIGINAL_BMP:
+ result.Write(PICTURE_WMF, 0, PICTURE_WMF.Length);
+ break;
+ }
+ result.Write(PICTURE_WIDTH, 0, PICTURE_WIDTH.Length);
+ result.Write(t = IntToByteArray((int) width), 0, t.Length);
+ result.Write(PICTURE_HEIGHT, 0, PICTURE_HEIGHT.Length);
+ result.Write(t = IntToByteArray((int) height), 0, t.Length);
+ if (this.document.GetDocumentSettings().IsWriteImageScalingInformation()) {
+ result.Write(PICTURE_SCALE_X, 0, PICTURE_SCALE_X.Length);
+ result.Write(t = IntToByteArray((int)(100 * plainWidth / width)), 0, t.Length);
+ result.Write(PICTURE_SCALE_Y, 0, PICTURE_SCALE_Y.Length);
+ result.Write(t = IntToByteArray((int)(100 * plainHeight / height)), 0, t.Length);
+ }
+ if (this.document.GetDocumentSettings().IsImagePDFConformance()) {
+ result.Write(PICTURE_SCALED_WIDTH, 0, PICTURE_SCALED_WIDTH.Length);
+ result.Write(t = IntToByteArray((int) (plainWidth * RtfElement.TWIPS_FACTOR)), 0, t.Length);
+ result.Write(PICTURE_SCALED_HEIGHT, 0, PICTURE_SCALED_HEIGHT.Length);
+ result.Write(t = IntToByteArray((int) (plainHeight * RtfElement.TWIPS_FACTOR)), 0, t.Length);
+ } else {
+ if (this.width != this.plainWidth || this.imageType == Image.ORIGINAL_BMP) {
+ result.Write(PICTURE_SCALED_WIDTH, 0, PICTURE_SCALED_WIDTH.Length);
+ result.Write(t = IntToByteArray((int) (plainWidth * PIXEL_TWIPS_FACTOR)), 0, t.Length);
+ }
+ if (this.height != this.plainHeight || this.imageType == Image.ORIGINAL_BMP) {
+ result.Write(PICTURE_SCALED_HEIGHT, 0, PICTURE_SCALED_HEIGHT.Length);
+ result.Write(t = IntToByteArray((int) (plainHeight * PIXEL_TWIPS_FACTOR)), 0, t.Length);
+ }
+ }
+
+ if (this.document.GetDocumentSettings().IsImageWrittenAsBinary()) {
+ //binary
+ result.WriteByte((byte)'\n');
+ result.Write(PICTURE_BINARY_DATA, 0, PICTURE_BINARY_DATA.Length);
+ result.Write(t = IntToByteArray(ImageDataSize()), 0, t.Length);
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ if (result is RtfByteArrayBuffer) {
+ ((RtfByteArrayBuffer)result).Append(imageData);
+ } else {
+ for (int k = 0; k < imageData.Length; k++) {
+ result.Write(imageData[k], 0, imageData[k].Length);
+ }
+ }
+ } else {
+ //hex encoded
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ result.WriteByte((byte)'\n');
+ WriteImageDataHexEncoded(result);
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ if (this.topLevelElement) {
+ result.Write(RtfParagraph.PARAGRAPH, 0, RtfParagraph.PARAGRAPH.Length);
+ }
+ result.WriteByte((byte)'\n');
+ }
+
+ /**
+ * Sets the alignment of this RtfImage. Uses the alignments from com.lowagie.text.Element.
+ *
+ * @param alignment The alignment to use.
+ */
+ public void SetAlignment(int alignment) {
+ this.alignment = alignment;
+ }
+
+ /**
+ * Set whether this RtfImage should behave like a top level element
+ * and enclose itself in a paragraph.
+ *
+ * @param topLevelElement Whether to behave like a top level element.
+ */
+ public void SetTopLevelElement(bool topLevelElement) {
+ this.topLevelElement = topLevelElement;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/graphic/RtfShape.cs b/iTechSharp/iTextSharp/text/rtf/graphic/RtfShape.cs
new file mode 100644
index 0000000..212da88
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/graphic/RtfShape.cs
@@ -0,0 +1,379 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/**
+ * $Id: RtfShape.cs,v 1.7 2008/05/23 17:24:27 psoares33 Exp $
+ *
+ *
+ * Copyright 2006 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.graphic {
+
+ /**
+ * The RtfShape provides the interface for adding shapes to
+ * the RTF document. This will only work for Word 97+, older
+ * Word versions are not supported by this class.
+ *
+ * Only very simple shapes are directly supported by the RtfShape.
+ * For more complex shapes you will have to read the RTF
+ * specification (iText follows the 1.6 specification) and add
+ * the desired properties via the RtfShapeProperty.
+ *
+ * One thing to keep in mind is that distances are not expressed
+ * in the standard iText point, but in EMU where 1 inch = 914400 EMU
+ * or 1 cm = 360000 EMU.
+ *
+ * @version $Revision: 1.7 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfShape : RtfAddableElement {
+ /**
+ * Constant for a free form shape. The shape verticies must
+ * be specified with an array of Point objects in a
+ * RtfShapeProperty with the name PROPERTY_VERTICIES.
+ */
+ public const int SHAPE_FREEFORM = 0;
+ /**
+ * Constant for a rectangle.
+ */
+ public const int SHAPE_RECTANGLE = 1;
+ /**
+ * Constant for a rounded rectangle. The roundness is
+ * set via a RtfShapeProperty with the name PROPERTY_ADJUST_VALUE.
+ */
+ public const int SHAPE_ROUND_RECTANGLE = 2;
+ /**
+ * Constant for an ellipse. Use this to create circles.
+ */
+ public const int SHAPE_ELLIPSE = 3;
+ /**
+ * Constant for a diamond.
+ */
+ public const int SHAPE_DIAMOND = 4;
+ /**
+ * Constant for a isoscelle triangle.
+ */
+ public const int SHAPE_TRIANGLE_ISOSCELES = 5;
+ /**
+ * Constant for a right triangle.
+ */
+ public const int SHAPE_TRIANGLE_RIGHT = 6;
+ /**
+ * Constant for a parallelogram.
+ */
+ public const int SHAPE_PARALLELOGRAM = 7;
+ /**
+ * Constant for a trapezoid.
+ */
+ public const int SHAPE_TRAPEZOID = 8;
+ /**
+ * Constant for a hexagon.
+ */
+ public const int SHAPE_HEXAGON = 9;
+ /**
+ * Constant for an ocatagon.
+ */
+ public const int SHAPE_OCTAGON = 10;
+ /**
+ * Constant for a star.
+ */
+ public const int SHAPE_STAR = 12;
+ /**
+ * Constant for an arrow.
+ */
+ public const int SHAPE_ARROW = 13;
+ /**
+ * Constant for a thick arrow.
+ */
+ public const int SHAPE_ARROR_THICK = 14;
+ /**
+ * Constant for a home plate style shape.
+ */
+ public const int SHAPE_HOME_PLATE = 15;
+ /**
+ * Constant for a cube shape.
+ */
+ public const int SHAPE_CUBE = 16;
+ /**
+ * Constant for a balloon shape.
+ */
+ public const int SHAPE_BALLOON = 17;
+ /**
+ * Constant for a seal shape.
+ */
+ public const int SHAPE_SEAL = 18;
+ /**
+ * Constant for an arc shape.
+ */
+ public const int SHAPE_ARC = 19;
+ /**
+ * Constant for a line shape.
+ */
+ public const int SHAPE_LINE = 20;
+ /**
+ * Constant for a can shape.
+ */
+ public const int SHAPE_CAN = 22;
+ /**
+ * Constant for a donut shape.
+ */
+ public const int SHAPE_DONUT = 23;
+
+ /**
+ * Constant for a Picture Frame.
+ */
+ public const int SHAPE_PICTURE_FRAME = 75;
+ /**
+ * Text is not wrapped around the shape.
+ */
+ public const int SHAPE_WRAP_NONE = 0;
+ /**
+ * Text is wrapped to the top and bottom.
+ */
+ public const int SHAPE_WRAP_TOP_BOTTOM = 1;
+ /**
+ * Text is wrapped on the left and right side.
+ */
+ public const int SHAPE_WRAP_BOTH = 2;
+ /**
+ * Text is wrapped on the left side.
+ */
+ public const int SHAPE_WRAP_LEFT = 3;
+ /**
+ * Text is wrapped on the right side.
+ */
+ public const int SHAPE_WRAP_RIGHT = 4;
+ /**
+ * Text is wrapped on the largest side.
+ */
+ public const int SHAPE_WRAP_LARGEST = 5;
+ /**
+ * Text is tightly wrapped on the left and right side.
+ */
+ public const int SHAPE_WRAP_TIGHT_BOTH = 6;
+ /**
+ * Text is tightly wrapped on the left side.
+ */
+ public const int SHAPE_WRAP_TIGHT_LEFT = 7;
+ /**
+ * Text is tightly wrapped on the right side.
+ */
+ public const int SHAPE_WRAP_TIGHT_RIGHT = 8;
+ /**
+ * Text is tightly wrapped on the largest side.
+ */
+ public const int SHAPE_WRAP_TIGHT_LARGEST = 9;
+ /**
+ * Text is wrapped through the shape.
+ */
+ public const int SHAPE_WRAP_THROUGH = 10;
+
+ /**
+ * The shape nr is a random unique id.
+ */
+ private int shapeNr = 0;
+ /**
+ * The shape type.
+ */
+ private int type = 0;
+ /**
+ * The RtfShapePosition that defines position settings for this RtfShape.
+ */
+ private RtfShapePosition position = null;
+ /**
+ * A Hashtable with RtfShapePropertys that define further shape properties.
+ */
+ private Hashtable properties = null;
+ /**
+ * The wrapping mode. Defaults to SHAPE_WRAP_NONE;
+ */
+ private int wrapping = SHAPE_WRAP_NONE;
+ /**
+ * Text that is contained in the shape.
+ */
+ private String shapeText = "";
+
+ /**
+ * Constructs a new RtfShape of a given shape at the given RtfShapePosition.
+ *
+ * @param type The type of shape to create.
+ * @param position The RtfShapePosition to create this RtfShape at.
+ */
+ public RtfShape(int type, RtfShapePosition position) {
+ this.type = type;
+ this.position = position;
+ this.properties = new Hashtable();
+ }
+
+ /**
+ * Sets a property.
+ *
+ * @param property The property to set for this RtfShape.
+ */
+ public void SetProperty(RtfShapeProperty property) {
+ this.properties[property.GetName()] = property;
+ }
+
+ /**
+ * Sets the text to display in this RtfShape.
+ *
+ * @param shapeText The text to display.
+ */
+ public void SetShapeText(String shapeText) {
+ this.shapeText = shapeText;
+ }
+
+ /**
+ * Set the wrapping mode.
+ *
+ * @param wrapping The wrapping mode to use for this RtfShape.
+ */
+ public void SetWrapping(int wrapping) {
+ this.wrapping = wrapping;
+ }
+
+ /**
+ * Writes the RtfShape. Some settings are automatically translated into
+ * or require other properties and these are set first.
+ */
+ public override void WriteContent(Stream result) {
+ this.shapeNr = this.doc.GetRandomInt();
+
+ this.properties["ShapeType"] = new RtfShapeProperty("ShapeType", this.type);
+ if (this.position.IsShapeBelowText()) {
+ this.properties["fBehindDocument"] = new RtfShapeProperty("fBehindDocument", true);
+ }
+ if (this.inTable) {
+ this.properties["fLayoutInCell"] = new RtfShapeProperty("fLayoutInCell", true);
+ }
+ if (this.properties.ContainsKey("posh")) {
+ this.position.SetIgnoreXRelative(true);
+ }
+ if (this.properties.ContainsKey("posv")) {
+ this.position.SetIgnoreYRelative(true);
+ }
+
+ byte[] t;
+ result.Write(RtfElement.OPEN_GROUP, 0, RtfElement.OPEN_GROUP.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shp"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shplid"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.shapeNr), 0, t.Length);
+ this.position.WriteContent(result);
+ switch (this.wrapping) {
+ case SHAPE_WRAP_NONE:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr3"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_TOP_BOTTOM:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr1"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_BOTH:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr2"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpwrk0"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_LEFT:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr2"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpwrk1"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_RIGHT:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr2"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpwrk2"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_LARGEST:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr2"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpwrk3"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_TIGHT_BOTH:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr4"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpwrk0"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_TIGHT_LEFT:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr4"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpwrk1"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_TIGHT_RIGHT:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr4"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpwrk2"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_TIGHT_LARGEST:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr4"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpwrk3"), 0, t.Length);
+ break;
+ case SHAPE_WRAP_THROUGH:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr5"), 0, t.Length);
+ break;
+ default:
+ result.Write(t = DocWriter.GetISOBytes("\\shpwr3"), 0, t.Length);
+ break;
+ }
+ if (this.inHeader) {
+ result.Write(t = DocWriter.GetISOBytes("\\shpfhdr1"), 0, t.Length);
+ }
+ if (this.doc.GetDocumentSettings().IsOutputDebugLineBreaks()) {
+ result.WriteByte((byte)'\n');
+ }
+ result.Write(RtfElement.OPEN_GROUP, 0, RtfElement.OPEN_GROUP.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\*\\shpinst"), 0, t.Length);
+ foreach (RtfShapeProperty rsp in this.properties.Values) {
+ rsp.WriteContent(result);
+ }
+ if (!this.shapeText.Equals("")) {
+ result.Write(RtfElement.OPEN_GROUP, 0, RtfElement.OPEN_GROUP.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shptxt"), 0, t.Length);
+ result.Write(RtfElement.DELIMITER, 0, RtfElement.DELIMITER.Length);
+ result.Write(t = DocWriter.GetISOBytes(this.shapeText), 0, t.Length);
+ result.Write(RtfElement.CLOSE_GROUP, 0, RtfElement.CLOSE_GROUP.Length);
+ }
+ result.Write(RtfElement.CLOSE_GROUP, 0, RtfElement.CLOSE_GROUP.Length);
+ if (this.doc.GetDocumentSettings().IsOutputDebugLineBreaks()) {
+ result.WriteByte((byte)'\n');
+ }
+ result.Write(RtfElement.CLOSE_GROUP, 0, RtfElement.CLOSE_GROUP.Length);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/graphic/RtfShapePosition.cs b/iTechSharp/iTextSharp/text/rtf/graphic/RtfShapePosition.cs
new file mode 100644
index 0000000..37d3ada
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/graphic/RtfShapePosition.cs
@@ -0,0 +1,249 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/**
+ * $Id: RtfShapePosition.cs,v 1.6 2008/05/23 17:24:27 psoares33 Exp $
+ *
+ *
+ * Copyright 2006 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.graphic {
+
+ /**
+ * The RtfShapePosition stores position and ordering
+ * information for one RtfShape.
+ *
+ * @version $Revision: 1.6 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfShapePosition : RtfAddableElement {
+ /**
+ * Constant for horizontal positioning relative to the page.
+ */
+ public const int POSITION_X_RELATIVE_PAGE = 0;
+ /**
+ * Constant for horizontal positioning relative to the margin.
+ */
+ public const int POSITION_X_RELATIVE_MARGIN = 1;
+ /**
+ * Constant for horizontal positioning relative to the column.
+ */
+ public const int POSITION_X_RELATIVE_COLUMN = 2;
+ /**
+ * Constant for vertical positioning relative to the page.
+ */
+ public const int POSITION_Y_RELATIVE_PAGE = 0;
+ /**
+ * Constant for vertical positioning relative to the margin.
+ */
+ public const int POSITION_Y_RELATIVE_MARGIN = 1;
+ /**
+ * Constant for vertical positioning relative to the paragraph.
+ */
+ public const int POSITION_Y_RELATIVE_PARAGRAPH = 2;
+
+ /**
+ * The top coordinate of this RtfShapePosition.
+ */
+ private int top = 0;
+ /**
+ * The left coordinate of this RtfShapePosition.
+ */
+ private int left = 0;
+ /**
+ * The right coordinate of this RtfShapePosition.
+ */
+ private int right = 0;
+ /**
+ * The bottom coordinate of this RtfShapePosition.
+ */
+ private int bottom = 0;
+ /**
+ * The z order of this RtfShapePosition.
+ */
+ private int zOrder = 0;
+ /**
+ * The horizontal relative position.
+ */
+ private int xRelativePos = POSITION_X_RELATIVE_PAGE;
+ /**
+ * The vertical relative position.
+ */
+ private int yRelativePos = POSITION_Y_RELATIVE_PAGE;
+ /**
+ * Whether to ignore the horizontal relative position.
+ */
+ private bool ignoreXRelative = false;
+ /**
+ * Whether to ignore the vertical relative position.
+ */
+ private bool ignoreYRelative = false;
+ /**
+ * Whether the shape is below the text.
+ */
+ private bool shapeBelowText = false;
+
+ /**
+ * Constructs a new RtfShapePosition with the four bounding coordinates.
+ *
+ * @param top The top coordinate.
+ * @param left The left coordinate.
+ * @param right The right coordinate.
+ * @param bottom The bottom coordinate.
+ */
+ public RtfShapePosition(int top, int left, int right, int bottom) {
+ this.top = top;
+ this.left = left;
+ this.right = right;
+ this.bottom = bottom;
+ }
+
+ /**
+ * Gets whether the shape is below the text.
+ *
+ * @return True
if the shape is below, false
if the text is below.
+ */
+ public bool IsShapeBelowText() {
+ return shapeBelowText;
+ }
+
+ /**
+ * Sets whether the shape is below the text.
+ *
+ * @param shapeBelowText True
if the shape is below, false
if the text is below.
+ */
+ public void SetShapeBelowText(bool shapeBelowText) {
+ this.shapeBelowText = shapeBelowText;
+ }
+
+ /**
+ * Sets the relative horizontal position. Use one of the constants
+ * provided in this class.
+ *
+ * @param relativePos The relative horizontal position to use.
+ */
+ public void SetXRelativePos(int relativePos) {
+ xRelativePos = relativePos;
+ }
+
+ /**
+ * Sets the relative vertical position. Use one of the constants
+ * provides in this class.
+ *
+ * @param relativePos The relative vertical position to use.
+ */
+ public void SetYRelativePos(int relativePos) {
+ yRelativePos = relativePos;
+ }
+
+ /**
+ * Sets the z order to use.
+ *
+ * @param order The z order to use.
+ */
+ public void SetZOrder(int order) {
+ zOrder = order;
+ }
+
+ /**
+ * Set whether to ignore the horizontal relative position.
+ *
+ * @param ignoreXRelative True
to ignore the horizontal relative position, false
otherwise.
+ */
+ protected internal void SetIgnoreXRelative(bool ignoreXRelative) {
+ this.ignoreXRelative = ignoreXRelative;
+ }
+
+ /**
+ * Set whether to ignore the vertical relative position.
+ *
+ * @param ignoreYRelative True
to ignore the vertical relative position, false
otherwise.
+ */
+ protected internal void SetIgnoreYRelative(bool ignoreYRelative) {
+ this.ignoreYRelative = ignoreYRelative;
+ }
+
+ /**
+ * Write this RtfShapePosition.
+ */
+ public override void WriteContent(Stream result) {
+ byte[] t;
+ result.Write(t = DocWriter.GetISOBytes("\\shpleft"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.left), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shptop"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.top), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpright"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.right), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpbottom"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.bottom), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\shpz"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.zOrder), 0, t.Length);
+ switch(this.xRelativePos) {
+ case POSITION_X_RELATIVE_PAGE: result.Write(t = DocWriter.GetISOBytes("\\shpbxpage"), 0, t.Length); break;
+ case POSITION_X_RELATIVE_MARGIN: result.Write(t = DocWriter.GetISOBytes("\\shpbxmargin"), 0, t.Length); break;
+ case POSITION_X_RELATIVE_COLUMN: result.Write(t = DocWriter.GetISOBytes("\\shpbxcolumn"), 0, t.Length); break;
+ }
+ if(this.ignoreXRelative) {
+ result.Write(t = DocWriter.GetISOBytes("\\shpbxignore"), 0, t.Length);
+ }
+ switch(this.yRelativePos) {
+ case POSITION_Y_RELATIVE_PAGE: result.Write(t = DocWriter.GetISOBytes("\\shpbypage"), 0, t.Length); break;
+ case POSITION_Y_RELATIVE_MARGIN: result.Write(t = DocWriter.GetISOBytes("\\shpbymargin"), 0, t.Length); break;
+ case POSITION_Y_RELATIVE_PARAGRAPH: result.Write(t = DocWriter.GetISOBytes("\\shpbypara"), 0, t.Length); break;
+ }
+ if(this.ignoreYRelative) {
+ result.Write(t = DocWriter.GetISOBytes("\\shpbyignore"), 0, t.Length);
+ }
+ if(this.shapeBelowText) {
+ result.Write(t = DocWriter.GetISOBytes("\\shpfblwtxt1"), 0, t.Length);
+ } else {
+ result.Write(t = DocWriter.GetISOBytes("\\shpfblwtxt0"), 0, t.Length);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/graphic/RtfShapeProperty.cs b/iTechSharp/iTextSharp/text/rtf/graphic/RtfShapeProperty.cs
new file mode 100644
index 0000000..cf2b192
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/graphic/RtfShapeProperty.cs
@@ -0,0 +1,356 @@
+using System;
+using System.IO;
+using System.Drawing;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/**
+ * $Id: RtfShapeProperty.cs,v 1.8 2008/05/23 17:24:27 psoares33 Exp $
+ *
+ *
+ * Copyright 2006 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.graphic {
+
+ /**
+ * The RtfShapeProperty stores all shape properties that are
+ * not handled by the RtfShape and RtfShapePosition.
+ *
+ * There is a huge selection of properties that can be set. For
+ * the most important properites there are constants for the
+ * property name, for all others you must find the correct
+ * property name in the RTF specification (version 1.6).
+ *
+ * The following types of property values are supported:
+ *
+ *
+ *
+ * @version $Revision: 1.8 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfShapeProperty : RtfAddableElement {
+ /**
+ * Property for defining an image.
+ */
+ public const String PROPERTY_IMAGE = "pib";
+ /**
+ * Property for defining vertices in freeform shapes. Requires a
+ * Point array as the value.
+ */
+ public const String PROPERTY_VERTICIES = "pVerticies";
+ /**
+ * Property for defining the minimum vertical coordinate that is
+ * visible. Requires a long value.
+ */
+ public const String PROPERTY_GEO_TOP = "geoTop";
+ /**
+ * Property for defining the minimum horizontal coordinate that is
+ * visible. Requires a long value.
+ */
+ public const String PROPERTY_GEO_LEFT = "geoLeft";
+ /**
+ * Property for defining the maximum horizontal coordinate that is
+ * visible. Requires a long value.
+ */
+ public const String PROPERTY_GEO_RIGHT = "geoRight";
+ /**
+ * Property for defining the maximum vertical coordinate that is
+ * visible. Requires a long value.
+ */
+ public const String PROPERTY_GEO_BOTTOM = "geoBottom";
+ /**
+ * Property for defining that the shape is in a table cell. Requires
+ * a bool value.
+ */
+ public const String PROPERTY_LAYOUT_IN_CELL = "fLayoutInCell";
+ /**
+ * Property for signalling a vertical flip of the shape. Requires a
+ * bool value.
+ */
+ public const String PROPERTY_FLIP_V = "fFlipV";
+ /**
+ * Property for signalling a horizontal flip of the shape. Requires a
+ * bool value.
+ */
+ public const String PROPERTY_FLIP_H = "fFlipH";
+ /**
+ * Property for defining the fill color of the shape. Requires a
+ * Color value.
+ */
+ public const String PROPERTY_FILL_COLOR = "fillColor";
+ /**
+ * Property for defining the line color of the shape. Requires a
+ * Color value.
+ */
+ public const String PROPERTY_LINE_COLOR = "lineColor";
+ /**
+ * Property for defining the first adjust handle for shapes. Used
+ * with the rounded rectangle. Requires a long value.
+ */
+ public const String PROPERTY_ADJUST_VALUE = "adjustValue";
+
+ /**
+ * The stored value is a long.
+ */
+ private const int PROPERTY_TYPE_LONG = 1;
+ /**
+ * The stored value is bool.
+ */
+ private const int PROPERTY_TYPE_BOOLEAN = 2;
+ /**
+ * The stored value is a double.
+ */
+ private const int PROPERTY_TYPE_DOUBLE = 3;
+ /**
+ * The stored value is a Color.
+ */
+ private const int PROPERTY_TYPE_COLOR = 4;
+ /**
+ * The stored value is either an int or a Point array.
+ */
+ private const int PROPERTY_TYPE_ARRAY = 5;
+ /**
+ * The stored value is an Image.
+ */
+ private const int PROPERTY_TYPE_IMAGE = 6;
+
+ /**
+ * The value type.
+ */
+ private int type = 0;
+ /**
+ * The RtfShapeProperty name.
+ */
+ private String name = "";
+ /**
+ * The RtfShapeProperty value.
+ */
+ private Object value = null;
+
+ /**
+ * Internaly used to create the RtfShape.
+ *
+ * @param name The property name to use.
+ * @param value The property value to use.
+ */
+ private RtfShapeProperty(String name, Object value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Constructs a RtfShapeProperty with a long value.
+ *
+ * @param name The property name to use.
+ * @param value The long value to use.
+ */
+ public RtfShapeProperty(String name, long value) {
+ this.name = name;
+ this.value = value;
+ this.type = PROPERTY_TYPE_LONG;
+ }
+
+ /**
+ * Constructs a RtfShapeProperty with a double value.
+ *
+ * @param name The property name to use.
+ * @param value The double value to use.
+ */
+ public RtfShapeProperty(String name, double value) {
+ this.name = name;
+ this.value = value;
+ this.type = PROPERTY_TYPE_DOUBLE;
+ }
+
+ /**
+ * Constructs a RtfShapeProperty with a bool value.
+ *
+ * @param name The property name to use.
+ * @param value The bool value to use.
+ */
+ public RtfShapeProperty(String name, bool value) {
+ this.name = name;
+ this.value = value;
+ this.type = PROPERTY_TYPE_BOOLEAN;
+ }
+
+ /**
+ * Constructs a RtfShapeProperty with a Color value.
+ *
+ * @param name The property name to use.
+ * @param value The Color value to use.
+ */
+ public RtfShapeProperty(String name, Color value) {
+ this.name = name;
+ this.value = value;
+ this.type = PROPERTY_TYPE_COLOR;
+ }
+
+ /**
+ * Constructs a RtfShapeProperty with an int array value.
+ *
+ * @param name The property name to use.
+ * @param value The int array to use.
+ */
+ public RtfShapeProperty(String name, int[] value) {
+ this.name = name;
+ this.value = value;
+ this.type = PROPERTY_TYPE_ARRAY;
+ }
+
+ /**
+ * Constructs a RtfShapeProperty with a Point array value.
+ *
+ * @param name The property name to use.
+ * @param value The Point array to use.
+ */
+ public RtfShapeProperty(String name, Point[] value) {
+ this.name = name;
+ this.value = value;
+ this.type = PROPERTY_TYPE_ARRAY;
+ }
+
+ /**
+ * Constructs a RtfShapeProperty with an Image value.
+ *
+ * @param name The property name to use.
+ * @param value The Image to use.
+ */
+ public RtfShapeProperty(String name, Image value) {
+ this.name = name;
+ this.value = value;
+ this.type = PROPERTY_TYPE_IMAGE;
+ }
+
+ /**
+ * Gets the name of this RtfShapeProperty.
+ *
+ * @return The name of this RtfShapeProperty.
+ */
+ public String GetName() {
+ return this.name;
+ }
+
+ /**
+ * Write this RtfShapePosition.
+ */
+ public override void WriteContent(Stream result) {
+ byte[] t;
+ result.Write(RtfElement.OPEN_GROUP, 0, RtfElement.OPEN_GROUP.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\sp"), 0, t.Length);
+ result.Write(RtfElement.OPEN_GROUP, 0, RtfElement.OPEN_GROUP.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\sn"), 0, t.Length);
+ result.Write(RtfElement.DELIMITER, 0, RtfElement.DELIMITER.Length);
+ result.Write(t = DocWriter.GetISOBytes(this.name), 0, t.Length);
+ result.Write(RtfElement.CLOSE_GROUP, 0, RtfElement.CLOSE_GROUP.Length);
+ result.Write(RtfElement.OPEN_GROUP, 0, RtfElement.OPEN_GROUP.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\sv"), 0, t.Length);
+ result.Write(RtfElement.DELIMITER, 0, RtfElement.DELIMITER.Length);
+ switch (this.type) {
+ case PROPERTY_TYPE_LONG:
+ case PROPERTY_TYPE_DOUBLE:
+ result.Write(t = DocWriter.GetISOBytes(this.value.ToString()), 0, t.Length);
+ break;
+ case PROPERTY_TYPE_BOOLEAN:
+ if ((bool)this.value) {
+ result.Write(t = DocWriter.GetISOBytes("1"), 0, t.Length);
+ } else {
+ result.Write(t = DocWriter.GetISOBytes("0"), 0, t.Length);
+ }
+ break;
+ case PROPERTY_TYPE_COLOR:
+ Color color = (Color) this.value;
+ result.Write(t = IntToByteArray(color.R | (color.G << 8) | (color.B << 16)), 0, t.Length);
+ break;
+ case PROPERTY_TYPE_ARRAY:
+ if (this.value is int[]) {
+ int[] values = (int[]) this.value;
+ result.Write(t = DocWriter.GetISOBytes("4;"), 0, t.Length);
+ result.Write(t = IntToByteArray(values.Length), 0, t.Length);
+ result.Write(RtfElement.COMMA_DELIMITER, 0, RtfElement.COMMA_DELIMITER.Length);
+ for (int i = 0; i < values.Length; i++) {
+ result.Write(t = IntToByteArray(values[i]), 0, t.Length);
+ if (i < values.Length - 1) {
+ result.Write(RtfElement.COMMA_DELIMITER, 0, RtfElement.COMMA_DELIMITER.Length);
+ }
+ }
+ } else if (this.value is Point[]) {
+ Point[] values = (Point[]) this.value;
+ result.Write(t = DocWriter.GetISOBytes("8;"), 0, t.Length);
+ result.Write(t = IntToByteArray(values.Length), 0, t.Length);
+ result.Write(RtfElement.COMMA_DELIMITER, 0, RtfElement.COMMA_DELIMITER.Length);
+ for (int i = 0; i < values.Length; i++) {
+ result.Write(t = DocWriter.GetISOBytes("("), 0, t.Length);
+ result.Write(t = IntToByteArray(values[i].X), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes(","), 0, t.Length);
+ result.Write(t = IntToByteArray(values[i].Y), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes(")"), 0, t.Length);
+ if (i < values.Length - 1) {
+ result.Write(RtfElement.COMMA_DELIMITER, 0, RtfElement.COMMA_DELIMITER.Length);
+ }
+ }
+ }
+ break;
+ case PROPERTY_TYPE_IMAGE:
+ Image image = (Image)this.value;
+ RtfImage img = new RtfImage(this.doc, image);
+ img.SetTopLevelElement(true);
+ result.Write(RtfElement.OPEN_GROUP, 0, RtfElement.OPEN_GROUP.Length);
+ img.WriteContent(result);
+ result.Write(RtfElement.CLOSE_GROUP, 0, RtfElement.CLOSE_GROUP.Length);
+ break;
+ }
+ result.Write(RtfElement.CLOSE_GROUP, 0, RtfElement.CLOSE_GROUP.Length);
+ result.Write(RtfElement.CLOSE_GROUP, 0, RtfElement.CLOSE_GROUP.Length);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/headerfooter/RtfHeaderFooter.cs b/iTechSharp/iTextSharp/text/rtf/headerfooter/RtfHeaderFooter.cs
new file mode 100644
index 0000000..22c46d6
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/headerfooter/RtfHeaderFooter.cs
@@ -0,0 +1,326 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using FD = iTextSharp.text.rtf.field;
+/*
+ * Created on Aug 10, 2004
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+namespace iTextSharp.text.rtf.headerfooter {
+
+ /**
+ * The RtfHeaderFooter represents one header or footer. This class can be used
+ * directly.
+ *
+ * @version $Id: RtfHeaderFooter.cs,v 1.7 2008/05/16 19:30:59 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfHeaderFooter : HeaderFooter, IRtfBasicElement {
+
+ /**
+ * Constant for the header type
+ */
+ public const int TYPE_HEADER = 1;
+ /**
+ * Constant for the footer type
+ */
+ public const int TYPE_FOOTER = 2;
+ /**
+ * Constant for displaying the header/footer on the first page
+ */
+ public const int DISPLAY_FIRST_PAGE = 0;
+ /**
+ * Constant for displaying the header/footer on all pages
+ */
+ public const int DISPLAY_ALL_PAGES = 1;
+ /**
+ * Constant for displaying the header/footer on all left hand pages
+ */
+ public const int DISPLAY_LEFT_PAGES = 2;
+ /**
+ * Constant for displaying the header/footer on all right hand pages
+ */
+ public const int DISPLAY_RIGHT_PAGES = 4;
+
+ /**
+ * Constant for a header on all pages
+ */
+ private static byte[] HEADER_ALL = DocWriter.GetISOBytes("\\header");
+ /**
+ * Constant for a header on the first page
+ */
+ private static byte[] HEADER_FIRST = DocWriter.GetISOBytes("\\headerf");
+ /**
+ * Constant for a header on all left hand pages
+ */
+ private static byte[] HEADER_LEFT = DocWriter.GetISOBytes("\\headerl");
+ /**
+ * Constant for a header on all right hand pages
+ */
+ private static byte[] HEADER_RIGHT = DocWriter.GetISOBytes("\\headerr");
+ /**
+ * Constant for a footer on all pages
+ */
+ private static byte[] FOOTER_ALL = DocWriter.GetISOBytes("\\footer");
+ /**
+ * Constant for a footer on the first page
+ */
+ private static byte[] FOOTER_FIRST = DocWriter.GetISOBytes("\\footerf");
+ /**
+ * Constnat for a footer on the left hand pages
+ */
+ private static byte[] FOOTER_LEFT = DocWriter.GetISOBytes("\\footerl");
+ /**
+ * Constant for a footer on the right hand pages
+ */
+ private static byte[] FOOTER_RIGHT = DocWriter.GetISOBytes("\\footerr");
+
+ /**
+ * The RtfDocument this RtfHeaderFooter belongs to
+ */
+ private RtfDocument document = null;
+ /**
+ * The content of this RtfHeaderFooter
+ */
+ private Object[] content = null;
+ /**
+ * The display type of this RtfHeaderFooter. TYPE_HEADER or TYPE_FOOTER
+ */
+ private int type = TYPE_HEADER;
+ /**
+ * The display location of this RtfHeaderFooter. DISPLAY_FIRST_PAGE,
+ * DISPLAY_LEFT_PAGES, DISPLAY_RIGHT_PAGES or DISPLAY_ALL_PAGES
+ */
+ private int displayAt = DISPLAY_ALL_PAGES;
+
+ /**
+ * Constructs a RtfHeaderFooter based on a HeaderFooter with a certain type and displayAt
+ * location. For internal use only.
+ *
+ * @param doc The RtfDocument this RtfHeaderFooter belongs to
+ * @param headerFooter The HeaderFooter to base this RtfHeaderFooter on
+ * @param type The type of RtfHeaderFooter
+ * @param displayAt The display location of this RtfHeaderFooter
+ */
+ protected internal RtfHeaderFooter(RtfDocument doc, HeaderFooter headerFooter, int type, int displayAt) : base(new Phrase(""), false) {
+ this.document = doc;
+ this.type = type;
+ this.displayAt = displayAt;
+ Paragraph par = new Paragraph();
+ par.Alignment = headerFooter.Alignment;
+ if (headerFooter.Before != null) {
+ par.Add(headerFooter.Before);
+ }
+ if (headerFooter.IsNumbered()) {
+ par.Add(new FD.RtfPageNumber(this.document));
+ }
+ if (headerFooter.After != null) {
+ par.Add(headerFooter.After);
+ }
+ try {
+ this.content = new Object[1];
+ if (this.document != null) {
+ this.content[0] = this.document.GetMapper().MapElement(par)[0];
+ ((IRtfBasicElement) this.content[0]).SetInHeader(true);
+ } else {
+ this.content[0] = par;
+ }
+ } catch (DocumentException) {
+ }
+ }
+
+ /**
+ * Constructs a RtfHeaderFooter as a copy of an existing RtfHeaderFooter.
+ * For internal use only.
+ *
+ * @param doc The RtfDocument this RtfHeaderFooter belongs to
+ * @param headerFooter The RtfHeaderFooter to copy
+ * @param displayAt The display location of this RtfHeaderFooter
+ */
+ protected internal RtfHeaderFooter(RtfDocument doc, RtfHeaderFooter headerFooter, int displayAt) : base(new Phrase(""), false) {
+ this.document = doc;
+ this.content = headerFooter.GetContent();
+ this.displayAt = displayAt;
+ for (int i = 0; i < this.content.Length; i++) {
+ if (this.content[i] is IElement) {
+ try {
+ this.content[i] = this.document.GetMapper().MapElement((IElement) this.content[i])[0];
+ } catch (DocumentException) {
+ }
+ }
+ if (this.content[i] is IRtfBasicElement) {
+ ((IRtfBasicElement) this.content[i]).SetInHeader(true);
+ }
+ }
+ }
+
+ /**
+ * Constructs a RtfHeaderFooter for a HeaderFooter.
+ *
+ * @param doc The RtfDocument this RtfHeaderFooter belongs to
+ * @param headerFooter The HeaderFooter to base this RtfHeaderFooter on
+ */
+ protected internal RtfHeaderFooter(RtfDocument doc, HeaderFooter headerFooter) : base(new Phrase(""), false) {
+ this.document = doc;
+ Paragraph par = new Paragraph();
+ par.Alignment = headerFooter.Alignment;
+ if (headerFooter.Before != null) {
+ par.Add(headerFooter.Before);
+ }
+ if (headerFooter.IsNumbered()) {
+ par.Add(new FD.RtfPageNumber(this.document));
+ }
+ if (headerFooter.After != null) {
+ par.Add(headerFooter.After);
+ }
+ try {
+ this.content = new Object[1];
+ this.content[0] = doc.GetMapper().MapElement(par)[0];
+ ((IRtfBasicElement) this.content[0]).SetInHeader(true);
+ } catch (DocumentException) {
+ }
+ }
+
+ /**
+ * Constructs a RtfHeaderFooter for any Element.
+ *
+ * @param element The Element to display as content of this RtfHeaderFooter
+ */
+ public RtfHeaderFooter(IElement element) : this(new IElement[]{element}) {
+ }
+
+ /**
+ * Constructs a RtfHeaderFooter for an array of Elements.
+ *
+ * @param elements The Elements to display as the content of this RtfHeaderFooter.
+ */
+ public RtfHeaderFooter(IElement[] elements) : base(new Phrase(""), false){
+ this.content = new Object[elements.Length];
+ for (int i = 0; i < elements.Length; i++) {
+ this.content[i] = elements[i];
+ }
+ }
+
+ /**
+ * Sets the RtfDocument this RtfElement belongs to
+ *
+ * @param doc The RtfDocument to use
+ */
+ public void SetRtfDocument(RtfDocument doc) {
+ this.document = doc;
+ if (this.document != null) {
+ for (int i = 0; i < this.content.Length; i++) {
+ try {
+ if (this.content[i] is Element) {
+ this.content[i] = this.document.GetMapper().MapElement((IElement) this.content[i])[0];
+ ((IRtfBasicElement) this.content[i]).SetInHeader(true);
+ } else if (this.content[i] is IRtfBasicElement){
+ ((IRtfBasicElement) this.content[i]).SetRtfDocument(this.document);
+ ((IRtfBasicElement) this.content[i]).SetInHeader(true);
+ }
+ } catch (DocumentException) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Write the content of this RtfHeaderFooter.
+ */
+ public virtual void WriteContent(Stream result) {
+ result.Write(RtfElement.OPEN_GROUP, 0, RtfElement.OPEN_GROUP.Length);
+ if (this.type == TYPE_HEADER) {
+ if (this.displayAt == DISPLAY_ALL_PAGES) {
+ result.Write(HEADER_ALL, 0, HEADER_ALL.Length);
+ } else if (this.displayAt == DISPLAY_FIRST_PAGE) {
+ result.Write(HEADER_FIRST, 0, HEADER_FIRST.Length);
+ } else if (this.displayAt == DISPLAY_LEFT_PAGES) {
+ result.Write(HEADER_LEFT, 0, HEADER_LEFT.Length);
+ } else if (this.displayAt == DISPLAY_RIGHT_PAGES) {
+ result.Write(HEADER_RIGHT, 0, HEADER_RIGHT.Length);
+ }
+ } else {
+ if (this.displayAt == DISPLAY_ALL_PAGES) {
+ result.Write(FOOTER_ALL, 0, FOOTER_ALL.Length);
+ } else if (this.displayAt == DISPLAY_FIRST_PAGE) {
+ result.Write(FOOTER_FIRST, 0, FOOTER_FIRST.Length);
+ } else if (this.displayAt == DISPLAY_LEFT_PAGES) {
+ result.Write(FOOTER_LEFT, 0, FOOTER_LEFT.Length);
+ } else if (this.displayAt == DISPLAY_RIGHT_PAGES) {
+ result.Write(FOOTER_RIGHT, 0, FOOTER_RIGHT.Length);
+ }
+ }
+ result.Write(RtfElement.DELIMITER, 0, RtfElement.DELIMITER.Length);
+ for (int i = 0; i < this.content.Length; i++) {
+ if (this.content[i] is IRtfBasicElement) {
+ IRtfBasicElement rbe = (IRtfBasicElement)this.content[i];
+ rbe.WriteContent(result);
+ }
+ }
+ result.Write(RtfElement.CLOSE_GROUP, 0, RtfElement.CLOSE_GROUP.Length);
+ }
+
+
+ /**
+ * Sets the display location of this RtfHeaderFooter
+ *
+ * @param displayAt The display location to use.
+ */
+ public void SetDisplayAt(int displayAt) {
+ this.displayAt = displayAt;
+ }
+
+ /**
+ * Sets the type of this RtfHeaderFooter
+ *
+ * @param type The type to use.
+ */
+ public void SetType(int type) {
+ this.type = type;
+ }
+
+ /**
+ * Gets the content of this RtfHeaderFooter
+ *
+ * @return The content of this RtfHeaderFooter
+ */
+ private Object[] GetContent() {
+ return this.content;
+ }
+
+ /**
+ * Unused
+ * @param inTable
+ */
+ public void SetInTable(bool inTable) {
+ }
+
+ /**
+ * Unused
+ * @param inHeader
+ */
+ public void SetInHeader(bool inHeader) {
+ }
+
+ /**
+ * Set the alignment of this RtfHeaderFooter. Passes the setting
+ * on to the contained element.
+ */
+ public void SetAlignment(int alignment) {
+ base.Alignment = alignment;
+ for (int i = 0; i < this.content.Length; i++) {
+ if (this.content[i] is Paragraph) {
+ ((Paragraph) this.content[i]).Alignment = alignment;
+ } else if (this.content[i] is Table) {
+ ((Table) this.content[i]).Alignment = alignment;
+ } else if (this.content[i] is Image) {
+ ((Image) this.content[i]).Alignment = alignment;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/headerfooter/RtfHeaderFooterGroup.cs b/iTechSharp/iTextSharp/text/rtf/headerfooter/RtfHeaderFooterGroup.cs
new file mode 100644
index 0000000..0b0f4c0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/headerfooter/RtfHeaderFooterGroup.cs
@@ -0,0 +1,377 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+/*
+ * Created on Aug 6, 2004
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+namespace iTextSharp.text.rtf.headerfooter {
+
+ /**
+ * The RtfHeaderFooterGroup holds 0 - 3 RtfHeaderFooters that create a group
+ * of headers or footers.
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfHeaderFooterGroup : HeaderFooter, IRtfBasicElement {
+
+ /**
+ * This RtfHeaderFooterGroup contains no RtfHeaderFooter objects
+ */
+ private const int MODE_NONE = 0;
+ /**
+ * This RtfHeaderFooterGroup contains one RtfHeaderFooter object
+ */
+ private const int MODE_SINGLE = 1;
+ /**
+ * This RtfHeaderFooterGroup contains two or three RtfHeaderFooter objects
+ */
+ private const int MODE_MULTIPLE = 2;
+
+ /**
+ * The current mode of this RtfHeaderFooterGroup. Defaults to MODE_NONE
+ */
+ private int mode = MODE_NONE;
+ /**
+ * The current type of this RtfHeaderFooterGroup. Defaults to RtfHeaderFooter.TYPE_HEADER
+ */
+ private int type = RtfHeaderFooter.TYPE_HEADER;
+
+ /**
+ * The RtfHeaderFooter for all pages
+ */
+ private RtfHeaderFooter headerAll = null;
+ /**
+ * The RtfHeaderFooter for the first page
+ */
+ private RtfHeaderFooter headerFirst = null;
+ /**
+ * The RtfHeaderFooter for the left hand pages
+ */
+ private RtfHeaderFooter headerLeft = null;
+ /**
+ * The RtfHeaderFooter for the right hand pages
+ */
+ private RtfHeaderFooter headerRight = null;
+ /**
+ * The RtfDocument this RtfHeaderFooterGroup belongs to
+ */
+ private RtfDocument document = null;
+
+ /**
+ * Constructs a RtfHeaderGroup to which you add headers/footers using
+ * via the setHeaderFooter method.
+ *
+ */
+ public RtfHeaderFooterGroup() : base(new Phrase(""), false) {
+ this.mode = MODE_NONE;
+ }
+
+ /**
+ * Constructs a certain type of RtfHeaderFooterGroup. RtfHeaderFooter.TYPE_HEADER
+ * and RtfHeaderFooter.TYPE_FOOTER are valid values for type.
+ *
+ * @param doc The RtfDocument this RtfHeaderFooter belongs to
+ * @param type The type of RtfHeaderFooterGroup to create
+ */
+ public RtfHeaderFooterGroup(RtfDocument doc, int type) : base(new Phrase(""), false) {
+ this.document = doc;
+ this.type = type;
+ }
+
+ /**
+ * Constructs a RtfHeaderFooterGroup by copying the content of the original
+ * RtfHeaderFooterGroup
+ *
+ * @param doc The RtfDocument this RtfHeaderFooter belongs to
+ * @param headerFooter The RtfHeaderFooterGroup to copy
+ * @param type The type of RtfHeaderFooterGroup to create
+ */
+ public RtfHeaderFooterGroup(RtfDocument doc, RtfHeaderFooterGroup headerFooter, int type) : base(new Phrase(""), false) {
+ this.document = doc;
+ this.mode = headerFooter.GetMode();
+ this.type = type;
+ if (headerFooter.GetHeaderAll() != null) {
+ this.headerAll = new RtfHeaderFooter(this.document, headerFooter.GetHeaderAll(), RtfHeaderFooter.DISPLAY_ALL_PAGES);
+ }
+ if (headerFooter.GetHeaderFirst() != null) {
+ this.headerFirst = new RtfHeaderFooter(this.document, headerFooter.GetHeaderFirst(), RtfHeaderFooter.DISPLAY_FIRST_PAGE);
+ }
+ if (headerFooter.GetHeaderLeft() != null) {
+ this.headerLeft = new RtfHeaderFooter(this.document, headerFooter.GetHeaderLeft(), RtfHeaderFooter.DISPLAY_LEFT_PAGES);
+ }
+ if (headerFooter.GetHeaderRight() != null) {
+ this.headerRight = new RtfHeaderFooter(this.document, headerFooter.GetHeaderRight(), RtfHeaderFooter.DISPLAY_RIGHT_PAGES);
+ }
+ SetType(this.type);
+ }
+
+ /**
+ * Constructs a RtfHeaderFooterGroup for a certain RtfHeaderFooter.
+ *
+ * @param doc The RtfDocument this RtfHeaderFooter belongs to
+ * @param headerFooter The RtfHeaderFooter to display
+ * @param type The typ of RtfHeaderFooterGroup to create
+ */
+ public RtfHeaderFooterGroup(RtfDocument doc, RtfHeaderFooter headerFooter, int type) : base(new Phrase(""), false) {
+ this.document = doc;
+ this.type = type;
+ this.mode = MODE_SINGLE;
+ headerAll = new RtfHeaderFooter(doc, headerFooter, RtfHeaderFooter.DISPLAY_ALL_PAGES);
+ headerAll.SetType(this.type);
+ }
+
+ /**
+ * Constructs a RtfHeaderGroup for a certain HeaderFooter
+ *
+ * @param doc The RtfDocument this RtfHeaderFooter belongs to
+ * @param headerFooter The HeaderFooter to display
+ * @param type The typ of RtfHeaderFooterGroup to create
+ */
+ public RtfHeaderFooterGroup(RtfDocument doc, HeaderFooter headerFooter, int type) : base(new Phrase(""), false) {
+ this.document = doc;
+ this.type = type;
+ this.mode = MODE_SINGLE;
+ headerAll = new RtfHeaderFooter(doc, headerFooter, type, RtfHeaderFooter.DISPLAY_ALL_PAGES);
+ headerAll.SetType(this.type);
+ }
+
+ /**
+ * Sets the RtfDocument this RtfElement belongs to
+ *
+ * @param doc The RtfDocument to use
+ */
+ public void SetRtfDocument(RtfDocument doc) {
+ this.document = doc;
+ if (headerAll != null) {
+ headerAll.SetRtfDocument(this.document);
+ }
+ if (headerFirst != null) {
+ headerFirst.SetRtfDocument(this.document);
+ }
+ if (headerLeft != null) {
+ headerLeft.SetRtfDocument(this.document);
+ }
+ if (headerRight != null) {
+ headerRight.SetRtfDocument(this.document);
+ }
+ }
+
+ /**
+ * Write the content of this RtfHeaderFooterGroup.
+ */
+ public virtual void WriteContent(Stream result) {
+ if (this.mode == MODE_SINGLE) {
+ headerAll.WriteContent(result);
+ } else if (this.mode == MODE_MULTIPLE) {
+ if (headerFirst != null) {
+ headerFirst.WriteContent(result);
+ }
+ if (headerLeft != null) {
+ headerLeft.WriteContent(result);
+ }
+ if (headerRight != null) {
+ headerRight.WriteContent(result);
+ }
+ if (headerAll != null) {
+ headerAll.WriteContent(result);
+ }
+ }
+ }
+
+ /**
+ * Set a RtfHeaderFooter to be displayed at a certain position
+ *
+ * @param headerFooter The RtfHeaderFooter to display
+ * @param displayAt The display location to use
+ */
+ public void SetHeaderFooter(RtfHeaderFooter headerFooter, int displayAt) {
+ this.mode = MODE_MULTIPLE;
+ headerFooter.SetRtfDocument(this.document);
+ headerFooter.SetType(this.type);
+ headerFooter.SetDisplayAt(displayAt);
+ switch (displayAt) {
+ case RtfHeaderFooter.DISPLAY_ALL_PAGES:
+ headerAll = headerFooter;
+ break;
+ case RtfHeaderFooter.DISPLAY_FIRST_PAGE:
+ headerFirst = headerFooter;
+ break;
+ case RtfHeaderFooter.DISPLAY_LEFT_PAGES:
+ headerLeft = headerFooter;
+ break;
+ case RtfHeaderFooter.DISPLAY_RIGHT_PAGES:
+ headerRight = headerFooter;
+ break;
+ }
+ }
+
+ /**
+ * Set a HeaderFooter to be displayed at a certain position
+ *
+ * @param headerFooter The HeaderFooter to set
+ * @param displayAt The display location to use
+ */
+ public void SetHeaderFooter(HeaderFooter headerFooter, int displayAt) {
+ this.mode = MODE_MULTIPLE;
+ switch (displayAt) {
+ case RtfHeaderFooter.DISPLAY_ALL_PAGES:
+ headerAll = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt);
+ break;
+ case RtfHeaderFooter.DISPLAY_FIRST_PAGE:
+ headerFirst = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt);
+ break;
+ case RtfHeaderFooter.DISPLAY_LEFT_PAGES:
+ headerLeft = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt);
+ break;
+ case RtfHeaderFooter.DISPLAY_RIGHT_PAGES:
+ headerRight = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt);
+ break;
+ }
+ }
+
+ /**
+ * Set that this RtfHeaderFooterGroup should have a title page. If only
+ * a header / footer for all pages exists, then it will be copied to the
+ * first page aswell.
+ */
+ public void SetHasTitlePage() {
+ if (this.mode == MODE_SINGLE) {
+ this.mode = MODE_MULTIPLE;
+ headerFirst = new RtfHeaderFooter(this.document, headerAll, RtfHeaderFooter.DISPLAY_FIRST_PAGE);
+ headerFirst.SetType(this.type);
+ }
+ }
+
+ /**
+ * Set that this RtfHeaderFooterGroup should have facing pages. If only
+ * a header / footer for all pages exists, then it will be copied to the left
+ * and right pages aswell.
+ */
+ public void SetHasFacingPages() {
+ if (this.mode == MODE_SINGLE) {
+ this.mode = MODE_MULTIPLE;
+ this.headerLeft = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_LEFT_PAGES);
+ this.headerLeft.SetType(this.type);
+ this.headerRight = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_RIGHT_PAGES);
+ this.headerRight.SetType(this.type);
+ this.headerAll = null;
+ } else if (this.mode == MODE_MULTIPLE) {
+ if (this.headerLeft == null && this.headerAll != null) {
+ this.headerLeft = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_LEFT_PAGES);
+ this.headerLeft.SetType(this.type);
+ }
+ if (this.headerRight == null && this.headerAll != null) {
+ this.headerRight = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_RIGHT_PAGES);
+ this.headerRight.SetType(this.type);
+ }
+ this.headerAll = null;
+ }
+ }
+
+ /**
+ * Get whether this RtfHeaderFooterGroup has a titlepage
+ *
+ * @return Whether this RtfHeaderFooterGroup has a titlepage
+ */
+ public bool HasTitlePage() {
+ return (headerFirst != null);
+ }
+
+ /**
+ * Get whether this RtfHeaderFooterGroup has facing pages
+ *
+ * @return Whether this RtfHeaderFooterGroup has facing pages
+ */
+ public bool HasFacingPages() {
+ return (headerLeft != null || headerRight != null);
+ }
+
+ /**
+ * Unused
+ * @param inTable
+ */
+ public void SetInTable(bool inTable) {
+ }
+
+ /**
+ * Unused
+ * @param inHeader
+ */
+ public void SetInHeader(bool inHeader) {
+ }
+
+ /**
+ * Set the type of this RtfHeaderFooterGroup. RtfHeaderFooter.TYPE_HEADER
+ * or RtfHeaderFooter.TYPE_FOOTER. Also sets the type for all RtfHeaderFooters
+ * of this RtfHeaderFooterGroup.
+ *
+ * @param type The type to use
+ */
+ public void SetType(int type) {
+ this.type = type;
+ if (headerAll != null) {
+ headerAll.SetType(this.type);
+ }
+ if (headerFirst != null) {
+ headerFirst.SetType(this.type);
+ }
+ if (headerLeft != null) {
+ headerLeft.SetType(this.type);
+ }
+ if (headerRight != null) {
+ headerRight.SetType(this.type);
+ }
+ }
+
+ /**
+ * Gets the mode of this RtfHeaderFooterGroup
+ *
+ * @return The mode of this RtfHeaderFooterGroup
+ */
+ protected int GetMode() {
+ return this.mode;
+ }
+
+ /**
+ * Gets the RtfHeaderFooter for all pages
+ *
+ * @return The RtfHeaderFooter for all pages
+ */
+ protected RtfHeaderFooter GetHeaderAll() {
+ return headerAll;
+ }
+
+ /**
+ * Gets the RtfHeaderFooter for the title page
+ *
+ * @return The RtfHeaderFooter for the title page
+ */
+ protected RtfHeaderFooter GetHeaderFirst() {
+ return headerFirst;
+ }
+
+ /**
+ * Gets the RtfHeaderFooter for all left hand pages
+ *
+ * @return The RtfHeaderFooter for all left hand pages
+ */
+ protected RtfHeaderFooter GetHeaderLeft() {
+ return headerLeft;
+ }
+
+ /**
+ * Gets the RtfHeaderFooter for all right hand pages
+ *
+ * @return The RtfHeaderFooter for all right hand pages
+ */
+ protected RtfHeaderFooter GetHeaderRight() {
+ return headerRight;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/list/RtfList.cs b/iTechSharp/iTextSharp/text/rtf/list/RtfList.cs
new file mode 100644
index 0000000..fbea7fb
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/list/RtfList.cs
@@ -0,0 +1,629 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using ST = iTextSharp.text.rtf.style;
+using iTextSharp.text.rtf.text;
+using iTextSharp.text.factories;
+/*
+ * $Id: RtfList.cs,v 1.18 2008/05/16 19:31:01 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the 'GNU LIBRARY GENERAL PUBLIC LICENSE'), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.list {
+
+ /**
+ * The RtfList stores one List. It also provides the methods to write the
+ * list declaration and the list data.
+ *
+ * @version $Id: RtfList.cs,v 1.18 2008/05/16 19:31:01 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ * @author Felix Satyaputra (f_satyaputra@yahoo.co.uk)
+ */
+ public class RtfList : RtfElement, IRtfExtendedElement {
+
+ /**
+ * Constant for list level
+ */
+ private static byte[] LIST_LEVEL = DocWriter.GetISOBytes("\\listlevel");
+ /**
+ * Constant for list level style old
+ */
+ private static byte[] LIST_LEVEL_TYPE = DocWriter.GetISOBytes("\\levelnfc");
+ /**
+ * Constant for list level style new
+ */
+ private static byte[] LIST_LEVEL_TYPE_NEW = DocWriter.GetISOBytes("\\levelnfcn");
+ /**
+ * Constant for list level alignment old
+ */
+ private static byte[] LIST_LEVEL_ALIGNMENT = DocWriter.GetISOBytes("\\leveljc");
+ /**
+ * Constant for list level alignment new
+ */
+ private static byte[] LIST_LEVEL_ALIGNMENT_NEW = DocWriter.GetISOBytes("\\leveljcn");
+ /**
+ * Constant for list level start at
+ */
+ private static byte[] LIST_LEVEL_START_AT = DocWriter.GetISOBytes("\\levelstartat");
+ /**
+ * Constant for list level text
+ */
+ private static byte[] LIST_LEVEL_TEXT = DocWriter.GetISOBytes("\\leveltext");
+ /**
+ * Constant for the beginning of the list level numbered style
+ */
+ private static byte[] LIST_LEVEL_STYLE_NUMBERED_BEGIN = DocWriter.GetISOBytes("\\\'02\\\'");
+ /**
+ * Constant for the end of the list level numbered style
+ */
+ private static byte[] LIST_LEVEL_STYLE_NUMBERED_END = DocWriter.GetISOBytes(".;");
+ /**
+ * Constant for the beginning of the list level bulleted style
+ */
+ private static byte[] LIST_LEVEL_STYLE_BULLETED_BEGIN = DocWriter.GetISOBytes("\\\'01");
+ /**
+ * Constant for the end of the list level bulleted style
+ */
+ private static byte[] LIST_LEVEL_STYLE_BULLETED_END = DocWriter.GetISOBytes(";");
+ /**
+ * Constant for the beginning of the list level numbers
+ */
+ private static byte[] LIST_LEVEL_NUMBERS_BEGIN = DocWriter.GetISOBytes("\\levelnumbers");
+ /**
+ * Constant for the list level numbers
+ */
+ private static byte[] LIST_LEVEL_NUMBERS_NUMBERED = DocWriter.GetISOBytes("\\\'01");
+ /**
+ * Constant for the end of the list level numbers
+ */
+ private static byte[] LIST_LEVEL_NUMBERS_END = DocWriter.GetISOBytes(";");
+ /**
+ * Constant for the first indentation
+ */
+ private static byte[] LIST_LEVEL_FIRST_INDENT = DocWriter.GetISOBytes("\\fi");
+ /**
+ * Constant for the symbol indentation
+ */
+ private static byte[] LIST_LEVEL_SYMBOL_INDENT = DocWriter.GetISOBytes("\\tx");
+ /**
+ * Constant for the list level value
+ */
+ private static byte[] LIST_LEVEL_NUMBER = DocWriter.GetISOBytes("\\ilvl");
+ /**
+ * Constant for a tab character
+ */
+ private static byte[] TAB = DocWriter.GetISOBytes("\\tab");
+ /**
+ * Constant for the old list text
+ */
+ private static byte[] LIST_TEXT = DocWriter.GetISOBytes("\\listtext");
+ /**
+ * Constant for the old list number end
+ */
+ private static byte[] LIST_NUMBER_END = DocWriter.GetISOBytes(".");
+
+ private const int LIST_TYPE_BULLET = 0;
+ private const int LIST_TYPE_NUMBERED = 1;
+ private const int LIST_TYPE_UPPER_LETTERS = 2;
+ private const int LIST_TYPE_LOWER_LETTERS = 3;
+ private const int LIST_TYPE_UPPER_ROMAN = 4;
+ private const int LIST_TYPE_LOWER_ROMAN = 5;
+
+ /**
+ * The subitems of this RtfList
+ */
+ private ArrayList items;
+ /**
+ * The level of this RtfList
+ */
+ private int listLevel = 0;
+ /**
+ * The first indentation of this RtfList
+ */
+ private int firstIndent = 0;
+ /**
+ * The left indentation of this RtfList
+ */
+ private int leftIndent = 0;
+ /**
+ * The right indentation of this RtfList
+ */
+ private int rightIndent = 0;
+ /**
+ * The symbol indentation of this RtfList
+ */
+ private int symbolIndent = 0;
+ /**
+ * The list number of this RtfList
+ */
+ private int listNumber = 1;
+ /**
+ * Whether this RtfList is numbered
+ */
+ private int listType = LIST_TYPE_BULLET;
+ /**
+ * The number to start counting at
+ */
+ private int listStartAt = 1;
+ /**
+ * The RtfFont for numbered lists
+ */
+ private ST.RtfFont fontNumber;
+ /**
+ * The RtfFont for bulleted lists
+ */
+ private ST.RtfFont fontBullet;
+ /**
+ * The alignment of this RtfList
+ */
+ private int alignment = Element.ALIGN_LEFT;
+
+ /**
+ * The parent List in multi-level lists.
+ */
+ private RtfList parentList = null;
+ /**
+ * The text to use as the bullet character
+ */
+ private String bulletCharacter = "\u00b7";
+
+ /**
+ * Constructs a new RtfList for the specified List.
+ *
+ * @param doc The RtfDocument this RtfList belongs to
+ * @param list The List this RtfList is based on
+ */
+ public RtfList(RtfDocument doc, List list) : base(doc) {
+
+ this.listNumber = document.GetDocumentHeader().GetListNumber(this);
+
+ this.items = new ArrayList();
+ if (list.SymbolIndent > 0 && list.IndentationLeft > 0) {
+ this.firstIndent = (int) (list.SymbolIndent * RtfElement.TWIPS_FACTOR * -1);
+ this.leftIndent = (int) ((list.IndentationLeft + list.SymbolIndent) * RtfElement.TWIPS_FACTOR);
+ } else if (list.SymbolIndent > 0) {
+ this.firstIndent = (int) (list.SymbolIndent * RtfElement.TWIPS_FACTOR * -1);
+ this.leftIndent = (int) (list.SymbolIndent * RtfElement.TWIPS_FACTOR);
+ } else if (list.IndentationLeft > 0) {
+ this.firstIndent = 0;
+ this.leftIndent = (int) (list.IndentationLeft * RtfElement.TWIPS_FACTOR);
+ } else {
+ this.firstIndent = 0;
+ this.leftIndent = 0;
+ }
+ this.rightIndent = (int) (list.IndentationRight * RtfElement.TWIPS_FACTOR);
+ this.symbolIndent = (int) ((list.SymbolIndent + list.IndentationLeft) * RtfElement.TWIPS_FACTOR);
+ if (list is RomanList) {
+ if (list.Lowercase) {
+ this.listType = LIST_TYPE_LOWER_ROMAN;
+ } else {
+ this.listType = LIST_TYPE_UPPER_ROMAN;
+ }
+ } else if (list.Numbered) {
+ this.listType = LIST_TYPE_NUMBERED;
+ } else if (list.Lettered) {
+ if (list.Lowercase) {
+ this.listType = LIST_TYPE_LOWER_LETTERS;
+ } else {
+ this.listType = LIST_TYPE_UPPER_LETTERS;
+ }
+ }
+ this.listStartAt = list.First;
+ if(this.listStartAt < 1) {
+ this.listStartAt = 1;
+ }
+
+ for (int i = 0; i < list.Items.Count; i++) {
+ try {
+ IElement element = (IElement) list.Items[i];
+ if (element.Type == Element.CHUNK) {
+ element = new ListItem((Chunk) element);
+ }
+ if (element is ListItem) {
+ this.alignment = ((ListItem) element).Alignment;
+ }
+ IRtfBasicElement[] rtfElements = doc.GetMapper().MapElement(element);
+ for(int j = 0; j < rtfElements.Length; j++) {
+ IRtfBasicElement rtfElement = rtfElements[j];
+ if (rtfElement is RtfList) {
+ ((RtfList) rtfElement).SetListNumber(listNumber);
+ ((RtfList) rtfElement).SetListLevel(listLevel + 1);
+ ((RtfList) rtfElement).SetParent(this);
+ } else if (rtfElement is RtfListItem) {
+ ((RtfListItem) rtfElement).SetParent(this);
+ ((RtfListItem) rtfElement).InheritListSettings(listNumber, listLevel + 1);
+ }
+ items.Add(rtfElement);
+ }
+ } catch (DocumentException ) {
+ }
+ }
+
+ fontNumber = new ST.RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0)));
+ if (list.Symbol != null && list.Symbol.Font != null && !list.Symbol.Content.StartsWith("-") && list.Symbol.Content.Length > 0) {
+ // only set this to bullet symbol is not default
+ this.fontBullet = new ST.RtfFont(document, list.Symbol.Font);
+ this.bulletCharacter = list.Symbol.Content.Substring(0, 1);
+ } else {
+ this.fontBullet = new ST.RtfFont(document, new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0)));
+ }
+ }
+
+ /**
+ * Write the indentation values for this RtfList
.
+ *
+ * @param result The OutputStream
to write to.
+ * @throws IOException On i/o errors.
+ */
+ private void WriteIndentation(Stream result) {
+ byte[] t;
+ result.Write(LIST_LEVEL_FIRST_INDENT, 0, LIST_LEVEL_FIRST_INDENT.Length);
+ result.Write(t = IntToByteArray(firstIndent), 0, t.Length);
+ result.Write(ST.RtfParagraphStyle.INDENT_LEFT, 0, ST.RtfParagraphStyle.INDENT_LEFT.Length);
+ result.Write(t = IntToByteArray(leftIndent), 0, t.Length);
+ result.Write(ST.RtfParagraphStyle.INDENT_RIGHT, 0, ST.RtfParagraphStyle.INDENT_RIGHT.Length);
+ result.Write(t = IntToByteArray(rightIndent), 0, t.Length);
+ }
+
+ /**
+ * Writes the definition part of this list level
+ */
+ public virtual void WriteDefinition(Stream result) {
+ byte[] t;
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(LIST_LEVEL, 0, LIST_LEVEL.Length);
+ result.Write(LIST_LEVEL_TYPE, 0, LIST_LEVEL_TYPE.Length);
+ switch (this.listType) {
+ case LIST_TYPE_BULLET : result.Write(t = IntToByteArray(23), 0, t.Length); break;
+ case LIST_TYPE_NUMBERED : result.Write(t = IntToByteArray(0), 0, t.Length); break;
+ case LIST_TYPE_UPPER_LETTERS : result.Write(t = IntToByteArray(3), 0, t.Length); break;
+ case LIST_TYPE_LOWER_LETTERS : result.Write(t = IntToByteArray(4), 0, t.Length); break;
+ case LIST_TYPE_UPPER_ROMAN : result.Write(t = IntToByteArray(1), 0, t.Length); break;
+ case LIST_TYPE_LOWER_ROMAN : result.Write(t = IntToByteArray(2), 0, t.Length); break;
+ }
+ result.Write(LIST_LEVEL_TYPE_NEW, 0, LIST_LEVEL_TYPE_NEW.Length);
+ switch (this.listType) {
+ case LIST_TYPE_BULLET : result.Write(t = IntToByteArray(23), 0, t.Length); break;
+ case LIST_TYPE_NUMBERED : result.Write(t = IntToByteArray(0), 0, t.Length); break;
+ case LIST_TYPE_UPPER_LETTERS : result.Write(t = IntToByteArray(3), 0, t.Length); break;
+ case LIST_TYPE_LOWER_LETTERS : result.Write(t = IntToByteArray(4), 0, t.Length); break;
+ case LIST_TYPE_UPPER_ROMAN : result.Write(t = IntToByteArray(1), 0, t.Length); break;
+ case LIST_TYPE_LOWER_ROMAN : result.Write(t = IntToByteArray(2), 0, t.Length); break;
+ }
+ result.Write(LIST_LEVEL_ALIGNMENT, 0, LIST_LEVEL_ALIGNMENT.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ result.Write(LIST_LEVEL_ALIGNMENT_NEW, 0, LIST_LEVEL_ALIGNMENT_NEW.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ result.Write(LIST_LEVEL_START_AT, 0, LIST_LEVEL_START_AT.Length);
+ result.Write(t = IntToByteArray(this.listStartAt), 0, t.Length);
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(LIST_LEVEL_TEXT, 0, LIST_LEVEL_TEXT.Length);
+ if (this.listType != LIST_TYPE_BULLET) {
+ result.Write(LIST_LEVEL_STYLE_NUMBERED_BEGIN, 0, LIST_LEVEL_STYLE_NUMBERED_BEGIN.Length);
+ if (listLevel < 10) {
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ result.Write(t = IntToByteArray(listLevel), 0, t.Length);
+ result.Write(LIST_LEVEL_STYLE_NUMBERED_END, 0, LIST_LEVEL_STYLE_NUMBERED_END.Length);
+ } else {
+ result.Write(LIST_LEVEL_STYLE_BULLETED_BEGIN, 0, LIST_LEVEL_STYLE_BULLETED_BEGIN.Length);
+ this.document.FilterSpecialChar(result, this.bulletCharacter, false, false);
+ result.Write(LIST_LEVEL_STYLE_BULLETED_END, 0, LIST_LEVEL_STYLE_BULLETED_END.Length);
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(LIST_LEVEL_NUMBERS_BEGIN, 0, LIST_LEVEL_NUMBERS_BEGIN.Length);
+ if (this.listType != LIST_TYPE_BULLET) {
+ result.Write(LIST_LEVEL_NUMBERS_NUMBERED, 0, LIST_LEVEL_NUMBERS_NUMBERED.Length);
+ }
+ result.Write(LIST_LEVEL_NUMBERS_END, 0, LIST_LEVEL_NUMBERS_END.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.Write(ST.RtfFontList.FONT_NUMBER, 0, ST.RtfFontList.FONT_NUMBER.Length);
+ if (this.listType != LIST_TYPE_BULLET) {
+ result.Write(t = IntToByteArray(fontNumber.GetFontNumber()), 0, t.Length);
+ } else {
+ result.Write(t = IntToByteArray(fontBullet.GetFontNumber()), 0, t.Length);
+ }
+ WriteIndentation(result);
+ result.Write(LIST_LEVEL_SYMBOL_INDENT, 0, LIST_LEVEL_SYMBOL_INDENT.Length);
+ result.Write(t = IntToByteArray(this.leftIndent), 0, t.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ for (int i = 0; i < items.Count; i++) {
+ RtfElement rtfElement = (RtfElement) items[i];
+ if (rtfElement is RtfList) {
+ RtfList rl = (RtfList)rtfElement;
+ rl.WriteDefinition(result);
+ break;
+ } else if (rtfElement is RtfListItem) {
+ RtfListItem rli = (RtfListItem) rtfElement;
+ if (rli.WriteDefinition(result)) break;
+ }
+ }
+ }
+
+ /**
+ * Writes the initialisation part of the RtfList
+ *
+ * @return A byte array containing the initialisation part
+ */
+ protected internal void WriteListBeginning(Stream result) {
+ byte[] t;
+ result.Write(RtfParagraph.PARAGRAPH_DEFAULTS, 0, RtfParagraph.PARAGRAPH_DEFAULTS.Length);
+ if (this.inTable) {
+ result.Write(RtfParagraph.IN_TABLE, 0, RtfParagraph.IN_TABLE.Length);
+ }
+ switch (this.alignment) {
+ case Element.ALIGN_LEFT:
+ result.Write(ST.RtfParagraphStyle.ALIGN_LEFT, 0, ST.RtfParagraphStyle.ALIGN_LEFT.Length);
+ break;
+ case Element.ALIGN_RIGHT:
+ result.Write(ST.RtfParagraphStyle.ALIGN_RIGHT, 0, ST.RtfParagraphStyle.ALIGN_RIGHT.Length);
+ break;
+ case Element.ALIGN_CENTER:
+ result.Write(ST.RtfParagraphStyle.ALIGN_CENTER, 0, ST.RtfParagraphStyle.ALIGN_CENTER.Length);
+ break;
+ case Element.ALIGN_JUSTIFIED:
+ case Element.ALIGN_JUSTIFIED_ALL:
+ result.Write(ST.RtfParagraphStyle.ALIGN_JUSTIFY, 0, ST.RtfParagraphStyle.ALIGN_JUSTIFY.Length);
+ break;
+ }
+ WriteIndentation(result);
+ result.Write(ST.RtfFont.FONT_SIZE, 0, ST.RtfFont.FONT_SIZE.Length);
+ result.Write(t = IntToByteArray(fontNumber.GetFontSize() * 2), 0, t.Length);
+ if (this.symbolIndent > 0) {
+ result.Write(t = DocWriter.GetISOBytes("\\tx"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.leftIndent), 0, t.Length);
+ }
+ }
+
+ /**
+ * Writes only the list number and list level number.
+ *
+ * @return The list number and list level number of this RtfList.
+ */
+ protected void WriteListNumbers(Stream result) {
+ byte[] t;
+ result.Write(RtfListTable.LIST_NUMBER, 0, RtfListTable.LIST_NUMBER.Length);
+ result.Write(t = IntToByteArray(listNumber), 0, t.Length);
+ if (listLevel > 0) {
+ result.Write(LIST_LEVEL_NUMBER, 0, LIST_LEVEL_NUMBER.Length);
+ result.Write(t = IntToByteArray(listLevel), 0, t.Length);
+ }
+ }
+
+ /**
+ * Writes the content of the RtfList
+ */
+ public override void WriteContent(Stream result) {
+ if (this.listLevel == 0) {
+ CorrectIndentation();
+ }
+ byte[] t;
+ if (!this.inTable) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ }
+ int itemNr = 0;
+ for (int i = 0; i < items.Count; i++) {
+ RtfElement rtfElement = (RtfElement) items[i];
+ if (rtfElement is RtfListItem) {
+ itemNr++;
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(LIST_TEXT, 0, LIST_TEXT.Length);
+ result.Write(RtfParagraph.PARAGRAPH_DEFAULTS, 0, RtfParagraph.PARAGRAPH_DEFAULTS.Length);
+ if (this.inTable) {
+ result.Write(RtfParagraph.IN_TABLE, 0, RtfParagraph.IN_TABLE.Length);
+ }
+ result.Write(ST.RtfFontList.FONT_NUMBER, 0, ST.RtfFontList.FONT_NUMBER.Length);
+ if (this.listType != LIST_TYPE_BULLET) {
+ result.Write(t = IntToByteArray(fontNumber.GetFontNumber()), 0, t.Length);
+ } else {
+ result.Write(t = IntToByteArray(fontBullet.GetFontNumber()), 0, t.Length);
+ }
+ WriteIndentation(result);
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+ if (this.listType != LIST_TYPE_BULLET) {
+ switch (this.listType) {
+ case LIST_TYPE_NUMBERED : result.Write(t = IntToByteArray(itemNr), 0, t.Length); break;
+ case LIST_TYPE_UPPER_LETTERS : result.Write(t = DocWriter.GetISOBytes(RomanAlphabetFactory.GetUpperCaseString(itemNr)), 0, t.Length); break;
+ case LIST_TYPE_LOWER_LETTERS : result.Write(t = DocWriter.GetISOBytes(RomanAlphabetFactory.GetLowerCaseString(itemNr)), 0, t.Length); break;
+ case LIST_TYPE_UPPER_ROMAN : result.Write(t = DocWriter.GetISOBytes(RomanNumberFactory.GetUpperCaseString(itemNr)), 0, t.Length); break;
+ case LIST_TYPE_LOWER_ROMAN : result.Write(t = DocWriter.GetISOBytes(RomanNumberFactory.GetLowerCaseString(itemNr)), 0, t.Length); break;
+ }
+ result.Write(LIST_NUMBER_END, 0, LIST_NUMBER_END.Length);
+ } else {
+ this.document.FilterSpecialChar(result, this.bulletCharacter, true, false);
+ }
+ result.Write(TAB, 0, TAB.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ if (i == 0) {
+ WriteListBeginning(result);
+ WriteListNumbers(result);
+ }
+ rtfElement.WriteContent(result);
+ if (i < (items.Count - 1) || !this.inTable || this.listLevel > 0) {
+ result.Write(RtfParagraph.PARAGRAPH, 0, RtfParagraph.PARAGRAPH.Length);
+ }
+ result.WriteByte((byte)'\n');
+ } else if (rtfElement is RtfList) {
+ rtfElement.WriteContent(result);
+ WriteListBeginning(result);
+ WriteListNumbers(result);
+ result.WriteByte((byte)'\n');
+ }
+ }
+ if (!this.inTable) {
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.Write(RtfParagraph.PARAGRAPH_DEFAULTS, 0, RtfParagraph.PARAGRAPH_DEFAULTS.Length);
+ }
+ }
+
+
+ /**
+ * Gets the list level of this RtfList
+ *
+ * @return Returns the list level.
+ */
+ public int GetListLevel() {
+ return listLevel;
+ }
+
+ /**
+ * Sets the list level of this RtfList. A list level > 0 will
+ * unregister this RtfList from the RtfListTable
+ *
+ * @param listLevel The list level to set.
+ */
+ public void SetListLevel(int listLevel) {
+ this.listLevel = listLevel;
+ if (this.listLevel != 0) {
+ document.GetDocumentHeader().FreeListNumber(this);
+ for (int i = 0; i < this.items.Count; i++) {
+ if (this.items[i] is RtfList) {
+ ((RtfList) this.items[i]).SetListNumber(this.listNumber);
+ ((RtfList) this.items[i]).SetListLevel(this.listLevel + 1);
+ }
+ }
+ } else {
+ this.listNumber = document.GetDocumentHeader().GetListNumber(this);
+ }
+ }
+
+ /**
+ * Sets the parent RtfList of this RtfList
+ *
+ * @param parent The parent RtfList to use.
+ */
+ protected internal void SetParent(RtfList parent) {
+ this.parentList = parent;
+ }
+
+ /**
+ * Gets the id of this list
+ *
+ * @return Returns the list number.
+ */
+ public int GetListNumber() {
+ return listNumber;
+ }
+
+ /**
+ * Sets the id of this list
+ *
+ * @param listNumber The list number to set.
+ */
+ public void SetListNumber(int listNumber) {
+ this.listNumber = listNumber;
+ }
+
+ /**
+ * Sets whether this RtfList is in a table. Sets the correct inTable setting for all
+ * child elements.
+ *
+ * @param inTable True
if this RtfList is in a table, false
otherwise
+ */
+ public override void SetInTable(bool inTable) {
+ base.SetInTable(inTable);
+ for (int i = 0; i < this.items.Count; i++) {
+ ((IRtfBasicElement) this.items[i]).SetInTable(inTable);
+ }
+ }
+
+ /**
+ * Sets whether this RtfList is in a header. Sets the correct inTable setting for all
+ * child elements.
+ *
+ * @param inHeader True
if this RtfList is in a header, false
otherwise
+ */
+ public override void SetInHeader(bool inHeader) {
+ base.SetInHeader(inHeader);
+ for (int i = 0; i < this.items.Count; i++) {
+ ((IRtfBasicElement) this.items[i]).SetInHeader(inHeader);
+ }
+ }
+
+ /**
+ * Correct the indentation of this RtfList by adding left/first line indentation
+ * from the parent RtfList. Also calls correctIndentation on all child RtfLists.
+ */
+ protected internal void CorrectIndentation() {
+ if (this.parentList != null) {
+ this.leftIndent = this.leftIndent + this.parentList.GetLeftIndent() + this.parentList.GetFirstIndent();
+ }
+ for (int i = 0; i < this.items.Count; i++) {
+ if (this.items[i] is RtfList) {
+ ((RtfList) this.items[i]).CorrectIndentation();
+ } else if (this.items[i] is RtfListItem) {
+ ((RtfListItem) this.items[i]).CorrectIndentation();
+ }
+ }
+ }
+
+ /**
+ * Get the left indentation of this RtfList.
+ *
+ * @return The left indentation.
+ */
+ private int GetLeftIndent() {
+ return this.leftIndent;
+ }
+
+ /**
+ * Get the first line indentation of this RtfList.
+ *
+ * @return The first line indentation.
+ */
+ private int GetFirstIndent() {
+ return this.firstIndent;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/list/RtfListItem.cs b/iTechSharp/iTextSharp/text/rtf/list/RtfListItem.cs
new file mode 100644
index 0000000..52f5f30
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/list/RtfListItem.cs
@@ -0,0 +1,187 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.text;
+using iTextSharp.text.rtf.style;
+/*
+ * $Id: RtfListItem.cs,v 1.7 2008/05/16 19:31:02 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.list {
+
+ /**
+ * The RtfListItem acts as a wrapper for a ListItem.
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfListItem : RtfParagraph {
+
+ /**
+ * The RtfList this RtfListItem belongs to.
+ */
+ private RtfList parentList = null;
+ /**
+ * Whether this RtfListItem contains further RtfLists.
+ */
+ private bool containsInnerList = false;
+
+ /**
+ * Constructs a RtfListItem for a ListItem belonging to a RtfDocument.
+ *
+ * @param doc The RtfDocument this RtfListItem belongs to.
+ * @param listItem The ListItem this RtfListItem is based on.
+ */
+ public RtfListItem(RtfDocument doc, ListItem listItem) : base(doc, listItem) {
+ }
+
+ /**
+ * Writes the content of this RtfListItem.
+ */
+ public override void WriteContent(Stream result) {
+ byte[] t;
+ if (this.paragraphStyle.GetSpacingBefore() > 0) {
+ result.Write(RtfParagraphStyle.SPACING_BEFORE, 0, RtfParagraphStyle.SPACING_BEFORE.Length);
+ result.Write(t = IntToByteArray(paragraphStyle.GetSpacingBefore()), 0, t.Length);
+ }
+ if (this.paragraphStyle.GetSpacingAfter() > 0) {
+ result.Write(RtfParagraphStyle.SPACING_AFTER, 0, RtfParagraphStyle.SPACING_AFTER.Length);
+ result.Write(t = IntToByteArray(this.paragraphStyle.GetSpacingAfter()), 0, t.Length);
+ }
+ for (int i = 0; i < chunks.Count; i++) {
+ IRtfBasicElement rtfElement = (IRtfBasicElement) chunks[i];
+ if (rtfElement is RtfChunk) {
+ ((RtfChunk) rtfElement).SetSoftLineBreaks(true);
+ } else if (rtfElement is RtfList) {
+ result.Write(RtfParagraph.PARAGRAPH, 0, RtfParagraph.PARAGRAPH.Length);
+ this.containsInnerList = true;
+ }
+ rtfElement.WriteContent(result);
+ if (rtfElement is RtfList) {
+ this.parentList.WriteListBeginning(result);
+ result.Write(t = DocWriter.GetISOBytes("\\tab"), 0, t.Length);
+ }
+ }
+ }
+
+ /**
+ * Writes the definition of the first element in this RtfListItem that is
+ * an instanceof {@link RtfList} to the given stream.
+ * If this item does not contain a {@link RtfList} element nothing is written
+ * and the method returns false
.
+ *
+ * @param out destination stream
+ * @return true
if a RtfList definition was written, false
otherwise
+ * @throws IOException
+ * @see {@link RtfList#writeDefinition(OutputStream)}
+ */
+ public bool WriteDefinition(Stream outp) {
+ for (int i = 0; i < chunks.Count; i++) {
+ IRtfBasicElement rtfElement = (IRtfBasicElement)chunks[i];
+ if (rtfElement is RtfList) {
+ RtfList rl = (RtfList)rtfElement;
+ rl.WriteDefinition(outp);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Inherit the list settings from the parent list to RtfLists that
+ * are contained in this RtfListItem.
+ *
+ * @param listNumber The list number to inherit.
+ * @param listLevel The list level to inherit.
+ */
+ public void InheritListSettings(int listNumber, int listLevel) {
+ for (int i = 0; i < chunks.Count; i++) {
+ IRtfBasicElement rtfElement = (IRtfBasicElement) chunks[i];
+ if (rtfElement is RtfList) {
+ ((RtfList) rtfElement).SetListNumber(listNumber);
+ ((RtfList) rtfElement).SetListLevel(listLevel);
+ ((RtfList) rtfElement).SetParent(this.parentList);
+ }
+ }
+ }
+
+ /**
+ * Correct the indentation of RtfLists in this RtfListItem by adding left/first line indentation
+ * from the parent RtfList. Also calls correctIndentation on all child RtfLists.
+ */
+ protected internal void CorrectIndentation() {
+ for (int i = 0; i < chunks.Count; i++) {
+ IRtfBasicElement rtfElement = (IRtfBasicElement) chunks[i];
+ if (rtfElement is RtfList) {
+ ((RtfList) rtfElement).CorrectIndentation();
+ }
+ }
+ }
+
+ /**
+ * Set the parent RtfList.
+ *
+ * @param parentList The parent RtfList to use.
+ */
+ public void SetParent(RtfList parentList) {
+ this.parentList = parentList;
+ }
+
+ /**
+ * Gets whether this RtfListItem contains further RtfLists.
+ *
+ * @return Whether this RtfListItem contains further RtfLists.
+ */
+ public bool IsContainsInnerList() {
+ return this.containsInnerList;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/list/RtfListTable.cs b/iTechSharp/iTextSharp/text/rtf/list/RtfListTable.cs
new file mode 100644
index 0000000..799f8e4
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/list/RtfListTable.cs
@@ -0,0 +1,198 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfListTable.cs,v 1.6 2008/05/16 19:31:04 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.list {
+
+ /**
+ * The RtfListTable manages all RtfLists in one RtfDocument. It also generates
+ * the list and list override tables in the document header.
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfListTable : RtfElement, IRtfExtendedElement {
+
+ /**
+ * Constant for the list number
+ */
+ protected internal static byte[] LIST_NUMBER = DocWriter.GetISOBytes("\\ls");
+ /**
+ * Constant for the list table
+ */
+ private static byte[] LIST_TABLE = DocWriter.GetISOBytes("\\*\\listtable");
+ /**
+ * Constant for the list
+ */
+ private static byte[] LIST = DocWriter.GetISOBytes("\\list");
+ /**
+ * Constant for the list template id
+ */
+ private static byte[] LIST_TEMPLATE_ID = DocWriter.GetISOBytes("\\listtemplateid");
+ /**
+ * Constant for the hybrid list
+ */
+ private static byte[] LIST_HYBRID = DocWriter.GetISOBytes("\\listhybrid");
+ /**
+ * Constant for the list id
+ */
+ private static byte[] LIST_ID = DocWriter.GetISOBytes("\\listid");
+ /**
+ * Constant for the list override table
+ */
+ private static byte[] LIST_OVERRIDE_TABLE = DocWriter.GetISOBytes("\\*\\listoverridetable");
+ /**
+ * Constant for the list override
+ */
+ private static byte[] LIST_OVERRIDE = DocWriter.GetISOBytes("\\listoverride");
+ /**
+ * Constant for the list override count
+ */
+ private static byte[] LIST_OVERRIDE_COUNT = DocWriter.GetISOBytes("\\listoverridecount");
+
+ /**
+ * The RtfLists managed by this RtfListTable
+ */
+ private ArrayList lists;
+
+ /**
+ * Constructs a RtfListTable for a RtfDocument
+ *
+ * @param doc The RtfDocument this RtfListTable belongs to
+ */
+ public RtfListTable(RtfDocument doc) : base(doc) {
+ this.lists = new ArrayList();
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Writes the list and list override tables.
+ */
+ public virtual void WriteDefinition(Stream result) {
+ byte[] t;
+ int[] listIds = new int[lists.Count];
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(LIST_TABLE, 0, LIST_TABLE.Length);
+ result.WriteByte((byte)'\n');
+ for (int i = 0; i < lists.Count; i++) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(LIST, 0, LIST.Length);
+ result.Write(LIST_TEMPLATE_ID, 0, LIST_TEMPLATE_ID.Length);
+ result.Write(t = IntToByteArray(document.GetRandomInt()), 0, t.Length);
+ result.Write(LIST_HYBRID, 0, LIST_HYBRID.Length);
+ result.WriteByte((byte)'\n');
+ RtfList rList = (RtfList)lists[i];
+ rList.WriteDefinition(result);
+ result.Write(LIST_ID, 0, LIST_ID.Length);
+ listIds[i] = document.GetRandomInt();
+ result.Write(t = IntToByteArray(listIds[i]), 0, t.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(LIST_OVERRIDE_TABLE, 0, LIST_OVERRIDE_TABLE.Length);
+ result.WriteByte((byte)'\n');
+ for (int i = 0; i < lists.Count; i++) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(LIST_OVERRIDE, 0, LIST_OVERRIDE.Length);
+ result.Write(LIST_ID, 0, LIST_ID.Length);
+ result.Write(t = IntToByteArray(listIds[i]), 0, t.Length);
+ result.Write(LIST_OVERRIDE_COUNT, 0, LIST_OVERRIDE_COUNT.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ result.Write(LIST_NUMBER, 0, LIST_NUMBER.Length);
+ result.Write(t = IntToByteArray(((RtfList) lists[i]).GetListNumber()), 0, t.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ }
+
+ /**
+ * Gets the id of the specified RtfList. If the RtfList is not yet in the
+ * list of RtfLists, then it is added.
+ *
+ * @param list The RtfList for which to get the id.
+ * @return The id of the RtfList.
+ */
+ public int GetListNumber(RtfList list) {
+ if (lists.Contains(list)) {
+ return lists.IndexOf(list);
+ } else {
+ lists.Add(list);
+ return lists.Count;
+ }
+ }
+
+ /**
+ * Remove a RtfList from the list of RtfLists
+ *
+ * @param list The RtfList to remove.
+ */
+ public void FreeListNumber(RtfList list) {
+ int i = lists.IndexOf(list);
+ if (i >= 0) {
+ lists.RemoveAt(i);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/PushbackStream.cs b/iTechSharp/iTextSharp/text/rtf/parser/PushbackStream.cs
new file mode 100644
index 0000000..98b1a4e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/PushbackStream.cs
@@ -0,0 +1,86 @@
+using System;
+using System.IO;
+
+namespace iTextSharp.text.rtf.parser {
+ public class PushbackStream : Stream {
+ private int buf = -1;
+ private readonly Stream s;
+
+ public PushbackStream(Stream s) {
+ this.s = s;
+ }
+
+ public override bool CanRead
+ {
+ get { return s.CanRead; }
+ }
+ public override bool CanSeek
+ {
+ get { return s.CanSeek; }
+ }
+ public override bool CanWrite
+ {
+ get { return s.CanWrite; }
+ }
+ public override long Length
+ {
+ get { return s.Length; }
+ }
+ public override long Position
+ {
+ get { return s.Position; }
+ set { s.Position = value; }
+ }
+ public override void Close()
+ {
+ s.Close();
+ }
+ public override void Flush()
+ {
+ s.Flush();
+ }
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ return s.Seek(offset, origin);
+ }
+ public override void SetLength(long value)
+ {
+ s.SetLength(value);
+ }
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ s.Write(buffer, offset, count);
+ }
+ public override void WriteByte(byte value)
+ {
+ s.WriteByte(value);
+ }
+ public override int ReadByte() {
+ if (buf != -1) {
+ int tmp = buf;
+ buf = -1;
+ return tmp;
+ }
+
+ return s.ReadByte();
+ }
+
+ public override int Read(byte[] buffer, int offset, int count) {
+ if (buf != -1 && count > 0) {
+ // TODO Can this case be made more efficient?
+ buffer[offset] = (byte) buf;
+ buf = -1;
+ return 1;
+ }
+
+ return s.Read(buffer, offset, count);
+ }
+
+ public virtual void Unread(int b) {
+ if (buf != -1)
+ throw new InvalidOperationException("Can only push back one byte");
+
+ buf = b & 0xFF;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/RtfImportMappings.cs b/iTechSharp/iTextSharp/text/rtf/parser/RtfImportMappings.cs
new file mode 100644
index 0000000..2c18f01
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/RtfImportMappings.cs
@@ -0,0 +1,170 @@
+using System;
+using System.Collections;
+using iTextSharp.text;
+
+/*
+ * $Id: RtfImportMappings.cs,v 1.3 2008/05/16 19:31:06 psoares33 Exp $
+ *
+ *
+ * Copyright 2006 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser {
+
+ /**
+ * The RtfImportMappings make it possible to define font
+ * and color mappings when using the RtfWriter2.importRtfFragment
+ * method. This is necessary, because a RTF fragment does not
+ * contain font or color information, just references to the
+ * font and color tables.
+ *
+ * The font mappings are fontNr -> fontName and the color
+ * mappigns are colorNr -> Color.
+ *
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public class RtfImportMappings {
+ /**
+ * The fontNr to fontName mappings.
+ */
+ private Hashtable fontMappings = null;
+ /**
+ * The colorNr to Color mappings.
+ */
+ private Hashtable colorMappings = null;
+ /**
+ * The listNr to List mappings.
+ */
+ private Hashtable listMappings = null;
+ /**
+ * The sytlesheetListNr to Stylesheet mappings.
+ */
+ private Hashtable stylesheetListMappings = null;
+
+ /**
+ * Constructs a new RtfImportMappings initialising the mappings.
+ */
+ public RtfImportMappings() {
+ this.fontMappings = new Hashtable();
+ this.colorMappings = new Hashtable();
+ this.listMappings = new Hashtable();
+ this.stylesheetListMappings = new Hashtable();
+ }
+
+ /**
+ * Add a font to the list of mappings.
+ *
+ * @param fontNr The font number.
+ * @param fontName The font name.
+ */
+ public void AddFont(String fontNr, String fontName) {
+ this.fontMappings[fontNr] = fontName;
+ }
+ /**
+ * Add a color to the list of mappings.
+ *
+ * @param colorNr The color number.
+ * @param color The Color.
+ */
+ public void AddColor(String colorNr, Color color) {
+ this.colorMappings[colorNr] = color;
+ }
+ /**
+ * Add a List to the list of mappings.
+ *
+ * @param listNr The List number.
+ * @param list The List.
+ */
+ public void AddList(String listNr, Color list) {
+ this.listMappings[listNr] = list;
+ }
+ /**
+ * Add a Stylesheet List to the list of mappings.
+ *
+ * @param stylesheetListNr The Stylesheet List number.
+ * @param list The StylesheetList.
+ */
+ public void AddStylesheetList(String stylesheetListNr, Color list) {
+ this.stylesheetListMappings[stylesheetListNr] = list;
+ }
+
+ /**
+ * Gets the list of font mappings. String to String.
+ *
+ * @return The font mappings.
+ */
+ public Hashtable GetFontMappings() {
+ return this.fontMappings;
+ }
+
+ /**
+ * Gets the list of color mappings. String to Color.
+ *
+ * @return The color mappings.
+ */
+ public Hashtable GetColorMappings() {
+ return this.colorMappings;
+ }
+
+ /**
+ * Gets the list of List mappings.
+ *
+ * @return The List mappings.
+ */
+ public Hashtable GetListMappings() {
+ return this.listMappings;
+ }
+
+ /**
+ * Gets the list of Stylesheet mappings. .
+ *
+ * @return The Stylesheet List mappings.
+ */
+ public Hashtable GetStylesheetListMappings() {
+ return this.stylesheetListMappings;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/RtfImportMgr.cs b/iTechSharp/iTextSharp/text/rtf/parser/RtfImportMgr.cs
new file mode 100644
index 0000000..a263733
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/RtfImportMgr.cs
@@ -0,0 +1,281 @@
+using System;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.list;
+using iTextSharp.text.rtf.style;
+/*
+ * $Id: RtfImportMgr.cs,v 1.3 2008/05/16 19:31:07 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser {
+
+ /**
+ * The RtfImportHeader stores the docment header information from
+ * an RTF document that is being imported. Currently font and
+ * color settings are stored. The RtfImportHeader maintains a mapping
+ * from font and color numbers from the imported RTF document to
+ * the RTF document that is the target of the import. This guarantees
+ * that the merged document has the correct font and color settings.
+ * It also handles other list based items that need mapping, for example
+ * stylesheets and lists.
+ *
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+ public class RtfImportMgr {
+ //TODO: Add list, stylesheet, info, etc. mappings
+ /**
+ * The Hashtable storing the font number mappings.
+ */
+ private Hashtable importFontMapping = null;
+ /**
+ * The Hashtable storing the color number mapings.
+ */
+ private Hashtable importColorMapping = null;
+ /**
+ * The Hashtable storing the Stylesheet List number mapings.
+ */
+ private Hashtable importStylesheetListMapping = null;
+ /**
+ * The Hashtable storing the List number mapings.
+ */
+ private Hashtable importListMapping = null;
+ /**
+ * The RtfDocument to get font and color numbers from.
+ */
+ private RtfDocument rtfDoc = null;
+ /**
+ * The Document.
+ * Used for conversions, but not imports.
+ */
+ private Document doc = null;
+
+
+ /**
+ * Constructs a new RtfImportHeader.
+ *
+ * @param rtfDoc The RtfDocument to get font and color numbers from.
+ */
+ public RtfImportMgr(RtfDocument rtfDoc, Document doc) {
+ this.rtfDoc = rtfDoc;
+ this.doc = doc;
+ this.importFontMapping = new Hashtable();
+ this.importColorMapping = new Hashtable();
+ this.importStylesheetListMapping = new Hashtable();
+ this.importListMapping = new Hashtable();
+ }
+
+ /**
+ * Imports a font. The font name is looked up in the RtfDocumentHeader and
+ * then the mapping from original font number to actual font number is added.
+ *
+ * @param fontNr The original font number.
+ * @param fontName The font name to look up.
+ */
+ public bool ImportFont(String fontNr, String fontName) {
+ RtfFont rtfFont = new RtfFont(fontName);
+ if (rtfFont != null){
+ rtfFont.SetRtfDocument(this.rtfDoc);
+ this.importFontMapping[fontNr] = this.rtfDoc.GetDocumentHeader().GetFontNumber(rtfFont).ToString();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ /**
+ * Imports a font. The font name is looked up in the RtfDocumentHeader and
+ * then the mapping from original font number to actual font number is added.
+ *
+ * @param fontNr The original font number.
+ * @param fontName The font name to look up.
+ * @param charset The characterset to use for the font.
+ */
+ public bool ImportFont(String fontNr, String fontName, int charset) {
+ RtfFont rtfFont = new RtfFont(fontName);
+ if (charset>= 0)
+ rtfFont.SetCharset(charset);
+ if (rtfFont != null){
+ rtfFont.SetRtfDocument(this.rtfDoc);
+ this.importFontMapping[fontNr] = this.rtfDoc.GetDocumentHeader().GetFontNumber(rtfFont).ToString();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ /**
+ * Imports a font. The font name is looked up in the RtfDocumentHeader and
+ * then the mapping from original font number to actual font number is added.
+ *
+ * @param fontNr The original font number.
+ * @param fontName The font name to look up.
+ * @param charset The characterset to use for the font.
+ */
+ public bool ImportFont(String fontNr, String fontName, String fontFamily, int charset) {
+ RtfFont rtfFont = new RtfFont(fontName);
+
+ if (charset>= 0)
+ rtfFont.SetCharset(charset);
+ if (fontFamily != null && fontFamily.Length > 0)
+ rtfFont.SetFamily(fontFamily);
+ if (rtfFont != null){
+ rtfFont.SetRtfDocument(this.rtfDoc);
+ this.importFontMapping[fontNr] = this.rtfDoc.GetDocumentHeader().GetFontNumber(rtfFont).ToString();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ /**
+ * Performs the mapping from the original font number to the actual
+ * font number in the resulting RTF document. If the font number was not
+ * seen during import (thus no mapping) then 0 is returned, guaranteeing
+ * that the font number is always valid.
+ *
+ * @param fontNr The font number to map.
+ * @return The mapped font number.
+ */
+ public String MapFontNr(String fontNr) {
+ if (this.importFontMapping.ContainsKey(fontNr)) {
+ return (String) this.importFontMapping[fontNr];
+ } else {
+ return "0";
+ }
+ }
+
+ /**
+ * Imports a color value. The color number for the color defined
+ * by its red, green and blue values is determined and then the
+ * resulting mapping is added.
+ *
+ * @param colorNr The original color number.
+ * @param color The color to import.
+ */
+ public void ImportColor(String colorNr, Color color) {
+ RtfColor rtfColor = new RtfColor(this.rtfDoc, color);
+ this.importColorMapping[colorNr] = rtfColor.GetColorNumber().ToString();
+ }
+
+ /**
+ * Performs the mapping from the original font number to the actual font
+ * number used in the RTF document. If the color number was not
+ * seen during import (thus no mapping) then 0 is returned, guaranteeing
+ * that the color number is always valid.
+ *
+ * @param colorNr The color number to map.
+ * @return The mapped color number
+ */
+ public String MapColorNr(String colorNr) {
+ if (this.importColorMapping.ContainsKey(colorNr)) {
+ return (String) this.importColorMapping[colorNr];
+ } else {
+ return "0";
+ }
+ }
+
+ /**
+ * Imports a List value. The List number for the List defined
+ * is determined and then the resulting mapping is added.
+ */
+ public void ImportList(String listNr, List list) {
+ RtfList rtfList = new RtfList(this.rtfDoc, list);
+
+ //if(rtfList != null){
+ //rtfList.SetRtfDocument(this.rtfDoc);
+ this.importStylesheetListMapping[listNr] = this.rtfDoc.GetDocumentHeader().GetListNumber(rtfList).ToString();
+ // return true;
+ // } else {
+ // return false;
+ // }
+ }
+
+ /**
+ * Performs the mapping from the original list number to the actual
+ * list number in the resulting RTF document. If the list number was not
+ * seen during import (thus no mapping) then 0 is returned, guaranteeing
+ * that the list number is always valid.
+ */
+ public String MapListNr(String listNr) {
+ if (this.importListMapping.ContainsKey(listNr)) {
+ return (String) this.importListMapping[listNr];
+ } else {
+ return "0";
+ }
+ }
+
+ /**
+ * Imports a stylesheet list value. The stylesheet number for the stylesheet defined
+ * is determined and then the resulting mapping is added.
+ */
+ public bool ImportStylesheetList(String listNr, List listIn) {
+ RtfList rtfList = new RtfList(this.rtfDoc, listIn);
+
+ if (rtfList != null){
+ rtfList.SetRtfDocument(this.rtfDoc);
+ //this.importStylesheetListMapping[listNr] = Integer.ToString(this.rtfDoc.GetDocumentHeader().GetRtfParagraphStyle(styleName)(rtfList));
+ return true;
+ } else {
+ return false;
+ }
+ }
+ /**
+ * Performs the mapping from the original stylesheet number to the actual
+ * stylesheet number in the resulting RTF document. If the stylesheet number was not
+ * seen during import (thus no mapping) then 0 is returned, guaranteeing
+ * that the stylesheet number is always valid.
+ */
+ public String MapStylesheetListNr(String listNr) {
+ if (this.importStylesheetListMapping.ContainsKey(listNr)) {
+ return (String) this.importStylesheetListMapping[listNr];
+ } else {
+ return "0";
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/RtfParser.cs b/iTechSharp/iTextSharp/text/rtf/parser/RtfParser.cs
new file mode 100644
index 0000000..f85d509
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/RtfParser.cs
@@ -0,0 +1,1457 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Globalization;
+using System.Text;
+using iTextSharp.text;
+using iTextSharp.text.rtf.direct;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.parser.ctrlwords;
+using iTextSharp.text.rtf.parser.destinations;
+/*
+ * $Id: RtfParser.cs,v 1.4 2008/05/16 19:31:08 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser {
+
+ /**
+ * The RtfParser allows the importing of RTF documents or
+ * RTF document fragments. The RTF document or fragment is tokenised,
+ * font and color definitions corrected and then added to
+ * the document being written.
+ *
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+
+ public class RtfParser {
+ /**
+ * Debugging flag.
+ */
+ private static bool debugParser = false; // DEBUG Files are unlikely to be read by any reader!
+ private String logFile = null;
+ private bool logging = false;
+ private bool logAppend = false;
+
+ /**
+ * The iText document to add the RTF document to.
+ */
+ private Document document = null;
+ /**
+ * The RtfDocument to add the RTF document or fragment to.
+ */
+ private RtfDocument rtfDoc = null;
+ /**
+ * The RtfKeywords that creates and handles keywords that are implemented.
+ */
+ private RtfCtrlWordMgr rtfKeywordMgr = null;
+ /**
+ * The RtfImportHeader to store imported font and color mappings in.
+ */
+ private RtfImportMgr importMgr = null;
+ /**
+ * The RtfDestinationMgr object to manage destinations.
+ */
+ private RtfDestinationMgr destinationMgr = null;
+ /**
+ * Stack for saving states for groups
+ */
+ private Stack stackState = null;
+ /**
+ * The current parser state.
+ */
+ private RtfParserState currentState = null;
+ /**
+ * The pushback reader to read the input stream.
+ */
+ private PushbackStream pbReader = null;
+ /**
+ * Conversion type. Identifies if we are doing in import or a convert.
+ */
+ private int conversionType = TYPE_IMPORT_FULL;
+
+
+ /*
+ * Bitmapping:
+ *
+ * 0111 1111 1111 1111 = Unkown state
+ * 0xxx xxxx xxxx xxxx = In Header
+ * 1xxx xxxx xxxx xxxx = In Document
+ * 2xxx xxxx xxxx xxxx = Reserved
+ * 4xxx xxxx xxxx xxxx = Other
+ * 8xxx xxxx xxxx xxxx = Errors
+ */
+
+ /*
+ * Header state values
+ */
+
+ /**
+ * Currently the RTF document header is being parsed.
+ */
+ public const int PARSER_IN_HEADER = (0x0 << 28) | 0x000000;
+ /**
+ * Currently the RTF charset is being parsed.
+ */
+ public const int PARSER_IN_CHARSET = PARSER_IN_HEADER | 0x000001;
+ /**
+ * Currently the RTF deffont is being parsed.
+ */
+ public const int PARSER_IN_DEFFONT = PARSER_IN_HEADER | 0x000002;
+ /**
+ * Currently the RTF font table is being parsed.
+ */
+ public const int PARSER_IN_FONT_TABLE = PARSER_IN_HEADER | 0x000003;
+ /**
+ * Currently a RTF font table info element is being parsed.
+ */
+ public const int PARSER_IN_FONT_TABLE_INFO = PARSER_IN_HEADER | 0x000004;
+ /**
+ * Currently the RTF filetbl is being parsed.
+ */
+ public const int PARSER_IN_FILE_TABLE = PARSER_IN_HEADER | 0x000005;
+ /**
+ * Currently the RTF color table is being parsed.
+ */
+ public const int PARSER_IN_COLOR_TABLE = PARSER_IN_HEADER | 0x000006;
+ /**
+ * Currently the RTF stylesheet is being parsed.
+ */
+ public const int PARSER_IN_STYLESHEET = PARSER_IN_HEADER | 0x000007;
+ /**
+ * Currently the RTF listtables is being parsed.
+ */
+ public const int PARSER_IN_LIST_TABLE = PARSER_IN_HEADER | 0x000008;
+ /**
+ * Currently the RTF listtable override is being parsed.
+ */
+ public const int PARSER_IN_LISTOVERRIDE_TABLE = PARSER_IN_HEADER | 0x000009;
+ /**
+ * Currently the RTF revtbl is being parsed.
+ */
+ public const int PARSER_IN_REV_TABLE = PARSER_IN_HEADER | 0x00000A;
+ /**
+ * Currently the RTF rsidtable is being parsed.
+ */
+ public const int PARSER_IN_RSID_TABLE = PARSER_IN_HEADER | 0x0000B;
+ /**
+ * Currently the RTF generator is being parsed.
+ */
+ public const int PARSER_IN_GENERATOR = PARSER_IN_HEADER | 0x00000C;
+ /**
+ * Currently the RTF Paragraph group properties Table (word 2002)
+ */
+ public const int PARSER_IN_PARAGRAPH_TABLE = PARSER_IN_HEADER | 0x00000E;
+ /**
+ * Currently the RTF Old Properties.
+ */
+ public const int PARSER_IN_OLDCPROPS = PARSER_IN_HEADER | 0x00000F;
+ /**
+ * Currently the RTF Old Properties.
+ */
+ public const int PARSER_IN_OLDPPROPS = PARSER_IN_HEADER | 0x000010;
+ /**
+ * Currently the RTF Old Properties.
+ */
+ public const int PARSER_IN_OLDTPROPS = PARSER_IN_HEADER | 0x000012;
+ /**
+ * Currently the RTF Old Properties.
+ */
+ public const int PARSER_IN_OLDSPROPS = PARSER_IN_HEADER | 0x000013;
+ /**
+ * Currently the RTF User Protection Information.
+ */
+ public const int PARSER_IN_PROT_USER_TABLE = PARSER_IN_HEADER | 0x000014;
+ /**
+ * Currently the Latent Style and Formatting usage restrictions
+ */
+ public const int PARSER_IN_LATENTSTYLES = PARSER_IN_HEADER | 0x000015;
+
+ public const int PARSER_IN_PARAGRAPH_GROUP_PROPERTIES =PARSER_IN_HEADER | 0x000016;
+
+ /*
+ * Document state values
+ */
+
+ /**
+ * Currently the RTF document content is being parsed.
+ */
+ public const int PARSER_IN_DOCUMENT = (0x2 << 28 ) | 0x000000;
+
+ /**
+ * Currently the RTF info group is being parsed.
+ */
+ public const int PARSER_IN_INFO_GROUP = PARSER_IN_DOCUMENT | 0x000001;
+
+
+ public const int PARSER_IN_UPR = PARSER_IN_DOCUMENT | 0x000002;
+ /**
+ * Currently a shppict control word is being parsed.
+ */
+ public const int PARSER_IN_SHPPICT = PARSER_IN_DOCUMENT | 0x000010; //16
+ /**
+ * Currently a pict control word is being parsed.
+ */
+ public const int PARSER_IN_PICT = PARSER_IN_DOCUMENT | 0x000011; //17
+ /**
+ * Currently a picprop control word is being parsed.
+ */
+ public const int PARSER_IN_PICPROP = PARSER_IN_DOCUMENT | 0x000012; //18
+ /**
+ * Currently a blipuid control word is being parsed.
+ */
+ public const int PARSER_IN_BLIPUID = PARSER_IN_DOCUMENT | 0x000013; //18
+
+ /* other states */
+ /**
+ * The parser is at the beginning or the end of the file.
+ */
+ public const int PARSER_STARTSTOP = (0x4 << 28)| 0x0001;
+ /* ERRORS */
+ /**
+ * Currently the parser is in an error state.
+ */
+ public const int PARSER_ERROR = (0x8 << 28) | 0x0000;
+ /**
+ * The parser reached the end of the file.
+ */
+ public const int PARSER_ERROR_EOF = PARSER_ERROR | 0x0001;
+ /**
+ * Currently the parser is in an unknown state.
+ */
+ public const int PARSER_IN_UNKNOWN = PARSER_ERROR | 0x0FFFFFFF;
+
+
+ /**
+ * Conversion type is unknown
+ */
+ public const int TYPE_UNIDENTIFIED = -1;
+ /**
+ * Conversion type is an import. Uses direct content to add everything.
+ * This is what the original import does.
+ */
+ public const int TYPE_IMPORT_FULL = 0;
+ /**
+ * Conversion type is an import of a partial file/fragment. Uses direct content to add everything.
+ */
+ public const int TYPE_IMPORT_FRAGMENT = 1;
+ /**
+ * Conversion type is a conversion. This uses the document (not rtfDoc) to add
+ * all the elements making it a different supported documents depending on the writer used.
+ */
+ public const int TYPE_CONVERT = 2;
+
+
+ /**
+ * Destination is normal. Text is processed.
+ */
+ public const int DESTINATION_NORMAL = 0;
+ /**
+ * Destination is skipping. Text is ignored.
+ */
+ public const int DESTINATION_SKIP = 1;
+
+ //////////////////////////////////// TOKENISE VARIABLES ///////////////////
+ /*
+ * State flags use 4/28 bitmask.
+ * First 4 bits (nibble) indicates major state. Used for unknown and error
+ * Last 28 bits indicates the value;
+ */
+
+ /**
+ * The RtfTokeniser is in its ground state. Any token may follow.
+ */
+ public const int TOKENISER_NORMAL = 0x00000000;
+ /**
+ * The last token parsed was a slash.
+ */
+ public const int TOKENISER_SKIP_BYTES = 0x00000001;
+ /**
+ * The RtfTokeniser is currently tokenising a control word.
+ */
+ public const int TOKENISER_SKIP_GROUP = 0x00000002;
+ /**
+ * The RtfTokeniser is currently reading binary stream.
+ */
+ public const int TOKENISER_BINARY= 0x00000003;
+ /**
+ * The RtfTokeniser is currently reading hex data.
+ */
+ public const int TOKENISER_HEX= 0x00000004;
+ /**
+ * The RtfTokeniser ignore result
+ */
+ public const int TOKENISER_IGNORE_RESULT= 0x00000005;
+ /**
+ * The RtfTokeniser is currently in error state
+ */
+ public const int TOKENISER_STATE_IN_ERROR = unchecked((int)0x80000000); // 1000 0000 0000 0000 0000 0000 0000 0000
+ /**
+ * The RtfTokeniser is currently in an unkown state
+ */
+ public const int TOKENISER_STATE_IN_UNKOWN = unchecked((int)0xFF000000); // 1111 0000 0000 0000 0000 0000 0000 0000
+
+ /**
+ * The current group nesting level.
+ */
+ private int groupLevel = 0;
+ /**
+ * The current document group nesting level. Used for fragments.
+ */
+ private int docGroupLevel = 0;
+ /**
+ * When the tokeniser is Binary.
+ */
+ private long binByteCount = 0;
+ /**
+ * When the tokeniser is set to skip bytes, binSkipByteCount is the number of bytes to skip.
+ */
+ private long binSkipByteCount = 0;
+ /**
+ * When the tokeniser is set to skip to next group, this is the group indentifier to return to.
+ */
+ private int skipGroupLevel = 0;
+
+ //RTF parser error codes
+ public const int errOK =0; // Everything's fine!
+ public const int errStackUnderflow = -1; // Unmatched '}'
+ public const int errStackOverflow = -2; // Too many '{' -- memory exhausted
+ public const int errUnmatchedBrace = -3; // RTF ended during an open group.
+ public const int errInvalidHex = -4; // invalid hex character found in data
+ public const int errBadTable = -5; // RTF table (sym or prop) invalid
+ public const int errAssertion = -6; // Assertion failure
+ public const int errEndOfFile = -7; // End of file reached while reading RTF
+ public const int errCtrlWordNotFound = -8; // control word was not found
+ //////////////////////////////////// TOKENISE VARIABLES ///////////////////
+
+
+ //////////////////////////////////// STATS VARIABLES ///////////////////
+ /**
+ * Total bytes read.
+ */
+ private long byteCount = 0;
+ /**
+ * Total control words processed.
+ *
+ * Contains both known and unknown.
+ *
+ * ctrlWordCount
should equal
+ * ctrlWrodHandlecCount
+ ctrlWordNotHandledCount
ctrlWordSkippedCountRtfCtrlWordListener
. */
+ private ArrayList listeners = new ArrayList();
+
+ /* *********
+ * READER *
+ ***********/
+ /**
+ * Imports a complete RTF document.
+ *
+ * @param readerIn
+ * The Reader to read the RTF document from.
+ * @param rtfDoc
+ * The RtfDocument to add the imported document to.
+ * @throws IOException On I/O errors.
+ */
+ public void ImportRtfDocument(Stream readerIn, RtfDocument rtfDoc) {
+ if (readerIn == null || rtfDoc == null) return;
+ this.Init(TYPE_IMPORT_FULL, rtfDoc, readerIn, null);
+ this.SetCurrentDestination(RtfDestinationMgr.DESTINATION_NULL);
+ startDate = DateTime.Now;
+ startTime = startDate.Ticks / 10000L;
+ this.groupLevel = 0;
+ try {
+ this.Tokenise();
+ }
+ catch {
+ }
+ endDate = DateTime.Now;
+ endTime = endDate.Ticks / 10000L;
+ }
+
+ /**
+ * Converts an RTF document to an iText document.
+ *
+ * Usage: Create a parser object and call this method with the input stream and the iText Document object
+ *
+ * @param readerIn
+ * The Reader to read the RTF file from.
+ * @param doc
+ * The iText document that the RTF file is to be added to.
+ * @throws IOException
+ * On I/O errors.
+ */
+ public void ConvertRtfDocument(Stream readerIn, Document doc) {
+ if (readerIn == null || doc == null) return;
+ this.Init(TYPE_CONVERT, null, readerIn, doc);
+ this.SetCurrentDestination(RtfDestinationMgr.DESTINATION_DOCUMENT);
+ startDate = DateTime.Now;
+ startTime = startDate.Ticks / 10000L;
+ this.groupLevel = 0;
+ this.Tokenise();
+ endDate = DateTime.Now;
+ endTime = endDate.Ticks / 10000L;
+ }
+
+ /**
+ * Imports an RTF fragment.
+ *
+ * @param readerIn
+ * The Reader to read the RTF fragment from.
+ * @param rtfDoc
+ * The RTF document to add the RTF fragment to.
+ * @param importMappings
+ * The RtfImportMappings defining font and color mappings for the fragment.
+ * @throws IOException
+ * On I/O errors.
+ */
+ public void ImportRtfFragment(Stream readerIn, RtfDocument rtfDoc, RtfImportMappings importMappings) {
+ //public void ImportRtfFragment2(Reader readerIn, RtfDocument rtfDoc, RtfImportMappings importMappings) throws IOException {
+ if (readerIn == null || rtfDoc == null || importMappings==null) return;
+ this.Init(TYPE_IMPORT_FRAGMENT, rtfDoc, readerIn, null);
+ this.HandleImportMappings(importMappings);
+ this.SetCurrentDestination(RtfDestinationMgr.DESTINATION_DOCUMENT);
+ this.groupLevel = 1;
+ SetParserState(RtfParser.PARSER_IN_DOCUMENT);
+ startDate = DateTime.Now;
+ startTime = startDate.Ticks / 10000L;
+ this.Tokenise();
+ endDate = DateTime.Now;
+ endTime = endDate.Ticks / 10000L;
+ }
+
+ // listener methods
+
+ /**
+ * Adds a EventListener
to the RtfCtrlWordMgr
.
+ *
+ * @param listener
+ * the new EventListener.
+ */
+ public void AddListener(IEventListener listener) {
+ listeners.Add(listener);
+ }
+
+ /**
+ * Removes a EventListener
from the RtfCtrlWordMgr
.
+ *
+ * @param listener
+ * the EventListener that has to be removed.
+ */
+ public void RemoveListener(IEventListener listener) {
+ listeners.Remove(listener);
+ }
+
+ /**
+ * Initialize the parser object values.
+ *
+ * @param type Type of conversion or import
+ * @param rtfDoc The RtfDocument
+ * @param readerIn The input stream
+ * @param doc The iText Document
+ */
+ private void Init(int type, RtfDocument rtfDoc, Stream readerIn, Document doc) {
+
+ Init_stats();
+ // initialize reader to a PushbackReader
+ this.pbReader = Init_Reader(readerIn);
+
+ this.conversionType = type;
+ this.rtfDoc = rtfDoc;
+ this.document = doc;
+ this.currentState = new RtfParserState();
+ this.stackState = new Stack();
+ this.SetParserState(PARSER_STARTSTOP);
+ this.importMgr = new RtfImportMgr(this.rtfDoc, this.document);
+
+ // get destination Mgr
+ this.destinationMgr = RtfDestinationMgr.GetInstance(this);
+ // set the parser
+ RtfDestinationMgr.SetParser(this);
+
+
+ // DEBUG INFO for timing and memory usage of RtfCtrlWordMgr object
+ // create multiple new RtfCtrlWordMgr objects to check timing and memory usage
+ // System.Gc();
+ // long endTime = 0;
+ // Date endDate = null;
+ // long endFree = 0;
+ // DecimalFormat df = new DecimalFormat("#,##0");
+ // Date startDate = new Date();
+ // long startTime = System.CurrentTimeMillis();
+ // long startFree = Runtime.GetRuntime().FreeMemory();
+ // System.out.Println("1:");
+
+ this.rtfKeywordMgr = new RtfCtrlWordMgr(this, this.pbReader);/////////DO NOT COMMENT OUT THIS LINE ///////////
+
+ foreach (object listener in listeners) {
+ if (listener is IRtfCtrlWordListener) {
+ this.rtfKeywordMgr.AddRtfCtrlWordListener((IRtfCtrlWordListener)listener);
+ }
+ }
+ // endFree = Runtime.GetRuntime().FreeMemory();
+ // endTime = System.CurrentTimeMillis();
+ // endDate = new Date();
+ // System.out.Println("RtfCtrlWordMgr start date: " + startDate.ToLocaleString());
+ // System.out.Println("RtfCtrlWordMgr end date : " + endDate.ToLocaleString());
+ // System.out.Println(" Elapsed time : " + Long.ToString(endTime - startTime) + " milliseconds.");
+ // System.out.Println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.Format(startFree / 1024) + "k");
+ // System.out.Println("End Constructor RtfCtrlWordMgr , free mem is " + df.Format(endFree / 1024) + "k");
+ // System.out.Println("RtfCtrlWordMgr used approximately " + df.Format((startFree - endFree) / 1024) + "k");
+ //
+ // System.Gc();
+ // System.out.Println("2:");
+ // startDate = new Date();
+ // startTime = System.CurrentTimeMillis();
+ // startFree = Runtime.GetRuntime().FreeMemory();
+ // RtfCtrlWordMgr rtfKeywordMgr2 = new RtfCtrlWordMgr(this, this.pbReader);
+ // endFree = Runtime.GetRuntime().FreeMemory();
+ // endTime = System.CurrentTimeMillis();
+ // endDate = new Date();
+ // System.out.Println("RtfCtrlWordMgr start date: " + startDate.ToLocaleString());
+ // System.out.Println("RtfCtrlWordMgr end date : " + endDate.ToLocaleString());
+ // System.out.Println(" Elapsed time : " + Long.ToString(endTime - startTime) + " milliseconds.");
+ // System.out.Println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.Format(startFree / 1024) + "k");
+ // System.out.Println("End Constructor RtfCtrlWordMgr , free mem is " + df.Format(endFree / 1024) + "k");
+ // System.out.Println("RtfCtrlWordMgr used approximately " + df.Format((startFree - endFree) / 1024) + "k");
+ //
+ // System.Gc();
+ // System.out.Println("3:");
+ // startDate = new Date();
+ // startTime = System.CurrentTimeMillis();
+ // startFree = Runtime.GetRuntime().FreeMemory();
+ // RtfCtrlWordMgr rtfKeywordMgr3 = new RtfCtrlWordMgr(this, this.pbReader);
+ // endFree = Runtime.GetRuntime().FreeMemory();
+ // endTime = System.CurrentTimeMillis();
+ // endDate = new Date();
+ // System.out.Println("RtfCtrlWordMgr start date: " + startDate.ToLocaleString());
+ // System.out.Println("RtfCtrlWordMgr end date : " + endDate.ToLocaleString());
+ // System.out.Println(" Elapsed time : " + Long.ToString(endTime - startTime) + " milliseconds.");
+ // System.out.Println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.Format(startFree / 1024) + "k");
+ // System.out.Println("End Constructor RtfCtrlWordMgr , free mem is " + df.Format(endFree / 1024) + "k");
+ // System.out.Println("RtfCtrlWordMgr used approximately " + df.Format((startFree - endFree) / 1024) + "k");
+ //
+ // System.Gc();
+ // System.out.Println("4:");
+ // startDate = new Date();
+ // startTime = System.CurrentTimeMillis();
+ // startFree = Runtime.GetRuntime().FreeMemory();
+ // RtfCtrlWordMgr rtfKeywordMgr4 = new RtfCtrlWordMgr(this, this.pbReader);
+ // endFree = Runtime.GetRuntime().FreeMemory();
+ // endTime = System.CurrentTimeMillis();
+ // endDate = new Date();
+ // System.out.Println("RtfCtrlWordMgr start date: " + startDate.ToLocaleString());
+ // System.out.Println("RtfCtrlWordMgr end date : " + endDate.ToLocaleString());
+ // System.out.Println(" Elapsed time : " + Long.ToString(endTime - startTime) + " milliseconds.");
+ // System.out.Println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.Format(startFree / 1024) + "k");
+ // System.out.Println("End Constructor RtfCtrlWordMgr , free mem is " + df.Format(endFree / 1024) + "k");
+ // System.out.Println("RtfCtrlWordMgr used approximately " + df.Format((startFree - endFree) / 1024) + "k");
+ //
+ // System.Gc();
+ // System.out.Println("5:");
+ // startDate = new Date();
+ // startTime = System.CurrentTimeMillis();
+ // startFree = Runtime.GetRuntime().FreeMemory();
+ // RtfCtrlWordMgr rtfKeywordMgr5 = new RtfCtrlWordMgr(this, this.pbReader);
+ // endFree = Runtime.GetRuntime().FreeMemory();
+ // endTime = System.CurrentTimeMillis();
+ // endDate = new Date();
+ // System.out.Println("RtfCtrlWordMgr start date: " + startDate.ToLocaleString());
+ // System.out.Println("RtfCtrlWordMgr end date : " + endDate.ToLocaleString());
+ // System.out.Println(" Elapsed time : " + Long.ToString(endTime - startTime) + " milliseconds.");
+ // System.out.Println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.Format(startFree / 1024) + "k");
+ // System.out.Println("End Constructor RtfCtrlWordMgr , free mem is " + df.Format(endFree / 1024) + "k");
+ // System.out.Println("RtfCtrlWordMgr used approximately " + df.Format((startFree - endFree) / 1024) + "k");
+ // System.Gc();
+ // System.out.Println("At ed:");
+ // startDate = new Date();
+ // startTime = System.CurrentTimeMillis();
+ // startFree = Runtime.GetRuntime().FreeMemory();
+ // //RtfCtrlWordMgr rtfKeywordMgr6 = new RtfCtrlWordMgr(this, this.pbReader);
+ // endFree = Runtime.GetRuntime().FreeMemory();
+ // endTime = System.CurrentTimeMillis();
+ // endDate = new Date();
+ // System.out.Println("RtfCtrlWordMgr start date: " + startDate.ToLocaleString());
+ // System.out.Println("RtfCtrlWordMgr end date : " + endDate.ToLocaleString());
+ // System.out.Println(" Elapsed time : " + Long.ToString(endTime - startTime) + " milliseconds.");
+ // System.out.Println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.Format(startFree / 1024) + "k");
+ // System.out.Println("End Constructor RtfCtrlWordMgr , free mem is " + df.Format(endFree / 1024) + "k");
+ // System.out.Println("RtfCtrlWordMgr used approximately " + df.Format((startFree - endFree) / 1024) + "k");
+ }
+ /**
+ * Initialize the statistics values.
+ */
+ protected void Init_stats() {
+ byteCount = 0;
+ ctrlWordCount = 0;
+ openGroupCount = 0;
+ closeGroupCount = 0;
+ characterCount = 0;
+ ctrlWordHandledCount = 0;
+ ctrlWordNotHandledCount = 0;
+ ctrlWordSkippedCount = 0;
+ groupSkippedCount = 0;
+ startTime = 0;
+ endTime = 0;
+ //startDate = null;
+ //endDate = null;
+ }
+
+ /**
+ * Casts the input reader to a PushbackReader or
+ * creates a new PushbackReader from the Reader passed in.
+ * The reader is also transformed into a BufferedReader if necessary.
+ *
+ * @param readerIn
+ * The Reader object for the input file.
+ * @return
+ * PushbackReader object
+ */
+ private PushbackStream Init_Reader(Stream readerIn) {
+ if (readerIn is PushbackStream) {
+ return (PushbackStream)readerIn;
+ }
+
+ // return the proper reader object to the parser setup
+ return new PushbackStream(readerIn);
+ }
+
+ /**
+ * Imports the mappings defined in the RtfImportMappings into the
+ * RtfImportHeader of this RtfParser2.
+ *
+ * @param importMappings
+ * The RtfImportMappings to import.
+ */
+ private void HandleImportMappings(RtfImportMappings importMappings) {
+ foreach (String fontNr in importMappings.GetFontMappings().Keys) {
+ this.importMgr.ImportFont(fontNr, (String) importMappings.GetFontMappings()[fontNr]);
+ }
+ foreach (String colorNr in importMappings.GetColorMappings().Keys) {
+ this.importMgr.ImportColor(colorNr, (Color) importMappings.GetColorMappings()[colorNr]);
+ }
+ foreach (String listNr in importMappings.GetListMappings().Keys) {
+ this.importMgr.ImportList(listNr, (List) importMappings.GetListMappings()[listNr]);
+ }
+ foreach (String stylesheetListNr in importMappings.GetStylesheetListMappings().Keys) {
+ this.importMgr.ImportStylesheetList(stylesheetListNr, (List) importMappings.GetStylesheetListMappings()[stylesheetListNr]);
+ }
+
+ }
+
+
+ /* *****************************************
+ * DOCUMENT CONTROL METHODS
+ *
+ * Handles -
+ * handleOpenGroup: Open groups - '{'
+ * handleCloseGroup: Close groups - '}'
+ * handleCtrlWord: Ctrl Words - '\...'
+ * handleCharacter: Characters - Plain Text, etc.
+ *
+ */
+
+ /**
+ * Handles open group tokens. ({)
+ *
+ * @return errOK if ok, other if an error occurred.
+ */
+ public int HandleOpenGroup() {
+ int result = errOK;
+ this.openGroupCount++; // stats
+ this.groupLevel++; // current group level in tokeniser
+ this.docGroupLevel++; // current group level in document
+ if (this.GetTokeniserState() == TOKENISER_SKIP_GROUP) {
+ this.groupSkippedCount++;
+ }
+
+ RtfDestination dest = (RtfDestination)this.GetCurrentDestination();
+ bool handled = false;
+
+ if (dest != null) {
+ if (debugParser) {
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: before dest.HandleOpeningSubGroup()");
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + dest.ToString());
+ }
+ handled = dest.HandleOpeningSubGroup();
+ if (debugParser) {
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: after dest.HandleOpeningSubGroup()");
+ }
+ }
+
+ this.stackState.Push(this.currentState);
+ this.currentState = new RtfParserState(this.currentState);
+ // do not set this true until after the state is pushed
+ // otherwise it inserts a { where one does not belong.
+ this.currentState.newGroup = true;
+ dest = (RtfDestination)this.GetCurrentDestination();
+
+ if (debugParser) {
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: HandleOpenGroup()");
+ if (this.lastCtrlWordParam != null)
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: LastCtrlWord=" + this.lastCtrlWordParam.ctrlWord);
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: grouplevel=" + groupLevel.ToString());
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + dest.ToString());
+ }
+
+ if (dest != null) {
+ handled = dest.HandleOpenGroup();
+ }
+
+ if (debugParser) {
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: after dest.HandleOpenGroup(); handled=" + handled.ToString());
+ }
+
+ return result;
+ }
+ public static void OutputDebug(object doc, int groupLevel, String str) {
+ Console.Out.WriteLine(str);
+ if(doc == null) return;
+ if (groupLevel<0) groupLevel = 0;
+ String spaces = new String(' ', groupLevel*2);
+ if(doc is RtfDocument) {
+ ((RtfDocument)doc).Add(new RtfDirectContent("\n" + spaces + str));
+ }
+ else if(doc is Document) {
+ try {
+ ((Document)doc).Add(new RtfDirectContent("\n" + spaces + str));
+ } catch (DocumentException) {
+ }
+ }
+ }
+ /**
+ * Handles close group tokens. (})
+ *
+ * @return errOK if ok, other if an error occurred.
+ */
+ public int HandleCloseGroup() {
+ int result = errOK;
+ this.closeGroupCount++; // stats
+
+ if (this.GetTokeniserState() != TOKENISER_SKIP_GROUP) {
+ if (debugParser) {
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: HandleCloseGroup()");
+ if (this.lastCtrlWordParam != null)
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: LastCtrlWord=" + this.lastCtrlWordParam.ctrlWord);
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: grouplevel=" + groupLevel.ToString());
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + this.GetCurrentDestination().ToString());
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "");
+ }
+ RtfDestination dest = (RtfDestination)this.GetCurrentDestination();
+ bool handled = false;
+
+ if (dest != null) {
+ handled = dest.HandleCloseGroup();
+ }
+ if (debugParser) {
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: After dest.HandleCloseGroup(); handled = " + handled.ToString());
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "");
+ }
+ }
+
+ if (this.stackState.Count >0 ) {
+ this.currentState = (RtfParserState)this.stackState.Pop();
+ } else {
+ result = errStackUnderflow;
+ }
+
+ this.docGroupLevel--;
+ this.groupLevel--;
+
+ if (this.GetTokeniserState() == TOKENISER_SKIP_GROUP && this.groupLevel < this.skipGroupLevel) {
+ this.SetTokeniserState(TOKENISER_NORMAL);
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Handles control word tokens. Depending on the current
+ * state a control word can lead to a state change. When
+ * parsing the actual document contents, certain tabled
+ * values are remapped. i.e. colors, fonts, styles, etc.
+ *
+ * @param ctrlWordData The control word to handle.
+ * @return errOK if ok, other if an error occurred.
+ */
+ public int HandleCtrlWord(RtfCtrlWordData ctrlWordData) {
+ int result = errOK;
+ this.ctrlWordCount++; // stats
+
+ if (debugParser) {
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: handleCtrlWord=" + ctrlWordData.ctrlWord);
+ }
+
+ if (this.GetTokeniserState() == TOKENISER_SKIP_GROUP) {
+ this.ctrlWordSkippedCount++;
+ if (debugParser) {
+ RtfParser.OutputDebug(this.rtfDoc, groupLevel, "DEBUG: SKIPPED");
+ }
+ return result;
+ }
+
+ // RtfDestination dest = (RtfDestination)this.GetCurrentDestination();
+ // bool handled = false;
+ // if (dest != null) {
+ // handled = dest.HandleControlWord(ctrlWordData);
+ // }
+
+ result = this.rtfKeywordMgr.HandleKeyword(ctrlWordData, this.groupLevel);
+
+ if ( result == errOK){
+ this.ctrlWordHandledCount++;
+ } else {
+ this.ctrlWordNotHandledCount++;
+ result = errOK; // hack for now.
+ }
+
+ return result;
+ }
+
+ /**
+ * Handles text tokens. These are either handed on to the
+ * appropriate destination handler.
+ *
+ * @param nextChar
+ * The text token to handle.
+ * @return errOK if ok, other if an error occurred.
+ */
+ public int HandleCharacter(int nextChar) {
+ this.characterCount++; // stats
+
+ if (this.GetTokeniserState() == TOKENISER_SKIP_GROUP) {
+ return errOK;
+ }
+
+ bool handled = false;
+
+ RtfDestination dest = (RtfDestination)this.GetCurrentDestination();
+ if (dest != null) {
+ handled = dest.HandleCharacter(nextChar);
+ }
+
+ return errOK;
+ }
+
+ /**
+ * Get the state of the parser.
+ *
+ * @return
+ * The current RtfParserState state object.
+ */
+ public RtfParserState GetState(){
+ return this.currentState;
+ }
+
+ /**
+ * Get the current state of the parser.
+ *
+ * @return
+ * The current state of the parser.
+ */
+ public int GetParserState(){
+ return this.currentState.parserState;
+ }
+
+ /**
+ * Set the state value of the parser.
+ *
+ * @param newState
+ * The new state for the parser
+ * @return
+ * The state of the parser.
+ */
+ public int SetParserState(int newState){
+ this.currentState.parserState = newState;
+ return this.currentState.parserState;
+ }
+
+ /**
+ * Get the conversion type.
+ *
+ * @return
+ * The type of the conversion. Import or Convert.
+ */
+ public int GetConversionType() {
+ return this.conversionType;
+ }
+
+ /**
+ * Get the RTF Document object.
+ * @return
+ * Returns the object rtfDoc.
+ */
+ public RtfDocument GetRtfDocument() {
+ return this.rtfDoc;
+ }
+
+ /**
+ * Get the Document object.
+ * @return
+ * Returns the object rtfDoc.
+ */
+ public Document GetDocument() {
+ return this.document;
+ }
+
+ /**
+ * Get the RtfImportHeader object.
+ * @return
+ * Returns the object importHeader.
+ */
+ public RtfImportMgr GetImportManager() {
+ return importMgr;
+ }
+
+
+ /////////////////////////////////////////////////////////////
+ // accessors for destinations
+ /**
+ * Set the current destination object for the current state.
+ * @param dest The destination value to set.
+ */
+ public bool SetCurrentDestination(String destination) {
+ RtfDestination dest = RtfDestinationMgr.GetDestination(destination);
+ if (dest != null) {
+ this.currentState.destination = dest;
+ return false;
+ } else {
+ this.SetTokeniserStateSkipGroup();
+ return false;
+ }
+ }
+ /**
+ * Get the current destination object.
+ *
+ * @return The current state destination
+ */
+ public RtfDestination GetCurrentDestination() {
+ return this.currentState.destination;
+ }
+ /**
+ * Get a destination from the map
+ *
+ * @para destination The string destination.
+ * @return The destination object from the map
+ */
+ public RtfDestination GetDestination(String destination) {
+ return RtfDestinationMgr.GetDestination(destination);
+ }
+
+ /**
+ * Helper method to determine if this is a new group.
+ *
+ * @return true if this is a new group, otherwise it returns false.
+ */
+ public bool IsNewGroup() {
+ return this.currentState.newGroup;
+ }
+ /**
+ * Helper method to set the new group flag
+ * @param value The bool value to set the flag
+ * @return The value of newGroup
+ */
+ public bool SetNewGroup(bool value) {
+ this.currentState.newGroup = value;
+ return this.currentState.newGroup;
+ }
+
+ /* ************
+ * TOKENISER *
+ **************/
+
+ /**
+ * Read through the input file and parse the data stream into tokens.
+ *
+ * @throws IOException on IO error.
+ */
+ public void Tokenise() {
+ int errorCode = errOK; // error code
+ int nextChar = 0;
+ this.SetTokeniserState(TOKENISER_NORMAL); // set initial tokeniser state
+
+
+ while((nextChar = this.pbReader.ReadByte()) != -1) {
+ this.byteCount++;
+
+ if (this.GetTokeniserState() == TOKENISER_BINARY) // if we're parsing binary data, handle it directly
+ {
+ if ((errorCode = ParseChar(nextChar)) != errOK)
+ return;
+ } else {
+ switch (nextChar) {
+ case '{': // scope delimiter - Open
+ this.HandleOpenGroup();
+ break;
+ case '}': // scope delimiter - Close
+ this.HandleCloseGroup();
+ break;
+ case '\n': // noise character
+ case '\r': // noise character
+ // if (this.IsImport()) {
+ // this.rtfDoc.Add(new RtfDirectContent(new String(nextChar)));
+ // }
+ break;
+ case '\\': // Control word start delimiter
+ if (ParseCtrlWord(pbReader) != errOK) {
+ // TODO: Indicate some type of error
+ return;
+ }
+ break;
+ default:
+ if (groupLevel == 0) { // BOMs
+ break;
+ }
+ if (this.GetTokeniserState() == TOKENISER_HEX) {
+ StringBuilder hexChars = new StringBuilder();
+ hexChars.Append(nextChar);
+ if((nextChar = pbReader.ReadByte()) == -1) {
+ return;
+ }
+ this.byteCount++;
+ hexChars.Append(nextChar);
+ try {
+ nextChar=int.Parse(hexChars.ToString(), NumberStyles.HexNumber);
+ } catch {
+ return;
+ }
+ this.SetTokeniserState(TOKENISER_NORMAL);
+ }
+ if ((errorCode = ParseChar(nextChar)) != errOK) {
+ return; // some error occurred. we should send a
+ // real error
+ }
+ break;
+ } // switch (nextChar[0])
+ } // end if (this.GetTokeniserState() == TOKENISER_BINARY)
+
+ // if (groupLevel < 1 && this.IsImportFragment()) return; //return errOK;
+ // if (groupLevel < 0 && this.IsImportFull()) return; //return errStackUnderflow;
+ // if (groupLevel < 0 && this.IsConvert()) return; //return errStackUnderflow;
+
+ }// end while (reader.Read(nextChar) != -1)
+ RtfDestination dest = (RtfDestination)this.GetCurrentDestination();
+ if (dest != null) {
+ dest.CloseDestination();
+ }
+ }
+
+ /**
+ * Process the character and send it to the current destination.
+ * @param nextChar
+ * The character to process
+ * @return
+ * Returns an error code or errOK if no error.
+ */
+ private int ParseChar(int nextChar) {
+ // figure out where to put the character
+ // needs to handle group levels for parsing
+ // examples
+ /*
+ * {\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}
+ * {\f7\fswiss\fcharset0\fprq2{\*\panose 020b0604020202030204}Helv{\*\falt Arial};} <- special case!!!!
+ * {\f5\froman\fcharset0 Tahoma;}
+ * {\f6\froman\fcharset0 Arial Black;}
+ * {\info(\author name}{\company company name}}
+ * ... document text ...
+ */
+ if (this.GetTokeniserState() == TOKENISER_BINARY && --binByteCount <= 0)
+ this.SetTokeniserStateNormal();
+ if (this.GetTokeniserState() == TOKENISER_SKIP_BYTES && --binSkipByteCount <= 0)
+ this.SetTokeniserStateNormal();
+ return this.HandleCharacter(nextChar);
+ }
+
+ /**
+ * Parses a keyword and it's parameter if one exists
+ * @param reader
+ * This is a pushback reader for file input.
+ * @return
+ * Returns an error code or errOK if no error.
+ * @throws IOException
+ * Catch any file read problem.
+ */
+ private int ParseCtrlWord(PushbackStream reader) {
+ int nextChar = 0;
+ int result = errOK;
+
+ if((nextChar = reader.ReadByte()) == -1) {
+ return errEndOfFile;
+ }
+ this.byteCount++;
+
+ StringBuilder parsedCtrlWord = new StringBuilder();
+ StringBuilder parsedParam= new StringBuilder();
+ RtfCtrlWordData ctrlWordParam = new RtfCtrlWordData();
+
+ if (!Char.IsLetterOrDigit((char)nextChar)) {
+ parsedCtrlWord.Append((char)nextChar);
+ ctrlWordParam.ctrlWord = parsedCtrlWord.ToString();
+ result = this.HandleCtrlWord(ctrlWordParam);
+ lastCtrlWordParam = ctrlWordParam;
+ return result;
+ }
+
+ // for ( ; Character.IsLetter(nextChar[0]); reader.Read(nextChar) ) {
+ // parsedCtrlWord.Append(nextChar[0]);
+ // }
+ do {
+ parsedCtrlWord.Append((char)nextChar);
+ //TODO: catch EOF
+ nextChar = reader.ReadByte();
+ this.byteCount++;
+ } while (Char.IsLetter((char)nextChar));
+
+ ctrlWordParam.ctrlWord = parsedCtrlWord.ToString();
+
+ if ((char)nextChar == '-') {
+ ctrlWordParam.isNeg = true;
+ if((nextChar = reader.ReadByte()) == -1) {
+ return errEndOfFile;
+ }
+ this.byteCount++;
+ }
+
+ if (Char.IsDigit((char)nextChar)) {
+ ctrlWordParam.hasParam = true;
+ // for ( ; Character.IsDigit(nextChar[0]); reader.Read(nextChar) ) {
+ // parsedParam.Append(nextChar[0]);
+ // }
+ do {
+ parsedParam.Append((char)nextChar);
+ //TODO: catch EOF
+ nextChar = reader.ReadByte();
+ this.byteCount++;
+ } while (Char.IsDigit((char)nextChar));
+
+ ctrlWordParam.param = parsedParam.ToString();
+ }
+
+ // push this character back into the stream
+ if ((char)nextChar != ' ') { // || this.IsImport() ) {
+ reader.Unread(nextChar);
+ }
+
+ if (debugParser) {
+ // // debug: insrsid6254399
+ // if (ctrlWordParam.ctrlWord.Equals("proptype") && ctrlWordParam.param.Equals("30")) {
+ // System.out.Print("Debug value found\n");
+ // }
+ // if (ctrlWordParam.ctrlWord.Equals("panose") ) {
+ // System.out.Print("Debug value found\n");
+ // }
+ }
+
+ result = this.HandleCtrlWord(ctrlWordParam);
+ lastCtrlWordParam = ctrlWordParam;
+ return result;
+
+ }
+
+ /**
+ * Set the current state of the tokeniser.
+ * @param value The new state of the tokeniser.
+ * @return The state of the tokeniser.
+ */
+ public int SetTokeniserState(int value) {
+ this.currentState.tokeniserState = value;
+ return this.currentState.tokeniserState;
+ }
+
+ /**
+ * Get the current state of the tokeniser.
+ * @return The current state of the tokeniser.
+ */
+ public int GetTokeniserState() {
+ return this.currentState.tokeniserState;
+ }
+
+ /**
+ * Gets the current group level
+ *
+ * @return
+ * The current group level value.
+ */
+ public int GetLevel() {
+ return this.groupLevel;
+ }
+
+
+ /**
+ * Set the tokeniser state to skip to the end of the group.
+ * Sets the state to TOKENISER_SKIP_GROUP and skipGroupLevel to the current group level.
+ */
+ public void SetTokeniserStateNormal() {
+ this.SetTokeniserState(TOKENISER_NORMAL);
+ }
+
+ /**
+ * Set the tokeniser state to skip to the end of the group.
+ * Sets the state to TOKENISER_SKIP_GROUP and skipGroupLevel to the current group level.
+ */
+ public void SetTokeniserStateSkipGroup() {
+ this.SetTokeniserState(TOKENISER_SKIP_GROUP);
+ this.skipGroupLevel = this.groupLevel;
+ }
+
+ /**
+ * Sets the number of bytes to skip and the state of the tokeniser.
+ *
+ * @param numberOfBytesToSkip
+ * The numbere of bytes to skip in the file.
+ */
+ public void SetTokeniserSkipBytes(long numberOfBytesToSkip) {
+ this.SetTokeniserState(TOKENISER_SKIP_BYTES);
+ this.binSkipByteCount = numberOfBytesToSkip;
+ }
+
+ /**
+ * Sets the number of binary bytes.
+ *
+ * @param binaryCount
+ * The number of binary bytes.
+ */
+ public void SetTokeniserStateBinary(int binaryCount) {
+ this.SetTokeniserState(TOKENISER_BINARY);
+ this.binByteCount = binaryCount;
+ }
+ /**
+ * Sets the number of binary bytes.
+ *
+ * @param binaryCount
+ * The number of binary bytes.
+ */
+ public void SetTokeniserStateBinary(long binaryCount) {
+ this.SetTokeniserState(TOKENISER_BINARY);
+ this.binByteCount = binaryCount;
+ }
+ /**
+ * Helper method to determin if conversion is TYPE_CONVERT
+ * @return true if TYPE_CONVERT, otherwise false
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_CONVERT
+ */
+ public bool IsConvert() {
+ return (this.GetConversionType() == RtfParser.TYPE_CONVERT);
+ }
+
+ /**
+ * Helper method to determin if conversion is TYPE_IMPORT_FULL or TYPE_IMPORT_FRAGMENT
+ * @return true if TYPE_CONVERT, otherwise false
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_IMPORT_FULL
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_IMPORT_FRAGMENT
+ */
+ public bool IsImport() {
+ return (IsImportFull() || this.IsImportFragment());
+ }
+ /**
+ * Helper method to determin if conversion is TYPE_IMPORT_FULL
+ * @return true if TYPE_CONVERT, otherwise false
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_IMPORT_FULL
+ */
+ public bool IsImportFull() {
+ return (this.GetConversionType() == RtfParser.TYPE_IMPORT_FULL);
+ }
+ /**
+ * Helper method to determin if conversion is TYPE_IMPORT_FRAGMENT
+ * @return true if TYPE_CONVERT, otherwise false
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_IMPORT_FRAGMENT
+ */
+ public bool IsImportFragment() {
+ return (this.GetConversionType() == RtfParser.TYPE_IMPORT_FRAGMENT);
+ }
+ /**
+ * Helper method to indicate if this control word was a \* control word.
+ * @return true if it was a \* control word, otherwise false
+ */
+ public bool GetExtendedDestination() {
+ return this.currentState.isExtendedDestination;
+ }
+ /**
+ * Helper method to set the extended control word flag.
+ * @param value Boolean to set the value to.
+ * @return isExtendedDestination.
+ */
+ public bool SetExtendedDestination(bool value) {
+ this.currentState.isExtendedDestination = value;
+ return this.currentState.isExtendedDestination;
+ }
+
+ /**
+ * Get the logfile name.
+ *
+ * @return the logFile
+ */
+ public String GetLogFile() {
+ return logFile;
+ }
+
+ /**
+ * Set the logFile name
+ *
+ * @param logFile the logFile to set
+ */
+ public void SetLogFile(String logFile) {
+ this.logFile = logFile;
+ }
+ /**
+ * Set the logFile name
+ *
+ * @param logFile the logFile to set
+ */
+ public void SetLogFile(String logFile, bool logAppend) {
+ this.logFile = logFile;
+ this.SetLogAppend(logAppend);
+ }
+
+ /**
+ * Get flag indicating if logging is on or off.
+ *
+ * @return the logging
+ */
+ public bool IsLogging() {
+ return logging;
+ }
+
+ /**
+ * Set flag indicating if logging is on or off
+ * @param logging true
to turn on logging, false
to turn off logging.
+ */
+ public void SetLogging(bool logging) {
+ this.logging = logging;
+ }
+
+ /**
+ * @return the logAppend
+ */
+ public bool IsLogAppend() {
+ return logAppend;
+ }
+
+ /**
+ * @param logAppend the logAppend to set
+ */
+ public void SetLogAppend(bool logAppend) {
+ this.logAppend = logAppend;
+ }
+
+ /*
+ * Statistics
+ *
+ public void PrintStats(PrintStream out) {
+ if (out == null) return;
+
+ out.Println("");
+ out.Println("Parser statistics:");
+ out.Println("Process start date: " + startDate.ToLocaleString());
+ out.Println("Process end date : " + endDate.ToLocaleString());
+ out.Println(" Elapsed time : " + Long.ToString(endTime - startTime) + " milliseconds.");
+ out.Println("Total bytes read : " + Long.ToString(byteCount));
+ out.Println("Open group count : " + Long.ToString(openGroupCount));
+ out.Print("Close group count : " + Long.ToString(closeGroupCount));
+ out.Println(" (Groups Skipped): " + Long.ToString(groupSkippedCount));
+ out.Print("Control word count: " + Long.ToString(ctrlWordCount));
+ out.Print(" - Handled: " + Long.ToString(ctrlWordHandledCount));
+ out.Print(" Not Handled: " + Long.ToString(ctrlWordNotHandledCount));
+ out.Println(" Skipped: " + Long.ToString(ctrlWordSkippedCount));
+ out.Println("Plain text char count: " + Long.ToString(characterCount));
+ }*/
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/RtfParserState.cs b/iTechSharp/iTextSharp/text/rtf/parser/RtfParserState.cs
new file mode 100644
index 0000000..a17745e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/RtfParserState.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections;
+using System.Text;
+using iTextSharp.text.rtf.parser.ctrlwords;
+using iTextSharp.text.rtf.parser.destinations;
+using iTextSharp.text.rtf.parser.properties;
+/*
+ * $Id: RtfParserState.cs,v 1.2 2008/05/13 11:25:58 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser {
+
+ /**
+ * The RtfParserState
contains the state information
+ * for the parser. The current state object is pushed/popped in a stack
+ * when a group change is made.
+ *
+ * When an open group is encountered, the current state is copied and
+ * then pushed on the top of the stack
+ * When a close group is encountered, the current state is overwritten with
+ * the popped value from the top of the stack
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public class RtfParserState {
+ /**
+ * The parser state.
+ */
+ public int parserState = RtfParser.PARSER_IN_UNKNOWN;
+ /**
+ * The tokeniser state.
+ */
+ public int tokeniserState = RtfParser.TOKENISER_STATE_IN_UNKOWN;
+ /**
+ * The control word set as the group handler.
+ */
+ public Object groupHandler = null;
+ /**
+ * The parsed value for the current group/control word.
+ */
+ public StringBuilder text = null;
+ /**
+ * Stack containing control word handlers. There could be multiple
+ * control words in a group.
+ */
+ public Stack ctrlWordHandlers = null;
+ /**
+ * The current control word handler.
+ */
+ public Object ctrlWordHandler = null;
+ /**
+ * The current destination.
+ */
+ public RtfDestination destination = null;
+ /**
+ * Flag indicating if this is an extended destination \* control word
+ */
+ public bool isExtendedDestination = false;
+ /**
+ * Flag to indicate if last token was an open group token '{'
+ */
+ public bool newGroup = false;
+
+ public RtfProperty properties = null;
+ /**
+ * Default constructor
+ *
+ */
+ public RtfParserState() {
+ this.text = new StringBuilder();
+ this.ctrlWordHandlers = new Stack();
+ this.properties = new RtfProperty();
+ this.destination = RtfDestinationNull.GetInstance();
+ this.newGroup = false;
+ }
+ /**
+ * Copy constructor
+ * @param orig The object to copy
+ */
+ public RtfParserState(RtfParserState orig) {
+ this.properties = orig.properties;
+ this.parserState = orig.parserState;
+ this.tokeniserState = orig.tokeniserState;
+ this.groupHandler = null;
+ this.destination = orig.destination;
+ this.text = new StringBuilder();
+ this.ctrlWordHandlers = new Stack();
+ this.destination = orig.destination;
+ this.newGroup = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/IRtfCtrlWordListener.cs b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/IRtfCtrlWordListener.cs
new file mode 100644
index 0000000..fcb100d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/IRtfCtrlWordListener.cs
@@ -0,0 +1,78 @@
+using System;
+using iTextSharp.text.rtf.parser;
+/*
+ * $Id: IRtfCtrlWordListener.cs,v 1.2 2008/05/13 11:25:58 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.ctrlwords {
+
+ /**
+ * RtfCtrlWordListener
interface for handling events.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ * @since 2.0.8
+ */
+ public interface IRtfCtrlWordListener : IEventListener {
+ /**
+ *
+ * @return null or modified copy of the ctrlWordData object
+ */
+ RtfCtrlWordData BeforeCtrlWord(RtfCtrlWordData ctrlWordData);
+ /**
+ *
+ * @return null or modified copy of the ctrlWordData object
+ */
+ RtfCtrlWordData OnCtrlWord(RtfCtrlWordData ctrlWordData);
+ /**
+ *
+ * @return null or modified copy of the ctrlWordData object
+ */
+ RtfCtrlWordData AfterCtrlWord(RtfCtrlWordData ctrlWordData);
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordData.cs b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordData.cs
new file mode 100644
index 0000000..0e5e68f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordData.cs
@@ -0,0 +1,132 @@
+using System;
+using iTextSharp.text.rtf.parser.properties;
+/* $Id: RtfCtrlWordData.cs,v 1.2 2008/05/13 11:25:58 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.parser.ctrlwords {
+
+ /**
+ * The control word and parameter information as parsed by the parser.
+ * Contains the control word,
+ * Flag indicating if there is a parameter.
+ * The parameter value as a string.
+ * Flag indicating the parameter is positive or negative.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public class RtfCtrlWordData {
+ public String prefix = "";
+ public String suffix = "";
+ /**
+ * The control word found by the parser
+ */
+ public String ctrlWord = "";
+ /**
+ * Flag indicating if this keyword has a parameter.
+ */
+ public bool hasParam = false;
+ /**
+ * The parameter for the control word.
+ */
+ public String param = "";
+ /**
+ * Flag indicating if parameter is positive or negative.
+ */
+ public bool isNeg = false;
+ /**
+ * Flag indicating a new group
+ */
+ public bool newGroup = false;
+ /**
+ * Flag indicating if this object has been modified.
+ */
+ public bool modified = false;
+
+ public int ctrlWordType = RtfCtrlWordType.UNIDENTIFIED;
+ public String specialHandler = "";
+
+ /**
+ * Return the parameter value as an integer (int) value.
+ *
+ * @return
+ * Returns the parameter value as an int vlaue.
+ */
+ public int IntValue() {
+ int value;
+ value = int.Parse(this.param);
+ if (this.isNeg) value = (-value);
+ return value;
+ }
+
+ /**
+ * Return the parameter value as a long value
+ *
+ * @return
+ * Returns the parameter value as a long value
+ */
+ public long LongValue() {
+ long value;
+ value = long.Parse(this.param);
+ if (this.isNeg) value = (-value);
+ return value;
+ }
+
+ public override String ToString() {
+ String outp = "";
+ outp = this.prefix + this.ctrlWord;
+ if (this.hasParam) {
+ if (this.isNeg) outp += "-";
+ outp += this.param;
+ }
+ outp += this.suffix;
+ return outp;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordHandler.cs b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordHandler.cs
new file mode 100644
index 0000000..0dc5a18
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordHandler.cs
@@ -0,0 +1,358 @@
+using System;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.destinations;
+using iTextSharp.text.rtf.parser.properties;
+using iTextSharp.text.rtf.direct;
+
+/* $Id: RtfCtrlWordHandler.cs,v 1.3 2008/05/13 11:25:58 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.ctrlwords {
+
+ /**
+ * RtfCtrlWordBase
is the base class for all
+ * control word handlers to extend from.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public class RtfCtrlWordHandler {
+ /**
+ * Debug flag - internal use
+ * @since 2.0.8
+ */
+ private static bool debug = false;
+
+ /**
+ * Local variable referencing the parser object.
+ * @since 2.0.8
+ */
+ protected RtfParser rtfParser = null;
+ /**
+ * The control word for this class.
+ * @since 2.0.8
+ */
+ protected String ctrlWord = "";
+ /**
+ * The default value for this control word.
+ * Not all control words use a default parameter value.
+ * @since 2.0.8
+ */
+ protected int defaultParameterValue = 0;
+ /**
+ * Does this control word use the default value?
+ * @since 2.0.8
+ */
+ protected bool passDefaultParameterValue = false;
+ /**
+ * Control Word type. Destination, toggle, value, etc.
+ * @since 2.0.8
+ */
+ protected int ctrlWordType = RtfCtrlWordType.UNIDENTIFIED;
+ /**
+ * Class, property, etc.
+ * @since 2.0.8
+ */
+ protected String specialHandler = "";
+ /**
+ * What version of the RTF spec the control word was introduced.
+ * @since 2.0.8
+ */
+ protected float rtfVersionSupported = -1.0f; // -1.0 unknown. Each class should override this as implemented.
+ /**
+ * The control word as parsed by the parser.
+ * @since 2.0.8
+ */
+ protected RtfCtrlWordData ctrlWordData = null;
+ /**
+ * String containing the value of "{" or "" (blank) depending on if this is the
+ * first control word in a group.
+ * @since 2.0.8
+ */
+ protected String groupPrefix = "";
+ /**
+ * The prefix for all control words.
+ * @since 2.0.8
+ */
+ protected String ctrlWordPrefix = "\\";
+ /**
+ * The prefix for all control words.
+ * @since 2.0.8
+ */
+ protected String ctrlWordSuffix = " ";
+
+ /**
+ * Constructor:
+ *
+ * @param rtfParser
+ * The parser for this control word.
+ * @param ctrlWord
+ * The string value of this control word.
+ * @param defaultParameterValue
+ * The default value of this control word. Not all control words have values.
+ * @param passDefaultParameterValue
+ * Flag indicating if this control word should use the default value.
+ * @param ctrlWordType
+ * Indicator of the type of control word this is. DESTINATION|DESTINATION_EX|VALUE|FLAG|TOGGLE|SYMBOL
+ * @param prefix
+ * String to prefix the ctrl word with. "\" or "\*\" are the 2 used values.
+ * @param suffix
+ * String to add as suffix to the ctrl word. " " and "" are the 2 used values.
+ * @param specialHandler
+ * If TOGGLE then the property name as String (propertyGroup.propertyName format ex. "character.bold")
+ * If FLAG then the property name as String (propertyGroup.propertyName format ex. "character.bold")
+ * If VALUE then the property name as String (propertyGroup.propertyName format ex. "character.bold")
+ * If SYMBOL then the character to use for substitution as String
+ * If DESTINATION|DESTINATION_EX then the RtfDestination class name as String
+ *
+ * @since 2.0.8
+ */
+ public RtfCtrlWordHandler(RtfParser rtfParser, String ctrlWord, int defaultParameterValue, bool passDefaultParameterValue,
+ int ctrlWordType, String prefix, String suffix, String specialHandler) {
+ this.rtfParser = rtfParser;
+ this.ctrlWord = ctrlWord;
+ this.defaultParameterValue = defaultParameterValue;
+ this.passDefaultParameterValue = passDefaultParameterValue;
+ this.ctrlWordType = ctrlWordType;
+ this.ctrlWordPrefix = prefix;
+ this.ctrlWordSuffix = suffix;
+ this.specialHandler = specialHandler;
+
+ if (this.ctrlWordType == RtfCtrlWordType.DESTINATION || this.ctrlWordType == RtfCtrlWordType.DESTINATION_EX){
+ if (this.specialHandler == null) {
+ this.specialHandler = "RtfDestinationNull";
+ }
+ String arg1 = ""; // stylesheet value - S, CS, TS
+ RtfDestinationMgr.AddDestination(this.ctrlWord, new Object[] { this.specialHandler, arg1 });
+ } else {
+ if (this.ctrlWordType == RtfCtrlWordType.SYMBOL){
+
+ } else {
+ if (this.specialHandler == null) {
+ this.specialHandler = this.ctrlWord; // if null, make the property the name of the ctrl word
+ } else {
+ if (this.specialHandler.Length > 1 && this.specialHandler.EndsWith(".")) {
+ this.specialHandler += this.ctrlWord; // if string length>1 and ends with a period, it's a group. Add ctrlWord
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * The primary control word handler method.
+ * Called by the parser once it has a control word and parameter if applicable.
+ *
+ * @param ctrlWordDataIn
+ * The control word and associated parameter if applicable.
+ * @return
+ * true
or false
if the control word was handled.
+ * @since 2.0.8
+ */
+ public bool HandleControlword(RtfCtrlWordData ctrlWordDataIn){
+ bool result = false;
+ this.ctrlWordData = ctrlWordDataIn;
+ RtfDestination dest = null;
+ bool handled = false;
+
+ this.ctrlWordData.prefix = this.ctrlWordPrefix;
+ this.ctrlWordData.suffix = this.ctrlWordSuffix;
+ this.ctrlWordData.newGroup = this.rtfParser.GetState().newGroup;
+ this.ctrlWordData.ctrlWordType = this.ctrlWordType;
+ this.ctrlWordData.specialHandler = this.specialHandler;
+
+ if (!this.ctrlWordData.hasParam && this.passDefaultParameterValue) {
+ this.ctrlWordData.hasParam = true;
+ this.ctrlWordData.param = this.defaultParameterValue.ToString();
+ }
+
+ if (debug) {
+ PrintDebug("handleKeyword: [" + this.ctrlWordData.ctrlWord + "] param=" + ctrlWordDataIn.param);
+ RtfParser.OutputDebug(this.rtfParser.GetRtfDocument(), this.rtfParser.GetLevel()+1, "RtfCtrlWordHandler debug Start: " + this.ctrlWordData.ctrlWord + " ");
+ }
+ if (this.ctrlWordData.ctrlWord.Equals("*")) {
+ return true;
+ }
+
+ if (!BeforeControlWord()) {
+ return true;
+ }
+
+ switch (this.ctrlWordType) {
+ case RtfCtrlWordType.FLAG:
+ case RtfCtrlWordType.TOGGLE:
+ case RtfCtrlWordType.VALUE:
+ dest = (RtfDestination)this.rtfParser.GetCurrentDestination();
+ if (dest != null) {
+ handled = dest.HandleControlWord(this.ctrlWordData);
+ }
+ break;
+
+ case RtfCtrlWordType.SYMBOL:
+ dest = (RtfDestination)this.rtfParser.GetCurrentDestination();
+ if (dest != null) {
+ String data = null;
+ // if doing an import, then put the control word in the output stream through the character handler
+ if (this.rtfParser.IsImport()) {
+ data = this.ctrlWordPrefix + this.ctrlWordData.ctrlWord + this.ctrlWordSuffix;
+ }
+ if (this.rtfParser.IsConvert()) {
+ data = this.specialHandler;
+ }
+
+ // If there is a substitute character, process the character.
+ // If no substitute character, then provide special handling in the destination for the ctrl word.
+ if (data != null) {
+ foreach (char cc in data.ToCharArray()) {
+ handled = dest.HandleCharacter((int)cc);
+ }
+ } else {
+ handled = dest.HandleControlWord(this.ctrlWordData);
+ }
+ }
+ break;
+
+ case RtfCtrlWordType.DESTINATION_EX:
+ case RtfCtrlWordType.DESTINATION:
+ // set the destination
+ int x=0;
+ if(this.ctrlWord == "shppict" || this.ctrlWord == "nonshppict") {
+ x++;
+ }
+ handled = this.rtfParser.SetCurrentDestination(this.ctrlWord);
+ // let destination handle the ctrl word now.
+ dest = (RtfDestination)this.rtfParser.GetCurrentDestination();
+ if(dest != null) {
+ if(dest.GetNewTokeniserState() == RtfParser.TOKENISER_IGNORE_RESULT) {
+ handled = dest.HandleControlWord(this.ctrlWordData);
+ }
+ else {
+ this.rtfParser.SetTokeniserState(dest.GetNewTokeniserState());
+ }
+ }
+ break;
+ }
+
+ AfterControlWord();
+
+ if (debug) {
+ RtfParser.OutputDebug(this.rtfParser.GetRtfDocument(), this.rtfParser.GetLevel()+1, "RtfCtrlWordHandler debug End: " + this.ctrlWordData.ctrlWord + " ");
+ }
+
+ return result;
+ }
+
+ /**
+ * Pre-processing before the control word.
+ *
+ * If return value is true, no further processing will be performed on
+ * this control word.
+ *
+ * @return false
= stop processing, true
= continue processing
+ * @since 2.0.8
+ */
+ //Primary purpose is for \* control word and event handling.
+ protected bool BeforeControlWord() {
+ if (debug) PrintDebug("beforeControlWord");
+ // TODO: This is where events would be triggered
+ return true;
+ }
+ /**
+ * Handle the control word.
+ *
+ * @return true
if control word was handled, false
if it was not handled.
+ * @since 2.0.8
+ */
+ protected bool OnControlWord() {
+ if (debug) PrintDebug("onCtrlWord");
+ // TODO: This is where events would be triggered
+ return false;
+ }
+ /**
+ * Post-processing after the control word.
+ *
+ * @return false
= stop processing, true
= continue processing
+ * @since 2.0.8
+ */
+ protected bool AfterControlWord() {
+ if (debug) PrintDebug("afterControlWord");
+ // TODO: This is where events would be triggered
+ return true;
+ }
+
+ // public String CtrlWordString() {
+ // //String out = ctrlWordPrefix + this.ctrlWord;
+ // String out = "";
+ // if (this.bExtendedDestination) {
+ // out += "\\*";
+ // }
+ // out = ctrlWordPrefix + this.ctrlWordData.ctrlWord;
+ // if (this.ctrlWordData.hasParam) {
+ // if (this.ctrlWordData.isNeg) out += "-";
+ // out += this.ctrlWordData.param;
+ // } else {
+ // if (this.passDefaultParameterValue == true) {
+ // out += Integer.ToString(this.defaultParameterValue);
+ // }
+ // }
+ // out += this.ctrlWordSuffix;
+ // return out;
+ // }
+
+ /**
+ * Debug function to print class/method
+ * @param txt The String
to output.
+ * @since 2.0.8
+ */
+ private void PrintDebug(String txt) {
+ Console.Out.WriteLine(this.GetType().Name + " : " + txt);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordMap.cs b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordMap.cs
new file mode 100644
index 0000000..c729f56
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordMap.cs
@@ -0,0 +1,1903 @@
+using System;
+using System.Collections;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.properties;
+/*
+ * $Id: RtfCtrlWordMap.cs,v 1.2 2008/05/13 11:25:59 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.ctrlwords {
+
+ /**
+ * RtfCtrlWords
handles the creation of the control word wiring.
+ * It is a class containing the hash map of the control words (key)
+ * and their associated class (value).
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ internal sealed class RtfCtrlWordMap {
+
+ // 1810 control words in Spec v1.9. might be a few more for other apps that implement
+ // additional control words such as exchange, outlook, etc.
+ // 1810/.9(loadfactor) = 2011.111111...
+ // set approximate initial size to initial count / load factor.
+ // Hashtable default size is 16. Load Factor .75
+ /**
+ * Control Word Hashtable mapping object.
+ */
+ private Hashtable ctrlWords = new Hashtable(2012, 0.9f);
+
+ /**
+ * Get the Hashtable object containing the control words.
+ * Initializes the instance if this is the first instantiation
+ * of RtfCtrlWords class.
+ * @since 2.0.8
+ */
+ public RtfCtrlWordHandler GetCtrlWordHandler(String ctrlWord) {
+ try {
+ if (ctrlWords.ContainsKey(ctrlWord)) {
+ // add 1 to known control words
+ return (RtfCtrlWordHandler)ctrlWords[ctrlWord];
+ } else {
+ // add 1 to unknown control words
+ return (RtfCtrlWordHandler)ctrlWords["unknown"];
+ }
+ } catch {
+ }
+ return null;
+ }
+
+ /**
+ * Constructor
+ * @param rtfParser The parser object.
+ * @since 2.0.8
+ */
+ public RtfCtrlWordMap(RtfParser rtfParser) {
+ /*
+ * Parameters:
+ * RtfParser rtfParser
+ * String ctrlWord
+ * int defaultParameterValue
+ * bool passDefaultParameterValue
+ * RtfCtrlWordType ctrlWordType
+ * String prefix
+ * String suffix
+ * String specialHandler =
+ * If TOGGLE then the property name as String
+ * If FLAG then the property name as String
+ * If VALUE then the property name as String
+ * If SYMBOL then the character to use for substitution as String
+ * If DESTINATION|DESTINATION_EX then the RtfDestination class name as String
+ */
+ //starwriter
+ ctrlWords["aftnnrlc"] = new RtfCtrlWordHandler(rtfParser, "aftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgdsctbl"] = new RtfCtrlWordHandler(rtfParser, "pgdsctbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["pgdsc"] = new RtfCtrlWordHandler(rtfParser, "pgdsc", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgdscuse"] = new RtfCtrlWordHandler(rtfParser, "pgdscuse", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgdscnxt"] = new RtfCtrlWordHandler(rtfParser, "pgdscnxt", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgdscno"] = new RtfCtrlWordHandler(rtfParser, "pgdsctbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+
+ //office
+ ctrlWords["'"] = new RtfCtrlWordHandler(rtfParser, "'", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "'");
+ ctrlWords["*"] = new RtfCtrlWordHandler(rtfParser, "*", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "*");
+ ctrlWords["-"] = new RtfCtrlWordHandler(rtfParser, "-", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "-");
+ ctrlWords[":"] = new RtfCtrlWordHandler(rtfParser, ":", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", ":");
+ ctrlWords["ApplyBrkRules"] = new RtfCtrlWordHandler(rtfParser, "ApplyBrkRules", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);// "ApplyBrkRules",
+ ctrlWords["\\"] = new RtfCtrlWordHandler(rtfParser, "\\", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "\\");
+ ctrlWords["_"] = new RtfCtrlWordHandler(rtfParser, "_", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "_");
+ ctrlWords["ab"] = new RtfCtrlWordHandler(rtfParser, "ab", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);//"ab",
+ ctrlWords["absh"] = new RtfCtrlWordHandler(rtfParser, "absh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);//"absh",
+ ctrlWords["abslock"] = new RtfCtrlWordHandler(rtfParser, "abslock", 0, false, RtfCtrlWordType.FLAG, "", " ", null);//"abslock",
+ ctrlWords["absnoovrlp"] = new RtfCtrlWordHandler(rtfParser, "absnoovrlp", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);//"absnoovrlp",
+ ctrlWords["absw"] = new RtfCtrlWordHandler(rtfParser, "absw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);//"absw",
+ ctrlWords["acaps"] = new RtfCtrlWordHandler(rtfParser, "acaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);//"acaps",
+ ctrlWords["acccircle"] = new RtfCtrlWordHandler(rtfParser, "acccircle", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);//"acccircle",
+ ctrlWords["acccomma"] = new RtfCtrlWordHandler(rtfParser, "acccomma", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["accdot"] = new RtfCtrlWordHandler(rtfParser, "accdot", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["accnone"] = new RtfCtrlWordHandler(rtfParser, "accnone", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["accunderdot"] = new RtfCtrlWordHandler(rtfParser, "accunderdot", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["acf"] = new RtfCtrlWordHandler(rtfParser, "acf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["additive"] = new RtfCtrlWordHandler(rtfParser, "additive", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["adeflang"] = new RtfCtrlWordHandler(rtfParser, "adeflang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["adjustright"] = new RtfCtrlWordHandler(rtfParser, "adjustright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["adn"] = new RtfCtrlWordHandler(rtfParser, "adn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["aenddoc"] = new RtfCtrlWordHandler(rtfParser, "aenddoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aendnotes"] = new RtfCtrlWordHandler(rtfParser, "aendnotes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aexpnd"] = new RtfCtrlWordHandler(rtfParser, "aexpnd", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["af"] = new RtfCtrlWordHandler(rtfParser, "af", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["afelev"] = new RtfCtrlWordHandler(rtfParser, "afelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["affixed"] = new RtfCtrlWordHandler(rtfParser, "affixed", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["afs"] = new RtfCtrlWordHandler(rtfParser, "afs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["aftnbj"] = new RtfCtrlWordHandler(rtfParser, "aftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftncn"] = new RtfCtrlWordHandler(rtfParser, "aftncn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["aftnnalc"] = new RtfCtrlWordHandler(rtfParser, "aftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnar"] = new RtfCtrlWordHandler(rtfParser, "aftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnauc"] = new RtfCtrlWordHandler(rtfParser, "aftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnchi"] = new RtfCtrlWordHandler(rtfParser, "aftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnchosung"] = new RtfCtrlWordHandler(rtfParser, "aftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnncnum"] = new RtfCtrlWordHandler(rtfParser, "aftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnndbar"] = new RtfCtrlWordHandler(rtfParser, "aftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnndbnum"] = new RtfCtrlWordHandler(rtfParser, "aftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnndbnumd"] = new RtfCtrlWordHandler(rtfParser, "aftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnndbnumk"] = new RtfCtrlWordHandler(rtfParser, "aftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnndbnumt"] = new RtfCtrlWordHandler(rtfParser, "aftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnganada"] = new RtfCtrlWordHandler(rtfParser, "aftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnngbnum"] = new RtfCtrlWordHandler(rtfParser, "aftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnngbnumd"] = new RtfCtrlWordHandler(rtfParser, "aftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnngbnumk"] = new RtfCtrlWordHandler(rtfParser, "aftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnngbnuml"] = new RtfCtrlWordHandler(rtfParser, "aftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnrlc"] = new RtfCtrlWordHandler(rtfParser, "aftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnruc"] = new RtfCtrlWordHandler(rtfParser, "aftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnzodiac"] = new RtfCtrlWordHandler(rtfParser, "aftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnzodiacd"] = new RtfCtrlWordHandler(rtfParser, "aftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnnzodiacl"] = new RtfCtrlWordHandler(rtfParser, "aftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnrestart"] = new RtfCtrlWordHandler(rtfParser, "aftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnrstcont"] = new RtfCtrlWordHandler(rtfParser, "aftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aftnsep"] = new RtfCtrlWordHandler(rtfParser, "aftnsep", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["aftnsepc"] = new RtfCtrlWordHandler(rtfParser, "aftnsepc", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["aftnstart"] = new RtfCtrlWordHandler(rtfParser, "aftnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["aftntj"] = new RtfCtrlWordHandler(rtfParser, "aftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ai"] = new RtfCtrlWordHandler(rtfParser, "ai", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["alang"] = new RtfCtrlWordHandler(rtfParser, "alang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["allowfieldendsel"] = new RtfCtrlWordHandler(rtfParser, "allowfieldendsel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["allprot"] = new RtfCtrlWordHandler(rtfParser, "allprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["alntblind"] = new RtfCtrlWordHandler(rtfParser, "alntblind", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["alt"] = new RtfCtrlWordHandler(rtfParser, "alt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["animtext"] = new RtfCtrlWordHandler(rtfParser, "animtext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["annotation"] = new RtfCtrlWordHandler(rtfParser, "annotation", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["annotprot"] = new RtfCtrlWordHandler(rtfParser, "annotprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ansi"] = new RtfCtrlWordHandler(rtfParser, "ansi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ansicpg"] = new RtfCtrlWordHandler(rtfParser, "ansicpg", 1252, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["aoutl"] = new RtfCtrlWordHandler(rtfParser, "aoutl", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ascaps"] = new RtfCtrlWordHandler(rtfParser, "ascaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ashad"] = new RtfCtrlWordHandler(rtfParser, "ashad", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["asianbrkrule"] = new RtfCtrlWordHandler(rtfParser, "asianbrkrule", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["aspalpha"] = new RtfCtrlWordHandler(rtfParser, "aspalpha", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["aspnum"] = new RtfCtrlWordHandler(rtfParser, "aspnum", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["astrike"] = new RtfCtrlWordHandler(rtfParser, "astrike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["atnauthor"] = new RtfCtrlWordHandler(rtfParser, "atnauthor", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["atndate"] = new RtfCtrlWordHandler(rtfParser, "atndate", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["atnicn"] = new RtfCtrlWordHandler(rtfParser, "atnicn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["atnid"] = new RtfCtrlWordHandler(rtfParser, "atnid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["atnparent"] = new RtfCtrlWordHandler(rtfParser, "atnparent", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["atnref"] = new RtfCtrlWordHandler(rtfParser, "atnref", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["atntime"] = new RtfCtrlWordHandler(rtfParser, "atntime", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["atrfend"] = new RtfCtrlWordHandler(rtfParser, "atrfend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["atrfstart"] = new RtfCtrlWordHandler(rtfParser, "atrfstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["aul"] = new RtfCtrlWordHandler(rtfParser, "aul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["auld"] = new RtfCtrlWordHandler(rtfParser, "auld", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["auldb"] = new RtfCtrlWordHandler(rtfParser, "auldb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["aulnone"] = new RtfCtrlWordHandler(rtfParser, "aulnone", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["aulw"] = new RtfCtrlWordHandler(rtfParser, "aulw", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["aup"] = new RtfCtrlWordHandler(rtfParser, "aup", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["author"] = new RtfCtrlWordHandler(rtfParser, "author", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["autofmtoverride"] = new RtfCtrlWordHandler(rtfParser, "autofmtoverride", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["b"] = new RtfCtrlWordHandler(rtfParser, "b", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", RtfProperty.CHARACTER_BOLD);
+ ctrlWords["background"] = new RtfCtrlWordHandler(rtfParser, "background", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["bdbfhdr"] = new RtfCtrlWordHandler(rtfParser, "bdbfhdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bdrrlswsix"] = new RtfCtrlWordHandler(rtfParser, "bdrrlswsix", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgbdiag"] = new RtfCtrlWordHandler(rtfParser, "bgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgcross"] = new RtfCtrlWordHandler(rtfParser, "bgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgdcross"] = new RtfCtrlWordHandler(rtfParser, "bgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgdkbdiag"] = new RtfCtrlWordHandler(rtfParser, "bgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgdkcross"] = new RtfCtrlWordHandler(rtfParser, "bgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgdkdcross"] = new RtfCtrlWordHandler(rtfParser, "bgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgdkfdiag"] = new RtfCtrlWordHandler(rtfParser, "bgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgdkhoriz"] = new RtfCtrlWordHandler(rtfParser, "bgdkhoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgdkvert"] = new RtfCtrlWordHandler(rtfParser, "bgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgfdiag"] = new RtfCtrlWordHandler(rtfParser, "bgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bghoriz"] = new RtfCtrlWordHandler(rtfParser, "bghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bgvert"] = new RtfCtrlWordHandler(rtfParser, "bgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bin"] = new RtfCtrlWordHandler(rtfParser, "bin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["binfsxn"] = new RtfCtrlWordHandler(rtfParser, "binfsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["binsxn"] = new RtfCtrlWordHandler(rtfParser, "binsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["bkmkcolf"] = new RtfCtrlWordHandler(rtfParser, "bkmkcolf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["bkmkcoll"] = new RtfCtrlWordHandler(rtfParser, "bkmkcoll", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["bkmkend"] = new RtfCtrlWordHandler(rtfParser, "bkmkend", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["bkmkpub"] = new RtfCtrlWordHandler(rtfParser, "bkmkpub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bkmkstart"] = new RtfCtrlWordHandler(rtfParser, "bkmkstart", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["bliptag"] = new RtfCtrlWordHandler(rtfParser, "bliptag", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["blipuid"] = new RtfCtrlWordHandler(rtfParser, "blipuid", 0, false, RtfCtrlWordType.VALUE, "\\*\\", " ", "RtfDestinationShppict");//"RtfDestinationBlipuid";
+ ctrlWords["blipupi"] = new RtfCtrlWordHandler(rtfParser, "blipupi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", "RtfDestinationShppict");
+ ctrlWords["blue"] = new RtfCtrlWordHandler(rtfParser, "blue", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["bookfold"] = new RtfCtrlWordHandler(rtfParser, "bookfold", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bookfoldrev"] = new RtfCtrlWordHandler(rtfParser, "bookfoldrev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["bookfoldsheets"] = new RtfCtrlWordHandler(rtfParser, "bookfoldsheets", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["box"] = new RtfCtrlWordHandler(rtfParser, "box", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrart"] = new RtfCtrlWordHandler(rtfParser, "brdrart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["brdrb"] = new RtfCtrlWordHandler(rtfParser, "brdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrbar"] = new RtfCtrlWordHandler(rtfParser, "brdrbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrbtw"] = new RtfCtrlWordHandler(rtfParser, "brdrbtw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrcf"] = new RtfCtrlWordHandler(rtfParser, "brdrcf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["brdrdash"] = new RtfCtrlWordHandler(rtfParser, "brdrdash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrdashd"] = new RtfCtrlWordHandler(rtfParser, "brdrdashd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrdashdd"] = new RtfCtrlWordHandler(rtfParser, "brdrdashdd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrdashdotstr"] = new RtfCtrlWordHandler(rtfParser, "brdrdashdotstr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrdashsm"] = new RtfCtrlWordHandler(rtfParser, "brdrdashsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrdb"] = new RtfCtrlWordHandler(rtfParser, "brdrdb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrdot"] = new RtfCtrlWordHandler(rtfParser, "brdrdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdremboss"] = new RtfCtrlWordHandler(rtfParser, "brdremboss", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrengrave"] = new RtfCtrlWordHandler(rtfParser, "brdrengrave", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrframe"] = new RtfCtrlWordHandler(rtfParser, "brdrframe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrhair"] = new RtfCtrlWordHandler(rtfParser, "brdrhair", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrinset"] = new RtfCtrlWordHandler(rtfParser, "brdrinset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrl"] = new RtfCtrlWordHandler(rtfParser, "brdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrnil"] = new RtfCtrlWordHandler(rtfParser, "brdrnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrnone"] = new RtfCtrlWordHandler(rtfParser, "brdrnone", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["brdroutset"] = new RtfCtrlWordHandler(rtfParser, "brdroutset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrr"] = new RtfCtrlWordHandler(rtfParser, "brdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrs"] = new RtfCtrlWordHandler(rtfParser, "brdrs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrsh"] = new RtfCtrlWordHandler(rtfParser, "brdrsh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrt"] = new RtfCtrlWordHandler(rtfParser, "brdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrtbl"] = new RtfCtrlWordHandler(rtfParser, "brdrtbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrth"] = new RtfCtrlWordHandler(rtfParser, "brdrth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrthtnlg"] = new RtfCtrlWordHandler(rtfParser, "brdrthtnlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrthtnmg"] = new RtfCtrlWordHandler(rtfParser, "brdrthtnmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrthtnsg"] = new RtfCtrlWordHandler(rtfParser, "brdrthtnsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrtnthlg"] = new RtfCtrlWordHandler(rtfParser, "brdrtnthlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrtnthmg"] = new RtfCtrlWordHandler(rtfParser, "brdrtnthmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrtnthsg"] = new RtfCtrlWordHandler(rtfParser, "brdrtnthsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrtnthtnlg"] = new RtfCtrlWordHandler(rtfParser, "brdrtnthtnlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrtnthtnmg"] = new RtfCtrlWordHandler(rtfParser, "brdrtnthtnmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrtnthtnsg"] = new RtfCtrlWordHandler(rtfParser, "brdrtnthtnsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrtriple"] = new RtfCtrlWordHandler(rtfParser, "brdrtriple", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrw"] = new RtfCtrlWordHandler(rtfParser, "brdrw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["brdrwavy"] = new RtfCtrlWordHandler(rtfParser, "brdrwavy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brdrwavydb"] = new RtfCtrlWordHandler(rtfParser, "brdrwavydb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brkfrm"] = new RtfCtrlWordHandler(rtfParser, "brkfrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["brsp"] = new RtfCtrlWordHandler(rtfParser, "brsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["bullet"] = new RtfCtrlWordHandler(rtfParser, "bullet", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x149");
+ ctrlWords["buptim"] = new RtfCtrlWordHandler(rtfParser, "buptim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["bxe"] = new RtfCtrlWordHandler(rtfParser, "bxe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["caccentfive"] = new RtfCtrlWordHandler(rtfParser, "caccentfive", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["caccentfour"] = new RtfCtrlWordHandler(rtfParser, "caccentfour", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["caccentone"] = new RtfCtrlWordHandler(rtfParser, "caccentone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["caccentsix"] = new RtfCtrlWordHandler(rtfParser, "caccentsix", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["caccentthree"] = new RtfCtrlWordHandler(rtfParser, "caccentthree", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["caccenttwo"] = new RtfCtrlWordHandler(rtfParser, "caccenttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cachedcolbal"] = new RtfCtrlWordHandler(rtfParser, "cachedcolbal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["caps"] = new RtfCtrlWordHandler(rtfParser, "caps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["category"] = new RtfCtrlWordHandler(rtfParser, "category", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["cb"] = new RtfCtrlWordHandler(rtfParser, "cb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cbackgroundone"] = new RtfCtrlWordHandler(rtfParser, "cbackgroundone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cbackgroundtwo"] = new RtfCtrlWordHandler(rtfParser, "cbackgroundtwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cbpat"] = new RtfCtrlWordHandler(rtfParser, "cbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cchs"] = new RtfCtrlWordHandler(rtfParser, "cchs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cell"] = new RtfCtrlWordHandler(rtfParser, "cell", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["cellx"] = new RtfCtrlWordHandler(rtfParser, "cellx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cf"] = new RtfCtrlWordHandler(rtfParser, "cf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cfollowedhyperlink"] = new RtfCtrlWordHandler(rtfParser, "cfollowedhyperlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cfpat"] = new RtfCtrlWordHandler(rtfParser, "cfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cgrid"] = new RtfCtrlWordHandler(rtfParser, "cgrid", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["charrsid"] = new RtfCtrlWordHandler(rtfParser, "charrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["charscalex"] = new RtfCtrlWordHandler(rtfParser, "charscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["chatn"] = new RtfCtrlWordHandler(rtfParser, "chatn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chbgbdiag"] = new RtfCtrlWordHandler(rtfParser, "chbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgcross"] = new RtfCtrlWordHandler(rtfParser, "chbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgdcross"] = new RtfCtrlWordHandler(rtfParser, "chbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgdkbdiag"] = new RtfCtrlWordHandler(rtfParser, "chbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgdkcross"] = new RtfCtrlWordHandler(rtfParser, "chbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgdkdcross"] = new RtfCtrlWordHandler(rtfParser, "chbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgdkfdiag"] = new RtfCtrlWordHandler(rtfParser, "chbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgdkhoriz"] = new RtfCtrlWordHandler(rtfParser, "chbgdkhoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgdkvert"] = new RtfCtrlWordHandler(rtfParser, "chbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgfdiag"] = new RtfCtrlWordHandler(rtfParser, "chbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbghoriz"] = new RtfCtrlWordHandler(rtfParser, "chbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbgvert"] = new RtfCtrlWordHandler(rtfParser, "chbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chbrdr"] = new RtfCtrlWordHandler(rtfParser, "chbrdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["chcbpat"] = new RtfCtrlWordHandler(rtfParser, "chcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["chcfpat"] = new RtfCtrlWordHandler(rtfParser, "chcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["chdate"] = new RtfCtrlWordHandler(rtfParser, "chdate", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chdpa"] = new RtfCtrlWordHandler(rtfParser, "chdpa", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chdpl"] = new RtfCtrlWordHandler(rtfParser, "chdpl", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chftn"] = new RtfCtrlWordHandler(rtfParser, "chftn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chftnsep"] = new RtfCtrlWordHandler(rtfParser, "chftnsep", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chftnsepc"] = new RtfCtrlWordHandler(rtfParser, "chftnsepc", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chpgn"] = new RtfCtrlWordHandler(rtfParser, "chpgn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chshdng"] = new RtfCtrlWordHandler(rtfParser, "chshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["chtime"] = new RtfCtrlWordHandler(rtfParser, "chtime", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["chyperlink"] = new RtfCtrlWordHandler(rtfParser, "chyperlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clFitText"] = new RtfCtrlWordHandler(rtfParser, "clFitText", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clNoWrap"] = new RtfCtrlWordHandler(rtfParser, "clNoWrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgbdiag"] = new RtfCtrlWordHandler(rtfParser, "clbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgcross"] = new RtfCtrlWordHandler(rtfParser, "clbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgdcross"] = new RtfCtrlWordHandler(rtfParser, "clbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgdkbdiag"] = new RtfCtrlWordHandler(rtfParser, "clbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgdkcross"] = new RtfCtrlWordHandler(rtfParser, "clbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgdkdcross"] = new RtfCtrlWordHandler(rtfParser, "clbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgdkfdiag"] = new RtfCtrlWordHandler(rtfParser, "clbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgdkhor"] = new RtfCtrlWordHandler(rtfParser, "clbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgdkvert"] = new RtfCtrlWordHandler(rtfParser, "clbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgfdiag"] = new RtfCtrlWordHandler(rtfParser, "clbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbghoriz"] = new RtfCtrlWordHandler(rtfParser, "clbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbgvert"] = new RtfCtrlWordHandler(rtfParser, "clbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbrdrb"] = new RtfCtrlWordHandler(rtfParser, "clbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbrdrl"] = new RtfCtrlWordHandler(rtfParser, "clbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbrdrr"] = new RtfCtrlWordHandler(rtfParser, "clbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clbrdrt"] = new RtfCtrlWordHandler(rtfParser, "clbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clcbpat"] = new RtfCtrlWordHandler(rtfParser, "clcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clcbpatraw"] = new RtfCtrlWordHandler(rtfParser, "clcbpatraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clcfpat"] = new RtfCtrlWordHandler(rtfParser, "clcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clcfpatraw"] = new RtfCtrlWordHandler(rtfParser, "clcfpatraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cldel"] = new RtfCtrlWordHandler(rtfParser, "cldel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cldelauth"] = new RtfCtrlWordHandler(rtfParser, "cldelauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cldeldttm"] = new RtfCtrlWordHandler(rtfParser, "cldeldttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cldgll"] = new RtfCtrlWordHandler(rtfParser, "cldgll", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cldglu"] = new RtfCtrlWordHandler(rtfParser, "cldglu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clftsWidth"] = new RtfCtrlWordHandler(rtfParser, "clftsWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clhidemark"] = new RtfCtrlWordHandler(rtfParser, "clhidemark", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clins"] = new RtfCtrlWordHandler(rtfParser, "clins", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clinsauth"] = new RtfCtrlWordHandler(rtfParser, "clinsauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clinsdttm"] = new RtfCtrlWordHandler(rtfParser, "clinsdttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clmgf"] = new RtfCtrlWordHandler(rtfParser, "clmgf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clmrg"] = new RtfCtrlWordHandler(rtfParser, "clmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clmrgd"] = new RtfCtrlWordHandler(rtfParser, "clmrgd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clmrgdauth"] = new RtfCtrlWordHandler(rtfParser, "clmrgdauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clmrgddttm"] = new RtfCtrlWordHandler(rtfParser, "clmrgddttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clmrgdr"] = new RtfCtrlWordHandler(rtfParser, "clmrgdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clpadb"] = new RtfCtrlWordHandler(rtfParser, "clpadb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clpadfb"] = new RtfCtrlWordHandler(rtfParser, "clpadfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clpadfl"] = new RtfCtrlWordHandler(rtfParser, "clpadfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clpadfr"] = new RtfCtrlWordHandler(rtfParser, "clpadfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clpadft"] = new RtfCtrlWordHandler(rtfParser, "clpadft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clpadl"] = new RtfCtrlWordHandler(rtfParser, "clpadl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clpadr"] = new RtfCtrlWordHandler(rtfParser, "clpadr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clpadt"] = new RtfCtrlWordHandler(rtfParser, "clpadt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clshdng"] = new RtfCtrlWordHandler(rtfParser, "clshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clshdngraw"] = new RtfCtrlWordHandler(rtfParser, "clshdngraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["clshdrawnil"] = new RtfCtrlWordHandler(rtfParser, "clshdrawnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clsplit"] = new RtfCtrlWordHandler(rtfParser, "clsplit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clsplitr"] = new RtfCtrlWordHandler(rtfParser, "clsplitr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cltxbtlr"] = new RtfCtrlWordHandler(rtfParser, "cltxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cltxlrtb"] = new RtfCtrlWordHandler(rtfParser, "cltxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cltxlrtbv"] = new RtfCtrlWordHandler(rtfParser, "cltxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cltxtbrl"] = new RtfCtrlWordHandler(rtfParser, "cltxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cltxtbrlv"] = new RtfCtrlWordHandler(rtfParser, "cltxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clvertalb"] = new RtfCtrlWordHandler(rtfParser, "clvertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clvertalc"] = new RtfCtrlWordHandler(rtfParser, "clvertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clvertalt"] = new RtfCtrlWordHandler(rtfParser, "clvertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clvmgf"] = new RtfCtrlWordHandler(rtfParser, "clvmgf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clvmrg"] = new RtfCtrlWordHandler(rtfParser, "clvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["clwWidth"] = new RtfCtrlWordHandler(rtfParser, "clwWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cmaindarkone"] = new RtfCtrlWordHandler(rtfParser, "cmaindarkone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cmaindarktwo"] = new RtfCtrlWordHandler(rtfParser, "cmaindarktwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cmainlightone"] = new RtfCtrlWordHandler(rtfParser, "cmainlightone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cmainlighttwo"] = new RtfCtrlWordHandler(rtfParser, "cmainlighttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["collapsed"] = new RtfCtrlWordHandler(rtfParser, "collapsed", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["colno"] = new RtfCtrlWordHandler(rtfParser, "colno", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["colorschememapping"] = new RtfCtrlWordHandler(rtfParser, "colorschememapping", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null);
+ ctrlWords["colortbl"] = new RtfCtrlWordHandler(rtfParser, "colortbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationColorTable");
+ ctrlWords["cols"] = new RtfCtrlWordHandler(rtfParser, "cols", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["colsr"] = new RtfCtrlWordHandler(rtfParser, "colsr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["colsx"] = new RtfCtrlWordHandler(rtfParser, "colsx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["column"] = new RtfCtrlWordHandler(rtfParser, "column", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["colw"] = new RtfCtrlWordHandler(rtfParser, "colw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["comment"] = new RtfCtrlWordHandler(rtfParser, "comment", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["company"] = new RtfCtrlWordHandler(rtfParser, "company", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["contextualspace"] = new RtfCtrlWordHandler(rtfParser, "contextualspace", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cpg"] = new RtfCtrlWordHandler(rtfParser, "cpg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["crauth"] = new RtfCtrlWordHandler(rtfParser, "crauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["crdate"] = new RtfCtrlWordHandler(rtfParser, "crdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["creatim"] = new RtfCtrlWordHandler(rtfParser, "creatim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["cs"] = new RtfCtrlWordHandler(rtfParser, "cs", 0, true, RtfCtrlWordType.VALUE, "\\*\\", " ", null);
+ ctrlWords["cshade"] = new RtfCtrlWordHandler(rtfParser, "cshade", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ctextone"] = new RtfCtrlWordHandler(rtfParser, "ctextone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ctexttwo"] = new RtfCtrlWordHandler(rtfParser, "ctexttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ctint"] = new RtfCtrlWordHandler(rtfParser, "ctint", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ctrl"] = new RtfCtrlWordHandler(rtfParser, "ctrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["cts"] = new RtfCtrlWordHandler(rtfParser, "cts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cufi"] = new RtfCtrlWordHandler(rtfParser, "cufi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["culi"] = new RtfCtrlWordHandler(rtfParser, "culi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["curi"] = new RtfCtrlWordHandler(rtfParser, "curi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["cvmme"] = new RtfCtrlWordHandler(rtfParser, "cvmme", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["datafield"] = new RtfCtrlWordHandler(rtfParser, "datafield", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["datastore"] = new RtfCtrlWordHandler(rtfParser, "datastore", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["date"] = new RtfCtrlWordHandler(rtfParser, "date", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dbch"] = new RtfCtrlWordHandler(rtfParser, "dbch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["defchp"] = new RtfCtrlWordHandler(rtfParser, "defchp", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["deff"] = new RtfCtrlWordHandler(rtfParser, "deff", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["defformat"] = new RtfCtrlWordHandler(rtfParser, "defformat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["deflang"] = new RtfCtrlWordHandler(rtfParser, "deflang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["deflangfe"] = new RtfCtrlWordHandler(rtfParser, "deflangfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["defpap"] = new RtfCtrlWordHandler(rtfParser, "defpap", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["defshp"] = new RtfCtrlWordHandler(rtfParser, "defshp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["deftab"] = new RtfCtrlWordHandler(rtfParser, "deftab", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["deleted"] = new RtfCtrlWordHandler(rtfParser, "deleted", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["delrsid"] = new RtfCtrlWordHandler(rtfParser, "delrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dfrauth"] = new RtfCtrlWordHandler(rtfParser, "dfrauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dfrdate"] = new RtfCtrlWordHandler(rtfParser, "dfrdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dfrmtxtx"] = new RtfCtrlWordHandler(rtfParser, "dfrmtxtx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dfrmtxty"] = new RtfCtrlWordHandler(rtfParser, "dfrmtxty", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dfrstart"] = new RtfCtrlWordHandler(rtfParser, "dfrstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dfrstop"] = new RtfCtrlWordHandler(rtfParser, "dfrstop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dfrxst"] = new RtfCtrlWordHandler(rtfParser, "dfrxst", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dghorigin"] = new RtfCtrlWordHandler(rtfParser, "dghorigin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dghshow"] = new RtfCtrlWordHandler(rtfParser, "dghshow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dghspace"] = new RtfCtrlWordHandler(rtfParser, "dghspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dgmargin"] = new RtfCtrlWordHandler(rtfParser, "dgmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dgsnap"] = new RtfCtrlWordHandler(rtfParser, "dgsnap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dgvorigin"] = new RtfCtrlWordHandler(rtfParser, "dgvorigin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dgvshow"] = new RtfCtrlWordHandler(rtfParser, "dgvshow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dgvspace"] = new RtfCtrlWordHandler(rtfParser, "dgvspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dibitmap"] = new RtfCtrlWordHandler(rtfParser, "dibitmap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dn"] = new RtfCtrlWordHandler(rtfParser, "dn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dntblnsbdb"] = new RtfCtrlWordHandler(rtfParser, "dntblnsbdb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["do"] = new RtfCtrlWordHandler(rtfParser, "do", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["dobxcolumn"] = new RtfCtrlWordHandler(rtfParser, "dobxcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dobxmargin"] = new RtfCtrlWordHandler(rtfParser, "dobxmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dobxpage"] = new RtfCtrlWordHandler(rtfParser, "dobxpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dobymargin"] = new RtfCtrlWordHandler(rtfParser, "dobymargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dobypage"] = new RtfCtrlWordHandler(rtfParser, "dobypage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dobypara"] = new RtfCtrlWordHandler(rtfParser, "dobypara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["doccomm"] = new RtfCtrlWordHandler(rtfParser, "doccomm", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["doctemp"] = new RtfCtrlWordHandler(rtfParser, "doctemp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["doctype"] = new RtfCtrlWordHandler(rtfParser, "doctype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["docvar"] = new RtfCtrlWordHandler(rtfParser, "docvar", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["dodhgt"] = new RtfCtrlWordHandler(rtfParser, "dodhgt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dolock"] = new RtfCtrlWordHandler(rtfParser, "dolock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["donotembedlingdata"] = new RtfCtrlWordHandler(rtfParser, "donotembedlingdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["donotembedsysfont"] = new RtfCtrlWordHandler(rtfParser, "donotembedsysfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["donotshowcomments"] = new RtfCtrlWordHandler(rtfParser, "donotshowcomments", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["donotshowinsdel"] = new RtfCtrlWordHandler(rtfParser, "donotshowinsdel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["donotshowmarkup"] = new RtfCtrlWordHandler(rtfParser, "donotshowmarkup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["donotshowprops"] = new RtfCtrlWordHandler(rtfParser, "donotshowprops", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpaendhol"] = new RtfCtrlWordHandler(rtfParser, "dpaendhol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpaendl"] = new RtfCtrlWordHandler(rtfParser, "dpaendl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpaendsol"] = new RtfCtrlWordHandler(rtfParser, "dpaendsol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpaendw"] = new RtfCtrlWordHandler(rtfParser, "dpaendw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dparc"] = new RtfCtrlWordHandler(rtfParser, "dparc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dparcflipx"] = new RtfCtrlWordHandler(rtfParser, "dparcflipx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dparcflipy"] = new RtfCtrlWordHandler(rtfParser, "dparcflipy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpastarthol"] = new RtfCtrlWordHandler(rtfParser, "dpastarthol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpastartl"] = new RtfCtrlWordHandler(rtfParser, "dpastartl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpastartsol"] = new RtfCtrlWordHandler(rtfParser, "dpastartsol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpastartw"] = new RtfCtrlWordHandler(rtfParser, "dpastartw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpcallout"] = new RtfCtrlWordHandler(rtfParser, "dpcallout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcoa"] = new RtfCtrlWordHandler(rtfParser, "dpcoa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpcoaccent"] = new RtfCtrlWordHandler(rtfParser, "dpcoaccent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcobestfit"] = new RtfCtrlWordHandler(rtfParser, "dpcobestfit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcoborder"] = new RtfCtrlWordHandler(rtfParser, "dpcoborder", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcodabs"] = new RtfCtrlWordHandler(rtfParser, "dpcodabs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpcodbottom"] = new RtfCtrlWordHandler(rtfParser, "dpcodbottom", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcodcenter"] = new RtfCtrlWordHandler(rtfParser, "dpcodcenter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcodescent"] = new RtfCtrlWordHandler(rtfParser, "dpcodescent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpcodtop"] = new RtfCtrlWordHandler(rtfParser, "dpcodtop", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcolength"] = new RtfCtrlWordHandler(rtfParser, "dpcolength", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpcominusx"] = new RtfCtrlWordHandler(rtfParser, "dpcominusx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcominusy"] = new RtfCtrlWordHandler(rtfParser, "dpcominusy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcooffset"] = new RtfCtrlWordHandler(rtfParser, "dpcooffset", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpcosmarta"] = new RtfCtrlWordHandler(rtfParser, "dpcosmarta", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcotdouble"] = new RtfCtrlWordHandler(rtfParser, "dpcotdouble", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcotright"] = new RtfCtrlWordHandler(rtfParser, "dpcotright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcotsingle"] = new RtfCtrlWordHandler(rtfParser, "dpcotsingle", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcottriple"] = new RtfCtrlWordHandler(rtfParser, "dpcottriple", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpcount"] = new RtfCtrlWordHandler(rtfParser, "dpcount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpellipse"] = new RtfCtrlWordHandler(rtfParser, "dpellipse", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpendgroup"] = new RtfCtrlWordHandler(rtfParser, "dpendgroup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpfillbgcb"] = new RtfCtrlWordHandler(rtfParser, "dpfillbgcb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpfillbgcg"] = new RtfCtrlWordHandler(rtfParser, "dpfillbgcg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpfillbgcr"] = new RtfCtrlWordHandler(rtfParser, "dpfillbgcr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpfillbggray"] = new RtfCtrlWordHandler(rtfParser, "dpfillbggray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpfillbgpal"] = new RtfCtrlWordHandler(rtfParser, "dpfillbgpal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpfillfgcb"] = new RtfCtrlWordHandler(rtfParser, "dpfillfgcb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpfillfgcg"] = new RtfCtrlWordHandler(rtfParser, "dpfillfgcg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpfillfgcr"] = new RtfCtrlWordHandler(rtfParser, "dpfillfgcr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpfillfggray"] = new RtfCtrlWordHandler(rtfParser, "dpfillfggray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpfillfgpal"] = new RtfCtrlWordHandler(rtfParser, "dpfillfgpal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpfillpat"] = new RtfCtrlWordHandler(rtfParser, "dpfillpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpgroup"] = new RtfCtrlWordHandler(rtfParser, "dpgroup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpline"] = new RtfCtrlWordHandler(rtfParser, "dpline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dplinecob"] = new RtfCtrlWordHandler(rtfParser, "dplinecob", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dplinecog"] = new RtfCtrlWordHandler(rtfParser, "dplinecog", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dplinecor"] = new RtfCtrlWordHandler(rtfParser, "dplinecor", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dplinedado"] = new RtfCtrlWordHandler(rtfParser, "dplinedado", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dplinedadodo"] = new RtfCtrlWordHandler(rtfParser, "dplinedadodo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dplinedash"] = new RtfCtrlWordHandler(rtfParser, "dplinedash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dplinedot"] = new RtfCtrlWordHandler(rtfParser, "dplinedot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dplinegray"] = new RtfCtrlWordHandler(rtfParser, "dplinegray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dplinehollow"] = new RtfCtrlWordHandler(rtfParser, "dplinehollow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dplinepal"] = new RtfCtrlWordHandler(rtfParser, "dplinepal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dplinesolid"] = new RtfCtrlWordHandler(rtfParser, "dplinesolid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dplinew"] = new RtfCtrlWordHandler(rtfParser, "dplinew", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dppolycount"] = new RtfCtrlWordHandler(rtfParser, "dppolycount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dppolygon"] = new RtfCtrlWordHandler(rtfParser, "dppolygon", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dppolyline"] = new RtfCtrlWordHandler(rtfParser, "dppolyline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpptx"] = new RtfCtrlWordHandler(rtfParser, "dpptx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dppty"] = new RtfCtrlWordHandler(rtfParser, "dppty", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dprect"] = new RtfCtrlWordHandler(rtfParser, "dprect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dproundr"] = new RtfCtrlWordHandler(rtfParser, "dproundr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpshadow"] = new RtfCtrlWordHandler(rtfParser, "dpshadow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpshadx"] = new RtfCtrlWordHandler(rtfParser, "dpshadx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpshady"] = new RtfCtrlWordHandler(rtfParser, "dpshady", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dptxbtlr"] = new RtfCtrlWordHandler(rtfParser, "dptxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dptxbx"] = new RtfCtrlWordHandler(rtfParser, "dptxbx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dptxbxmar"] = new RtfCtrlWordHandler(rtfParser, "dptxbxmar", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dptxbxtext"] = new RtfCtrlWordHandler(rtfParser, "dptxbxtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null);
+ ctrlWords["dptxlrtb"] = new RtfCtrlWordHandler(rtfParser, "dptxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dptxlrtbv"] = new RtfCtrlWordHandler(rtfParser, "dptxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dptxtbrl"] = new RtfCtrlWordHandler(rtfParser, "dptxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dptxtbrlv"] = new RtfCtrlWordHandler(rtfParser, "dptxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["dpx"] = new RtfCtrlWordHandler(rtfParser, "dpx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpxsize"] = new RtfCtrlWordHandler(rtfParser, "dpxsize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpy"] = new RtfCtrlWordHandler(rtfParser, "dpy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dpysize"] = new RtfCtrlWordHandler(rtfParser, "dpysize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dropcapli"] = new RtfCtrlWordHandler(rtfParser, "dropcapli", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dropcapt"] = new RtfCtrlWordHandler(rtfParser, "dropcapt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ds"] = new RtfCtrlWordHandler(rtfParser, "ds", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dxfrtext"] = new RtfCtrlWordHandler(rtfParser, "dxfrtext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["dy"] = new RtfCtrlWordHandler(rtfParser, "dy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ebcend"] = new RtfCtrlWordHandler(rtfParser, "ebcend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null);
+ ctrlWords["ebcstart"] = new RtfCtrlWordHandler(rtfParser, "ebcstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null);
+ ctrlWords["edmins"] = new RtfCtrlWordHandler(rtfParser, "edmins", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["embo"] = new RtfCtrlWordHandler(rtfParser, "embo", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["emdash"] = new RtfCtrlWordHandler(rtfParser, "emdash", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x151");
+ ctrlWords["emfblip"] = new RtfCtrlWordHandler(rtfParser, "emfblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["emspace"] = new RtfCtrlWordHandler(rtfParser, "emspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["endash"] = new RtfCtrlWordHandler(rtfParser, "endash", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x150");
+ ctrlWords["enddoc"] = new RtfCtrlWordHandler(rtfParser, "enddoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["endnhere"] = new RtfCtrlWordHandler(rtfParser, "endnhere", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["endnotes"] = new RtfCtrlWordHandler(rtfParser, "endnotes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["enforceprot"] = new RtfCtrlWordHandler(rtfParser, "enforceprot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["enspace"] = new RtfCtrlWordHandler(rtfParser, "enspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["expnd"] = new RtfCtrlWordHandler(rtfParser, "expnd", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["expndtw"] = new RtfCtrlWordHandler(rtfParser, "expndtw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["expshrtn"] = new RtfCtrlWordHandler(rtfParser, "expshrtn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["f"] = new RtfCtrlWordHandler(rtfParser, "f", 0, true, RtfCtrlWordType.VALUE, "\\", " ", RtfProperty.CHARACTER_FONT);
+ ctrlWords["faauto"] = new RtfCtrlWordHandler(rtfParser, "faauto", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["facenter"] = new RtfCtrlWordHandler(rtfParser, "facenter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["facingp"] = new RtfCtrlWordHandler(rtfParser, "facingp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["factoidname"] = new RtfCtrlWordHandler(rtfParser, "factoidname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null);
+ ctrlWords["fafixed"] = new RtfCtrlWordHandler(rtfParser, "fafixed", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fahang"] = new RtfCtrlWordHandler(rtfParser, "fahang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["falt"] = new RtfCtrlWordHandler(rtfParser, "falt", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationFontTable"); //"RtfDestinationAlternateFont";
+ ctrlWords["faroman"] = new RtfCtrlWordHandler(rtfParser, "faroman", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["favar"] = new RtfCtrlWordHandler(rtfParser, "favar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fbias"] = new RtfCtrlWordHandler(rtfParser, "fbias", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fbidi"] = new RtfCtrlWordHandler(rtfParser, "fbidi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fbimajor"] = new RtfCtrlWordHandler(rtfParser, "fbimajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fbiminor"] = new RtfCtrlWordHandler(rtfParser, "fbiminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fchars"] = new RtfCtrlWordHandler(rtfParser, "fchars", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null);
+ ctrlWords["fcharset"] = new RtfCtrlWordHandler(rtfParser, "fcharset", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fdbmajor"] = new RtfCtrlWordHandler(rtfParser, "fdbmajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fdbminor"] = new RtfCtrlWordHandler(rtfParser, "fdbminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fdecor"] = new RtfCtrlWordHandler(rtfParser, "fdecor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["felnbrelev"] = new RtfCtrlWordHandler(rtfParser, "felnbrelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fet"] = new RtfCtrlWordHandler(rtfParser, "fet", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fetch"] = new RtfCtrlWordHandler(rtfParser, "fetch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ffdefres"] = new RtfCtrlWordHandler(rtfParser, "ffdefres", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffdeftext"] = new RtfCtrlWordHandler(rtfParser, "ffdeftext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["ffentrymcr"] = new RtfCtrlWordHandler(rtfParser, "ffentrymcr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["ffexitmcr"] = new RtfCtrlWordHandler(rtfParser, "ffexitmcr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["ffformat"] = new RtfCtrlWordHandler(rtfParser, "ffformat", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["ffhaslistbox"] = new RtfCtrlWordHandler(rtfParser, "ffhaslistbox", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffhelptext"] = new RtfCtrlWordHandler(rtfParser, "ffhelptext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["ffhps"] = new RtfCtrlWordHandler(rtfParser, "ffhps", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffl"] = new RtfCtrlWordHandler(rtfParser, "ffl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["ffmaxlen"] = new RtfCtrlWordHandler(rtfParser, "ffmaxlen", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffname"] = new RtfCtrlWordHandler(rtfParser, "ffname", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["ffownhelp"] = new RtfCtrlWordHandler(rtfParser, "ffownhelp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffownstat"] = new RtfCtrlWordHandler(rtfParser, "ffownstat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffprot"] = new RtfCtrlWordHandler(rtfParser, "ffprot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffrecalc"] = new RtfCtrlWordHandler(rtfParser, "ffrecalc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffres"] = new RtfCtrlWordHandler(rtfParser, "ffres", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffsize"] = new RtfCtrlWordHandler(rtfParser, "ffsize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ffstattext"] = new RtfCtrlWordHandler(rtfParser, "ffstattext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["fftype"] = new RtfCtrlWordHandler(rtfParser, "fftype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fftypetxt"] = new RtfCtrlWordHandler(rtfParser, "fftypetxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fhimajor"] = new RtfCtrlWordHandler(rtfParser, "fhimajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fhiminor"] = new RtfCtrlWordHandler(rtfParser, "fhiminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fi"] = new RtfCtrlWordHandler(rtfParser, "fi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fid"] = new RtfCtrlWordHandler(rtfParser, "fid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["field"] = new RtfCtrlWordHandler(rtfParser, "field", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["file"] = new RtfCtrlWordHandler(rtfParser, "file", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["filetbl"] = new RtfCtrlWordHandler(rtfParser, "filetbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["fittext"] = new RtfCtrlWordHandler(rtfParser, "fittext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fjgothic"] = new RtfCtrlWordHandler(rtfParser, "fjgothic", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fjminchou"] = new RtfCtrlWordHandler(rtfParser, "fjminchou", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fldalt"] = new RtfCtrlWordHandler(rtfParser, "fldalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["flddirty"] = new RtfCtrlWordHandler(rtfParser, "flddirty", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fldedit"] = new RtfCtrlWordHandler(rtfParser, "fldedit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fldinst"] = new RtfCtrlWordHandler(rtfParser, "fldinst", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["fldlock"] = new RtfCtrlWordHandler(rtfParser, "fldlock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fldpriv"] = new RtfCtrlWordHandler(rtfParser, "fldpriv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fldrslt"] = new RtfCtrlWordHandler(rtfParser, "fldrslt", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["fldtype"] = new RtfCtrlWordHandler(rtfParser, "fldtype", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["flomajor"] = new RtfCtrlWordHandler(rtfParser, "flomajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["flominor"] = new RtfCtrlWordHandler(rtfParser, "flominor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fmodern"] = new RtfCtrlWordHandler(rtfParser, "fmodern", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fn"] = new RtfCtrlWordHandler(rtfParser, "fn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fname"] = new RtfCtrlWordHandler(rtfParser, "fname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["fnetwork"] = new RtfCtrlWordHandler(rtfParser, "fnetwork", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fnil"] = new RtfCtrlWordHandler(rtfParser, "fnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fnonfilesys"] = new RtfCtrlWordHandler(rtfParser, "fnonfilesys", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fontemb"] = new RtfCtrlWordHandler(rtfParser, "fontemb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["fontfile"] = new RtfCtrlWordHandler(rtfParser, "fontfile", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["fonttbl"] = new RtfCtrlWordHandler(rtfParser, "fonttbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationFontTable");
+ ctrlWords["footer"] = new RtfCtrlWordHandler(rtfParser, "footer", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["footerf"] = new RtfCtrlWordHandler(rtfParser, "footerf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["footerl"] = new RtfCtrlWordHandler(rtfParser, "footerl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null);
+ ctrlWords["footerr"] = new RtfCtrlWordHandler(rtfParser, "footerr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["footery"] = new RtfCtrlWordHandler(rtfParser, "footery", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["footnote"] = new RtfCtrlWordHandler(rtfParser, "footnote", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["forceupgrade"] = new RtfCtrlWordHandler(rtfParser, "forceupgrade", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["formdisp"] = new RtfCtrlWordHandler(rtfParser, "formdisp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["formfield"] = new RtfCtrlWordHandler(rtfParser, "formfield", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["formprot"] = new RtfCtrlWordHandler(rtfParser, "formprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["formshade"] = new RtfCtrlWordHandler(rtfParser, "formshade", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fosnum"] = new RtfCtrlWordHandler(rtfParser, "fosnum", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fprq"] = new RtfCtrlWordHandler(rtfParser, "fprq", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fracwidth"] = new RtfCtrlWordHandler(rtfParser, "fracwidth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["frelative"] = new RtfCtrlWordHandler(rtfParser, "frelative", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["frmtxbtlr"] = new RtfCtrlWordHandler(rtfParser, "frmtxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["frmtxlrtb"] = new RtfCtrlWordHandler(rtfParser, "frmtxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["frmtxlrtbv"] = new RtfCtrlWordHandler(rtfParser, "frmtxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["frmtxtbrl"] = new RtfCtrlWordHandler(rtfParser, "frmtxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["frmtxtbrlv"] = new RtfCtrlWordHandler(rtfParser, "frmtxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["froman"] = new RtfCtrlWordHandler(rtfParser, "froman", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fromhtml"] = new RtfCtrlWordHandler(rtfParser, "fromhtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fromtext"] = new RtfCtrlWordHandler(rtfParser, "fromtext", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fs"] = new RtfCtrlWordHandler(rtfParser, "fs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["fscript"] = new RtfCtrlWordHandler(rtfParser, "fscript", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fswiss"] = new RtfCtrlWordHandler(rtfParser, "fswiss", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftech"] = new RtfCtrlWordHandler(rtfParser, "ftech", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnalt"] = new RtfCtrlWordHandler(rtfParser, "ftnalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnbj"] = new RtfCtrlWordHandler(rtfParser, "ftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftncn"] = new RtfCtrlWordHandler(rtfParser, "ftncn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["ftnil"] = new RtfCtrlWordHandler(rtfParser, "ftnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnlytwnine"] = new RtfCtrlWordHandler(rtfParser, "ftnlytwnine", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnalc"] = new RtfCtrlWordHandler(rtfParser, "ftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnar"] = new RtfCtrlWordHandler(rtfParser, "ftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnauc"] = new RtfCtrlWordHandler(rtfParser, "ftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnchi"] = new RtfCtrlWordHandler(rtfParser, "ftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnchosung"] = new RtfCtrlWordHandler(rtfParser, "ftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnncnum"] = new RtfCtrlWordHandler(rtfParser, "ftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnndbar"] = new RtfCtrlWordHandler(rtfParser, "ftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnndbnum"] = new RtfCtrlWordHandler(rtfParser, "ftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnndbnumd"] = new RtfCtrlWordHandler(rtfParser, "ftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnndbnumk"] = new RtfCtrlWordHandler(rtfParser, "ftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnndbnumt"] = new RtfCtrlWordHandler(rtfParser, "ftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnganada"] = new RtfCtrlWordHandler(rtfParser, "ftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnngbnum"] = new RtfCtrlWordHandler(rtfParser, "ftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnngbnumd"] = new RtfCtrlWordHandler(rtfParser, "ftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnngbnumk"] = new RtfCtrlWordHandler(rtfParser, "ftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnngbnuml"] = new RtfCtrlWordHandler(rtfParser, "ftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnrlc"] = new RtfCtrlWordHandler(rtfParser, "ftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnruc"] = new RtfCtrlWordHandler(rtfParser, "ftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnzodiac"] = new RtfCtrlWordHandler(rtfParser, "ftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnzodiacd"] = new RtfCtrlWordHandler(rtfParser, "ftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnnzodiacl"] = new RtfCtrlWordHandler(rtfParser, "ftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnrestart"] = new RtfCtrlWordHandler(rtfParser, "ftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnrstcont"] = new RtfCtrlWordHandler(rtfParser, "ftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnrstpg"] = new RtfCtrlWordHandler(rtfParser, "ftnrstpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ftnsep"] = new RtfCtrlWordHandler(rtfParser, "ftnsep", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["ftnsepc"] = new RtfCtrlWordHandler(rtfParser, "ftnsepc", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["ftnstart"] = new RtfCtrlWordHandler(rtfParser, "ftnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ftntj"] = new RtfCtrlWordHandler(rtfParser, "ftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fttruetype"] = new RtfCtrlWordHandler(rtfParser, "fttruetype", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fvaliddos"] = new RtfCtrlWordHandler(rtfParser, "fvaliddos", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fvalidhpfs"] = new RtfCtrlWordHandler(rtfParser, "fvalidhpfs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fvalidmac"] = new RtfCtrlWordHandler(rtfParser, "fvalidmac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["fvalidntfs"] = new RtfCtrlWordHandler(rtfParser, "fvalidntfs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["g"] = new RtfCtrlWordHandler(rtfParser, "g", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["gcw"] = new RtfCtrlWordHandler(rtfParser, "gcw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["generator"] = new RtfCtrlWordHandler(rtfParser, "generator", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["green"] = new RtfCtrlWordHandler(rtfParser, "green", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["gridtbl"] = new RtfCtrlWordHandler(rtfParser, "gridtbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["gutter"] = new RtfCtrlWordHandler(rtfParser, "gutter", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["gutterprl"] = new RtfCtrlWordHandler(rtfParser, "gutterprl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["guttersxn"] = new RtfCtrlWordHandler(rtfParser, "guttersxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["header"] = new RtfCtrlWordHandler(rtfParser, "header", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["headerf"] = new RtfCtrlWordHandler(rtfParser, "headerf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["headerl"] = new RtfCtrlWordHandler(rtfParser, "headerl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["headerr"] = new RtfCtrlWordHandler(rtfParser, "headerr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["headery"] = new RtfCtrlWordHandler(rtfParser, "headery", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hich"] = new RtfCtrlWordHandler(rtfParser, "hich", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["highlight"] = new RtfCtrlWordHandler(rtfParser, "highlight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hlfr"] = new RtfCtrlWordHandler(rtfParser, "hlfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hlinkbase"] = new RtfCtrlWordHandler(rtfParser, "hlinkbase", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hlloc"] = new RtfCtrlWordHandler(rtfParser, "hlloc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hlsrc"] = new RtfCtrlWordHandler(rtfParser, "hlsrc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["horzdoc"] = new RtfCtrlWordHandler(rtfParser, "horzdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["horzsect"] = new RtfCtrlWordHandler(rtfParser, "horzsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["horzvert"] = new RtfCtrlWordHandler(rtfParser, "horzvert", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hr"] = new RtfCtrlWordHandler(rtfParser, "hr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hsv"] = new RtfCtrlWordHandler(rtfParser, "hsv", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["htmautsp"] = new RtfCtrlWordHandler(rtfParser, "htmautsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["htmlbase"] = new RtfCtrlWordHandler(rtfParser, "htmlbase", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["htmlrtf"] = new RtfCtrlWordHandler(rtfParser, "htmlrtf", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["htmltag"] = new RtfCtrlWordHandler(rtfParser, "htmltag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["hwelev"] = new RtfCtrlWordHandler(rtfParser, "hwelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["hyphauto"] = new RtfCtrlWordHandler(rtfParser, "hyphauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["hyphcaps"] = new RtfCtrlWordHandler(rtfParser, "hyphcaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["hyphconsec"] = new RtfCtrlWordHandler(rtfParser, "hyphconsec", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hyphhotz"] = new RtfCtrlWordHandler(rtfParser, "hyphhotz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["hyphpar"] = new RtfCtrlWordHandler(rtfParser, "hyphpar", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["i"] = new RtfCtrlWordHandler(rtfParser, "i", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["id"] = new RtfCtrlWordHandler(rtfParser, "id", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ignoremixedcontent"] = new RtfCtrlWordHandler(rtfParser, "ignoremixedcontent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ilfomacatclnup"] = new RtfCtrlWordHandler(rtfParser, "ilfomacatclnup", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ilvl"] = new RtfCtrlWordHandler(rtfParser, "ilvl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["impr"] = new RtfCtrlWordHandler(rtfParser, "impr", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["indmirror"] = new RtfCtrlWordHandler(rtfParser, "indmirror", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["indrlsweleven"] = new RtfCtrlWordHandler(rtfParser, "indrlsweleven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["info"] = new RtfCtrlWordHandler(rtfParser, "info", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["insrsid"] = new RtfCtrlWordHandler(rtfParser, "insrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["intbl"] = new RtfCtrlWordHandler(rtfParser, "intbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ipgp"] = new RtfCtrlWordHandler(rtfParser, "ipgp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["irow"] = new RtfCtrlWordHandler(rtfParser, "irow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["irowband"] = new RtfCtrlWordHandler(rtfParser, "irowband", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["itap"] = new RtfCtrlWordHandler(rtfParser, "itap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ixe"] = new RtfCtrlWordHandler(rtfParser, "ixe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["jclisttab"] = new RtfCtrlWordHandler(rtfParser, "jclisttab", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["jcompress"] = new RtfCtrlWordHandler(rtfParser, "jcompress", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["jexpand"] = new RtfCtrlWordHandler(rtfParser, "jexpand", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["jis"] = new RtfCtrlWordHandler(rtfParser, "jis", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["jpegblip"] = new RtfCtrlWordHandler(rtfParser, "jpegblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["jsksu"] = new RtfCtrlWordHandler(rtfParser, "jsksu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["keep"] = new RtfCtrlWordHandler(rtfParser, "keep", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["keepn"] = new RtfCtrlWordHandler(rtfParser, "keepn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["kerning"] = new RtfCtrlWordHandler(rtfParser, "kerning", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["keycode"] = new RtfCtrlWordHandler(rtfParser, "keycode", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["keywords"] = new RtfCtrlWordHandler(rtfParser, "keywords", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["krnprsnet"] = new RtfCtrlWordHandler(rtfParser, "krnprsnet", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ksulang"] = new RtfCtrlWordHandler(rtfParser, "ksulang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["landscape"] = new RtfCtrlWordHandler(rtfParser, "landscape", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lang"] = new RtfCtrlWordHandler(rtfParser, "lang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["langfe"] = new RtfCtrlWordHandler(rtfParser, "langfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["langfenp"] = new RtfCtrlWordHandler(rtfParser, "langfenp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["langnp"] = new RtfCtrlWordHandler(rtfParser, "langnp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lastrow"] = new RtfCtrlWordHandler(rtfParser, "lastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["latentstyles"] = new RtfCtrlWordHandler(rtfParser, "latentstyles", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["lbr"] = new RtfCtrlWordHandler(rtfParser, "lbr", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["lchars"] = new RtfCtrlWordHandler(rtfParser, "lchars", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["ldblquote"] = new RtfCtrlWordHandler(rtfParser, "ldblquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x147");
+ ctrlWords["level"] = new RtfCtrlWordHandler(rtfParser, "level", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelfollow"] = new RtfCtrlWordHandler(rtfParser, "levelfollow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelindent"] = new RtfCtrlWordHandler(rtfParser, "levelindent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["leveljc"] = new RtfCtrlWordHandler(rtfParser, "leveljc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["leveljcn"] = new RtfCtrlWordHandler(rtfParser, "leveljcn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levellegal"] = new RtfCtrlWordHandler(rtfParser, "levellegal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelnfc"] = new RtfCtrlWordHandler(rtfParser, "levelnfc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelnfcn"] = new RtfCtrlWordHandler(rtfParser, "levelnfcn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelnorestart"] = new RtfCtrlWordHandler(rtfParser, "levelnorestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelnumbers"] = new RtfCtrlWordHandler(rtfParser, "levelnumbers", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["levelold"] = new RtfCtrlWordHandler(rtfParser, "levelold", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelpicture"] = new RtfCtrlWordHandler(rtfParser, "levelpicture", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelprev"] = new RtfCtrlWordHandler(rtfParser, "levelprev", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelprevspace"] = new RtfCtrlWordHandler(rtfParser, "levelprevspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelspace"] = new RtfCtrlWordHandler(rtfParser, "levelspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["levelstartat"] = new RtfCtrlWordHandler(rtfParser, "levelstartat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["leveltemplateid"] = new RtfCtrlWordHandler(rtfParser, "leveltemplateid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["leveltext"] = new RtfCtrlWordHandler(rtfParser, "leveltext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["li"] = new RtfCtrlWordHandler(rtfParser, "li", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lin"] = new RtfCtrlWordHandler(rtfParser, "lin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["line"] = new RtfCtrlWordHandler(rtfParser, "line", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["linebetcol"] = new RtfCtrlWordHandler(rtfParser, "linebetcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["linecont"] = new RtfCtrlWordHandler(rtfParser, "linecont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["linemod"] = new RtfCtrlWordHandler(rtfParser, "linemod", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lineppage"] = new RtfCtrlWordHandler(rtfParser, "lineppage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["linerestart"] = new RtfCtrlWordHandler(rtfParser, "linerestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["linestart"] = new RtfCtrlWordHandler(rtfParser, "linestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["linestarts"] = new RtfCtrlWordHandler(rtfParser, "linestarts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["linex"] = new RtfCtrlWordHandler(rtfParser, "linex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["linkself"] = new RtfCtrlWordHandler(rtfParser, "linkself", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["linkstyles"] = new RtfCtrlWordHandler(rtfParser, "linkstyles", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["linktoquery"] = new RtfCtrlWordHandler(rtfParser, "linktoquery", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["linkval"] = new RtfCtrlWordHandler(rtfParser, "linkval", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lisa"] = new RtfCtrlWordHandler(rtfParser, "lisa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lisb"] = new RtfCtrlWordHandler(rtfParser, "lisb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["list"] = new RtfCtrlWordHandler(rtfParser, "list", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["listhybrid"] = new RtfCtrlWordHandler(rtfParser, "listhybrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["listid"] = new RtfCtrlWordHandler(rtfParser, "listid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["listname"] = new RtfCtrlWordHandler(rtfParser, "listname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["listoverride"] = new RtfCtrlWordHandler(rtfParser, "listoverride", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["listoverridecount"] = new RtfCtrlWordHandler(rtfParser, "listoverridecount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["listoverrideformat"] = new RtfCtrlWordHandler(rtfParser, "listoverrideformat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["listoverridestart"] = new RtfCtrlWordHandler(rtfParser, "listoverridestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["listoverridestartat"] = new RtfCtrlWordHandler(rtfParser, "listoverridestartat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["listoverridetable"] = new RtfCtrlWordHandler(rtfParser, "listoverridetable", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull");
+ ctrlWords["listpicture"] = new RtfCtrlWordHandler(rtfParser, "listpicture", 0, true, RtfCtrlWordType.DESTINATION, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["listrestarthdn"] = new RtfCtrlWordHandler(rtfParser, "listrestarthdn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["listsimple"] = new RtfCtrlWordHandler(rtfParser, "listsimple", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["liststyleid"] = new RtfCtrlWordHandler(rtfParser, "liststyleid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["liststylename"] = new RtfCtrlWordHandler(rtfParser, "liststylename", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["listtable"] = new RtfCtrlWordHandler(rtfParser, "listtable", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationListTable");
+ ctrlWords["listtemplateid"] = new RtfCtrlWordHandler(rtfParser, "listtemplateid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["listtext"] = new RtfCtrlWordHandler(rtfParser, "listtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["lnbrkrule"] = new RtfCtrlWordHandler(rtfParser, "lnbrkrule", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lndscpsxn"] = new RtfCtrlWordHandler(rtfParser, "lndscpsxn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lnongrid"] = new RtfCtrlWordHandler(rtfParser, "lnongrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["loch"] = new RtfCtrlWordHandler(rtfParser, "loch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lquote"] = new RtfCtrlWordHandler(rtfParser, "lquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x145");
+ ctrlWords["ls"] = new RtfCtrlWordHandler(rtfParser, "ls", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdlocked"] = new RtfCtrlWordHandler(rtfParser, "lsdlocked", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdlockeddef"] = new RtfCtrlWordHandler(rtfParser, "lsdlockeddef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdlockedexcept"] = new RtfCtrlWordHandler(rtfParser, "lsdlockedexcept", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["lsdpriority"] = new RtfCtrlWordHandler(rtfParser, "lsdpriority", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdprioritydef"] = new RtfCtrlWordHandler(rtfParser, "lsdprioritydef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdqformat"] = new RtfCtrlWordHandler(rtfParser, "lsdqformat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdqformatdef"] = new RtfCtrlWordHandler(rtfParser, "lsdqformatdef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdsemihidden"] = new RtfCtrlWordHandler(rtfParser, "lsdsemihidden", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdsemihiddendef"] = new RtfCtrlWordHandler(rtfParser, "lsdsemihiddendef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdstimax"] = new RtfCtrlWordHandler(rtfParser, "lsdstimax", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdunhideused"] = new RtfCtrlWordHandler(rtfParser, "lsdunhideused", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["lsdunhideuseddef"] = new RtfCtrlWordHandler(rtfParser, "lsdunhideuseddef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ltrch"] = new RtfCtrlWordHandler(rtfParser, "ltrch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ltrdoc"] = new RtfCtrlWordHandler(rtfParser, "ltrdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ltrmark"] = new RtfCtrlWordHandler(rtfParser, "ltrmark", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["ltrpar"] = new RtfCtrlWordHandler(rtfParser, "ltrpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ltrrow"] = new RtfCtrlWordHandler(rtfParser, "ltrrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ltrsect"] = new RtfCtrlWordHandler(rtfParser, "ltrsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lvltentative"] = new RtfCtrlWordHandler(rtfParser, "lvltentative", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lytcalctblwd"] = new RtfCtrlWordHandler(rtfParser, "lytcalctblwd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lytexcttp"] = new RtfCtrlWordHandler(rtfParser, "lytexcttp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lytprtmet"] = new RtfCtrlWordHandler(rtfParser, "lytprtmet", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["lyttblrtgr"] = new RtfCtrlWordHandler(rtfParser, "lyttblrtgr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mac"] = new RtfCtrlWordHandler(rtfParser, "mac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["macc"] = new RtfCtrlWordHandler(rtfParser, "macc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["maccpr"] = new RtfCtrlWordHandler(rtfParser, "maccpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["macpict"] = new RtfCtrlWordHandler(rtfParser, "macpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mailmerge"] = new RtfCtrlWordHandler(rtfParser, "mailmerge", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["makebackup"] = new RtfCtrlWordHandler(rtfParser, "makebackup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["maln"] = new RtfCtrlWordHandler(rtfParser, "maln", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["malnscr"] = new RtfCtrlWordHandler(rtfParser, "malnscr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["manager"] = new RtfCtrlWordHandler(rtfParser, "manager", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["margb"] = new RtfCtrlWordHandler(rtfParser, "margb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["margbsxn"] = new RtfCtrlWordHandler(rtfParser, "margbsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["margl"] = new RtfCtrlWordHandler(rtfParser, "margl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["marglsxn"] = new RtfCtrlWordHandler(rtfParser, "marglsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["margmirror"] = new RtfCtrlWordHandler(rtfParser, "margmirror", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["margmirsxn"] = new RtfCtrlWordHandler(rtfParser, "margmirsxn", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["margpr"] = new RtfCtrlWordHandler(rtfParser, "margpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["margr"] = new RtfCtrlWordHandler(rtfParser, "margr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["margrsxn"] = new RtfCtrlWordHandler(rtfParser, "margrsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["margsz"] = new RtfCtrlWordHandler(rtfParser, "margsz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["margt"] = new RtfCtrlWordHandler(rtfParser, "margt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["margtsxn"] = new RtfCtrlWordHandler(rtfParser, "margtsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mbar"] = new RtfCtrlWordHandler(rtfParser, "mbar", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mbarpr"] = new RtfCtrlWordHandler(rtfParser, "mbarpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mbasejc"] = new RtfCtrlWordHandler(rtfParser, "mbasejc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mbegchr"] = new RtfCtrlWordHandler(rtfParser, "mbegchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mborderbox"] = new RtfCtrlWordHandler(rtfParser, "mborderbox", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mborderboxpr"] = new RtfCtrlWordHandler(rtfParser, "mborderboxpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mbox"] = new RtfCtrlWordHandler(rtfParser, "mbox", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mboxpr"] = new RtfCtrlWordHandler(rtfParser, "mboxpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mbrk"] = new RtfCtrlWordHandler(rtfParser, "mbrk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mbrkbin"] = new RtfCtrlWordHandler(rtfParser, "mbrkbin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mbrkbinsub"] = new RtfCtrlWordHandler(rtfParser, "mbrkbinsub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mcgp"] = new RtfCtrlWordHandler(rtfParser, "mcgp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mcgprule"] = new RtfCtrlWordHandler(rtfParser, "mcgprule", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mchr"] = new RtfCtrlWordHandler(rtfParser, "mchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mcount"] = new RtfCtrlWordHandler(rtfParser, "mcount", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mcsp"] = new RtfCtrlWordHandler(rtfParser, "mcsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mctrlpr"] = new RtfCtrlWordHandler(rtfParser, "mctrlpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["md"] = new RtfCtrlWordHandler(rtfParser, "md", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mdefjc"] = new RtfCtrlWordHandler(rtfParser, "mdefjc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mdeg"] = new RtfCtrlWordHandler(rtfParser, "mdeg", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mdeghide"] = new RtfCtrlWordHandler(rtfParser, "mdeghide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mden"] = new RtfCtrlWordHandler(rtfParser, "mden", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mdiff"] = new RtfCtrlWordHandler(rtfParser, "mdiff", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mdispdef"] = new RtfCtrlWordHandler(rtfParser, "mdispdef", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mdpr"] = new RtfCtrlWordHandler(rtfParser, "mdpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["me"] = new RtfCtrlWordHandler(rtfParser, "me", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mendchr"] = new RtfCtrlWordHandler(rtfParser, "mendchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["meqarr"] = new RtfCtrlWordHandler(rtfParser, "meqarr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["meqarrpr"] = new RtfCtrlWordHandler(rtfParser, "meqarrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mf"] = new RtfCtrlWordHandler(rtfParser, "mf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mfname"] = new RtfCtrlWordHandler(rtfParser, "mfname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mfpr"] = new RtfCtrlWordHandler(rtfParser, "mfpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mfunc"] = new RtfCtrlWordHandler(rtfParser, "mfunc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mfuncpr"] = new RtfCtrlWordHandler(rtfParser, "mfuncpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mgroupchr"] = new RtfCtrlWordHandler(rtfParser, "mgroupchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mgroupchrpr"] = new RtfCtrlWordHandler(rtfParser, "mgroupchrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mgrow"] = new RtfCtrlWordHandler(rtfParser, "mgrow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mhidebot"] = new RtfCtrlWordHandler(rtfParser, "mhidebot", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mhideleft"] = new RtfCtrlWordHandler(rtfParser, "mhideleft", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mhideright"] = new RtfCtrlWordHandler(rtfParser, "mhideright", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mhidetop"] = new RtfCtrlWordHandler(rtfParser, "mhidetop", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mhtmltag"] = new RtfCtrlWordHandler(rtfParser, "mhtmltag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["min"] = new RtfCtrlWordHandler(rtfParser, "min", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mintersp"] = new RtfCtrlWordHandler(rtfParser, "mintersp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mintlim"] = new RtfCtrlWordHandler(rtfParser, "mintlim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mintrasp"] = new RtfCtrlWordHandler(rtfParser, "mintrasp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mjc"] = new RtfCtrlWordHandler(rtfParser, "mjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mlim"] = new RtfCtrlWordHandler(rtfParser, "mlim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mlimloc"] = new RtfCtrlWordHandler(rtfParser, "mlimloc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mlimlow"] = new RtfCtrlWordHandler(rtfParser, "mlimlow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mlimlowpr"] = new RtfCtrlWordHandler(rtfParser, "mlimlowpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mlimupp"] = new RtfCtrlWordHandler(rtfParser, "mlimupp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mlimupppr"] = new RtfCtrlWordHandler(rtfParser, "mlimupppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mlit"] = new RtfCtrlWordHandler(rtfParser, "mlit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mlmargin"] = new RtfCtrlWordHandler(rtfParser, "mlmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mm"] = new RtfCtrlWordHandler(rtfParser, "mm", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmaddfieldname"] = new RtfCtrlWordHandler(rtfParser, "mmaddfieldname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmath"] = new RtfCtrlWordHandler(rtfParser, "mmath", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmathfont"] = new RtfCtrlWordHandler(rtfParser, "mmathfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmathpara"] = new RtfCtrlWordHandler(rtfParser, "mmathpara", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmathpict"] = new RtfCtrlWordHandler(rtfParser, "mmathpict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmathpr"] = new RtfCtrlWordHandler(rtfParser, "mmathpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmattach"] = new RtfCtrlWordHandler(rtfParser, "mmattach", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmaxdist"] = new RtfCtrlWordHandler(rtfParser, "mmaxdist", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmblanklines"] = new RtfCtrlWordHandler(rtfParser, "mmblanklines", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmblanklinks"] = new RtfCtrlWordHandler(rtfParser, "mmblanklinks", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmc"] = new RtfCtrlWordHandler(rtfParser, "mmc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmcjc"] = new RtfCtrlWordHandler(rtfParser, "mmcjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmconnectstrdata"] = new RtfCtrlWordHandler(rtfParser, "mmconnectstrdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null);
+ ctrlWords["mmcpr"] = new RtfCtrlWordHandler(rtfParser, "mmcpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmcs"] = new RtfCtrlWordHandler(rtfParser, "mmcs", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmdatasource"] = new RtfCtrlWordHandler(rtfParser, "mmdatasource", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmdatatypeaccess"] = new RtfCtrlWordHandler(rtfParser, "mmdatatypeaccess", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdatatypeexcel"] = new RtfCtrlWordHandler(rtfParser, "mmdatatypeexcel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdatatypefile"] = new RtfCtrlWordHandler(rtfParser, "mmdatatypefile", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdatatypeodbc"] = new RtfCtrlWordHandler(rtfParser, "mmdatatypeodbc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdatatypeodso"] = new RtfCtrlWordHandler(rtfParser, "mmdatatypeodso", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdatatypeqt"] = new RtfCtrlWordHandler(rtfParser, "mmdatatypeqt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdefaultStructuredQueryLanguage"] = new RtfCtrlWordHandler(rtfParser, "mmdefaultStructuredQueryLanguage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdestemail"] = new RtfCtrlWordHandler(rtfParser, "mmdestemail", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdestfax"] = new RtfCtrlWordHandler(rtfParser, "mmdestfax", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdestnewdoc"] = new RtfCtrlWordHandler(rtfParser, "mmdestnewdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmdestprinter"] = new RtfCtrlWordHandler(rtfParser, "mmdestprinter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmerrors"] = new RtfCtrlWordHandler(rtfParser, "mmerrors", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmfttypeaddress"] = new RtfCtrlWordHandler(rtfParser, "mmfttypeaddress", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmfttypebarcode"] = new RtfCtrlWordHandler(rtfParser, "mmfttypebarcode", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmfttypedbcolumn"] = new RtfCtrlWordHandler(rtfParser, "mmfttypedbcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmfttypemapped"] = new RtfCtrlWordHandler(rtfParser, "mmfttypemapped", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmfttypenull"] = new RtfCtrlWordHandler(rtfParser, "mmfttypenull", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmfttypesalutation"] = new RtfCtrlWordHandler(rtfParser, "mmfttypesalutation", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmheadersource"] = new RtfCtrlWordHandler(rtfParser, "mmheadersource", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmjdsotype"] = new RtfCtrlWordHandler(rtfParser, "mmjdsotype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmlinktoquery"] = new RtfCtrlWordHandler(rtfParser, "mmlinktoquery", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmmailsubject"] = new RtfCtrlWordHandler(rtfParser, "mmmailsubject", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmmaintypecatalog"] = new RtfCtrlWordHandler(rtfParser, "mmmaintypecatalog", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmmaintypeemail"] = new RtfCtrlWordHandler(rtfParser, "mmmaintypeemail", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmmaintypeenvelopes"] = new RtfCtrlWordHandler(rtfParser, "mmmaintypeenvelopes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmmaintypefax"] = new RtfCtrlWordHandler(rtfParser, "mmmaintypefax", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmmaintypelabels"] = new RtfCtrlWordHandler(rtfParser, "mmmaintypelabels", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmmaintypeletters"] = new RtfCtrlWordHandler(rtfParser, "mmmaintypeletters", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mmodso"] = new RtfCtrlWordHandler(rtfParser, "mmodso", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsoactive"] = new RtfCtrlWordHandler(rtfParser, "mmodsoactive", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmodsocoldelim"] = new RtfCtrlWordHandler(rtfParser, "mmodsocoldelim", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmodsocolumn"] = new RtfCtrlWordHandler(rtfParser, "mmodsocolumn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmodsodynaddr"] = new RtfCtrlWordHandler(rtfParser, "mmodsodynaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmodsofhdr"] = new RtfCtrlWordHandler(rtfParser, "mmodsofhdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmodsofilter"] = new RtfCtrlWordHandler(rtfParser, "mmodsofilter", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsofldmpdata"] = new RtfCtrlWordHandler(rtfParser, "mmodsofldmpdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsofmcolumn"] = new RtfCtrlWordHandler(rtfParser, "mmodsofmcolumn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmodsohash"] = new RtfCtrlWordHandler(rtfParser, "mmodsohash", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmodsolid"] = new RtfCtrlWordHandler(rtfParser, "mmodsolid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmodsomappedname"] = new RtfCtrlWordHandler(rtfParser, "mmodsomappedname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsoname"] = new RtfCtrlWordHandler(rtfParser, "mmodsoname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null);
+ ctrlWords["mmodsorecipdata"] = new RtfCtrlWordHandler(rtfParser, "mmodsorecipdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsosort"] = new RtfCtrlWordHandler(rtfParser, "mmodsosort", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsosrc"] = new RtfCtrlWordHandler(rtfParser, "mmodsosrc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsotable"] = new RtfCtrlWordHandler(rtfParser, "mmodsotable", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsoudldata"] = new RtfCtrlWordHandler(rtfParser, "mmodsoudldata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmodsouniquetag"] = new RtfCtrlWordHandler(rtfParser, "mmodsouniquetag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmpr"] = new RtfCtrlWordHandler(rtfParser, "mmpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmquery"] = new RtfCtrlWordHandler(rtfParser, "mmquery", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmr"] = new RtfCtrlWordHandler(rtfParser, "mmr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mmreccur"] = new RtfCtrlWordHandler(rtfParser, "mmreccur", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mmshowdata"] = new RtfCtrlWordHandler(rtfParser, "mmshowdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mnary"] = new RtfCtrlWordHandler(rtfParser, "mnary", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mnarylim"] = new RtfCtrlWordHandler(rtfParser, "mnarylim", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mnarypr"] = new RtfCtrlWordHandler(rtfParser, "mnarypr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mnobreak"] = new RtfCtrlWordHandler(rtfParser, "mnobreak", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mnor"] = new RtfCtrlWordHandler(rtfParser, "mnor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mnum"] = new RtfCtrlWordHandler(rtfParser, "mnum", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mo"] = new RtfCtrlWordHandler(rtfParser, "mo", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mobjdist"] = new RtfCtrlWordHandler(rtfParser, "mobjdist", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["momath"] = new RtfCtrlWordHandler(rtfParser, "momath", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["momathpara"] = new RtfCtrlWordHandler(rtfParser, "momathpara", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["momathparapr"] = new RtfCtrlWordHandler(rtfParser, "momathparapr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mopemu"] = new RtfCtrlWordHandler(rtfParser, "mopemu", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mphant"] = new RtfCtrlWordHandler(rtfParser, "mphant", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mphantpr"] = new RtfCtrlWordHandler(rtfParser, "mphantpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mplchide"] = new RtfCtrlWordHandler(rtfParser, "mplchide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mpos"] = new RtfCtrlWordHandler(rtfParser, "mpos", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mpostsp"] = new RtfCtrlWordHandler(rtfParser, "mpostsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mpresp"] = new RtfCtrlWordHandler(rtfParser, "mpresp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mr"] = new RtfCtrlWordHandler(rtfParser, "mr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mrad"] = new RtfCtrlWordHandler(rtfParser, "mrad", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mradpr"] = new RtfCtrlWordHandler(rtfParser, "mradpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mrmargin"] = new RtfCtrlWordHandler(rtfParser, "mrmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mrpr"] = new RtfCtrlWordHandler(rtfParser, "mrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mrsp"] = new RtfCtrlWordHandler(rtfParser, "mrsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mrsprule"] = new RtfCtrlWordHandler(rtfParser, "mrsprule", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mscr"] = new RtfCtrlWordHandler(rtfParser, "mscr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["msepchr"] = new RtfCtrlWordHandler(rtfParser, "msepchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mshow"] = new RtfCtrlWordHandler(rtfParser, "mshow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mshp"] = new RtfCtrlWordHandler(rtfParser, "mshp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["msize"] = new RtfCtrlWordHandler(rtfParser, "msize", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["msmallfrac"] = new RtfCtrlWordHandler(rtfParser, "msmallfrac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["msmcap"] = new RtfCtrlWordHandler(rtfParser, "msmcap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mspre"] = new RtfCtrlWordHandler(rtfParser, "mspre", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["msprepr"] = new RtfCtrlWordHandler(rtfParser, "msprepr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mssub"] = new RtfCtrlWordHandler(rtfParser, "mssub", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mssubpr"] = new RtfCtrlWordHandler(rtfParser, "mssubpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mssubsup"] = new RtfCtrlWordHandler(rtfParser, "mssubsup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mssubsuppr"] = new RtfCtrlWordHandler(rtfParser, "mssubsuppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mssup"] = new RtfCtrlWordHandler(rtfParser, "mssup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mssuppr"] = new RtfCtrlWordHandler(rtfParser, "mssuppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mstrikebltr"] = new RtfCtrlWordHandler(rtfParser, "mstrikebltr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mstrikeh"] = new RtfCtrlWordHandler(rtfParser, "mstrikeh", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mstriketlbr"] = new RtfCtrlWordHandler(rtfParser, "mstriketlbr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mstrikev"] = new RtfCtrlWordHandler(rtfParser, "mstrikev", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["msty"] = new RtfCtrlWordHandler(rtfParser, "msty", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["msub"] = new RtfCtrlWordHandler(rtfParser, "msub", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["msubhide"] = new RtfCtrlWordHandler(rtfParser, "msubhide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["msup"] = new RtfCtrlWordHandler(rtfParser, "msup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["msuphide"] = new RtfCtrlWordHandler(rtfParser, "msuphide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mt"] = new RtfCtrlWordHandler(rtfParser, "mt", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mtext"] = new RtfCtrlWordHandler(rtfParser, "mtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mtransp"] = new RtfCtrlWordHandler(rtfParser, "mtransp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mtype"] = new RtfCtrlWordHandler(rtfParser, "mtype", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mvauth"] = new RtfCtrlWordHandler(rtfParser, "mvauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mvdate"] = new RtfCtrlWordHandler(rtfParser, "mvdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mvertjc"] = new RtfCtrlWordHandler(rtfParser, "mvertjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mvf"] = new RtfCtrlWordHandler(rtfParser, "mvf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mvfmf"] = new RtfCtrlWordHandler(rtfParser, "mvfmf", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mvfml"] = new RtfCtrlWordHandler(rtfParser, "mvfml", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mvt"] = new RtfCtrlWordHandler(rtfParser, "mvt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mvtof"] = new RtfCtrlWordHandler(rtfParser, "mvtof", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mvtol"] = new RtfCtrlWordHandler(rtfParser, "mvtol", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["mwrapindent"] = new RtfCtrlWordHandler(rtfParser, "mwrapindent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mwrapindet"] = new RtfCtrlWordHandler(rtfParser, "mwrapindet", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["mwrapright"] = new RtfCtrlWordHandler(rtfParser, "mwrapright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["mzeroasc"] = new RtfCtrlWordHandler(rtfParser, "mzeroasc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mzerodesc"] = new RtfCtrlWordHandler(rtfParser, "mzerodesc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["mzerowid"] = new RtfCtrlWordHandler(rtfParser, "mzerowid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["nestcell"] = new RtfCtrlWordHandler(rtfParser, "nestcell", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["nestrow"] = new RtfCtrlWordHandler(rtfParser, "nestrow", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["nesttableprops"] = new RtfCtrlWordHandler(rtfParser, "nesttableprops", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["newtblstyruls"] = new RtfCtrlWordHandler(rtfParser, "newtblstyruls", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nextfile"] = new RtfCtrlWordHandler(rtfParser, "nextfile", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["noafcnsttbl"] = new RtfCtrlWordHandler(rtfParser, "noafcnsttbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nobrkwrptbl"] = new RtfCtrlWordHandler(rtfParser, "nobrkwrptbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nocolbal"] = new RtfCtrlWordHandler(rtfParser, "nocolbal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nocompatoptions"] = new RtfCtrlWordHandler(rtfParser, "nocompatoptions", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nocwrap"] = new RtfCtrlWordHandler(rtfParser, "nocwrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nocxsptable"] = new RtfCtrlWordHandler(rtfParser, "nocxsptable", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["noextrasprl"] = new RtfCtrlWordHandler(rtfParser, "noextrasprl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nofchars"] = new RtfCtrlWordHandler(rtfParser, "nofchars", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["nofcharsws"] = new RtfCtrlWordHandler(rtfParser, "nofcharsws", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["nofeaturethrottle"] = new RtfCtrlWordHandler(rtfParser, "nofeaturethrottle", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nofpages"] = new RtfCtrlWordHandler(rtfParser, "nofpages", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["nofwords"] = new RtfCtrlWordHandler(rtfParser, "nofwords", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["nogrowautofit"] = new RtfCtrlWordHandler(rtfParser, "nogrowautofit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["noindnmbrts"] = new RtfCtrlWordHandler(rtfParser, "noindnmbrts", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nojkernpunct"] = new RtfCtrlWordHandler(rtfParser, "nojkernpunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nolead"] = new RtfCtrlWordHandler(rtfParser, "nolead", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["noline"] = new RtfCtrlWordHandler(rtfParser, "noline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nolnhtadjtbl"] = new RtfCtrlWordHandler(rtfParser, "nolnhtadjtbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nonesttables"] = new RtfCtrlWordHandler(rtfParser, "nonesttables", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["nonshppict"] = new RtfCtrlWordHandler(rtfParser, "nonshppict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["nooverflow"] = new RtfCtrlWordHandler(rtfParser, "nooverflow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["noproof"] = new RtfCtrlWordHandler(rtfParser, "noproof", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["noqfpromote"] = new RtfCtrlWordHandler(rtfParser, "noqfpromote", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nosectexpand"] = new RtfCtrlWordHandler(rtfParser, "nosectexpand", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nosnaplinegrid"] = new RtfCtrlWordHandler(rtfParser, "nosnaplinegrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nospaceforul"] = new RtfCtrlWordHandler(rtfParser, "nospaceforul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nosupersub"] = new RtfCtrlWordHandler(rtfParser, "nosupersub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["notabind"] = new RtfCtrlWordHandler(rtfParser, "notabind", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["notbrkcnstfrctbl"] = new RtfCtrlWordHandler(rtfParser, "notbrkcnstfrctbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["notcvasp"] = new RtfCtrlWordHandler(rtfParser, "notcvasp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["notvatxbx"] = new RtfCtrlWordHandler(rtfParser, "notvatxbx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nouicompat"] = new RtfCtrlWordHandler(rtfParser, "nouicompat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["noultrlspc"] = new RtfCtrlWordHandler(rtfParser, "noultrlspc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nowidctlpar"] = new RtfCtrlWordHandler(rtfParser, "nowidctlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nowrap"] = new RtfCtrlWordHandler(rtfParser, "nowrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["nowwrap"] = new RtfCtrlWordHandler(rtfParser, "nowwrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["noxlattoyen"] = new RtfCtrlWordHandler(rtfParser, "noxlattoyen", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objalias"] = new RtfCtrlWordHandler(rtfParser, "objalias", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["objalign"] = new RtfCtrlWordHandler(rtfParser, "objalign", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objattph"] = new RtfCtrlWordHandler(rtfParser, "objattph", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objautlink"] = new RtfCtrlWordHandler(rtfParser, "objautlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objclass"] = new RtfCtrlWordHandler(rtfParser, "objclass", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["objcropb"] = new RtfCtrlWordHandler(rtfParser, "objcropb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objcropl"] = new RtfCtrlWordHandler(rtfParser, "objcropl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objcropr"] = new RtfCtrlWordHandler(rtfParser, "objcropr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objcropt"] = new RtfCtrlWordHandler(rtfParser, "objcropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objdata"] = new RtfCtrlWordHandler(rtfParser, "objdata", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["object"] = new RtfCtrlWordHandler(rtfParser, "object", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["objemb"] = new RtfCtrlWordHandler(rtfParser, "objemb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objh"] = new RtfCtrlWordHandler(rtfParser, "objh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objhtml"] = new RtfCtrlWordHandler(rtfParser, "objhtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objicemb"] = new RtfCtrlWordHandler(rtfParser, "objicemb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objlink"] = new RtfCtrlWordHandler(rtfParser, "objlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objlock"] = new RtfCtrlWordHandler(rtfParser, "objlock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objname"] = new RtfCtrlWordHandler(rtfParser, "objname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["objocx"] = new RtfCtrlWordHandler(rtfParser, "objocx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objpub"] = new RtfCtrlWordHandler(rtfParser, "objpub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objscalex"] = new RtfCtrlWordHandler(rtfParser, "objscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objscaley"] = new RtfCtrlWordHandler(rtfParser, "objscaley", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objsect"] = new RtfCtrlWordHandler(rtfParser, "objsect", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["objsetsize"] = new RtfCtrlWordHandler(rtfParser, "objsetsize", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objsub"] = new RtfCtrlWordHandler(rtfParser, "objsub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objtime"] = new RtfCtrlWordHandler(rtfParser, "objtime", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["objtransy"] = new RtfCtrlWordHandler(rtfParser, "objtransy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["objupdate"] = new RtfCtrlWordHandler(rtfParser, "objupdate", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["objw"] = new RtfCtrlWordHandler(rtfParser, "objw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["oldas"] = new RtfCtrlWordHandler(rtfParser, "oldas", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["oldcprops"] = new RtfCtrlWordHandler(rtfParser, "oldcprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["oldlinewrap"] = new RtfCtrlWordHandler(rtfParser, "oldlinewrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["oldpprops"] = new RtfCtrlWordHandler(rtfParser, "oldpprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["oldsprops"] = new RtfCtrlWordHandler(rtfParser, "oldsprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["oldtprops"] = new RtfCtrlWordHandler(rtfParser, "oldtprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["oleclsid"] = new RtfCtrlWordHandler(rtfParser, "oleclsid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["operator"] = new RtfCtrlWordHandler(rtfParser, "operator", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["otblrul"] = new RtfCtrlWordHandler(rtfParser, "otblrul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["outl"] = new RtfCtrlWordHandler(rtfParser, "outl", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["outlinelevel"] = new RtfCtrlWordHandler(rtfParser, "outlinelevel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["overlay"] = new RtfCtrlWordHandler(rtfParser, "overlay", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["page"] = new RtfCtrlWordHandler(rtfParser, "page", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["pagebb"] = new RtfCtrlWordHandler(rtfParser, "pagebb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["panose"] = new RtfCtrlWordHandler(rtfParser, "panose", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull");
+ ctrlWords["paperh"] = new RtfCtrlWordHandler(rtfParser, "paperh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["paperw"] = new RtfCtrlWordHandler(rtfParser, "paperw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["par"] = new RtfCtrlWordHandler(rtfParser, "par", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\n");
+ ctrlWords["pararsid"] = new RtfCtrlWordHandler(rtfParser, "pararsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pard"] = new RtfCtrlWordHandler(rtfParser, "pard", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["passwordhash"] = new RtfCtrlWordHandler(rtfParser, "passwordhash", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["pc"] = new RtfCtrlWordHandler(rtfParser, "pc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pca"] = new RtfCtrlWordHandler(rtfParser, "pca", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgbrdrb"] = new RtfCtrlWordHandler(rtfParser, "pgbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgbrdrfoot"] = new RtfCtrlWordHandler(rtfParser, "pgbrdrfoot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgbrdrhead"] = new RtfCtrlWordHandler(rtfParser, "pgbrdrhead", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgbrdrl"] = new RtfCtrlWordHandler(rtfParser, "pgbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgbrdropt"] = new RtfCtrlWordHandler(rtfParser, "pgbrdropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgbrdrr"] = new RtfCtrlWordHandler(rtfParser, "pgbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgbrdrsnap"] = new RtfCtrlWordHandler(rtfParser, "pgbrdrsnap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgbrdrt"] = new RtfCtrlWordHandler(rtfParser, "pgbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pghsxn"] = new RtfCtrlWordHandler(rtfParser, "pghsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgnbidia"] = new RtfCtrlWordHandler(rtfParser, "pgnbidia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnbidib"] = new RtfCtrlWordHandler(rtfParser, "pgnbidib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnchosung"] = new RtfCtrlWordHandler(rtfParser, "pgnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgncnum"] = new RtfCtrlWordHandler(rtfParser, "pgncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgncont"] = new RtfCtrlWordHandler(rtfParser, "pgncont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgndbnum"] = new RtfCtrlWordHandler(rtfParser, "pgndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgndbnumd"] = new RtfCtrlWordHandler(rtfParser, "pgndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgndbnumk"] = new RtfCtrlWordHandler(rtfParser, "pgndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgndbnumt"] = new RtfCtrlWordHandler(rtfParser, "pgndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgndec"] = new RtfCtrlWordHandler(rtfParser, "pgndec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgndecd"] = new RtfCtrlWordHandler(rtfParser, "pgndecd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnganada"] = new RtfCtrlWordHandler(rtfParser, "pgnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgngbnum"] = new RtfCtrlWordHandler(rtfParser, "pgngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgngbnumd"] = new RtfCtrlWordHandler(rtfParser, "pgngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgngbnumk"] = new RtfCtrlWordHandler(rtfParser, "pgngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgngbnuml"] = new RtfCtrlWordHandler(rtfParser, "pgngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhindia"] = new RtfCtrlWordHandler(rtfParser, "pgnhindia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhindib"] = new RtfCtrlWordHandler(rtfParser, "pgnhindib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhindic"] = new RtfCtrlWordHandler(rtfParser, "pgnhindic", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhindid"] = new RtfCtrlWordHandler(rtfParser, "pgnhindid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhn"] = new RtfCtrlWordHandler(rtfParser, "pgnhn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgnhnsc"] = new RtfCtrlWordHandler(rtfParser, "pgnhnsc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhnsh"] = new RtfCtrlWordHandler(rtfParser, "pgnhnsh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhnsm"] = new RtfCtrlWordHandler(rtfParser, "pgnhnsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhnsn"] = new RtfCtrlWordHandler(rtfParser, "pgnhnsn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnhnsp"] = new RtfCtrlWordHandler(rtfParser, "pgnhnsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnid"] = new RtfCtrlWordHandler(rtfParser, "pgnid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgnlcltr"] = new RtfCtrlWordHandler(rtfParser, "pgnlcltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnlcrm"] = new RtfCtrlWordHandler(rtfParser, "pgnlcrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnrestart"] = new RtfCtrlWordHandler(rtfParser, "pgnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnstart"] = new RtfCtrlWordHandler(rtfParser, "pgnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgnstarts"] = new RtfCtrlWordHandler(rtfParser, "pgnstarts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgnthaia"] = new RtfCtrlWordHandler(rtfParser, "pgnthaia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnthaib"] = new RtfCtrlWordHandler(rtfParser, "pgnthaib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnthaic"] = new RtfCtrlWordHandler(rtfParser, "pgnthaic", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnucltr"] = new RtfCtrlWordHandler(rtfParser, "pgnucltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnucrm"] = new RtfCtrlWordHandler(rtfParser, "pgnucrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnvieta"] = new RtfCtrlWordHandler(rtfParser, "pgnvieta", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnx"] = new RtfCtrlWordHandler(rtfParser, "pgnx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgny"] = new RtfCtrlWordHandler(rtfParser, "pgny", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pgnzodiac"] = new RtfCtrlWordHandler(rtfParser, "pgnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnzodiacd"] = new RtfCtrlWordHandler(rtfParser, "pgnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgnzodiacl"] = new RtfCtrlWordHandler(rtfParser, "pgnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pgp"] = new RtfCtrlWordHandler(rtfParser, "pgp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["pgptbl"] = new RtfCtrlWordHandler(rtfParser, "pgptbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull");
+ ctrlWords["pgwsxn"] = new RtfCtrlWordHandler(rtfParser, "pgwsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["phcol"] = new RtfCtrlWordHandler(rtfParser, "phcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["phmrg"] = new RtfCtrlWordHandler(rtfParser, "phmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["phnthaia"] = new RtfCtrlWordHandler(rtfParser, "phnthaia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["phpg"] = new RtfCtrlWordHandler(rtfParser, "phpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["picbmp"] = new RtfCtrlWordHandler(rtfParser, "picbmp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["picbpp"] = new RtfCtrlWordHandler(rtfParser, "picbpp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["piccropb"] = new RtfCtrlWordHandler(rtfParser, "piccropb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["piccropl"] = new RtfCtrlWordHandler(rtfParser, "piccropl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["piccropr"] = new RtfCtrlWordHandler(rtfParser, "piccropr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["piccropt"] = new RtfCtrlWordHandler(rtfParser, "piccropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pich"] = new RtfCtrlWordHandler(rtfParser, "pich", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pichgoal"] = new RtfCtrlWordHandler(rtfParser, "pichgoal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["picprop"] = new RtfCtrlWordHandler(rtfParser, "picprop", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationShppict" );
+ ctrlWords["picscaled"] = new RtfCtrlWordHandler(rtfParser, "picscaled", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["picscalex"] = new RtfCtrlWordHandler(rtfParser, "picscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["picscaley"] = new RtfCtrlWordHandler(rtfParser, "picscaley", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pict"] = new RtfCtrlWordHandler(rtfParser, "pict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationShppict" );
+ ctrlWords["picw"] = new RtfCtrlWordHandler(rtfParser, "picw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["picwgoal"] = new RtfCtrlWordHandler(rtfParser, "picwgoal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pindtabqc"] = new RtfCtrlWordHandler(rtfParser, "pindtabqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pindtabql"] = new RtfCtrlWordHandler(rtfParser, "pindtabql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pindtabqr"] = new RtfCtrlWordHandler(rtfParser, "pindtabqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["plain"] = new RtfCtrlWordHandler(rtfParser, "plain", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pmartabqc"] = new RtfCtrlWordHandler(rtfParser, "pmartabqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pmartabql"] = new RtfCtrlWordHandler(rtfParser, "pmartabql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pmartabqr"] = new RtfCtrlWordHandler(rtfParser, "pmartabqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pmmetafile"] = new RtfCtrlWordHandler(rtfParser, "pmmetafile", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pn"] = new RtfCtrlWordHandler(rtfParser, "pn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["pnacross"] = new RtfCtrlWordHandler(rtfParser, "pnacross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnaiu"] = new RtfCtrlWordHandler(rtfParser, "pnaiu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnaiud"] = new RtfCtrlWordHandler(rtfParser, "pnaiud", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnaiueo"] = new RtfCtrlWordHandler(rtfParser, "pnaiueo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnaiueod"] = new RtfCtrlWordHandler(rtfParser, "pnaiueod", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnb"] = new RtfCtrlWordHandler(rtfParser, "pnb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["pnbidia"] = new RtfCtrlWordHandler(rtfParser, "pnbidia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnbidib"] = new RtfCtrlWordHandler(rtfParser, "pnbidib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pncaps"] = new RtfCtrlWordHandler(rtfParser, "pncaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["pncard"] = new RtfCtrlWordHandler(rtfParser, "pncard", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pncf"] = new RtfCtrlWordHandler(rtfParser, "pncf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnchosung"] = new RtfCtrlWordHandler(rtfParser, "pnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pncnum"] = new RtfCtrlWordHandler(rtfParser, "pncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pndbnum"] = new RtfCtrlWordHandler(rtfParser, "pndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pndbnumd"] = new RtfCtrlWordHandler(rtfParser, "pndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pndbnumk"] = new RtfCtrlWordHandler(rtfParser, "pndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pndbnuml"] = new RtfCtrlWordHandler(rtfParser, "pndbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pndbnumt"] = new RtfCtrlWordHandler(rtfParser, "pndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pndec"] = new RtfCtrlWordHandler(rtfParser, "pndec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pndecd"] = new RtfCtrlWordHandler(rtfParser, "pndecd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnf"] = new RtfCtrlWordHandler(rtfParser, "pnf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnfs"] = new RtfCtrlWordHandler(rtfParser, "pnfs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnganada"] = new RtfCtrlWordHandler(rtfParser, "pnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pngblip"] = new RtfCtrlWordHandler(rtfParser, "pngblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pngbnum"] = new RtfCtrlWordHandler(rtfParser, "pngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pngbnumd"] = new RtfCtrlWordHandler(rtfParser, "pngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pngbnumk"] = new RtfCtrlWordHandler(rtfParser, "pngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pngbnuml"] = new RtfCtrlWordHandler(rtfParser, "pngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnhang"] = new RtfCtrlWordHandler(rtfParser, "pnhang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pni"] = new RtfCtrlWordHandler(rtfParser, "pni", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["pnindent"] = new RtfCtrlWordHandler(rtfParser, "pnindent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pniroha"] = new RtfCtrlWordHandler(rtfParser, "pniroha", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnirohad"] = new RtfCtrlWordHandler(rtfParser, "pnirohad", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnlcltr"] = new RtfCtrlWordHandler(rtfParser, "pnlcltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnlcrm"] = new RtfCtrlWordHandler(rtfParser, "pnlcrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnlvl"] = new RtfCtrlWordHandler(rtfParser, "pnlvl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnlvlblt"] = new RtfCtrlWordHandler(rtfParser, "pnlvlblt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnlvlbody"] = new RtfCtrlWordHandler(rtfParser, "pnlvlbody", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnlvlcont"] = new RtfCtrlWordHandler(rtfParser, "pnlvlcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnnumonce"] = new RtfCtrlWordHandler(rtfParser, "pnnumonce", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnord"] = new RtfCtrlWordHandler(rtfParser, "pnord", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnordt"] = new RtfCtrlWordHandler(rtfParser, "pnordt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnprev"] = new RtfCtrlWordHandler(rtfParser, "pnprev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnqc"] = new RtfCtrlWordHandler(rtfParser, "pnqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnql"] = new RtfCtrlWordHandler(rtfParser, "pnql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnqr"] = new RtfCtrlWordHandler(rtfParser, "pnqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnrauth"] = new RtfCtrlWordHandler(rtfParser, "pnrauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnrdate"] = new RtfCtrlWordHandler(rtfParser, "pnrdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnrestart"] = new RtfCtrlWordHandler(rtfParser, "pnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnrnfc"] = new RtfCtrlWordHandler(rtfParser, "pnrnfc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnrnot"] = new RtfCtrlWordHandler(rtfParser, "pnrnot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnrpnbr"] = new RtfCtrlWordHandler(rtfParser, "pnrpnbr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnrrgb"] = new RtfCtrlWordHandler(rtfParser, "pnrrgb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnrstart"] = new RtfCtrlWordHandler(rtfParser, "pnrstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnrstop"] = new RtfCtrlWordHandler(rtfParser, "pnrstop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnrxst"] = new RtfCtrlWordHandler(rtfParser, "pnrxst", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnscaps"] = new RtfCtrlWordHandler(rtfParser, "pnscaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["pnseclvl"] = new RtfCtrlWordHandler(rtfParser, "pnseclvl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["pnsp"] = new RtfCtrlWordHandler(rtfParser, "pnsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnstart"] = new RtfCtrlWordHandler(rtfParser, "pnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["pnstrike"] = new RtfCtrlWordHandler(rtfParser, "pnstrike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["pntext"] = new RtfCtrlWordHandler(rtfParser, "pntext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["pntxta"] = new RtfCtrlWordHandler(rtfParser, "pntxta", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["pntxtb"] = new RtfCtrlWordHandler(rtfParser, "pntxtb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["pnucltr"] = new RtfCtrlWordHandler(rtfParser, "pnucltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnucrm"] = new RtfCtrlWordHandler(rtfParser, "pnucrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnul"] = new RtfCtrlWordHandler(rtfParser, "pnul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["pnuld"] = new RtfCtrlWordHandler(rtfParser, "pnuld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnuldash"] = new RtfCtrlWordHandler(rtfParser, "pnuldash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnuldashd"] = new RtfCtrlWordHandler(rtfParser, "pnuldashd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnuldashdd"] = new RtfCtrlWordHandler(rtfParser, "pnuldashdd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnuldb"] = new RtfCtrlWordHandler(rtfParser, "pnuldb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnulhair"] = new RtfCtrlWordHandler(rtfParser, "pnulhair", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnulnone"] = new RtfCtrlWordHandler(rtfParser, "pnulnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnulth"] = new RtfCtrlWordHandler(rtfParser, "pnulth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnulw"] = new RtfCtrlWordHandler(rtfParser, "pnulw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnulwave"] = new RtfCtrlWordHandler(rtfParser, "pnulwave", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnzodiac"] = new RtfCtrlWordHandler(rtfParser, "pnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnzodiacd"] = new RtfCtrlWordHandler(rtfParser, "pnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pnzodiacl"] = new RtfCtrlWordHandler(rtfParser, "pnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posnegx"] = new RtfCtrlWordHandler(rtfParser, "posnegx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["posnegy"] = new RtfCtrlWordHandler(rtfParser, "posnegy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["posx"] = new RtfCtrlWordHandler(rtfParser, "posx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["posxc"] = new RtfCtrlWordHandler(rtfParser, "posxc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posxi"] = new RtfCtrlWordHandler(rtfParser, "posxi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posxl"] = new RtfCtrlWordHandler(rtfParser, "posxl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posxo"] = new RtfCtrlWordHandler(rtfParser, "posxo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posxr"] = new RtfCtrlWordHandler(rtfParser, "posxr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posy"] = new RtfCtrlWordHandler(rtfParser, "posy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["posyb"] = new RtfCtrlWordHandler(rtfParser, "posyb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posyc"] = new RtfCtrlWordHandler(rtfParser, "posyc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posyil"] = new RtfCtrlWordHandler(rtfParser, "posyil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posyin"] = new RtfCtrlWordHandler(rtfParser, "posyin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posyout"] = new RtfCtrlWordHandler(rtfParser, "posyout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["posyt"] = new RtfCtrlWordHandler(rtfParser, "posyt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["prcolbl"] = new RtfCtrlWordHandler(rtfParser, "prcolbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["printdata"] = new RtfCtrlWordHandler(rtfParser, "printdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["printim"] = new RtfCtrlWordHandler(rtfParser, "printim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["private"] = new RtfCtrlWordHandler(rtfParser, "private", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["propname"] = new RtfCtrlWordHandler(rtfParser, "propname", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["proptype"] = new RtfCtrlWordHandler(rtfParser, "proptype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["protend"] = new RtfCtrlWordHandler(rtfParser, "protend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["protlevel"] = new RtfCtrlWordHandler(rtfParser, "protlevel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["protstart"] = new RtfCtrlWordHandler(rtfParser, "protstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["protusertbl"] = new RtfCtrlWordHandler(rtfParser, "protusertbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["psover"] = new RtfCtrlWordHandler(rtfParser, "psover", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["psz"] = new RtfCtrlWordHandler(rtfParser, "psz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ptabldot"] = new RtfCtrlWordHandler(rtfParser, "ptabldot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ptablmdot"] = new RtfCtrlWordHandler(rtfParser, "ptablmdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ptablminus"] = new RtfCtrlWordHandler(rtfParser, "ptablminus", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ptablnone"] = new RtfCtrlWordHandler(rtfParser, "ptablnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ptabluscore"] = new RtfCtrlWordHandler(rtfParser, "ptabluscore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pubauto"] = new RtfCtrlWordHandler(rtfParser, "pubauto", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pvmrg"] = new RtfCtrlWordHandler(rtfParser, "pvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pvpara"] = new RtfCtrlWordHandler(rtfParser, "pvpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pvpg"] = new RtfCtrlWordHandler(rtfParser, "pvpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["pwd"] = new RtfCtrlWordHandler(rtfParser, "pwd", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["pxe"] = new RtfCtrlWordHandler(rtfParser, "pxe", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["qc"] = new RtfCtrlWordHandler(rtfParser, "qc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["qd"] = new RtfCtrlWordHandler(rtfParser, "qd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["qj"] = new RtfCtrlWordHandler(rtfParser, "qj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["qk"] = new RtfCtrlWordHandler(rtfParser, "qk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ql"] = new RtfCtrlWordHandler(rtfParser, "ql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["qmspace"] = new RtfCtrlWordHandler(rtfParser, "qmspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["qr"] = new RtfCtrlWordHandler(rtfParser, "qr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["qt"] = new RtfCtrlWordHandler(rtfParser, "qt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawbgdkbdiag"] = new RtfCtrlWordHandler(rtfParser, "rawbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgbdiag"] = new RtfCtrlWordHandler(rtfParser, "rawclbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgcross"] = new RtfCtrlWordHandler(rtfParser, "rawclbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgdcross"] = new RtfCtrlWordHandler(rtfParser, "rawclbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgdkbdiag"] = new RtfCtrlWordHandler(rtfParser, "rawclbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgdkcross"] = new RtfCtrlWordHandler(rtfParser, "rawclbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgdkdcross"] = new RtfCtrlWordHandler(rtfParser, "rawclbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgdkfdiag"] = new RtfCtrlWordHandler(rtfParser, "rawclbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgdkhor"] = new RtfCtrlWordHandler(rtfParser, "rawclbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgdkvert"] = new RtfCtrlWordHandler(rtfParser, "rawclbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgfdiag"] = new RtfCtrlWordHandler(rtfParser, "rawclbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbghoriz"] = new RtfCtrlWordHandler(rtfParser, "rawclbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rawclbgvert"] = new RtfCtrlWordHandler(rtfParser, "rawclbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rdblquote"] = new RtfCtrlWordHandler(rtfParser, "rdblquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x148");
+ ctrlWords["readonlyrecommended"] = new RtfCtrlWordHandler(rtfParser, "readonlyrecommended", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["readprot"] = new RtfCtrlWordHandler(rtfParser, "readprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["red"] = new RtfCtrlWordHandler(rtfParser, "red", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["relyonvml"] = new RtfCtrlWordHandler(rtfParser, "relyonvml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rempersonalinfo"] = new RtfCtrlWordHandler(rtfParser, "rempersonalinfo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["result"] = new RtfCtrlWordHandler(rtfParser, "result", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["revauth"] = new RtfCtrlWordHandler(rtfParser, "revauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["revauthdel"] = new RtfCtrlWordHandler(rtfParser, "revauthdel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["revbar"] = new RtfCtrlWordHandler(rtfParser, "revbar", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["revdttm"] = new RtfCtrlWordHandler(rtfParser, "revdttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["revdttmdel"] = new RtfCtrlWordHandler(rtfParser, "revdttmdel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["revised"] = new RtfCtrlWordHandler(rtfParser, "revised", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["revisions"] = new RtfCtrlWordHandler(rtfParser, "revisions", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["revprop"] = new RtfCtrlWordHandler(rtfParser, "revprop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["revprot"] = new RtfCtrlWordHandler(rtfParser, "revprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["revtbl"] = new RtfCtrlWordHandler(rtfParser, "revtbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull");
+ ctrlWords["revtim"] = new RtfCtrlWordHandler(rtfParser, "revtim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull");
+ ctrlWords["ri"] = new RtfCtrlWordHandler(rtfParser, "ri", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["rin"] = new RtfCtrlWordHandler(rtfParser, "rin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["row"] = new RtfCtrlWordHandler(rtfParser, "row", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["rquote"] = new RtfCtrlWordHandler(rtfParser, "rquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x146");
+ ctrlWords["rsid"] = new RtfCtrlWordHandler(rtfParser, "rsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["rsidroot"] = new RtfCtrlWordHandler(rtfParser, "rsidroot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["rsidtbl"] = new RtfCtrlWordHandler(rtfParser, "rsidtbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull");
+ ctrlWords["rsltbmp"] = new RtfCtrlWordHandler(rtfParser, "rsltbmp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rslthtml"] = new RtfCtrlWordHandler(rtfParser, "rslthtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rsltmerge"] = new RtfCtrlWordHandler(rtfParser, "rsltmerge", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rsltpict"] = new RtfCtrlWordHandler(rtfParser, "rsltpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rsltrtf"] = new RtfCtrlWordHandler(rtfParser, "rsltrtf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rslttxt"] = new RtfCtrlWordHandler(rtfParser, "rslttxt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rtf"] = new RtfCtrlWordHandler(rtfParser, "rtf", 1, true, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["rtlch"] = new RtfCtrlWordHandler(rtfParser, "rtlch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rtldoc"] = new RtfCtrlWordHandler(rtfParser, "rtldoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rtlgutter"] = new RtfCtrlWordHandler(rtfParser, "rtlgutter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rtlmark"] = new RtfCtrlWordHandler(rtfParser, "rtlmark", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["rtlpar"] = new RtfCtrlWordHandler(rtfParser, "rtlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rtlrow"] = new RtfCtrlWordHandler(rtfParser, "rtlrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rtlsect"] = new RtfCtrlWordHandler(rtfParser, "rtlsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["rxe"] = new RtfCtrlWordHandler(rtfParser, "rxe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["s"] = new RtfCtrlWordHandler(rtfParser, "s", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sa"] = new RtfCtrlWordHandler(rtfParser, "sa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["saauto"] = new RtfCtrlWordHandler(rtfParser, "saauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["saftnnalc"] = new RtfCtrlWordHandler(rtfParser, "saftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnar"] = new RtfCtrlWordHandler(rtfParser, "saftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnauc"] = new RtfCtrlWordHandler(rtfParser, "saftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnchi"] = new RtfCtrlWordHandler(rtfParser, "saftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnchosung"] = new RtfCtrlWordHandler(rtfParser, "saftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnncnum"] = new RtfCtrlWordHandler(rtfParser, "saftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnndbar"] = new RtfCtrlWordHandler(rtfParser, "saftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnndbnum"] = new RtfCtrlWordHandler(rtfParser, "saftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnndbnumd"] = new RtfCtrlWordHandler(rtfParser, "saftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnndbnumk"] = new RtfCtrlWordHandler(rtfParser, "saftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnndbnumt"] = new RtfCtrlWordHandler(rtfParser, "saftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnganada"] = new RtfCtrlWordHandler(rtfParser, "saftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnngbnum"] = new RtfCtrlWordHandler(rtfParser, "saftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnngbnumd"] = new RtfCtrlWordHandler(rtfParser, "saftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnngbnumk"] = new RtfCtrlWordHandler(rtfParser, "saftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnngbnuml"] = new RtfCtrlWordHandler(rtfParser, "saftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnrlc"] = new RtfCtrlWordHandler(rtfParser, "saftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnruc"] = new RtfCtrlWordHandler(rtfParser, "saftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnzodiac"] = new RtfCtrlWordHandler(rtfParser, "saftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnzodiacd"] = new RtfCtrlWordHandler(rtfParser, "saftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnnzodiacl"] = new RtfCtrlWordHandler(rtfParser, "saftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnrestart"] = new RtfCtrlWordHandler(rtfParser, "saftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnrstcont"] = new RtfCtrlWordHandler(rtfParser, "saftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saftnstart"] = new RtfCtrlWordHandler(rtfParser, "saftnstart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sautoupd"] = new RtfCtrlWordHandler(rtfParser, "sautoupd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saveinvalidxml"] = new RtfCtrlWordHandler(rtfParser, "saveinvalidxml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["saveprevpict"] = new RtfCtrlWordHandler(rtfParser, "saveprevpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sb"] = new RtfCtrlWordHandler(rtfParser, "sb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sbasedon"] = new RtfCtrlWordHandler(rtfParser, "sbasedon", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sbauto"] = new RtfCtrlWordHandler(rtfParser, "sbauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["sbkcol"] = new RtfCtrlWordHandler(rtfParser, "sbkcol", RtfProperty.SBK_COLUMN, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE);
+ ctrlWords["sbkeven"] = new RtfCtrlWordHandler(rtfParser, "sbkeven", RtfProperty.SBK_EVEN, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE);
+ ctrlWords["sbknone"] = new RtfCtrlWordHandler(rtfParser, "sbknone", RtfProperty.SBK_NONE, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE);
+ ctrlWords["sbkodd"] = new RtfCtrlWordHandler(rtfParser, "sbkodd", RtfProperty.SBK_ODD, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE);
+ ctrlWords["sbkpage"] = new RtfCtrlWordHandler(rtfParser, "sbkpage", RtfProperty.SBK_PAGE, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE);
+ ctrlWords["sbys"] = new RtfCtrlWordHandler(rtfParser, "sbys", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["scaps"] = new RtfCtrlWordHandler(rtfParser, "scaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["scompose"] = new RtfCtrlWordHandler(rtfParser, "scompose", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sec"] = new RtfCtrlWordHandler(rtfParser, "sec", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sect"] = new RtfCtrlWordHandler(rtfParser, "sect", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["sectd"] = new RtfCtrlWordHandler(rtfParser, "sectd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sectdefaultcl"] = new RtfCtrlWordHandler(rtfParser, "sectdefaultcl", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sectexpand"] = new RtfCtrlWordHandler(rtfParser, "sectexpand", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sectlinegrid"] = new RtfCtrlWordHandler(rtfParser, "sectlinegrid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sectnum"] = new RtfCtrlWordHandler(rtfParser, "sectnum", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["sectrsid"] = new RtfCtrlWordHandler(rtfParser, "sectrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sectspecifycl"] = new RtfCtrlWordHandler(rtfParser, "sectspecifycl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sectspecifygen"] = new RtfCtrlWordHandler(rtfParser, "sectspecifygen", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sectspecifyl"] = new RtfCtrlWordHandler(rtfParser, "sectspecifyl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sectunlocked"] = new RtfCtrlWordHandler(rtfParser, "sectunlocked", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnbj"] = new RtfCtrlWordHandler(rtfParser, "sftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnalc"] = new RtfCtrlWordHandler(rtfParser, "sftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnar"] = new RtfCtrlWordHandler(rtfParser, "sftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnauc"] = new RtfCtrlWordHandler(rtfParser, "sftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnchi"] = new RtfCtrlWordHandler(rtfParser, "sftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnchosung"] = new RtfCtrlWordHandler(rtfParser, "sftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnncnum"] = new RtfCtrlWordHandler(rtfParser, "sftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnndbar"] = new RtfCtrlWordHandler(rtfParser, "sftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnndbnum"] = new RtfCtrlWordHandler(rtfParser, "sftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnndbnumd"] = new RtfCtrlWordHandler(rtfParser, "sftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnndbnumk"] = new RtfCtrlWordHandler(rtfParser, "sftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnndbnumt"] = new RtfCtrlWordHandler(rtfParser, "sftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnganada"] = new RtfCtrlWordHandler(rtfParser, "sftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnngbnum"] = new RtfCtrlWordHandler(rtfParser, "sftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnngbnumd"] = new RtfCtrlWordHandler(rtfParser, "sftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnngbnumk"] = new RtfCtrlWordHandler(rtfParser, "sftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnngbnuml"] = new RtfCtrlWordHandler(rtfParser, "sftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnrlc"] = new RtfCtrlWordHandler(rtfParser, "sftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnruc"] = new RtfCtrlWordHandler(rtfParser, "sftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnzodiac"] = new RtfCtrlWordHandler(rtfParser, "sftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnzodiacd"] = new RtfCtrlWordHandler(rtfParser, "sftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnnzodiacl"] = new RtfCtrlWordHandler(rtfParser, "sftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnrestart"] = new RtfCtrlWordHandler(rtfParser, "sftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnrstcont"] = new RtfCtrlWordHandler(rtfParser, "sftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnrstpg"] = new RtfCtrlWordHandler(rtfParser, "sftnrstpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftnstart"] = new RtfCtrlWordHandler(rtfParser, "sftnstart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sftntj"] = new RtfCtrlWordHandler(rtfParser, "sftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shad"] = new RtfCtrlWordHandler(rtfParser, "shad", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["shading"] = new RtfCtrlWordHandler(rtfParser, "shading", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shidden"] = new RtfCtrlWordHandler(rtfParser, "shidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shift"] = new RtfCtrlWordHandler(rtfParser, "shift", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["showplaceholdtext"] = new RtfCtrlWordHandler(rtfParser, "showplaceholdtext", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["showxmlerrors"] = new RtfCtrlWordHandler(rtfParser, "showxmlerrors", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shp"] = new RtfCtrlWordHandler(rtfParser, "shp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["shpbottom"] = new RtfCtrlWordHandler(rtfParser, "shpbottom", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shpbxcolumn"] = new RtfCtrlWordHandler(rtfParser, "shpbxcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shpbxignore"] = new RtfCtrlWordHandler(rtfParser, "shpbxignore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shpbxmargin"] = new RtfCtrlWordHandler(rtfParser, "shpbxmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shpbxpage"] = new RtfCtrlWordHandler(rtfParser, "shpbxpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shpbyignore"] = new RtfCtrlWordHandler(rtfParser, "shpbyignore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shpbymargin"] = new RtfCtrlWordHandler(rtfParser, "shpbymargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shpbypage"] = new RtfCtrlWordHandler(rtfParser, "shpbypage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shpbypara"] = new RtfCtrlWordHandler(rtfParser, "shpbypara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shpfblwtxt"] = new RtfCtrlWordHandler(rtfParser, "shpfblwtxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shpfhdr"] = new RtfCtrlWordHandler(rtfParser, "shpfhdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shpgrp"] = new RtfCtrlWordHandler(rtfParser, "shpgrp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shpinst"] = new RtfCtrlWordHandler(rtfParser, "shpinst", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["shpleft"] = new RtfCtrlWordHandler(rtfParser, "shpleft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shplid"] = new RtfCtrlWordHandler(rtfParser, "shplid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shplockanchor"] = new RtfCtrlWordHandler(rtfParser, "shplockanchor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["shppict"] = new RtfCtrlWordHandler(rtfParser, "shppict", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationShppict" );//"RtfDestinationShppict";
+ ctrlWords["shpright"] = new RtfCtrlWordHandler(rtfParser, "shpright", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shprslt"] = new RtfCtrlWordHandler(rtfParser, "shprslt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shptop"] = new RtfCtrlWordHandler(rtfParser, "shptop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shptxt"] = new RtfCtrlWordHandler(rtfParser, "shptxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shpwr"] = new RtfCtrlWordHandler(rtfParser, "shpwr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shpwrk"] = new RtfCtrlWordHandler(rtfParser, "shpwrk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["shpz"] = new RtfCtrlWordHandler(rtfParser, "shpz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sl"] = new RtfCtrlWordHandler(rtfParser, "sl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["slink"] = new RtfCtrlWordHandler(rtfParser, "slink", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["slmult"] = new RtfCtrlWordHandler(rtfParser, "slmult", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["slocked"] = new RtfCtrlWordHandler(rtfParser, "slocked", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sn"] = new RtfCtrlWordHandler(rtfParser, "sn", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["snapgridtocell"] = new RtfCtrlWordHandler(rtfParser, "snapgridtocell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["snaptogridincell"] = new RtfCtrlWordHandler(rtfParser, "snaptogridincell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["snext"] = new RtfCtrlWordHandler(rtfParser, "snext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["softcol"] = new RtfCtrlWordHandler(rtfParser, "softcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["softlheight"] = new RtfCtrlWordHandler(rtfParser, "softlheight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["softline"] = new RtfCtrlWordHandler(rtfParser, "softline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["softpage"] = new RtfCtrlWordHandler(rtfParser, "softpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sp"] = new RtfCtrlWordHandler(rtfParser, "sp", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["spersonal"] = new RtfCtrlWordHandler(rtfParser, "spersonal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["spltpgpar"] = new RtfCtrlWordHandler(rtfParser, "spltpgpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["splytwnine"] = new RtfCtrlWordHandler(rtfParser, "splytwnine", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["spp"] = new RtfCtrlWordHandler(rtfParser, "spp", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["spriority"] = new RtfCtrlWordHandler(rtfParser, "spriority", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sprsbsp"] = new RtfCtrlWordHandler(rtfParser, "sprsbsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sprslnsp"] = new RtfCtrlWordHandler(rtfParser, "sprslnsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sprsspbf"] = new RtfCtrlWordHandler(rtfParser, "sprsspbf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sprstsm"] = new RtfCtrlWordHandler(rtfParser, "sprstsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sprstsp"] = new RtfCtrlWordHandler(rtfParser, "sprstsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["spv"] = new RtfCtrlWordHandler(rtfParser, "spv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sqformat"] = new RtfCtrlWordHandler(rtfParser, "sqformat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sreply"] = new RtfCtrlWordHandler(rtfParser, "sreply", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ssemihidden"] = new RtfCtrlWordHandler(rtfParser, "ssemihidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["staticval"] = new RtfCtrlWordHandler(rtfParser, "staticval", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["stextflow"] = new RtfCtrlWordHandler(rtfParser, "stextflow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["strike"] = new RtfCtrlWordHandler(rtfParser, "strike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["striked1"] = new RtfCtrlWordHandler(rtfParser, "striked1", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["stshfbi"] = new RtfCtrlWordHandler(rtfParser, "stshfbi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["stshfdbch"] = new RtfCtrlWordHandler(rtfParser, "stshfdbch", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["stshfhich"] = new RtfCtrlWordHandler(rtfParser, "stshfhich", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["stshfloch"] = new RtfCtrlWordHandler(rtfParser, "stshfloch", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["stylelock"] = new RtfCtrlWordHandler(rtfParser, "stylelock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["stylelockbackcomp"] = new RtfCtrlWordHandler(rtfParser, "stylelockbackcomp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["stylelockenforced"] = new RtfCtrlWordHandler(rtfParser, "stylelockenforced", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["stylelockqfset"] = new RtfCtrlWordHandler(rtfParser, "stylelockqfset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["stylelocktheme"] = new RtfCtrlWordHandler(rtfParser, "stylelocktheme", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["stylesheet"] = new RtfCtrlWordHandler(rtfParser, "stylesheet", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationStylesheetTable");
+ ctrlWords["stylesortmethod"] = new RtfCtrlWordHandler(rtfParser, "stylesortmethod", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["styrsid"] = new RtfCtrlWordHandler(rtfParser, "styrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["sub"] = new RtfCtrlWordHandler(rtfParser, "sub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["subdocument"] = new RtfCtrlWordHandler(rtfParser, "subdocument", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["subfontbysize"] = new RtfCtrlWordHandler(rtfParser, "subfontbysize", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["subject"] = new RtfCtrlWordHandler(rtfParser, "subject", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["sunhideused"] = new RtfCtrlWordHandler(rtfParser, "sunhideused", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["super"] = new RtfCtrlWordHandler(rtfParser, "super", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["sv"] = new RtfCtrlWordHandler(rtfParser, "sv", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["svb"] = new RtfCtrlWordHandler(rtfParser, "svb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["swpbdr"] = new RtfCtrlWordHandler(rtfParser, "swpbdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tab"] = new RtfCtrlWordHandler(rtfParser, "tab", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["tabsnoovrlp"] = new RtfCtrlWordHandler(rtfParser, "tabsnoovrlp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["taprtl"] = new RtfCtrlWordHandler(rtfParser, "taprtl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tb"] = new RtfCtrlWordHandler(rtfParser, "tb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tblind"] = new RtfCtrlWordHandler(rtfParser, "tblind", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tblindtype"] = new RtfCtrlWordHandler(rtfParser, "tblindtype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tbllkbestfit"] = new RtfCtrlWordHandler(rtfParser, "tbllkbestfit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllkborder"] = new RtfCtrlWordHandler(rtfParser, "tbllkborder", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllkcolor"] = new RtfCtrlWordHandler(rtfParser, "tbllkcolor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllkfont"] = new RtfCtrlWordHandler(rtfParser, "tbllkfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllkhdrcols"] = new RtfCtrlWordHandler(rtfParser, "tbllkhdrcols", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllkhdrrows"] = new RtfCtrlWordHandler(rtfParser, "tbllkhdrrows", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllklastcol"] = new RtfCtrlWordHandler(rtfParser, "tbllklastcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllklastrow"] = new RtfCtrlWordHandler(rtfParser, "tbllklastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllknocolband"] = new RtfCtrlWordHandler(rtfParser, "tbllknocolband", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllknorowband"] = new RtfCtrlWordHandler(rtfParser, "tbllknorowband", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tbllkshading"] = new RtfCtrlWordHandler(rtfParser, "tbllkshading", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tblrsid"] = new RtfCtrlWordHandler(rtfParser, "tblrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tc"] = new RtfCtrlWordHandler(rtfParser, "tc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["tcelld"] = new RtfCtrlWordHandler(rtfParser, "tcelld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tcf"] = new RtfCtrlWordHandler(rtfParser, "tcf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tcl"] = new RtfCtrlWordHandler(rtfParser, "tcl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tcn"] = new RtfCtrlWordHandler(rtfParser, "tcn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tdfrmtxtBottom"] = new RtfCtrlWordHandler(rtfParser, "tdfrmtxtBottom", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tdfrmtxtLeft"] = new RtfCtrlWordHandler(rtfParser, "tdfrmtxtLeft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tdfrmtxtRight"] = new RtfCtrlWordHandler(rtfParser, "tdfrmtxtRight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tdfrmtxtTop"] = new RtfCtrlWordHandler(rtfParser, "tdfrmtxtTop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["template"] = new RtfCtrlWordHandler(rtfParser, "template", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["themedata"] = new RtfCtrlWordHandler(rtfParser, "themedata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["themelang"] = new RtfCtrlWordHandler(rtfParser, "themelang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["themelangcs"] = new RtfCtrlWordHandler(rtfParser, "themelangcs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["themelangfe"] = new RtfCtrlWordHandler(rtfParser, "themelangfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["time"] = new RtfCtrlWordHandler(rtfParser, "time", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["title"] = new RtfCtrlWordHandler(rtfParser, "title", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo");
+ ctrlWords["titlepg"] = new RtfCtrlWordHandler(rtfParser, "titlepg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tldot"] = new RtfCtrlWordHandler(rtfParser, "tldot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tleq"] = new RtfCtrlWordHandler(rtfParser, "tleq", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tlhyph"] = new RtfCtrlWordHandler(rtfParser, "tlhyph", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tlmdot"] = new RtfCtrlWordHandler(rtfParser, "tlmdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tlth"] = new RtfCtrlWordHandler(rtfParser, "tlth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tlul"] = new RtfCtrlWordHandler(rtfParser, "tlul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["toplinepunct"] = new RtfCtrlWordHandler(rtfParser, "toplinepunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tphcol"] = new RtfCtrlWordHandler(rtfParser, "tphcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tphmrg"] = new RtfCtrlWordHandler(rtfParser, "tphmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tphpg"] = new RtfCtrlWordHandler(rtfParser, "tphpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposnegx"] = new RtfCtrlWordHandler(rtfParser, "tposnegx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tposnegy"] = new RtfCtrlWordHandler(rtfParser, "tposnegy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tposx"] = new RtfCtrlWordHandler(rtfParser, "tposx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tposxc"] = new RtfCtrlWordHandler(rtfParser, "tposxc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposxi"] = new RtfCtrlWordHandler(rtfParser, "tposxi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposxl"] = new RtfCtrlWordHandler(rtfParser, "tposxl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposxo"] = new RtfCtrlWordHandler(rtfParser, "tposxo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposxr"] = new RtfCtrlWordHandler(rtfParser, "tposxr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposy"] = new RtfCtrlWordHandler(rtfParser, "tposy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposyb"] = new RtfCtrlWordHandler(rtfParser, "tposyb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposyc"] = new RtfCtrlWordHandler(rtfParser, "tposyc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposyil"] = new RtfCtrlWordHandler(rtfParser, "tposyil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposyin"] = new RtfCtrlWordHandler(rtfParser, "tposyin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposyout"] = new RtfCtrlWordHandler(rtfParser, "tposyout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposyoutv"] = new RtfCtrlWordHandler(rtfParser, "tposyoutv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tposyt"] = new RtfCtrlWordHandler(rtfParser, "tposyt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tpvmrg"] = new RtfCtrlWordHandler(rtfParser, "tpvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tpvpara"] = new RtfCtrlWordHandler(rtfParser, "tpvpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tpvpg"] = new RtfCtrlWordHandler(rtfParser, "tpvpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tqc"] = new RtfCtrlWordHandler(rtfParser, "tqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tqdec"] = new RtfCtrlWordHandler(rtfParser, "tqdec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tqr"] = new RtfCtrlWordHandler(rtfParser, "tqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trackformatting"] = new RtfCtrlWordHandler(rtfParser, "trackformatting", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trackmoves"] = new RtfCtrlWordHandler(rtfParser, "trackmoves", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["transmf"] = new RtfCtrlWordHandler(rtfParser, "transmf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trauth"] = new RtfCtrlWordHandler(rtfParser, "trauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trautofit"] = new RtfCtrlWordHandler(rtfParser, "trautofit", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["trbgbdiag"] = new RtfCtrlWordHandler(rtfParser, "trbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgcross"] = new RtfCtrlWordHandler(rtfParser, "trbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgdcross"] = new RtfCtrlWordHandler(rtfParser, "trbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgdkbdiag"] = new RtfCtrlWordHandler(rtfParser, "trbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgdkcross"] = new RtfCtrlWordHandler(rtfParser, "trbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgdkdcross"] = new RtfCtrlWordHandler(rtfParser, "trbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgdkfdiag"] = new RtfCtrlWordHandler(rtfParser, "trbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgdkhor"] = new RtfCtrlWordHandler(rtfParser, "trbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgdkvert"] = new RtfCtrlWordHandler(rtfParser, "trbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgfdiag"] = new RtfCtrlWordHandler(rtfParser, "trbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbghoriz"] = new RtfCtrlWordHandler(rtfParser, "trbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbgvert"] = new RtfCtrlWordHandler(rtfParser, "trbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbrdrb"] = new RtfCtrlWordHandler(rtfParser, "trbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbrdrh"] = new RtfCtrlWordHandler(rtfParser, "trbrdrh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbrdrl"] = new RtfCtrlWordHandler(rtfParser, "trbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbrdrr"] = new RtfCtrlWordHandler(rtfParser, "trbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbrdrt"] = new RtfCtrlWordHandler(rtfParser, "trbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trbrdrv"] = new RtfCtrlWordHandler(rtfParser, "trbrdrv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trcbpat"] = new RtfCtrlWordHandler(rtfParser, "trcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trcfpat"] = new RtfCtrlWordHandler(rtfParser, "trcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trdate"] = new RtfCtrlWordHandler(rtfParser, "trdate", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trftsWidth"] = new RtfCtrlWordHandler(rtfParser, "trftsWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trftsWidthA"] = new RtfCtrlWordHandler(rtfParser, "trftsWidthA", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trftsWidthB"] = new RtfCtrlWordHandler(rtfParser, "trftsWidthB", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trgaph"] = new RtfCtrlWordHandler(rtfParser, "trgaph", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trhdr"] = new RtfCtrlWordHandler(rtfParser, "trhdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trkeep"] = new RtfCtrlWordHandler(rtfParser, "trkeep", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trkeepfollow"] = new RtfCtrlWordHandler(rtfParser, "trkeepfollow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trleft"] = new RtfCtrlWordHandler(rtfParser, "trleft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trowd"] = new RtfCtrlWordHandler(rtfParser, "trowd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trpaddb"] = new RtfCtrlWordHandler(rtfParser, "trpaddb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trpaddfb"] = new RtfCtrlWordHandler(rtfParser, "trpaddfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trpaddfl"] = new RtfCtrlWordHandler(rtfParser, "trpaddfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trpaddfr"] = new RtfCtrlWordHandler(rtfParser, "trpaddfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trpaddft"] = new RtfCtrlWordHandler(rtfParser, "trpaddft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trpaddl"] = new RtfCtrlWordHandler(rtfParser, "trpaddl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trpaddr"] = new RtfCtrlWordHandler(rtfParser, "trpaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trpaddt"] = new RtfCtrlWordHandler(rtfParser, "trpaddt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trpat"] = new RtfCtrlWordHandler(rtfParser, "trpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trqc"] = new RtfCtrlWordHandler(rtfParser, "trqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trql"] = new RtfCtrlWordHandler(rtfParser, "trql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trqr"] = new RtfCtrlWordHandler(rtfParser, "trqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trrh"] = new RtfCtrlWordHandler(rtfParser, "trrh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trshdng"] = new RtfCtrlWordHandler(rtfParser, "trshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trspdb"] = new RtfCtrlWordHandler(rtfParser, "trspdb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trspdfb"] = new RtfCtrlWordHandler(rtfParser, "trspdfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trspdfl"] = new RtfCtrlWordHandler(rtfParser, "trspdfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trspdfr"] = new RtfCtrlWordHandler(rtfParser, "trspdfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trspdft"] = new RtfCtrlWordHandler(rtfParser, "trspdft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trspdl"] = new RtfCtrlWordHandler(rtfParser, "trspdl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trspdr"] = new RtfCtrlWordHandler(rtfParser, "trspdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trspdt"] = new RtfCtrlWordHandler(rtfParser, "trspdt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["truncatefontheight"] = new RtfCtrlWordHandler(rtfParser, "truncatefontheight", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["truncex"] = new RtfCtrlWordHandler(rtfParser, "truncex", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["trwWidth"] = new RtfCtrlWordHandler(rtfParser, "trwWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trwWidthA"] = new RtfCtrlWordHandler(rtfParser, "trwWidthA", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["trwWidthB"] = new RtfCtrlWordHandler(rtfParser, "trwWidthB", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ts"] = new RtfCtrlWordHandler(rtfParser, "ts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tsbgbdiag"] = new RtfCtrlWordHandler(rtfParser, "tsbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgcross"] = new RtfCtrlWordHandler(rtfParser, "tsbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgdcross"] = new RtfCtrlWordHandler(rtfParser, "tsbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgdkbdiag"] = new RtfCtrlWordHandler(rtfParser, "tsbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgdkcross"] = new RtfCtrlWordHandler(rtfParser, "tsbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgdkdcross"] = new RtfCtrlWordHandler(rtfParser, "tsbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgdkfdiag"] = new RtfCtrlWordHandler(rtfParser, "tsbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgdkhor"] = new RtfCtrlWordHandler(rtfParser, "tsbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgdkvert"] = new RtfCtrlWordHandler(rtfParser, "tsbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgfdiag"] = new RtfCtrlWordHandler(rtfParser, "tsbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbghoriz"] = new RtfCtrlWordHandler(rtfParser, "tsbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbgvert"] = new RtfCtrlWordHandler(rtfParser, "tsbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbrdrb"] = new RtfCtrlWordHandler(rtfParser, "tsbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbrdrdgl"] = new RtfCtrlWordHandler(rtfParser, "tsbrdrdgl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbrdrdgr"] = new RtfCtrlWordHandler(rtfParser, "tsbrdrdgr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbrdrh"] = new RtfCtrlWordHandler(rtfParser, "tsbrdrh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbrdrl"] = new RtfCtrlWordHandler(rtfParser, "tsbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbrdrr"] = new RtfCtrlWordHandler(rtfParser, "tsbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbrdrt"] = new RtfCtrlWordHandler(rtfParser, "tsbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsbrdrv"] = new RtfCtrlWordHandler(rtfParser, "tsbrdrv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscbandhorzeven"] = new RtfCtrlWordHandler(rtfParser, "tscbandhorzeven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscbandhorzodd"] = new RtfCtrlWordHandler(rtfParser, "tscbandhorzodd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscbandsh"] = new RtfCtrlWordHandler(rtfParser, "tscbandsh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscbandsv"] = new RtfCtrlWordHandler(rtfParser, "tscbandsv", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscbandverteven"] = new RtfCtrlWordHandler(rtfParser, "tscbandverteven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscbandvertodd"] = new RtfCtrlWordHandler(rtfParser, "tscbandvertodd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscellcbpat"] = new RtfCtrlWordHandler(rtfParser, "tscellcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellcfpat"] = new RtfCtrlWordHandler(rtfParser, "tscellcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpaddb"] = new RtfCtrlWordHandler(rtfParser, "tscellpaddb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpaddfb"] = new RtfCtrlWordHandler(rtfParser, "tscellpaddfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpaddfl"] = new RtfCtrlWordHandler(rtfParser, "tscellpaddfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpaddfr"] = new RtfCtrlWordHandler(rtfParser, "tscellpaddfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpaddft"] = new RtfCtrlWordHandler(rtfParser, "tscellpaddft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpaddl"] = new RtfCtrlWordHandler(rtfParser, "tscellpaddl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpaddr"] = new RtfCtrlWordHandler(rtfParser, "tscellpaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpaddt"] = new RtfCtrlWordHandler(rtfParser, "tscellpaddt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellpct"] = new RtfCtrlWordHandler(rtfParser, "tscellpct", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["tscellwidth"] = new RtfCtrlWordHandler(rtfParser, "tscellwidth", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscellwidthfts"] = new RtfCtrlWordHandler(rtfParser, "tscellwidthfts", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscfirstcol"] = new RtfCtrlWordHandler(rtfParser, "tscfirstcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscfirstrow"] = new RtfCtrlWordHandler(rtfParser, "tscfirstrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsclastcol"] = new RtfCtrlWordHandler(rtfParser, "tsclastcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsclastrow"] = new RtfCtrlWordHandler(rtfParser, "tsclastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscnecell"] = new RtfCtrlWordHandler(rtfParser, "tscnecell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscnwcell"] = new RtfCtrlWordHandler(rtfParser, "tscnwcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscsecell"] = new RtfCtrlWordHandler(rtfParser, "tscsecell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tscswcell"] = new RtfCtrlWordHandler(rtfParser, "tscswcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsd"] = new RtfCtrlWordHandler(rtfParser, "tsd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsnowrap"] = new RtfCtrlWordHandler(rtfParser, "tsnowrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsrowd"] = new RtfCtrlWordHandler(rtfParser, "tsrowd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsvertalb"] = new RtfCtrlWordHandler(rtfParser, "tsvertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsvertalc"] = new RtfCtrlWordHandler(rtfParser, "tsvertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tsvertalt"] = new RtfCtrlWordHandler(rtfParser, "tsvertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["twoonone"] = new RtfCtrlWordHandler(rtfParser, "twoonone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["tx"] = new RtfCtrlWordHandler(rtfParser, "tx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["txbxtwalways"] = new RtfCtrlWordHandler(rtfParser, "txbxtwalways", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["txbxtwfirst"] = new RtfCtrlWordHandler(rtfParser, "txbxtwfirst", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["txbxtwfirstlast"] = new RtfCtrlWordHandler(rtfParser, "txbxtwfirstlast", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["txbxtwlast"] = new RtfCtrlWordHandler(rtfParser, "txbxtwlast", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["txbxtwno"] = new RtfCtrlWordHandler(rtfParser, "txbxtwno", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["txe"] = new RtfCtrlWordHandler(rtfParser, "txe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["u"] = new RtfCtrlWordHandler(rtfParser, "u", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["uc"] = new RtfCtrlWordHandler(rtfParser, "uc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["ud"] = new RtfCtrlWordHandler(rtfParser, "ud", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["ul"] = new RtfCtrlWordHandler(rtfParser, "ul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulc"] = new RtfCtrlWordHandler(rtfParser, "ulc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["uld"] = new RtfCtrlWordHandler(rtfParser, "uld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["uldash"] = new RtfCtrlWordHandler(rtfParser, "uldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["uldashd"] = new RtfCtrlWordHandler(rtfParser, "uldashd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["uldashdd"] = new RtfCtrlWordHandler(rtfParser, "uldashdd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["uldb"] = new RtfCtrlWordHandler(rtfParser, "uldb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulhair"] = new RtfCtrlWordHandler(rtfParser, "ulhair", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulhwave"] = new RtfCtrlWordHandler(rtfParser, "ulhwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulldash"] = new RtfCtrlWordHandler(rtfParser, "ulldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulnone"] = new RtfCtrlWordHandler(rtfParser, "ulnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ulth"] = new RtfCtrlWordHandler(rtfParser, "ulth", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulthd"] = new RtfCtrlWordHandler(rtfParser, "ulthd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulthdash"] = new RtfCtrlWordHandler(rtfParser, "ulthdash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulthdashd"] = new RtfCtrlWordHandler(rtfParser, "ulthdashd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulthdashdd"] = new RtfCtrlWordHandler(rtfParser, "ulthdashdd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulthldash"] = new RtfCtrlWordHandler(rtfParser, "ulthldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ululdbwave"] = new RtfCtrlWordHandler(rtfParser, "ululdbwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["ulw"] = new RtfCtrlWordHandler(rtfParser, "ulw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["ulwave"] = new RtfCtrlWordHandler(rtfParser, "ulwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["up"] = new RtfCtrlWordHandler(rtfParser, "up", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["upr"] = new RtfCtrlWordHandler(rtfParser, "upr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["urtf"] = new RtfCtrlWordHandler(rtfParser, "urtf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["useltbaln"] = new RtfCtrlWordHandler(rtfParser, "useltbaln", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["usenormstyforlist"] = new RtfCtrlWordHandler(rtfParser, "usenormstyforlist", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["userprops"] = new RtfCtrlWordHandler(rtfParser, "userprops", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null);
+ ctrlWords["usexform"] = new RtfCtrlWordHandler(rtfParser, "usexform", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["utinl"] = new RtfCtrlWordHandler(rtfParser, "utinl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["v"] = new RtfCtrlWordHandler(rtfParser, "v", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null);
+ ctrlWords["validatexml"] = new RtfCtrlWordHandler(rtfParser, "validatexml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["vern"] = new RtfCtrlWordHandler(rtfParser, "vern", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["version"] = new RtfCtrlWordHandler(rtfParser, "version", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["vertalb"] = new RtfCtrlWordHandler(rtfParser, "vertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["vertalc"] = new RtfCtrlWordHandler(rtfParser, "vertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["vertalj"] = new RtfCtrlWordHandler(rtfParser, "vertalj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["vertalt"] = new RtfCtrlWordHandler(rtfParser, "vertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["vertdoc"] = new RtfCtrlWordHandler(rtfParser, "vertdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["vertsect"] = new RtfCtrlWordHandler(rtfParser, "vertsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["viewbksp"] = new RtfCtrlWordHandler(rtfParser, "viewbksp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["viewkind"] = new RtfCtrlWordHandler(rtfParser, "viewkind", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["viewnobound"] = new RtfCtrlWordHandler(rtfParser, "viewnobound", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["viewscale"] = new RtfCtrlWordHandler(rtfParser, "viewscale", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["viewzk"] = new RtfCtrlWordHandler(rtfParser, "viewzk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["wbitmap"] = new RtfCtrlWordHandler(rtfParser, "wbitmap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["wbmbitspixel"] = new RtfCtrlWordHandler(rtfParser, "wbmbitspixel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["wbmplanes"] = new RtfCtrlWordHandler(rtfParser, "wbmplanes", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["wbmwidthbytes"] = new RtfCtrlWordHandler(rtfParser, "wbmwidthbytes", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["webhidden"] = new RtfCtrlWordHandler(rtfParser, "webhidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wgrffmtfilter"] = new RtfCtrlWordHandler(rtfParser, "wgrffmtfilter", 0, false, RtfCtrlWordType.VALUE, "\\*\\", " ", null);
+ ctrlWords["widctlpar"] = new RtfCtrlWordHandler(rtfParser, "widctlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["widowctrl"] = new RtfCtrlWordHandler(rtfParser, "widowctrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["windowcaption"] = new RtfCtrlWordHandler(rtfParser, "windowcaption", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["wmetafile"] = new RtfCtrlWordHandler(rtfParser, "wmetafile", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["wpeqn"] = new RtfCtrlWordHandler(rtfParser, "wpeqn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wpjst"] = new RtfCtrlWordHandler(rtfParser, "wpjst", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wpsp"] = new RtfCtrlWordHandler(rtfParser, "wpsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wptab"] = new RtfCtrlWordHandler(rtfParser, "wptab", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wraparound"] = new RtfCtrlWordHandler(rtfParser, "wraparound", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wrapdefault"] = new RtfCtrlWordHandler(rtfParser, "wrapdefault", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wrapthrough"] = new RtfCtrlWordHandler(rtfParser, "wrapthrough", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wraptight"] = new RtfCtrlWordHandler(rtfParser, "wraptight", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["wraptrsp"] = new RtfCtrlWordHandler(rtfParser, "wraptrsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["writereservhash"] = new RtfCtrlWordHandler(rtfParser, "writereservhash", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null);
+ ctrlWords["wrppunct"] = new RtfCtrlWordHandler(rtfParser, "wrppunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["xe"] = new RtfCtrlWordHandler(rtfParser, "xe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["xef"] = new RtfCtrlWordHandler(rtfParser, "xef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["xform"] = new RtfCtrlWordHandler(rtfParser, "xform", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["xmlattr"] = new RtfCtrlWordHandler(rtfParser, "xmlattr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["xmlattrname"] = new RtfCtrlWordHandler(rtfParser, "xmlattrname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["xmlattrns"] = new RtfCtrlWordHandler(rtfParser, "xmlattrns", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["xmlattrvalue"] = new RtfCtrlWordHandler(rtfParser, "xmlattrvalue", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["xmlclose"] = new RtfCtrlWordHandler(rtfParser, "xmlclose", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["xmlname"] = new RtfCtrlWordHandler(rtfParser, "xmlname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument");
+ ctrlWords["xmlns"] = new RtfCtrlWordHandler(rtfParser, "xmlns", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["xmlnstbl"] = new RtfCtrlWordHandler(rtfParser, "xmlnstbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["xmlopen"] = new RtfCtrlWordHandler(rtfParser, "xmlopen", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument");
+ ctrlWords["xmlsdttcell"] = new RtfCtrlWordHandler(rtfParser, "xmlsdttcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["xmlsdttpara"] = new RtfCtrlWordHandler(rtfParser, "xmlsdttpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["xmlsdttregular"] = new RtfCtrlWordHandler(rtfParser, "xmlsdttregular", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["xmlsdttrow"] = new RtfCtrlWordHandler(rtfParser, "xmlsdttrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["xmlsdttunknown"] = new RtfCtrlWordHandler(rtfParser, "xmlsdttunknown", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["yr"] = new RtfCtrlWordHandler(rtfParser, "yr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["yts"] = new RtfCtrlWordHandler(rtfParser, "yts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["yxe"] = new RtfCtrlWordHandler(rtfParser, "yxe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null);
+ ctrlWords["zwbo"] = new RtfCtrlWordHandler(rtfParser, "zwbo", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["zwj"] = new RtfCtrlWordHandler(rtfParser, "zwj", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["zwnbo"] = new RtfCtrlWordHandler(rtfParser, "zwnbo", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null);
+ ctrlWords["zwnj"] = new RtfCtrlWordHandler(rtfParser, "zwnj", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null);
+ ctrlWords["{"] = new RtfCtrlWordHandler(rtfParser, "{", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "{");
+ ctrlWords["|"] = new RtfCtrlWordHandler(rtfParser, "|", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "|");
+ ctrlWords["}"] = new RtfCtrlWordHandler(rtfParser, "}", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "}");
+ ctrlWords["~"] = new RtfCtrlWordHandler(rtfParser, "~", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "~");
+ ctrlWords["unknown"] = new RtfCtrlWordHandler(rtfParser, "unknown", 0,false, RtfCtrlWordType.UNIDENTIFIED, "\\", " ", null);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordMgr.cs b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordMgr.cs
new file mode 100644
index 0000000..7461c9f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordMgr.cs
@@ -0,0 +1,204 @@
+using System;
+using System.Collections;
+using iTextSharp.text.rtf.parser;
+/*
+ * $Id: RtfCtrlWordMgr.cs,v 1.2 2008/05/13 11:25:59 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.parser.ctrlwords {
+
+ /**
+ * RtfCtrlWordMgr
handles the dispatching of control words from
+ * the table of known control words.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public sealed class RtfCtrlWordMgr {
+ public static bool debug = false;
+ public static bool debugFound = false;
+ public static bool debugNotFound = true;
+ private PushbackStream reader = null;
+ private RtfParser rtfParser = null;
+ private RtfCtrlWordMap ctrlWordMap = null;
+
+ /** The RtfCtrlWordListener
. */
+ private ArrayList listeners = new ArrayList();
+
+ // // TIMING DEBUG INFO
+ // private long endTime = 0;
+ // private Date endDate = null;
+ // private long endFree = 0;
+ // private DecimalFormat df = new DecimalFormat("#,##0");
+ // private Date startDate = new Date();
+ // private long startTime = System.CurrentTimeMillis();
+ // private long startFree = Runtime.GetRuntime().FreeMemory();
+
+ /**
+ * Constructor
+ * @param rtfParser The parser object this manager works with.
+ * @param reader the PushbackReader from the tokeniser.
+ */
+ public RtfCtrlWordMgr(RtfParser rtfParser, PushbackStream reader) {
+ this.rtfParser = rtfParser; // set the parser
+ this.reader = reader; // set the reader value
+ ctrlWordMap = new RtfCtrlWordMap(rtfParser);
+
+ // // TIMING DEBUG INFO
+ // endFree = Runtime.GetRuntime().FreeMemory();
+ // endTime = System.CurrentTimeMillis();
+ // endDate = new Date();
+ // Console.Out.WriteLine("RtfCtrlWordMgr start date: " + startDate.ToLocaleString());
+ // Console.Out.WriteLine("RtfCtrlWordMgr end date : " + endDate.ToLocaleString());
+ // Console.Out.WriteLine(" Elapsed time : " + Long.ToString(endTime - startTime) + " milliseconds.");
+ // Console.Out.WriteLine("Begin Constructor RtfCtrlWordMgr , free mem is " + df.Format(startFree / 1024) + "k");
+ // Console.Out.WriteLine("End Constructor RtfCtrlWordMgr , free mem is " + df.Format(endFree / 1024) + "k");
+ // Console.Out.WriteLine("RtfCtrlWordMgr used approximately " + df.Format((startFree - endFree) / 1024) + "k");
+ }
+
+ /**
+ * Internal to control word manager class.
+ *
+ * @param ctrlWordData The RtfCtrlWordData
object with control word and param
+ * @param groupLevel The current document group parsing level
+ * @return errOK if ok, otherwise an error code.
+ */
+ public int HandleKeyword(RtfCtrlWordData ctrlWordData, int groupLevel) {
+ //TODO: May be used for event handling.
+ int result = RtfParser.errOK;
+
+ // Call before handler event here
+ BeforeCtrlWord(ctrlWordData);
+
+ result = DispatchKeyword(ctrlWordData, groupLevel);
+
+ // call after handler event here
+ AfterCtrlWord(ctrlWordData);
+
+ return result;
+ }
+
+ /**
+ * Dispatch the token to the correct control word handling object.
+ *
+ * @param ctrlWordData The RtfCtrlWordData
object with control word and param
+ * @param groupLevel The current document group parsing level
+ * @return errOK if ok, otherwise an error code.
+ */
+ private int DispatchKeyword(RtfCtrlWordData ctrlWordData, int groupLevel) {
+ int result = RtfParser.errOK;
+ if (ctrlWordData != null) {
+ RtfCtrlWordHandler ctrlWord = ctrlWordMap.GetCtrlWordHandler(ctrlWordData.ctrlWord);
+ if (ctrlWord != null) {
+ ctrlWord.HandleControlword(ctrlWordData);
+ if (debug && debugFound) {
+ Console.Out.WriteLine("Keyword found:" +
+ " New:" + ctrlWordData.ctrlWord +
+ " Param:" + ctrlWordData.param +
+ " bParam=" + ctrlWordData.hasParam.ToString());
+ }
+ } else {
+ result = RtfParser.errCtrlWordNotFound;
+ //result = RtfParser2.errAssertion;
+ if (debug && debugNotFound) {
+ Console.Out.WriteLine("Keyword unknown:" +
+ " New:" + ctrlWordData.ctrlWord +
+ " Param:" + ctrlWordData.param +
+ " bParam=" + ctrlWordData.hasParam.ToString());
+ }
+ }
+ }
+ return result;
+ }
+
+
+ // listener methods
+
+ /**
+ * Adds a RtfCtrlWordListener
to the RtfCtrlWordMgr
.
+ *
+ * @param listener
+ * the new RtfCtrlWordListener.
+ */
+ public void AddRtfCtrlWordListener(IRtfCtrlWordListener listener) {
+ listeners.Add(listener);
+ }
+
+ /**
+ * Removes a RtfCtrlWordListener
from the RtfCtrlWordMgr
.
+ *
+ * @param listener
+ * the RtfCtrlWordListener that has to be removed.
+ */
+ public void RemoveRtfCtrlWordListener(IRtfCtrlWordListener listener) {
+ listeners.Remove(listener);
+ }
+
+ private bool BeforeCtrlWord(RtfCtrlWordData ctrlWordData) {
+ foreach (IRtfCtrlWordListener listener in listeners) {
+ listener.BeforeCtrlWord(ctrlWordData);
+ }
+ return true;
+ }
+
+ private bool OnCtrlWord(RtfCtrlWordData ctrlWordData) {
+ foreach (IRtfCtrlWordListener listener in listeners) {
+ listener.OnCtrlWord(ctrlWordData);
+ }
+ return true;
+ }
+
+ private bool AfterCtrlWord(RtfCtrlWordData ctrlWordData) {
+ foreach (IRtfCtrlWordListener listener in listeners) {
+ listener.AfterCtrlWord(ctrlWordData);
+ }
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordType.cs b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordType.cs
new file mode 100644
index 0000000..d78f6d3
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/ctrlwords/RtfCtrlWordType.cs
@@ -0,0 +1,97 @@
+using System;
+
+/* $Id: RtfCtrlWordType.cs,v 1.2 2008/05/13 11:25:59 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.ctrlwords {
+ /**
+ * RtfCtrlWordType
indicates the type of control word.
+ *
+ * RTF control words are divided up into:
+ * Destination, Flag, Value, Toggle, Symbol.
+ *
+ * Destination: The current destination for values and text to be sent.
+ * Flag: 0/1 value types. Represents true/false, on/off value types.
+ * Toggle: Flips a Flag value on/off.
+ * Value: an Integer value data type. (Exception: Some control words this is a long data value type)
+ * Symbol: Special RTF characters such as \{, \} and others.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public sealed class RtfCtrlWordType {
+ /**
+ * Control word is unidentified.
+ */
+ public const int UNIDENTIFIED = -1;
+ /**
+ * Control word is a destination.
+ */
+ public const int DESTINATION = 0;
+ /**
+ * Control word is a newer destination.
+ */
+ public const int DESTINATION_EX = 1;
+ /**
+ * Control word is a flag.
+ */
+ public const int FLAG = 2;
+ /**
+ * Control word is a value.
+ */
+ public const int VALUE = 3;
+ /**
+ * Control word is a flag toggle.
+ */
+ public const int TOGGLE = 4;
+ /**
+ * Control word is a special symbol.
+ */
+ public const int SYMBOL = 5;
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/IRtfDestinationListener.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/IRtfDestinationListener.cs
new file mode 100644
index 0000000..4438dce
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/IRtfDestinationListener.cs
@@ -0,0 +1,98 @@
+using System;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: IRtfDestinationListener.cs,v 1.2 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationListener
interface for handling events.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ * @since 2.0.8
+ */
+ public interface IRtfDestinationListener : IEventListener {
+ /**
+ *
+ */
+ RtfCtrlWordData BeforeCtrlWord(RtfCtrlWordData ctrlWordData);
+ /**
+ *
+ */
+ RtfCtrlWordData OnCtrlWord(RtfCtrlWordData ctrlWordData);
+ /**
+ *
+ */
+ RtfCtrlWordData AfterCtrlWord(RtfCtrlWordData ctrlWordData);
+ /**
+ *
+ */
+ int BeforeCharacter(int ch);
+ /**
+ *
+ */
+ int OnCharacter(int ch);
+ /**
+ *
+ */
+ int AfterCharacter(int ch);
+ /**
+ *
+ * @return
+ */
+ bool OnOpenGroup();
+ /**
+ *
+ * @return
+ */
+ bool OnCloseGroup();
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestination.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestination.cs
new file mode 100644
index 0000000..305208f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestination.cs
@@ -0,0 +1,254 @@
+using System;
+using System.Collections;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: RtfDestination.cs,v 1.2 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestination
is the base class for destinations according
+ * to the RTF Specification. All destinations must extend from this class.
+ *
+ * @author Howard Shank (hgshank@yahoo.com
+ *
+ * @since 2.0.8
+ */
+ public abstract class RtfDestination {
+ /** Parser object */
+ protected RtfParser rtfParser = null;
+
+ /** Is data in destination modified? */
+ protected bool modified = false;
+
+ /** The last control word handled by this destination */
+ protected RtfCtrlWordData lastCtrlWord = null;
+
+ /** The RtfDestinationListener
. */
+ private static ArrayList listeners = new ArrayList();
+
+ /**
+ * Constructor.
+ */
+ public RtfDestination() {
+ rtfParser = null;
+ }
+ /**
+ * Constructor
+ * @param parser RtfParser
object.
+ */
+ public RtfDestination(RtfParser parser) {
+ this.rtfParser = parser;
+ }
+ /**
+ * Set the parser to use with the RtfDestination object.
+ *
+ * @param parser The RtfParser object.
+ */
+ public virtual void SetParser(RtfParser parser) {
+ if (this.rtfParser != null && this.rtfParser.Equals(parser)) return;
+ this.rtfParser = parser;
+ }
+ /**
+ * Clean up when destination is closed.
+ * @return true if handled, false if not handled
+ */
+ public abstract bool CloseDestination();
+ /**
+ * Handle a new subgroup contained within this group
+ * @return true if handled, false if not handled
+ */
+ public abstract bool HandleOpeningSubGroup();
+ /**
+ * Clean up when group is closed.
+ * @return true if handled, false if not handled
+ */
+ public abstract bool HandleCloseGroup();
+
+ /**
+ * Setup when group is opened.
+ * @return true if handled, false if not handled
+ */
+ public abstract bool HandleOpenGroup();
+ /**
+ * Handle text for this destination
+ * @return true if handled, false if not handled
+ */
+ public abstract bool HandleCharacter(int ch);
+ /**
+ * Handle control word for this destination
+ * @param ctrlWordData The control word and parameter information object
+ * @return true if handled, false if not handled
+ */
+ public abstract bool HandleControlWord(RtfCtrlWordData ctrlWordData);
+ /**
+ * Method to set this object to the default values. Must be implemented in child class.
+ */
+ public abstract void SetToDefaults();
+
+ /**
+ * Method to indicate if data in this destination has changed.
+ * @return true if modified, false if not modified.
+ */
+ public bool IsModified() {
+ return modified;
+ }
+
+ // listener methods
+
+ /**
+ * Adds a RtfDestinationListener
to the RtfDestinationMgr
.
+ *
+ * @param listener
+ * the new RtfDestinationListener.
+ */
+ public bool AddListener(IRtfDestinationListener listener) {
+ listeners.Add(listener);
+ return true;
+ }
+
+ /**
+ * Removes a RtfDestinationListener
from the RtfDestinationMgr
.
+ *
+ * @param listener
+ * the RtfCtrlWordListener that has to be removed.
+ */
+ public bool RemoveListener(IRtfDestinationListener listener) {
+ int i = listeners.IndexOf(listener);
+ if (i >= 0) {
+ listeners.RemoveAt(i);
+ return true;
+ }
+ return false;
+ }
+
+ protected RtfCtrlWordData BeforeCtrlWord(RtfCtrlWordData ctrlWordData) {
+ foreach (IRtfDestinationListener listener in listeners) {
+ listener.BeforeCtrlWord(ctrlWordData);
+ }
+ return null;
+ }
+ /**
+ *
+ */
+ protected RtfCtrlWordData OnCtrlWord(RtfCtrlWordData ctrlWordData){
+ foreach (IRtfDestinationListener listener in listeners) {
+ listener.OnCtrlWord(ctrlWordData);
+ }
+ return null;
+ }
+
+ /**
+ *
+ */
+ protected RtfCtrlWordData AfterCtrlWord(RtfCtrlWordData ctrlWordData){
+ foreach (IRtfDestinationListener listener in listeners) {
+ listener.AfterCtrlWord(ctrlWordData);
+ }
+ return null;
+ }
+
+ /**
+ *
+ */
+ protected int BeforeCharacter(int ch){
+ foreach (IRtfDestinationListener listener in listeners) {
+ listener.BeforeCharacter(ch);
+ }
+ return 0;
+ }
+
+ /**
+ *
+ */
+ protected int OnCharacter(int ch){
+ foreach (IRtfDestinationListener listener in listeners) {
+ listener.OnCharacter(ch);
+ }
+ return 0;
+ }
+
+ /**
+ *
+ */
+ protected int AfterCharacter(int ch){
+ foreach (IRtfDestinationListener listener in listeners) {
+ listener.AfterCharacter(ch);
+ }
+ return 0;
+ }
+
+ /**
+ *
+ * @return
+ */
+ protected bool OnOpenGroup(){
+ foreach (IRtfDestinationListener listener in listeners) {
+ listener.OnOpenGroup();
+ }
+ return true;
+ }
+
+ /**
+ *
+ * @return
+ */
+ protected bool OnCloseGroup(){
+ foreach (IRtfDestinationListener listener in listeners) {
+ listener.OnCloseGroup();
+ }
+ return true;
+ }
+
+ public virtual int GetNewTokeniserState() {
+ return RtfParser.TOKENISER_IGNORE_RESULT;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationColorTable.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationColorTable.cs
new file mode 100644
index 0000000..e192269
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationColorTable.cs
@@ -0,0 +1,317 @@
+using System;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+using iTextSharp.text.rtf.parser.enumerations;
+/*
+ * $Id: RtfDestinationColorTable.cs,v 1.2 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationColorTable
handles data destined for the color table destination
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ * @since 2.0.8
+ */
+ public class RtfDestinationColorTable : RtfDestination {
+
+ /**
+ * The RtfImportHeader to add color mappings to.
+ */
+ private RtfImportMgr importHeader = null;
+ /**
+ * The number of the current color being parsed.
+ */
+ private int colorNr = 0;
+ /**
+ * The red component of the current color being parsed.
+ */
+ private int red = -1;
+ /**
+ * The green component of the current color being parsed.
+ */
+ private int green = -1;
+ /**
+ * The blue component of the current color being parsed.
+ */
+ private int blue = -1;
+ /*
+ * Color themes - Introduced Word 2007
+ */
+ /**
+ * Specifies the tint when specifying a theme color.
+ * RTF control word ctint
+ *
+ * 0 - 255: 0 = full Tint(white), 255 = no tint.
+ * Default value: 255
+ *
+ * If tint is specified and is less than 255, cshade must equal 255.
+ * ctint/cshade are mutually exclusive
+ *
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#themeColor
+ */
+ private int ctint = 255;
+ /**
+ * Specifies the shade when specifying a theme color.
+ * RTF control word cshade
+ *
+ * 0 - 255: 0 = full Shade(black), 255 = no shade.
+ * Default value: 255
+ *
+ * If shade is specified and is less than 255, ctint must equal 255.
+ * cshade/ctint are mutually exclusive
+ *
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#themeColor
+ */
+ private int cshade = 255;
+ /**
+ * Specifies the use of a theme color.
+ *
+ * @see com.lowagie.text.rtf.parser.enumerations.RtfColorThemes
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade
+ */
+ private int themeColor = RtfColorThemes.THEME_UNDEFINED;
+ /**
+ * Color map object for conversions
+ */
+ private Hashtable colorMap = null;
+
+ /**
+ * Constructor.
+ */
+ public RtfDestinationColorTable() : base(null) {
+ colorMap = new Hashtable();
+ this.colorNr = 0;
+ }
+
+ /**
+ * Constructs a new RtfColorTableParser.
+ *
+ * @param importHeader The RtfImportHeader to add the color mappings to.
+ */
+ public RtfDestinationColorTable(RtfParser parser) : base(parser) {
+ colorMap = new Hashtable();
+ this.colorNr = 0;
+ this.importHeader = parser.GetImportManager();
+ this.SetToDefaults();
+ }
+
+ public override void SetParser(RtfParser parser) {
+ this.rtfParser = parser;
+ colorMap = new Hashtable();
+ this.colorNr = 0;
+ this.importHeader = parser.GetImportManager();
+ this.SetToDefaults();
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+ */
+ public override bool HandleOpeningSubGroup() {
+ return true;
+ }
+
+ public override bool CloseDestination() {
+ return true;
+ }
+
+ public override bool HandleCloseGroup() {
+ ProcessColor();
+ return true;
+ }
+ public override bool HandleOpenGroup() {
+ return true;
+ }
+
+ public override bool HandleCharacter(int ch) {
+ // color elements end with a semicolon (;)
+ if ((char)ch == ';') {
+ this.ProcessColor();
+ }
+ return true;
+ }
+
+ public override bool HandleControlWord(RtfCtrlWordData ctrlWordData) {
+ if (ctrlWordData.ctrlWord.Equals("blue")) this.SetBlue(ctrlWordData.IntValue());
+ if (ctrlWordData.ctrlWord.Equals("red")) this.SetRed(ctrlWordData.IntValue());
+ if (ctrlWordData.ctrlWord.Equals("green")) this.SetGreen(ctrlWordData.IntValue());
+ if (ctrlWordData.ctrlWord.Equals("cshade")) this.SetShade(ctrlWordData.IntValue());
+ if (ctrlWordData.ctrlWord.Equals("ctint")) this.SetTint(ctrlWordData.IntValue());
+ //if(ctrlWordData.ctrlWord.Equals("cmaindarkone")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("cmainlightone")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("cmaindarktwo")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("cmainlighttwo")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("caccentone")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("caccenttwo")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("caccentthree")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("caccentfour")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("caccentfive")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("caccentsix")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("chyperlink")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("cfollowedhyperlink")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("cbackgroundone")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("ctextone")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("cbacgroundtwo")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ //if(ctrlWordData.ctrlWord.Equals("ctexttwo")) this.SetThemeColor(ctrlWordData.ctrlWord);
+ return true;
+ }
+
+ /**
+ * Set default values.
+ */
+ public override void SetToDefaults() {
+ this.red = -1;
+ this.green = -1;
+ this.blue = -1;
+ this.ctint = 255;
+ this.cshade = 255;
+ this.themeColor = RtfColorThemes.THEME_UNDEFINED;
+ // do not reset colorNr
+ }
+ /**
+ * Processes the color triplet parsed from the document.
+ * Add it to the import mapping so colors can be mapped when encountered
+ * in the RTF import or conversion.
+ */
+ private void ProcessColor() {
+ if (red != -1 && green != -1 && blue != -1) {
+ if (this.rtfParser.IsImport()) {
+ this.importHeader.ImportColor(this.colorNr.ToString(), new Color(this.red, this.green, this.blue));
+ }
+
+ if (this.rtfParser.IsConvert()) {
+ colorMap[this.colorNr.ToString()] = new Color(this.red, this.green, this.blue);
+ }
+ }
+ this.SetToDefaults();
+ this.colorNr++;
+ }
+ /**
+ * Set the red color to value.
+ * @param value Value to set red to.
+ */
+ private void SetRed(int value) {
+ if (value >= 0 && value <= 255) {
+ this.red = value;
+ }
+ }
+ /**
+ * Set the green color value.
+ * @param value Value to set green to.
+ */
+ private void SetGreen(int value) {
+ if (value >= 0 && value <= 255) {
+ this.green = value;
+ }
+ }
+ /**
+ * Set the blue color value.
+ * @param value Value to set blue to.
+ */
+ private void SetBlue(int value) {
+ if (value >= 0 && value <= 255) {
+ this.blue = value;
+ }
+ }
+ /**
+ * Set the tint value
+ * @param value Value to set the tint to
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint
+ */
+ private void SetTint(int value) {
+ if (value >= 0 && value <= 255) {
+ this.ctint = value;
+ if (value >= 0 && value <255) {
+ this.cshade = 255;
+ }
+ }
+ }
+ /**
+ * Set the shade value
+ * @param value Value to set the shade to
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade
+ */
+ private void SetShade(int value) {
+ if (value >= 0 && value <= 255) {
+ this.cshade = value;
+ if (value >= 0 && value <255) {
+ this.ctint = 255;
+ }
+ }
+ }
+ /**
+ * Set the theme color value.
+ * @param value Value to set the theme color to
+ * @see com.lowagie.text.rtf.parser.enumerations.RtfColorThemes
+ */
+ private void SetThemeColor(int value) {
+ if (value >= RtfColorThemes.THEME_UNDEFINED && value <= RtfColorThemes.THEME_MAX) {
+ this.themeColor = value;
+ } else {
+ this.themeColor = RtfColorThemes.THEME_UNDEFINED;
+ }
+ }
+
+ // conversion functions
+ /**
+ * Get the Color
object that is mapped to the key.
+ * @param key The map number.
+ * *@return Color
object from the map. null if key does not exist.
+ */
+ public Color GetColor(String key) {
+ return (Color)colorMap[key];
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationDocument.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationDocument.cs
new file mode 100644
index 0000000..a39f75f
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationDocument.cs
@@ -0,0 +1,592 @@
+using System;
+using System.Collections;
+using System.Text;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.direct;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+using iTextSharp.text.rtf.parser.properties;
+/*
+ * $Id: RtfDestinationDocument.cs,v 1.4 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.destinations {
+ /**
+ * RtfDestinationDocument
handles data destined for the document destination
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ */
+ public sealed class RtfDestinationDocument : RtfDestination, IRtfPropertyListener {
+
+
+ /**
+ * The RtfDocument object.
+ *
+ * @see com.lowagie.text.rtf.document.RtfDocument
+ */
+ private RtfDocument rtfDoc = null;
+
+ /**
+ * The iText Document object.
+ *
+ * @see com.lowagie.text.Document
+ */
+ private Document doc = null;
+
+ private StringBuilder buffer = null;
+ /**
+ * Indicates the parser action. Import or Conversion.
+ *
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_UNIDENTIFIED
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_CONVERT
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_IMPORT_FRAGMENT
+ * @see com.lowagie.text.rtf.direct.RtfParser#TYPE_IMPORT_FULL
+ */
+ private int conversionType = 0;
+
+
+ /**
+ * Indicates the current table level being processed
+ */
+ private int tableLevel = 0;
+
+ private static ArrayList IMPORT_IGNORED_CTRLWORDS = new ArrayList(new string[]{
+ "rtf",
+ "ansicpg",
+ "deff",
+ "ansi",
+ "mac",
+ "pca",
+ "pc",
+ "stshfdbch",
+ "stshfloch",
+ "stshfhich",
+ "stshfbi",
+ "deflang",
+ "deflangfe",
+ "adeflang",
+ "adeflangfe"
+ }
+ );
+ private static ArrayList CONVERT_IGNORED_CTRLWORDS = new ArrayList(new string[]{"rtf"});
+
+ private Paragraph iTextParagraph = null;
+
+ public RtfDestinationDocument() : base(null) {
+ }
+ /**
+ * Constructs a new RtfDestinationDocument
using
+ * the parameters to initialize the object.
+ * @param rtfDoc The RtfDocument
this works with.
+ * @param doc The iText Document
this works with.
+ * @param type The type of conversion being done.
+ */
+ public RtfDestinationDocument(RtfParser parser) : base (parser){
+ this.rtfDoc = parser.GetRtfDocument();
+ this.doc = parser.GetDocument();
+ this.conversionType = parser.GetConversionType();
+ SetToDefaults();
+ if (this.rtfParser.IsConvert()) {
+ this.rtfParser.GetState().properties.AddRtfPropertyListener(this);
+ }
+ }
+
+ public override void SetParser(RtfParser parser) {
+ this.rtfParser = parser;
+ this.rtfDoc = parser.GetRtfDocument();
+ this.doc = parser.GetDocument();
+ this.conversionType = parser.GetConversionType();
+ SetToDefaults();
+ if (this.rtfParser.IsConvert()) {
+ this.rtfParser.GetState().properties.AddRtfPropertyListener(this);
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+ */
+ public override bool CloseDestination() {
+ if (this.rtfParser.IsImport()) {
+ if (this.buffer.Length>0) {
+ WriteBuffer();
+ }
+ }
+
+ this.rtfParser.GetState().properties.RemoveRtfPropertyListener(this);
+
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+ */
+ public override bool HandleOpenGroup() {
+ this.OnOpenGroup(); // event handler
+
+ if (this.rtfParser.IsImport()) {
+ }
+ if (this.rtfParser.IsConvert()) {
+ if (this.iTextParagraph == null) this.iTextParagraph = new Paragraph();
+ }
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+ */
+ public override bool HandleOpeningSubGroup() {
+ if (this.rtfParser.IsImport()) {
+ if (this.buffer.Length>0) {
+ WriteBuffer();
+ }
+ }
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+ */
+ public override bool HandleCloseGroup() {
+ this.OnCloseGroup(); // event handler
+
+ if (this.rtfParser.IsImport()) {
+ if (this.buffer.Length>0) {
+ WriteBuffer();
+ }
+ WriteText("}");
+ }
+ if (this.rtfParser.IsConvert()) {
+ if (this.buffer.Length > 0 && this.iTextParagraph == null) {
+ this.iTextParagraph = new Paragraph();
+ }
+ if (this.buffer.Length > 0 ) {
+ Chunk chunk = new Chunk();
+ chunk.Append(this.buffer.ToString());
+ this.iTextParagraph.Add(chunk);
+ }
+ if (this.iTextParagraph != null) {
+ AddParagraphToDocument();
+ }
+ }
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int)
+ */
+ public override bool HandleCharacter(int ch) {
+ bool result = true;
+ this.OnCharacter(ch); // event handler
+
+ if (this.rtfParser.IsImport()) {
+ if (buffer.Length > 254) {
+ this.WriteBuffer();
+ }
+ buffer.Append((char)ch);
+ }
+ if (this.rtfParser.IsConvert()) {
+ buffer.Append((char)ch);
+ }
+ return result;
+ }
+
+
+ public override bool HandleControlWord(RtfCtrlWordData ctrlWordData) {
+ bool result = false;
+ this.OnCtrlWord(ctrlWordData); // event handler
+
+ if (this.rtfParser.IsImport()) {
+ // map font information
+ if (ctrlWordData.ctrlWord.Equals("f")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapFontNr(ctrlWordData.param);}
+
+ // map color information
+ //colors
+ if (ctrlWordData.ctrlWord.Equals("cb")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ if (ctrlWordData.ctrlWord.Equals("cf")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ //cells
+ if (ctrlWordData.ctrlWord.Equals("clcbpat")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ if (ctrlWordData.ctrlWord.Equals("clcbpatraw")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ if (ctrlWordData.ctrlWord.Equals("clcfpat")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ if (ctrlWordData.ctrlWord.Equals("clcfpatraw")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ //table rows
+ if (ctrlWordData.ctrlWord.Equals("trcfpat")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ if (ctrlWordData.ctrlWord.Equals("trcbpat")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ //paragraph border
+ if (ctrlWordData.ctrlWord.Equals("brdrcf")) { ctrlWordData.param = this.rtfParser.GetImportManager().MapColorNr(ctrlWordData.param);}
+ }
+
+
+
+ if (this.rtfParser.IsConvert()) {
+ if (ctrlWordData.ctrlWord.Equals("par")) { AddParagraphToDocument(); }
+ // Set Font
+ if (ctrlWordData.ctrlWord.Equals("f")) {}
+
+ // color information
+ //colors
+ if (ctrlWordData.ctrlWord.Equals("cb")) {}
+ if (ctrlWordData.ctrlWord.Equals("cf")) {}
+ //cells
+ if (ctrlWordData.ctrlWord.Equals("clcbpat")) {}
+ if (ctrlWordData.ctrlWord.Equals("clcbpatraw")) {}
+ if (ctrlWordData.ctrlWord.Equals("clcfpat")) {}
+ if (ctrlWordData.ctrlWord.Equals("clcfpatraw")) {}
+ //table rows
+ if (ctrlWordData.ctrlWord.Equals("trcfpat")) {}
+ if (ctrlWordData.ctrlWord.Equals("trcbpat")) {}
+ //paragraph border
+ if (ctrlWordData.ctrlWord.Equals("brdrcf")) {}
+
+ /* TABLES */
+ if (ctrlWordData.ctrlWord.Equals("trowd")) /*Beginning of row*/ { tableLevel++;}
+ if (ctrlWordData.ctrlWord.Equals("cell")) /*End of Cell Denotes the end of a table cell*/ {
+ // String ctl = ctrlWordData.ctrlWord;
+ // System.out.Print("cell found");
+ }
+ if (ctrlWordData.ctrlWord.Equals("row")) /*End of row*/ { tableLevel++;}
+ if (ctrlWordData.ctrlWord.Equals("lastrow")) /*Last row of the table*/ {}
+ if (ctrlWordData.ctrlWord.Equals("row")) /*End of row*/ { tableLevel++;}
+ if (ctrlWordData.ctrlWord.Equals("irow")) /*param is the row index of this row.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("irowband")) /*param is the row index of the row, adjusted to account for header rows. A header row has a value of -1.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tcelld")) /*Sets table cell defaults*/ {}
+ if (ctrlWordData.ctrlWord.Equals("nestcell")) /*Denotes the end of a nested cell.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("nestrow")) /*Denotes the end of a nested row*/ {}
+ if (ctrlWordData.ctrlWord.Equals("nesttableprops")) /*Defines the properties of a nested table. This is a destination control word*/ {}
+ if (ctrlWordData.ctrlWord.Equals("nonesttables")) /*Contains text for readers that do not understand nested tables. This destination should be ignored by readers that support nested tables.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trgaph")) /*Half the space between the cells of a table row in twips.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("cellx")) /*param Defines the right boundary of a table cell, including its half of the space between cells.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("clmgf")) /*The first cell in a range of table cells to be merged.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("clmrg")) /*Contents of the table cell are merged with those of the preceding cell*/ {}
+ if (ctrlWordData.ctrlWord.Equals("clvmgf")) /*The first cell in a range of table cells to be vertically merged.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("clvmrg")) /*Contents of the table cell are vertically merged with those of the preceding cell*/ {}
+ /* TABLE: table row revision tracking */
+ if (ctrlWordData.ctrlWord.Equals("trauth")) /*With revision tracking enabled, this control word identifies the author of changes to a table row's properties. N refers to a value in the revision table*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trdate")) /*With revision tracking enabled, this control word identifies the date of a revision*/ {}
+ /* TABLE: Autoformatting flags */
+ if (ctrlWordData.ctrlWord.Equals("tbllkborder")) /*Flag sets table autoformat to format borders*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllkshading")) /*Flag sets table autoformat to affect shading.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllkfont")) /*Flag sets table autoformat to affect font*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllkcolor")) /*Flag sets table autoformat to affect color*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllkbestfit")) /*Flag sets table autoformat to apply best fit*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllkhdrrows")) /*Flag sets table autoformat to format the first (header) row*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllklastrow")) /*Flag sets table autoformat to format the last row.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllkhdrcols")) /*Flag sets table autoformat to format the first (header) column*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllklastcol")) /*Flag sets table autoformat to format the last column*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllknorowband")) /*Specifies row banding conditional formatting shall not be applied*/ {}
+ if (ctrlWordData.ctrlWord.Equals("tbllknocolband")) /*Specifies column banding conditional formatting shall not be applied.*/ {}
+ /* TABLE: Row Formatting */
+ if (ctrlWordData.ctrlWord.Equals("taprtl")) /*Table direction is right to left*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trautofit")) /*param = AutoFit:
+ 0 No AutoFit (default).
+ 1 AutoFit is on for the row. Overridden by \clwWidthN and \trwWidthN in any table row.
+ */ {}
+ if (ctrlWordData.ctrlWord.Equals("trhdr")) /*Table row header. This row should appear at the top of every page on which the current table appears*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trkeep")) /*Keep table row together. This row cannot be split by a page break. This property is assumed to be off unless the control word is present*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trkeepfollow")) /*Keep row in the same page as the following row.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trleft")) /*Position in twips of the leftmost edge of the table with respect to the left edge of its column.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trqc")) /*Centers a table row with respect to its containing column.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trql")) /*Left-justifies a table row with respect to its containing column.*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trqr")) /*Right-justifies a table row with respect to its containing column*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trrh")) /*Height of a table row in twips. When 0, the height is sufficient for all the text in the line; when positive, the height is guaranteed to be at least the specified height; when negative, the absolute value of the height is used, regardless of the height of the text in the line*/ {}
+ if (ctrlWordData.ctrlWord.Equals("trpaddb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trpaddl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trpaddr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trpaddt")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trpaddfb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trpaddfl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trpaddfr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trpaddft")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trspdl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trspdt")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trspdb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trspdr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trspdfl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trspdft")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trspdfb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trspdfr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trwWidth")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trftsWidth")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trwWidthB")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trftsWidthB")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trftsWidthB")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trwWidthA")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trftsWidthA")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tblind")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tblindtype")) /* */ {}
+ /*TABLE: Row shading and Background Colors*/
+ if (ctrlWordData.ctrlWord.Equals("trcbpat")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trcfpat")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trpat")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trshdng")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgbdiag")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgcross")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgdcross")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgdkbdiag")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgdkcross")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgdkdcross")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgdkfdiag")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgdkhor")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgdkvert")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgfdiag")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbghoriz")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbgvert")) /* */ {}
+ /* TABLE: Cell Formatting*/
+ if (ctrlWordData.ctrlWord.Equals("clFitText")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clNoWrap")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clpadl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clpadt")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clpadb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clpadr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clpadfl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clpadft")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clpadfb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clpadfr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clwWidth")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clftsWidth")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clhidemark")) /* */ {}
+ /* TABLE: Compared Table Cells */
+ if (ctrlWordData.ctrlWord.Equals("clins")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("cldel")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clmrgd")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clmrgdr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clsplit")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clsplitr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clinsauth")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clinsdttm")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("cldelauth")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("cldeldttm")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clmrgdauth")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clmrgddttm")) /* */ {}
+ /*TABLE: Position Wrapped Tables (The following properties must be the same for all rows in the table.)*/
+ if (ctrlWordData.ctrlWord.Equals("tdfrmtxtLeft")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tdfrmtxtRight")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tdfrmtxtTop")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tdfrmtxtBottom")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tabsnoovrlp")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tphcol")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tphmrg")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tphpg")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposnegx")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposnegy")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposx")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposxc")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposxi")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposxl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposxo")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposxr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposy")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposyb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposyc")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposyil")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposyin")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposyout")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tposyt")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tpvmrg")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tpvpara")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("tpvpg")) /* */ {}
+ /* TABLE: Bidirectional Controls */
+ if (ctrlWordData.ctrlWord.Equals("rtlrow")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("ltrrow")) /* */ {}
+ /* TABLE: Row Borders */
+ if (ctrlWordData.ctrlWord.Equals("trbrdrt")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbrdrl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbrdrb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbrdrr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbrdrh")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("trbrdrv")) /* */ {}
+ /* TABLE: Cell Borders */
+ if (ctrlWordData.ctrlWord.Equals("brdrnil")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clbrdrb")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clbrdrt")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clbrdrl")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("clbrdrr")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("cldglu")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("cldgll")) /* */ {}
+ if (ctrlWordData.ctrlWord.Equals("")) /* */ {}
+ }
+ if (ctrlWordData.ctrlWordType == RtfCtrlWordType.TOGGLE) {
+ this.rtfParser.GetState().properties.ToggleProperty(ctrlWordData);//ctrlWordData.specialHandler);
+ }
+
+ if (ctrlWordData.ctrlWordType == RtfCtrlWordType.FLAG ||
+ ctrlWordData.ctrlWordType == RtfCtrlWordType.VALUE) {
+ this.rtfParser.GetState().properties.SetProperty(ctrlWordData);//ctrlWordData.specialHandler, ctrlWordData.param);
+ }
+
+ switch (conversionType) {
+ case RtfParser.TYPE_IMPORT_FULL:
+ if (!IMPORT_IGNORED_CTRLWORDS.Contains(ctrlWordData.ctrlWord)) {
+ WriteBuffer();
+ WriteText(ctrlWordData.ToString());
+ }
+ result = true;
+ break;
+ case RtfParser.TYPE_IMPORT_FRAGMENT:
+ if (!IMPORT_IGNORED_CTRLWORDS.Contains(ctrlWordData.ctrlWord)) {
+ WriteBuffer();
+ WriteText(ctrlWordData.ToString());
+ }
+ result = true;
+ break;
+ case RtfParser.TYPE_CONVERT:
+ if (IMPORT_IGNORED_CTRLWORDS.Contains(ctrlWordData.ctrlWord) == false) {
+ }
+ result = true;
+ break;
+ default: // error because is should be an import or convert
+ result = false;
+ break;
+ }
+
+
+
+
+ return result;
+ }
+ /**
+ * Write the accumulated buffer to the destination.
+ * Used for direct content
+ */
+ private void WriteBuffer() {
+ WriteText(this.buffer.ToString());
+ SetToDefaults();
+ }
+ /**
+ * Write the string value to the destiation.
+ * Used for direct content
+ * @param value
+ */
+ private void WriteText(String value) {
+ if (this.rtfParser.IsNewGroup()) {
+ this.rtfDoc.Add(new RtfDirectContent("{"));
+ this.rtfParser.SetNewGroup(false);
+ }
+ if (value.Length > 0) {
+ this.rtfDoc.Add(new RtfDirectContent(value));
+ }
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults()
+ */
+ public override void SetToDefaults() {
+ this.buffer = new StringBuilder();
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.properties.RtfPropertyListener#afterChange(java.lang.String)
+ */
+ public void AfterPropertyChange(String propertyName) {
+ if (propertyName.StartsWith(RtfProperty.CHARACTER)) {
+ } else {
+ if (propertyName.StartsWith(RtfProperty.PARAGRAPH)) {
+ } else {
+ if (propertyName.StartsWith(RtfProperty.SECTION)) {
+ } else {
+ if (propertyName.StartsWith(RtfProperty.DOCUMENT)) {
+
+ }
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.properties.RtfPropertyListener#beforeChange(java.lang.String)
+ */
+ public void BeforePropertyChange(String propertyName) {
+ // do we have any text to do anything with?
+ // if not, then just return without action.
+ if (this.buffer.Length == 0) return;
+
+ if (propertyName.StartsWith(RtfProperty.CHARACTER)) {
+ // this is a character change,
+ // add a new chunck to the current paragraph using current character settings.
+ Chunk chunk = new Chunk();
+ chunk.Append(this.buffer.ToString());
+ this.buffer = new StringBuilder(255);
+ Hashtable charProperties = this.rtfParser.GetState().properties.GetProperties(RtfProperty.CHARACTER);
+ String defFont = (String)charProperties[RtfProperty.CHARACTER_FONT];
+ if (defFont == null) defFont = "0";
+ RtfDestinationFontTable fontTable = (RtfDestinationFontTable)this.rtfParser.GetDestination("fonttbl");
+ Font currFont = fontTable.GetFont(defFont);
+ int fs = Font.NORMAL;
+ if (charProperties.ContainsKey(RtfProperty.CHARACTER_BOLD)) fs |= Font.BOLD;
+ if (charProperties.ContainsKey(RtfProperty.CHARACTER_ITALIC)) fs |= Font.ITALIC;
+ if (charProperties.ContainsKey(RtfProperty.CHARACTER_UNDERLINE)) fs |= Font.UNDERLINE;
+ Font useFont = FontFactory.GetFont(currFont.Familyname, 12, fs, new Color(0,0,0));
+
+
+ chunk.Font = useFont;
+ if (iTextParagraph == null) this.iTextParagraph = new Paragraph();
+ this.iTextParagraph.Add(chunk);
+
+ } else {
+ if (propertyName.StartsWith(RtfProperty.PARAGRAPH)) {
+ // this is a paragraph change. what do we do?
+ } else {
+ if (propertyName.StartsWith(RtfProperty.SECTION)) {
+
+ } else {
+ if (propertyName.StartsWith(RtfProperty.DOCUMENT)) {
+
+ }
+ }
+ }
+ }
+ }
+
+ private void AddParagraphToDocument() {
+ if (this.iTextParagraph != null) {
+ try {
+ this.rtfParser.GetDocument().Add(this.iTextParagraph);
+ } catch {
+ }
+ this.iTextParagraph = null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationFontTable.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationFontTable.cs
new file mode 100644
index 0000000..0e563e0
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationFontTable.cs
@@ -0,0 +1,600 @@
+using System;
+using System.Collections;
+using System.Text;
+using iTextSharp.text;
+using iTextSharp.text.rtf.direct;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: RtfDestinationFontTable.cs,v 1.4 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationFontTable
handles data destined for the font table destination
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ * @since 2.0.8
+ */
+ public sealed class RtfDestinationFontTable : RtfDestination {
+ /**
+ * The RtfImportHeader to add font mappings to.
+ */
+ private RtfImportMgr importHeader = null;
+ /**
+ * The theme (Office 2007)
+ */
+ private String themeFont = "";
+ /**
+ * The number of the font being parsed.
+ */
+ private String fontNr = "";
+ /**
+ * The family of the font being parsed.
+ */
+ private String fontFamily = "";
+ /**
+ * The \charset value
+ */
+ private String charset = "";
+ private const String CHARSET_DEFAULT = "0";
+ /**
+ * The \fprq
+ */
+ private int fprq = 0;
+ /**
+ * The \*\panose font matching value if primary font is not available.
+ */
+ private String panose = "";
+ /**
+ * The \*\fname
+ */
+ //private String nontaggedname = "";
+ /**
+ * The name of the font being parsed.
+ */
+ private String fontName = "";
+ /**
+ * The \falt alternate font if primary font is not available.
+ */
+ private String falt = "";
+ /**
+ * The \falt alternate font if primary font is not available.
+ */
+ //private String fontemb = "";
+ /**
+ * The \falt alternate font if primary font is not available.
+ */
+ //private String fontType = "";
+ /**
+ * The \falt alternate font if primary font is not available.
+ */
+ //private String fontFile = "";
+ /**
+ * The \falt alternate font if primary font is not available.
+ */
+ //private String fontFileCpg = "";
+ /**
+ * The \fbias value
+ */
+ private int fbias = 0;
+ /**
+ * The \cpg value
+ */
+ private String cpg = "";
+ /**
+ * The \fnil, \fttruetype value
+ */
+ private String trueType = "";
+
+ /**
+ * state flag to handle different parsing of a font element
+ */
+ private int state = 0;
+ /* state values */
+ /** Normal */
+ private const int SETTING_NORMAL = 0;
+ /** \falt */
+ private const int SETTING_ALTERNATE = 1;
+ /** \fname */
+ private const int SETTING_FONTNAME = 2;
+ /** \panose */
+ private const int SETTING_PANOSE = 3;
+ /** \fontemb */
+ private const int SETTING_FONT_EMBED = 4;
+ /** \ffile */
+ private const int SETTING_FONT_FILE = 5;
+
+ /**
+ * Convert font mapping to FontFactory
font objects.
+ */
+ private Hashtable fontMap = null;
+
+ /**
+ * Constructor
+ */
+ public RtfDestinationFontTable() : base(null) {
+ }
+ /**
+ * Constructs a new RtfFontTableParser.
+ *
+ * @param importHeader The RtfImportHeader to add font mappings to.
+ *
+ * @since 2.0.8
+ */
+ public RtfDestinationFontTable(RtfParser parser) : base(parser) {
+ this.Init(true);
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setParser(com.lowagie.text.rtf.parser.RtfParser)
+ *
+ * @since 2.0.8
+ */
+ public override void SetParser(RtfParser parser) {
+ if (this.rtfParser != null && this.rtfParser.Equals(parser)) return;
+ this.rtfParser = parser;
+ this.Init(true);
+ }
+ /**
+ * Initialize the object.
+ *
+ * @param importFonts true to import the fonts into the FontFactory, false do not load fonts
+ *
+ * @since 2.0.8
+ */
+ private void Init(bool importFonts) {
+ fontMap = new Hashtable();
+ if (this.rtfParser != null) {
+ this.importHeader = this.rtfParser.GetImportManager();
+ }
+ this.SetToDefaults();
+ if (importFonts) {
+ ImportSystemFonts();
+ }
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+ *
+ * @since 2.0.8
+ */
+ public override bool HandleOpeningSubGroup() {
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+ *
+ * @since 2.0.8
+ */
+ public override bool CloseDestination() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+ *
+ * @since 2.0.8
+ */
+ public override bool HandleCloseGroup() {
+ if (this.state == SETTING_NORMAL) {
+ ProcessFont();
+ }
+ this.state = SETTING_NORMAL;
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+ *
+ * @since 2.0.8
+ */
+ public override bool HandleOpenGroup() {
+
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(char[])
+ *
+ * @since 2.0.8
+ */
+ public override bool HandleCharacter(int ch) {
+ switch (this.state) {
+ case SETTING_NORMAL:
+ this.fontName += (char)ch;
+ break;
+ case SETTING_ALTERNATE:
+ this.falt += (char)ch;
+ break;
+ case SETTING_PANOSE:
+ this.panose += (char)ch;
+ break;
+ case SETTING_FONT_EMBED:
+ break;
+ case SETTING_FONT_FILE:
+ break;
+ case SETTING_FONTNAME:
+ break;
+
+ }
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData)
+ *
+ * @since 2.0.8
+ */
+ public override bool HandleControlWord(RtfCtrlWordData ctrlWordData) {
+ bool result = true;
+ // just let fonttbl fall through and set last ctrl word object.
+
+ if (ctrlWordData.ctrlWord.Equals("f")) { this.SetFontNumber(ctrlWordData.param); result=true;}
+ if (ctrlWordData.ctrlWord.Equals("fcharset")) { this.SetCharset(ctrlWordData.param); result=true; }
+
+ // font families
+ if (ctrlWordData.ctrlWord.Equals("fnil")) { this.SetFontFamily("roman"); result=true; }
+ if (ctrlWordData.ctrlWord.Equals("froman")) { this.SetFontFamily("roman"); result=true; }
+ if (ctrlWordData.ctrlWord.Equals("fswiss")) { this.SetFontFamily("swiss"); result=true; }
+ if (ctrlWordData.ctrlWord.Equals("fmodern")) { this.SetFontFamily("modern"); result=true; }
+ if (ctrlWordData.ctrlWord.Equals("fscript")) { this.SetFontFamily("script"); result=true; }
+ if (ctrlWordData.ctrlWord.Equals("fdecor")) { this.SetFontFamily("decor"); result=true; }
+ if (ctrlWordData.ctrlWord.Equals("ftech")) { this.SetFontFamily("tech"); result=true; }
+ if (ctrlWordData.ctrlWord.Equals("fbidi")) { this.SetFontFamily("bidi"); result=true; }
+ // pitch
+ if (ctrlWordData.ctrlWord.Equals("fprq")) { this.SetPitch(ctrlWordData.param); result=true; }
+ // bias
+ if (ctrlWordData.ctrlWord.Equals("fbias")) { this.SetBias(ctrlWordData.param); result=true; }
+ // theme font information
+ if (ctrlWordData.ctrlWord.Equals("flomajor")) { this.SetThemeFont("flomajor"); result= true; }
+ if (ctrlWordData.ctrlWord.Equals("fhimajor")) { this.SetThemeFont("fhimajor"); result= true; }
+ if (ctrlWordData.ctrlWord.Equals("fdbmajor")) { this.SetThemeFont("fdbmajor"); result= true; }
+ if (ctrlWordData.ctrlWord.Equals("fbimajor")) { this.SetThemeFont("fbimajor"); result= true; }
+ if (ctrlWordData.ctrlWord.Equals("flominor")) { this.SetThemeFont("flominor"); result= true; }
+ if (ctrlWordData.ctrlWord.Equals("fhiminor")) { this.SetThemeFont("fhiminor"); result= true; }
+ if (ctrlWordData.ctrlWord.Equals("fdbminor")) { this.SetThemeFont("fdbminor"); result= true; }
+ if (ctrlWordData.ctrlWord.Equals("fbiminor")) { this.SetThemeFont("fbiminor"); result= true; }
+
+ // panose
+ if (ctrlWordData.ctrlWord.Equals("panose")) {state = SETTING_PANOSE; result = true; }
+
+ // \*\fname
+ // #PCDATA
+ if (ctrlWordData.ctrlWord.Equals("fname")) {state = SETTING_FONTNAME; result = true; }
+
+ // \*\falt
+ if (ctrlWordData.ctrlWord.Equals("falt")) { state = SETTING_ALTERNATE; result = true; }
+
+ // \*\fontemb
+ if (ctrlWordData.ctrlWord.Equals("fontemb")) { state = SETTING_FONT_EMBED; result = true; }
+
+ // font type
+ if (ctrlWordData.ctrlWord.Equals("ftnil")) { this.SetTrueType("ftnil"); result= true; }
+ if (ctrlWordData.ctrlWord.Equals("fttruetype")) { this.SetTrueType("fttruetype"); result= true; }
+
+ // \*\fontfile
+ if (ctrlWordData.ctrlWord.Equals("fontemb")) { state = SETTING_FONT_FILE; result = true; }
+
+ // codepage
+ if (ctrlWordData.ctrlWord.Equals("cpg")) { this.SetCodePage(ctrlWordData.param); result= true; }
+
+ this.lastCtrlWord = ctrlWordData;
+ return result;
+ }
+ /**
+ * Set the code page
+ * @param value The code page value
+ *
+ * @since 2.0.8
+ */
+ public void SetCodePage(String value) {
+ this.cpg = value;
+ }
+ /**
+ * Set the TrueTtype type
+ * @param value The type
+ *
+ * @since 2.0.8
+ */
+ public void SetTrueType(String value) {
+ this.trueType = value;
+ }
+ /**
+ * Set the font pitch
+ * @param value Pitch value
+ *
+ * @since 2.0.8
+ */
+ public void SetPitch(String value) {
+ this.fprq = int.Parse(value);
+ }
+ /**
+ * Set the font bias
+ * @param value Bias value
+ *
+ * @since 2.0.8
+ */
+ public void SetBias(String value) {
+ this.fbias = int.Parse(value);
+ }
+ /**
+ * Set the font theme
+ *
+ * @param themeFont Theme value
+ *
+ * @since 2.0.8
+ */
+ public void SetThemeFont(String themeFont) {
+ this.themeFont = themeFont;
+ }
+ /**
+ * Set the font name to the parsed value.
+ *
+ * @param fontName The font name.
+ *
+ * @since 2.0.8
+ */
+ public void SetFontName(String fontName) {
+ this.fontName = fontName;
+ }
+ /**
+ * Set the font family to the parsed value.
+ *
+ * @param fontFamily The font family.
+ *
+ * @since 2.0.8
+ */
+ public void SetFontFamily(String fontFamily) {
+ this.fontFamily = fontFamily;
+ }
+ /**
+ * Set the font number to the parsed value.
+ * This is used for mapping fonts to the new font numbers
+ *
+ * @param fontNr The font number.
+ *
+ * @since 2.0.8
+ */
+ public void SetFontNumber(String fontNr) {
+ this.fontNr = fontNr;
+ }
+ /**
+ * Set the alternate font name.
+ *
+ * @param fontAlternate The falt font value
+ *
+ * @since 2.0.8
+ */
+ public void SetFontAlternate(String fontAlternate) {
+ this.falt = fontAlternate;
+ }
+ /**
+ * Set the character-set to the parsed value.
+ *
+ * @param charset The charset value
+ *
+ * @since 2.0.8
+ */
+ public void SetCharset(String charset) {
+ if (charset.Length == 0) {
+ charset = "0";
+ }
+ this.charset = charset;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults()
+ *
+ * @since 2.0.8
+ */
+ public override void SetToDefaults() {
+ this.themeFont = "";
+ this.fontNr = "";
+ this.fontName = "";
+ this.fontFamily = "";
+
+ this.charset = "";
+ this.fprq = 0;
+ this.panose = "";
+ //this.nontaggedname = "";
+ this.falt = "";
+ //this.fontemb = "";
+ //this.fontType = "";
+ //this.fontFile = "";
+ //this.fontFileCpg = "";
+ this.fbias = 0;
+ this.cpg = "";
+ this.trueType = "";
+ this.state = SETTING_NORMAL;
+ }
+ /**
+ * Process the font information that was parsed from the input.
+ *
+ * @since 2.0.8
+ */
+ private void ProcessFont() {
+ this.fontName = this.fontName.Trim();
+ if (fontName.Length == 0) return;
+ if (fontNr.Length == 0) return;
+
+ if (fontName.Length>0 && fontName.IndexOf(';') >= 0) {
+ fontName = fontName.Substring(0,fontName.IndexOf(';'));
+ }
+
+ if (this.rtfParser.IsImport()) {
+ //TODO: If primary font fails, use the alternate
+ //TODO: Problem: RtfFont defaults family to \froman and doesn't allow any other family.
+ // if you set the family, it changes the font name and not the family in the Font.java class.
+
+ // if (this.fontFamily.Length() > 0) {
+ // if (this.importHeader.ImportFont(this.fontNr, this.fontName, this.fontFamily, Integer.ParseInt(this.charset)) == false) {
+ // if (this.falt.Length() > 0) {
+ // this.importHeader.ImportFont(this.fontNr, this.falt, this.fontFamily, Integer.ParseInt(this.charset));
+ // }
+ // }
+ // } else {
+ if (!this.importHeader.ImportFont(this.fontNr, this.fontName, int.Parse(this.charset==""?CHARSET_DEFAULT:this.charset))) {
+ if (this.falt.Length > 0) {
+ this.importHeader.ImportFont(this.fontNr, this.falt, int.Parse(this.charset==""?CHARSET_DEFAULT:this.charset));
+ }
+ }
+ // }
+ }
+ if (this.rtfParser.IsConvert()) {
+ // This could probably be written as a better font matching function
+
+ String fName = this.fontName; // work variable for trimming name if needed.
+ Font f1 = Createfont(fName);
+ if (f1.BaseFont == null && this.falt.Length>0)
+ f1 = Createfont(this.falt);
+
+ if (f1.BaseFont == null) {
+ // Did not find a font, let's try a substring of the first name.
+ if (FontFactory.COURIER.IndexOf(fName) > -1 ) {
+ f1 = FontFactory.GetFont(FontFactory.COURIER);
+ } else if (FontFactory.HELVETICA.IndexOf(fName) > -1 ) {
+ f1 = FontFactory.GetFont(FontFactory.HELVETICA);
+ } else if (FontFactory.TIMES.IndexOf(fName) > -1 ) {
+ f1 = FontFactory.GetFont(FontFactory.TIMES);
+ } else if (FontFactory.SYMBOL.IndexOf(fName) > -1 ) {
+ f1 = FontFactory.GetFont(FontFactory.SYMBOL);
+ } else if (FontFactory.ZAPFDINGBATS.IndexOf(fName) > -1 ) {
+ f1 = FontFactory.GetFont(FontFactory.ZAPFDINGBATS);
+ } else {
+ // we did not find a matching font in any form.
+ // default to HELVETICA for now.
+ f1 = FontFactory.GetFont(FontFactory.HELVETICA);
+ }
+ }
+ fontMap[this.fontNr] = f1;
+ //System.out.Println(f1.GetFamilyname());
+ }
+ this.SetToDefaults();
+ }
+ /**
+ * Create a font via the FontFactory
+ *
+ * @param fontName The font name to create
+ * @return The created Font
object
+ *
+ * @since 2.0.8
+ */
+ private Font Createfont(String fontName) {
+ Font f1 = null;
+ int pos=-1;
+ do {
+ f1 = FontFactory.GetFont(fontName);
+
+ if (f1.BaseFont != null) break; // found a font, exit the do/while
+
+ pos = fontName.LastIndexOf(' '); // find the last space
+ if (pos>0) {
+ fontName = fontName.Substring(0, pos ); // truncate it to the last space
+ }
+ } while (pos>0);
+ return f1;
+ }
+ /**
+ * Get a Font
object from the font map object
+ *
+ * @param key The font number to get
+ * @return The mapped Font
object.
+ *
+ * @since 2.0.8
+ */
+ public Font GetFont(String key) {
+ return (Font) fontMap[key];
+ }
+ /**
+ * Load system fonts into the static FontFactory
object
+ *
+ * @since 2.0.8
+ */
+ private void ImportSystemFonts() {
+ FontFactory.RegisterDirectories();
+ }
+
+ /**
+ * Utility method to load the environment variables.
+ *
+ * @return Properties object with environment variable information
+ * @throws Throwable
+ *
+ * @since 2.0.8
+ */
+// private Properties GetEnvironmentVariables() {
+// Properties environmentVariables = new Properties();
+// String operatingSystem = System.GetProperty("os.name").ToLowerCase();
+// Runtime runtime = Runtime.GetRuntime();
+// Process process = null;
+// if (operatingSystem.IndexOf("windows 95") > -1
+// || operatingSystem.IndexOf("windows 98") > -1
+// || operatingSystem.IndexOf("me") > -1) {
+// process = runtime.Exec("command.com /c set");
+// } else if ((operatingSystem.IndexOf("nt") > -1)
+// || (operatingSystem.IndexOf("windows 2000") > -1)
+// || (operatingSystem.IndexOf("windows xp") > -1)
+// || (operatingSystem.IndexOf("windows 2003") > -1)) {
+// process = runtime.Exec("cmd.exe /c set");
+// } else {
+// process = runtime.Exec("env");
+// }
+// BufferedReader environmentStream = new BufferedReader(new InputStreamReader(process.GetInputStream()));
+// String inputLine = "";
+// int idx = -1;
+// while ((inputLine = environmentStream.ReadLine()) != null) {
+// idx = inputLine.IndexOf('=');
+// environmentVariables.SetProperty(inputLine.Substring(0, idx),
+// inputLine.Substring(idx + 1));
+// }
+// return environmentVariables;
+// }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationInfo.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationInfo.cs
new file mode 100644
index 0000000..ce5de0c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationInfo.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: RtfDestinationInfo.cs,v 1.2 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationInfo
handles data destined for the info destination
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public class RtfDestinationInfo : RtfDestination {
+ private String elementName = "";
+ private String text = "";
+
+
+ public RtfDestinationInfo() : base(null) {
+ }
+ /**
+ * Constructs a new RtfDestinationInfo.
+ *
+ * @param parser The RtfParser object.
+ */
+ public RtfDestinationInfo(RtfParser parser, String elementname) : base(parser) {
+ SetToDefaults();
+ this.elementName = elementname;
+ }
+ public override void SetParser(RtfParser parser) {
+ this.rtfParser = parser;
+ this.SetToDefaults();
+ }
+ public void SetElementName(String value) {
+ this.elementName = value;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+ */
+ public override bool HandleOpeningSubGroup() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+ */
+ public override bool CloseDestination() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+ */
+ public override bool HandleCloseGroup() {
+ if (this.text.Length > 0) {
+ Document doc = this.rtfParser.GetDocument();
+ if (doc != null) {
+ if (this.elementName.Equals("author")){
+ doc.AddAuthor(this.text);
+ }
+ if (this.elementName.Equals("title")){
+ doc.AddTitle(this.text);
+ }
+ if (this.elementName.Equals("subject")){
+ doc.AddSubject(this.text);
+ }
+ } else {
+ RtfDocument rtfDoc = this.rtfParser.GetRtfDocument();
+ if (rtfDoc != null) {
+ if (this.elementName.Equals("author")){
+ Meta meta = new Meta(this.elementName, this.text);
+ RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta);
+ rtfDoc.GetDocumentHeader().AddInfoElement(elem);
+ }
+ if (this.elementName.Equals("title")){
+ Meta meta = new Meta(this.elementName, this.text);
+ RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta);
+ rtfDoc.GetDocumentHeader().AddInfoElement(elem);
+ }
+ if (this.elementName.Equals("subject")){
+ Meta meta = new Meta(this.elementName, this.text);
+ RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta);
+ rtfDoc.GetDocumentHeader().AddInfoElement(elem);
+ }
+ }
+ }
+ this.SetToDefaults();
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+ */
+ public override bool HandleOpenGroup() {
+
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(char[])
+ */
+ public override bool HandleCharacter(int ch) {
+ this.text += (char)ch;
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData)
+ */
+ public override bool HandleControlWord(RtfCtrlWordData ctrlWordData) {
+ elementName = ctrlWordData.ctrlWord;
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setToDefaults()
+ */
+ public override void SetToDefaults() {
+ this.text = "";
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationListTable.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationListTable.cs
new file mode 100644
index 0000000..e326646
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationListTable.cs
@@ -0,0 +1,130 @@
+using System;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: RtfDestinationListTable.cs,v 1.2 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationListTable
handles data destined for the List Table destination
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ */
+ public class RtfDestinationListTable : RtfDestination {
+ /**
+ * The RtfImportHeader to add List mappings to.
+ */
+ private RtfImportMgr importHeader = null;
+
+ public RtfDestinationListTable() : base(null) {
+ }
+
+ public RtfDestinationListTable(RtfParser parser) : base(parser) {
+ this.importHeader = parser.GetImportManager();
+ }
+
+ public override void SetParser(RtfParser parser) {
+ this.rtfParser = parser;
+ this.importHeader = parser.GetImportManager();
+ this.SetToDefaults();
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+ */
+ public override bool HandleOpeningSubGroup() {
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+ */
+ public override bool CloseDestination() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+ public override bool HandleControlWord(RtfCtrlWordData ctrlWordData) {
+ bool result = true;
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+ */
+ public override bool HandleCloseGroup() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+ */
+ public override bool HandleOpenGroup() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int)
+ */
+ public override bool HandleCharacter(int ch) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setToDefaults()
+ */
+ public override void SetToDefaults() {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationMgr.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationMgr.cs
new file mode 100644
index 0000000..40cc288
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationMgr.cs
@@ -0,0 +1,227 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: RtfDestinationMgr.cs,v 1.4 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationMgr
manages destination objects for the parser
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public sealed class RtfDestinationMgr {
+ /*
+ * Destinations
+ */
+ private static RtfDestinationMgr instance = null;
+
+ /**
+ * CtrlWord <-> Destination map object.
+ *
+ * Maps control words to their destinations objects.
+ * Null destination is a special destination used for
+ * discarding unwanted data. This is primarily used when
+ * skipping groups, binary data or unwanted/unknown data.
+ */
+ private static Hashtable destinations = new Hashtable(300, 0.95f);
+ /**
+ * Destination objects.
+ * There is only one of each destination.
+ */
+ private static Hashtable destinationObjects = new Hashtable(10, 0.95f);
+
+ private static bool ignoreUnknownDestinations = false;
+
+ private static RtfParser rtfParser = null;
+
+ /**
+ * String representation of null destination.
+ */
+ public const String DESTINATION_NULL = "null";
+ /**
+ * String representation of document destination.
+ */
+ public const String DESTINATION_DOCUMENT = "document";
+
+ /**
+ * Hidden default constructor becuase
+ */
+ private RtfDestinationMgr() {
+ }
+
+ public static void SetParser(RtfParser parser) {
+ rtfParser = parser;
+ }
+ public static RtfDestinationMgr GetInstance() {
+ lock(destinations) {
+ if (instance == null) {
+ instance = new RtfDestinationMgr();
+ // 2 required destinations for all documents
+ RtfDestinationMgr.AddDestination(RtfDestinationMgr.DESTINATION_DOCUMENT, new Object[] { "RtfDestinationDocument", "" } );
+ RtfDestinationMgr.AddDestination(RtfDestinationMgr.DESTINATION_NULL, new Object[] { "RtfDestinationNull", "" } );
+ }
+ return instance;
+ }
+ }
+ public static RtfDestinationMgr GetInstance(RtfParser parser) {
+ lock(destinations) {
+ RtfDestinationMgr.SetParser(parser);
+ if (instance == null) {
+ instance = new RtfDestinationMgr();
+ // 2 required destinations for all documents
+ RtfDestinationMgr.AddDestination(RtfDestinationMgr.DESTINATION_DOCUMENT, new Object[] { "RtfDestinationDocument", "" } );
+ RtfDestinationMgr.AddDestination(RtfDestinationMgr.DESTINATION_NULL, new Object[] { "RtfDestinationNull", "" } );
+ }
+ return instance;
+ }
+ }
+
+ public static RtfDestination GetDestination(String destination) {
+ RtfDestination dest = null;
+ if (destinations.ContainsKey(destination)) {
+ dest = (RtfDestination)destinations[destination];
+ } else {
+ if (ignoreUnknownDestinations) {
+ dest = (RtfDestination)destinations[DESTINATION_NULL];
+ } else {
+ dest = (RtfDestination)destinations[DESTINATION_DOCUMENT];
+ }
+ }
+ dest.SetParser(RtfDestinationMgr.rtfParser);
+ return dest;
+ }
+
+ public static bool AddDestination(String destination, Object[] args) {
+ if (destinations.ContainsKey(destination)) {
+ return true;
+ }
+
+ String thisClass = "iTextSharp.text.rtf.parser.destinations." + (String)args[0];
+
+ if (thisClass.IndexOf("RtfDestinationNull") >= 0) {
+ destinations[destination] = RtfDestinationNull.GetInstance();
+ return true;
+ }
+
+ Type value = null;
+
+ try {
+ value = Type.GetType(thisClass);
+ } catch {
+ return false;
+ }
+ if (value == null)
+ return false;
+
+ RtfDestination c = null;
+
+ if (destinationObjects.ContainsKey(value.Name)) {
+ c = (RtfDestination)destinationObjects[value.Name];
+ } else {
+ try {
+ c = (RtfDestination)value.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null).Invoke(null);
+ } catch {
+ return false;
+ }
+ }
+
+ c.SetParser(rtfParser);
+
+ if (value.Equals(typeof(RtfDestinationInfo))) {
+ ((RtfDestinationInfo)c).SetElementName(destination);
+ }
+
+ if (value.Equals(typeof(RtfDestinationStylesheetTable))) {
+ ((RtfDestinationStylesheetTable)c).SetElementName(destination);
+ ((RtfDestinationStylesheetTable)c).SetType((String)args[1]);
+ }
+
+ destinations[destination] = c;
+ destinationObjects[value.Name] = c;
+ return true;
+ }
+
+ // listener methods
+
+ /**
+ * Adds a RtfDestinationListener
to the appropriate RtfDestination
.
+ *
+ * @param destination the destination string for the listener
+ * @param listener
+ * the new RtfDestinationListener.
+ */
+ public static bool AddListener(String destination, IRtfDestinationListener listener) {
+ RtfDestination dest = GetDestination(destination);
+ if (dest != null) {
+ return dest.AddListener(listener);
+ }
+ return false;
+ }
+
+ /**
+ * Removes a RtfDestinationListener
from the appropriate RtfDestination
.
+ *
+ * @param destination the destination string for the listener
+ * @param listener
+ * the RtfCtrlWordListener that has to be removed.
+ */
+ public static bool RemoveListener(String destination, IRtfDestinationListener listener) {
+ RtfDestination dest = GetDestination(destination);
+ if (dest != null) {
+ return dest.RemoveListener(listener);
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationNull.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationNull.cs
new file mode 100644
index 0000000..3a74d6a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationNull.cs
@@ -0,0 +1,147 @@
+using System;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: RtfDestinationNull.cs,v 1.2 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationNull
is for discarded entries. They go nowhere.
+ * If a control word destination is unknown or ignored, this is the destination
+ * that should be set.
+ *
+ * All methods return true indicating they were handled.
+ *
+ * This is a unique destination in that it is a singleton.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public sealed class RtfDestinationNull : RtfDestination {
+ private static RtfDestinationNull instance = new RtfDestinationNull();
+ /**
+ * Constructs a new RtfDestinationNull.
+ *
+ * This constructor is hidden for internal use only.
+ */
+ private RtfDestinationNull() : base() {
+ }
+ /**
+ * Constructs a new RtfDestinationNull.
+ *
+ * This constructor is hidden for internal use only.
+ *
+ * @param parser Unused value
+ */
+ private RtfDestinationNull(RtfParser parser) : base(null) {
+ }
+ /**
+ * Get the singleton instance of RtfDestinationNull object.
+ */
+ static public RtfDestinationNull GetInstance() {
+ return instance;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+ */
+ public override bool HandleOpeningSubGroup() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults()
+ */
+ public override void SetToDefaults() {
+ }
+
+ // Interface definitions
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+ */
+ public override bool CloseDestination() {
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+ */
+ public override bool HandleCloseGroup() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+ */
+ public override bool HandleOpenGroup() {
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int)
+ */
+ public override bool HandleCharacter(int ch) {
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData)
+ */
+ public override bool HandleControlWord(RtfCtrlWordData ctrlWordData) {
+ return true;
+ }
+
+ public static String GetName() {
+ return typeof(RtfDestinationNull).Name;
+ }
+
+ public override int GetNewTokeniserState() {
+ return RtfParser.TOKENISER_SKIP_GROUP;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationShppict.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationShppict.cs
new file mode 100644
index 0000000..695f8e7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationShppict.cs
@@ -0,0 +1,488 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using iTextSharp.text;
+using iTextSharp.text.pdf;
+using iTextSharp.text.rtf.direct;
+using iTextSharp.text.rtf.graphic;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: RtfDestinationShppict.cs,v 1.2 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationShppict
handles data destined for picture destinations
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public class RtfDestinationShppict : RtfDestination {
+ private ByteBuffer data = null;
+
+ private StringBuilder hexChars = new StringBuilder(0);
+ private StringBuilder buffer = new StringBuilder();
+
+ /* picttype */
+ private int pictureType = Image.ORIGINAL_NONE;
+ public const int ORIGINAL_NONE = 0;
+ public const int ORIGINAL_GIF = 3;
+ public const int ORIGINAL_TIFF = 5;
+ public const int ORIGINAL_PS = 7;
+
+ // emfblip - EMF (nhanced metafile) - NOT HANDLED
+ // pngblip int ORIGINAL_PNG = 2;
+ // jpegblip Image.ORIGINAL_JPEG = 1; ORIGINAL_JPEG2000 = 8;
+
+ // shppict - Destination
+ // nonshpict - Destination - SKIP THIS
+ // macpict - Mac QuickDraw- NOT HANDLED
+ // pmmetafileN - OS/2 Metafile - NOT HANDLED
+ // N * Meaning
+ // 0x0004 PU_ARBITRARY
+ // 0x0008 PU_PELS
+ // 0x000C PU_LOMETRIC
+ // 0x0010 PU_HIMETRIC
+ // 0x0014 PU_LOENGLISH
+ // 0x0018 PU_HIENGLISH
+ // 0x001C PU_TWIPS
+ //private int pmmetafile = 0;
+ // wmetafileN Image.RIGINAL_WMF = 6;
+ // N * Type
+ // 1 = MM_TEXT
+ // 2 = M_LOMETRIC
+ // 3 = MM_HIMETRIC
+ // 4 = MM_LOENGLISH
+ // 5 = MM_HIENGLISH
+ // 6 = MM_TWIPS
+ // 7 = MM_ISOTROPIC
+ // 8 = MM_ANISOTROPIC
+ // dibitmapN - DIB - Convert to BMP?
+ // wbitmapN Image.ORIGINAL_BMP = 4;
+
+ /* bitapinfo */
+ // wbmbitspixelN - number of bits per pixel - 1 monochrome, 4 16 color, 8 256 color, 24 RGB - Default 1
+ //private int bitsPerPixel = 1;
+ // wbmplanesN - number of color planes - must be 1
+ //private int planes = 1;
+ // wbmwidthbytesN - number of bytes in each raster line
+ //private int widthBytes = 0;
+
+
+
+ /* pictsize */
+ // picwN Ext field if the picture is a Windows metafile; picture width in pixels if the picture is a bitmap or
+ // from quickdraw
+ private long width = 0;
+ // pichN
+ private long height = 0;
+ // picwgoalN
+ private long desiredWidth = 0;
+ // picgoalN
+ private long desiredHeight = 0;
+ // picscalexN
+ private int scaleX = 100;
+ // picscaleyN
+ private int scaleY = 100;
+ // picscaled - macpict setting
+ //private bool scaled = false;
+ // picprop
+ //private bool inlinePicture = false;
+ // defshp
+ //private bool wordArt = false;
+ // piccroptN
+ private int cropTop = 0;
+ // piccropbN
+ private int cropBottom = 0;
+ // piccroplN
+ private int cropLeft = 0;
+ // piccroprN
+ private int cropRight = 0;
+
+ /* metafileinfo */
+ // picbmp
+ //private bool bitmap = false;
+ //picbppN - Valid 1,4,8,24
+ //private int bbp = 1;
+
+ /* data */
+ // binN
+ // 0 = HEX, 1 = BINARY
+ public const int FORMAT_HEXADECIMAL = 0;
+ public const int FORMAT_BINARY = 1;
+ private int dataFormat = FORMAT_HEXADECIMAL;
+ private long binaryLength = 0;
+ // blipupiN
+ //private int unitsPerInch = 0;
+ // bliptagN
+ //private String tag = "";
+ private const int NORMAL = 0;
+ private const int BLIPUID = 1;
+
+ //private int state = NORMAL;
+ /**
+ * Constant for converting pixels to twips
+ */
+ private const int PIXEL_TWIPS_FACTOR = 15;
+
+ private MemoryStream dataOS = null;
+
+ public RtfDestinationShppict() : base(null) {
+ this.pictureType = pictureType; //get rid of a warning
+ }
+
+ /**
+ * Constructs a new RtfDestinationShppict.
+ */
+ public RtfDestinationShppict(RtfParser parser) : base(parser) {
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+ */
+ public override bool CloseDestination() {
+ if (this.rtfParser.IsImport()) {
+ if (this.buffer.Length>0) {
+ WriteBuffer();
+ }
+ }
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+ */
+ public override bool HandleCloseGroup() {
+ this.OnCloseGroup(); // event handler
+
+ if (this.rtfParser.IsImport()) {
+ if (this.buffer.Length>0) {
+ WriteBuffer();
+ }
+ if (dataOS != null) {
+ AddImage();
+ dataOS = null;
+ }
+ this.WriteText("}");
+ return true;
+ }
+ if (this.rtfParser.IsConvert()) {
+ }
+ return true;
+ }
+
+ private bool AddImage() {
+ Image img = null;
+ try {
+ img = Image.GetInstance(dataOS.ToArray());
+ } catch {
+ }
+// if (img != null) {
+// FileOutputStream out =null;
+// try {
+// out = new FileOutputStream("c:\\test.png");
+// out.Write(img.GetOriginalData());
+// out.Close();
+// } catch (FileNotFoundException e1) {
+// // TODO Auto-generated catch block
+// e1.PrintStackTrace();
+// } catch (IOException e1) {
+// // TODO Auto-generated catch block
+// e1.PrintStackTrace();
+// }
+
+ if (img != null) {
+ img.ScaleAbsolute((float)this.desiredWidth/PIXEL_TWIPS_FACTOR, (float)this.desiredHeight/PIXEL_TWIPS_FACTOR);
+ img.ScaleAbsolute((float)this.width/PIXEL_TWIPS_FACTOR, (float)this.height/PIXEL_TWIPS_FACTOR);
+ img.ScalePercent((float)this.scaleX, this.scaleY);
+
+ try {
+ if (this.rtfParser.IsImport()) {
+ RtfDocument rtfDoc = this.rtfParser.GetRtfDocument();
+ RtfImage rtfImage = new RtfImage(rtfDoc, img);
+ rtfDoc.Add(rtfImage);
+ }
+ if (this.rtfParser.IsConvert()) {
+ this.rtfParser.GetDocument().Add(img);
+ }
+ } catch {
+ }
+ }
+ dataFormat = FORMAT_HEXADECIMAL;
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+ */
+ public override bool HandleOpenGroup() {
+ this.OnOpenGroup(); // event handler
+
+ if (this.rtfParser.IsImport()) {
+ }
+ if (this.rtfParser.IsConvert()) {
+ }
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+ */
+ public override bool HandleOpeningSubGroup() {
+ if (this.rtfParser.IsImport()) {
+ if (this.buffer.Length>0) {
+ WriteBuffer();
+ }
+ }
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int)
+ */
+ public override bool HandleCharacter(int ch) {
+
+ if (this.rtfParser.IsImport()) {
+ if (buffer.Length > 254)
+ WriteBuffer();
+ }
+ if (data == null) data = new ByteBuffer();
+ switch (dataFormat) {
+ case FORMAT_HEXADECIMAL:
+ hexChars.Append(ch);
+ if (hexChars.Length == 2) {
+ try {
+ data.Append((char)int.Parse(hexChars.ToString(), NumberStyles.HexNumber));
+ } catch {
+ }
+ hexChars = new StringBuilder();
+ }
+ break;
+ case FORMAT_BINARY:
+ if (dataOS == null) {
+ dataOS = new MemoryStream();
+ }
+ // HGS - FIX ME IF PROBLEM!
+ dataOS.WriteByte((byte)ch);
+ // PNG signature should be.
+ // (decimal) 137 80 78 71 13 10 26 10
+ // (hexadecimal) 89 50 4e 47 0d 0a 1a 0a
+ // (ASCII C notation) \211 P N G \r \n \032 \n
+
+ binaryLength--;
+ if (binaryLength == 0) { dataFormat = FORMAT_HEXADECIMAL; }
+ break;
+ }
+
+ return true;
+ }
+
+ public override bool HandleControlWord(RtfCtrlWordData ctrlWordData) {
+ bool result = false;
+ bool skipCtrlWord = false;
+ if (this.rtfParser.IsImport()) {
+ skipCtrlWord = true;
+ if (ctrlWordData.ctrlWord.Equals("shppict")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("nonshppict")) { // never gets here because this is a destination set to null
+ skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;
+ }
+ if (ctrlWordData.ctrlWord.Equals("blipuid")) { skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picprop")) { skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("pict")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("emfblip")) { result = true; pictureType = Image.ORIGINAL_NONE;}
+ if (ctrlWordData.ctrlWord.Equals("pngblip")) { result = true; pictureType = Image.ORIGINAL_PNG;}
+ if (ctrlWordData.ctrlWord.Equals("jepgblip")) { result = true; pictureType = Image.ORIGINAL_JPEG;}
+ if (ctrlWordData.ctrlWord.Equals("macpict")) { result = true; pictureType = Image.ORIGINAL_NONE;}
+ if (ctrlWordData.ctrlWord.Equals("pmmetafile")) { result = true; pictureType = Image.ORIGINAL_NONE;}
+ if (ctrlWordData.ctrlWord.Equals("wmetafile")) { result = true; pictureType = Image.ORIGINAL_WMF;}
+ if (ctrlWordData.ctrlWord.Equals("dibitmap")) { result = true; pictureType = Image.ORIGINAL_NONE;}
+ if (ctrlWordData.ctrlWord.Equals("wbitmap")) { result = true; pictureType = Image.ORIGINAL_BMP;}
+ /* bitmap information */
+ if (ctrlWordData.ctrlWord.Equals("wbmbitspixel")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("wbmplanes")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("wbmwidthbytes")) { result = true;}
+ /* picture size, scaling and cropping */
+ if (ctrlWordData.ctrlWord.Equals("picw")) { this.width = ctrlWordData.LongValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("pich")) { this.height = ctrlWordData.LongValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picwgoal")) { this.desiredWidth = ctrlWordData.LongValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("pichgoal")) { this.desiredHeight = ctrlWordData.LongValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picscalex")) { this.scaleX = ctrlWordData.IntValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picscaley")) { this.scaleY = ctrlWordData.IntValue();result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picscaled")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picprop")) { skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("defshp")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("piccropt")) { this.cropTop = ctrlWordData.IntValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("piccropb")) { this.cropBottom = ctrlWordData.IntValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("piccropl")) { this.cropLeft = ctrlWordData.IntValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("piccropr")) { this.cropRight = ctrlWordData.IntValue(); result = true;}
+ /* metafile information */
+ if (ctrlWordData.ctrlWord.Equals("picbmp")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picbpp")) { result = true;}
+ /* picture data */
+ if (ctrlWordData.ctrlWord.Equals("bin")) {
+ this.dataFormat = FORMAT_BINARY;
+ // set length to param
+ this.binaryLength = ctrlWordData.LongValue();
+ this.rtfParser.SetTokeniserStateBinary(binaryLength);
+ result = true;
+ }
+ if (ctrlWordData.ctrlWord.Equals("blipupi")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("blipuid")) { skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("bliptag")) { result = true;}
+ }
+ if (this.rtfParser.IsConvert()) {
+ if (ctrlWordData.ctrlWord.Equals("shppict")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("nonshppict")) { skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("blipuid")) { result = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("pict")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("emfblip")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("pngblip")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("jepgblip")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("macpict")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("pmmetafile")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("wmetafile")) { skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("dibitmap")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("wbitmap")) { result = true;}
+ /* bitmap information */
+ if (ctrlWordData.ctrlWord.Equals("wbmbitspixel")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("wbmplanes")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("wbmwidthbytes")) { result = true;}
+ /* picture size, scaling and cropping */
+ if (ctrlWordData.ctrlWord.Equals("picw")) { this.width = ctrlWordData.LongValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("pich")) { this.height = ctrlWordData.LongValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picwgoal")) { this.desiredWidth = ctrlWordData.LongValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("pichgoal")) { this.desiredHeight = ctrlWordData.LongValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picscalex")) { this.scaleX = ctrlWordData.IntValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picscaley")) { this.scaleY = ctrlWordData.IntValue();result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picscaled")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picprop")) { skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("defshp")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("piccropt")) { this.cropTop = ctrlWordData.IntValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("piccropb")) { this.cropBottom = ctrlWordData.IntValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("piccropl")) { this.cropLeft = ctrlWordData.IntValue(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("piccropr")) { this.cropRight = ctrlWordData.IntValue(); result = true;}
+ /* metafile information */
+ if (ctrlWordData.ctrlWord.Equals("picbmp")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("picbpp")) { result = true;}
+ /* picture data */
+ if(ctrlWordData.ctrlWord.Equals("bin")) {
+ dataFormat = FORMAT_BINARY; result = true;
+ }
+ if (ctrlWordData.ctrlWord.Equals("blipupi")) { result = true;}
+ if (ctrlWordData.ctrlWord.Equals("blipuid")) { skipCtrlWord = true; this.rtfParser.SetTokeniserStateSkipGroup(); result = true;}
+ if (ctrlWordData.ctrlWord.Equals("bliptag")) { result = true;}
+
+ }
+ if (!skipCtrlWord) {
+ switch (this.rtfParser.GetConversionType()) {
+ case RtfParser.TYPE_IMPORT_FULL:
+ WriteBuffer();
+ WriteText(ctrlWordData.ToString());
+ result = true;
+ break;
+ case RtfParser.TYPE_IMPORT_FRAGMENT:
+ WriteBuffer();
+ WriteText(ctrlWordData.ToString());
+ result = true;
+ break;
+ case RtfParser.TYPE_CONVERT:
+ result = true;
+ break;
+ default: // error because is should be an import or convert
+ result = false;
+ break;
+ }
+ }
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults()
+ */
+ public override void SetToDefaults() {
+
+ this.buffer = new StringBuilder();
+ this.data = null;
+ this.width = 0;
+ this.height = 0;
+ this.desiredWidth = 0;
+ this.desiredHeight = 0;
+ this.scaleX = 100;
+ this.scaleY = 100;
+ //this.scaled = false;
+ //this.inlinePicture = false;
+ //this.wordArt = false;
+ this.cropTop = 0;
+ this.cropBottom = 0;
+ this.cropLeft = 0;
+ this.cropRight = 0;
+ //this.bitmap = false;
+ //this.bbp = 1;
+ this.dataFormat = FORMAT_HEXADECIMAL;
+ this.binaryLength = 0;
+ //this.unitsPerInch = 0;
+ //this.tag = "";
+ }
+
+ private void WriteBuffer() {
+ WriteText(this.buffer.ToString());
+ }
+ private void WriteText(String value) {
+ if (this.rtfParser.GetState().newGroup) {
+ this.rtfParser.GetRtfDocument().Add(new RtfDirectContent("{"));
+ this.rtfParser.GetState().newGroup = false;
+ }
+ if (value.Length > 0) {
+ this.rtfParser.GetRtfDocument().Add(new RtfDirectContent(value));
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationStylesheetTable.cs b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationStylesheetTable.cs
new file mode 100644
index 0000000..eaa5b4a
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/destinations/RtfDestinationStylesheetTable.cs
@@ -0,0 +1,585 @@
+using System;
+using iTextSharp.text;
+using iTextSharp.text.rtf.style;
+using iTextSharp.text.rtf.parser;
+using iTextSharp.text.rtf.parser.ctrlwords;
+/*
+ * $Id: RtfDestinationStylesheetTable.cs,v 1.2 2008/05/13 11:26:00 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.parser.destinations {
+
+ /**
+ * RtfDestinationStylesheetTable
handles data destined for the
+ * Stylesheet Table destination
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ */
+ public class RtfDestinationStylesheetTable : RtfDestination {
+ private String styleName = "";
+ /**
+ * RtfParagraphStyle
object for setting styleshee values
+ * as they are parsed from the input.
+ */
+ //private RtfParagraphStyle rtfParagraphStyle = null;
+
+ private String elementName = "";
+
+ /**
+ * RTF Style number from stylesheet table.
+ */
+ private int styleNr = 0;
+
+ /**
+ * What kind of style is this, Paragraph or Character or Table
+ */
+ private int styleType = RtfStyleTypes.PARAGRAPH;
+
+ // Alignment
+ /**
+ * Alignment - page 85
+ * \qc, \qj, \ql, \qr, \qd, \qkN, \qt
+ */
+ private int alignment = Element.ALIGN_LEFT;
+ /**
+ * Percentage of line occupied by Kashida justification (0 � low, 10 � medium, 20 � high).
+ * \qkN
+ */
+ private int justificationPercentage = 0;
+
+ // Indentation
+ /**
+ * First line indentation.
+ */
+ private int firstLineIndent = 0;
+ /**
+ * Left indentation
+ */
+ private int leftIndent = 0;
+ /**
+ * Right indentation
+ */
+ private int rightIndent = 0;
+ /**
+ * Automatically adjust right indentation when docunent grid is defined
+ */
+ private int adustRightIndent = 0;
+ /**
+ * Mirror indents?
+ */
+ private int mirrorIndent = 0;
+
+ // Document Foratting Properties
+ /**
+ * Override orphan/widow control.
+ */
+ private int overrideWidowControl = -1;
+
+ // Asian Typography
+ /**
+ * auto spacing betwee DBC and English
+ */
+ private int AutoSpaceBetweenDBCEnglish = 0;
+ /**
+ * auto spacing betwee DBC and numbers
+ */
+ private int AutoSpaceBetweenDBCNumbers = 0;
+ /**
+ * No Character wrapping
+ */
+ private int noCharacterWrapping = 0;
+ /**
+ * No Word wrapping
+ */
+ private int noWordWrapping = 0;
+ /**
+ * No overflow period and comma
+ */
+ private int noOverflowPeriodComma = 0;
+
+
+
+ //////////////////////////////////////////////////////
+ /**
+ * The RtfImportHeader to add color mappings to.
+ */
+ private RtfImportMgr importHeader = null;
+ private String type = "";
+
+ public RtfDestinationStylesheetTable() : base(null) {
+ }
+
+ public RtfDestinationStylesheetTable(RtfParser parser, String type) : base(parser){
+ this.importHeader = parser.GetImportManager();
+ this.type = type;
+ }
+ public override void SetParser(RtfParser parser) {
+ this.rtfParser = parser;
+ this.importHeader = parser.GetImportManager();
+ }
+ public void SetType(String value) {
+ this.type = value;
+ }
+ public void SetElementName(String value) {
+ this.elementName = value;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+ */
+ public override bool HandleOpeningSubGroup() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+ */
+ public override bool CloseDestination() {
+
+ return true;
+ }
+
+ public override bool HandleControlWord(RtfCtrlWordData ctrlWordData) {
+ bool result = true;
+ this.OnCtrlWord(ctrlWordData); // event handler
+
+ if (this.rtfParser.IsImport()) {
+ // information
+ if (ctrlWordData.ctrlWord.Equals("s")) { }
+ if (ctrlWordData.ctrlWord.Equals("cs")) {}
+ if (ctrlWordData.ctrlWord.Equals("ds")) {}
+ if (ctrlWordData.ctrlWord.Equals("ts")) {}
+ if (ctrlWordData.ctrlWord.Equals("tsrowd")) {}
+
+ if (ctrlWordData.ctrlWord.Equals("keycode")) {}
+ if (ctrlWordData.ctrlWord.Equals("shift")) { }
+ if (ctrlWordData.ctrlWord.Equals("ctrl")) { }
+ if (ctrlWordData.ctrlWord.Equals("alt")) { }
+ //cells
+ if (ctrlWordData.ctrlWord.Equals("fn")) { }
+ if (ctrlWordData.ctrlWord.Equals("additive")) { }
+ if (ctrlWordData.ctrlWord.Equals("sbasedon")) { }
+ if (ctrlWordData.ctrlWord.Equals("snext")) { }
+ if (ctrlWordData.ctrlWord.Equals("sautoupd")) { }
+ if (ctrlWordData.ctrlWord.Equals("shidden")) { }
+ if (ctrlWordData.ctrlWord.Equals("slink")) { }
+ if (ctrlWordData.ctrlWord.Equals("slocked")) { }
+ if (ctrlWordData.ctrlWord.Equals("spersonal")) { }
+ if (ctrlWordData.ctrlWord.Equals("scompose")) { }
+ if (ctrlWordData.ctrlWord.Equals("sreply")) { }
+ /* FORMATTING */
+ // brdrdef/parfmt/apoctl/tabdef/shading/chrfmt
+
+
+
+ if (ctrlWordData.ctrlWord.Equals("styrsid")) { }
+ if (ctrlWordData.ctrlWord.Equals("ssemihidden")) { }
+ if (ctrlWordData.ctrlWord.Equals("sqformat")) { }
+ if (ctrlWordData.ctrlWord.Equals("spriority")) { }
+ if (ctrlWordData.ctrlWord.Equals("sunhideused")) { }
+
+ /* TABLE STYLES */
+ if (ctrlWordData.ctrlWord.Equals("tscellwidth")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscellwidthfts")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscellpaddt")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscellpaddl")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscellpaddr")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscellpaddb")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscellpaddft"))/*0-auto, 3-twips*/ { }
+ if (ctrlWordData.ctrlWord.Equals("tscellpaddfl"))/*0-auto, 3-twips*/ { }
+ if (ctrlWordData.ctrlWord.Equals("tscellpaddfr"))/*0-auto, 3-twips*/ { }
+ if (ctrlWordData.ctrlWord.Equals("tscellpaddfb"))/*0-auto, 3-twips*/ { }
+ if (ctrlWordData.ctrlWord.Equals("tsvertalt")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsvertalc")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsvertalb")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsnowrap")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscellcfpat")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscellcbpat")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgbdiag")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgfdiag")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgcross")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgdcross")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgdkcross ")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgdkdcross")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbghoriz")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgvert")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgdkhor")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbgdkvert")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbrdrt")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbrdrb")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbrdrl")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbrdrr")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbrdrh")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbrdrv")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbrdrdgl")) { }
+ if (ctrlWordData.ctrlWord.Equals("tsbrdrdgr")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscbandsh")) { }
+ if (ctrlWordData.ctrlWord.Equals("tscbandsv")) { }
+ }
+ if (ctrlWordData.ctrlWordType == RtfCtrlWordType.FLAG ||
+ ctrlWordData.ctrlWordType == RtfCtrlWordType.TOGGLE ||
+ ctrlWordData.ctrlWordType == RtfCtrlWordType.VALUE) {
+ this.rtfParser.GetState().properties.SetProperty(ctrlWordData);
+ }
+
+ switch (this.rtfParser.GetConversionType()) {
+ case RtfParser.TYPE_IMPORT_FULL:
+ result = true;
+ break;
+ case RtfParser.TYPE_IMPORT_FRAGMENT:
+ result = true;
+ break;
+ case RtfParser.TYPE_CONVERT:
+ result = true;
+ break;
+ default: // error because is should be an import or convert
+ result = false;
+ break;
+ }
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+ */
+ public override bool HandleCloseGroup() {
+
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+ */
+ public override bool HandleOpenGroup() {
+
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int)
+ */
+ public override bool HandleCharacter(int ch) {
+ styleName += (char)ch;
+ return true;
+ }
+
+ public void CreateNewStyle() {
+ //public RtfParagraphStyle(String styleName, String fontName, int fontSize, int fontStyle, Color fontColor)
+ //this.rtfParagraphStyle = new RtfParagraphStyle();
+ }
+
+ /**
+ * Set the justification percentage from parsed value.
+ * @param percent The justification percentage
+ * @return The justification percentage
+ */
+ public int SetJustificationPercentage(int percent) {
+ this.justificationPercentage = percent;
+ return this.justificationPercentage;
+ }
+ /**
+ * Get the justification percentage.
+ * @return The justification percentage value.
+ */
+ public int GetJustificationPercentage() {
+ return this.justificationPercentage;
+ }
+ /**
+ * Set the alignment value from the parsed value.
+ * @param alignment The alignment value.
+ * @return The alignment value.
+ */
+ public int SetAlignment(int alignment) {
+ this.alignment = alignment;
+ return this.alignment;
+ }
+ /**
+ * Get the alignment value.
+ * @return The alignment value.
+ */
+ public int GetAlignment() {
+ return this.alignment;
+ }
+ /**
+ * Get the first line indent value.
+ *
+ * @return the firstLineIndent
+ */
+ public int GetFirstLineIndent() {
+ return firstLineIndent;
+ }
+ /**
+ * Set the first line indent value.
+ * @param firstLineIndent the firstLineIndent to set
+ */
+ public void SetFirstLineIndent(int firstLineIndent) {
+ this.firstLineIndent = firstLineIndent;
+ }
+ /**
+ * Get the left indent value
+ * @return the left indent
+ */
+ public int GetIndent() {
+ return leftIndent;
+ }
+ /**
+ * Set the left indent value from the value parsed.
+ * @param indent the left indent value.
+ */
+ public void SetIndent(int indent) {
+ this.leftIndent = indent;
+ }
+ /**
+ * Get the right indent adjustment value
+ * @return the adustRightIndent value
+ */
+ public int GetAdustRightIndent() {
+ return adustRightIndent;
+ }
+ /**
+ * Set the right indent adjustment value
+ * @param adustRightIndent the adustRightIndent to set
+ */
+ public void SetAdustRightIndent(int adustRightIndent) {
+ this.adustRightIndent = adustRightIndent;
+ }
+ /**
+ * Get the left indent value
+ * @return the leftIndent
+ */
+ public int GetLeftIndent() {
+ return leftIndent;
+ }
+ /**
+ * Set the left indent value
+ * @param leftIndent the leftIndent to set
+ */
+ public void SetLeftIndent(int leftIndent) {
+ this.leftIndent = leftIndent;
+ }
+ /**
+ * Get the value indicating if document has mirrored indents.
+ *
+ * @return the mirrorIndent
+ */
+ public int GetMirrorIndent() {
+ return mirrorIndent;
+ }
+ /**
+ * Set the mirrored indent value from the parsed value.
+ *
+ * @param mirrorIndent the mirrorIndent to set
+ */
+ public void SetMirrorIndent(int mirrorIndent) {
+ this.mirrorIndent = mirrorIndent;
+ }
+ /**
+ * Get the right indent value.
+ *
+ * @return the rightIndent
+ */
+ public int GetRightIndent() {
+ return rightIndent;
+ }
+ /**
+ * Set the right indent value.
+ *
+ * @param rightIndent the rightIndent to set
+ */
+ public void SetRightIndent(int rightIndent) {
+ this.rightIndent = rightIndent;
+ }
+ /**
+ * Get the ovirride widow control value.
+ *
+ * @return the overrideWidowControl
+ */
+ public int GetOverrideWidowControl() {
+ return overrideWidowControl;
+ }
+ /**
+ * Set the override widow control.
+ *
+ * @param overrideWidowControl the overrideWidowControl to set
+ */
+ public void SetOverrideWidowControl(int overrideWidowControl) {
+ this.overrideWidowControl = overrideWidowControl;
+ }
+ /**
+ * Get the auto space between DBC and English indicator.
+ *
+ * @return the autoSpaceBetweenDBCEnglish
+ */
+ public int GetAutoSpaceBetweenDBCEnglish() {
+ return AutoSpaceBetweenDBCEnglish;
+ }
+ /**
+ * Set the auto space between DBC and English indicator.
+ *
+ * @param autoSpaceBetweenDBCEnglish the autoSpaceBetweenDBCEnglish to set
+ */
+ public void SetAutoSpaceBetweenDBCEnglish(int autoSpaceBetweenDBCEnglish) {
+ AutoSpaceBetweenDBCEnglish = autoSpaceBetweenDBCEnglish;
+ }
+ /**
+ * Get the auto space between DBC and Numbers indicator.
+ * @return the autoSpaceBetweenDBCNumbers
+ */
+ public int GetAutoSpaceBetweenDBCNumbers() {
+ return AutoSpaceBetweenDBCNumbers;
+ }
+ /**
+ * Set the auto space between DBC and Numbers indicator.
+ * @param autoSpaceBetweenDBCNumbers the autoSpaceBetweenDBCNumbers to set
+ */
+ public void SetAutoSpaceBetweenDBCNumbers(int autoSpaceBetweenDBCNumbers) {
+ AutoSpaceBetweenDBCNumbers = autoSpaceBetweenDBCNumbers;
+ }
+ /**
+ * Get no character wrapping indicator.
+ *
+ * @return the noCharacterWrapping
+ */
+ public int GetNoCharacterWrapping() {
+ return noCharacterWrapping;
+ }
+ /**
+ * Set the no character wrapping indicator from parsed value
+ *
+ * @param noCharacterWrapping the noCharacterWrapping to set
+ */
+ public void SetNoCharacterWrapping(int noCharacterWrapping) {
+ this.noCharacterWrapping = noCharacterWrapping;
+ }
+ /**
+ * Get the no overflow period comma indicator.
+ *
+ * @return the noOverflowPeriodComma
+ */
+ public int GetNoOverflowPeriodComma() {
+ return noOverflowPeriodComma;
+ }
+ /**
+ * Set the no overflow period comma indicator from the parsed value.
+ *
+ * @param noOverflowPeriodComma the noOverflowPeriodComma to set
+ */
+ public void SetNoOverflowPeriodComma(int noOverflowPeriodComma) {
+ this.noOverflowPeriodComma = noOverflowPeriodComma;
+ }
+ /**
+ * Get the no word wrapping indicator.
+ *
+ * @return the noWordWrapping
+ */
+ public int GetNoWordWrapping() {
+ return noWordWrapping;
+ }
+ /**
+ * Set the no word wrapping indicator from the parsed value.
+ *
+ * @param noWordWrapping the noWordWrapping to set
+ */
+ public void SetNoWordWrapping(int noWordWrapping) {
+ this.noWordWrapping = noWordWrapping;
+ }
+ /**
+ * Get this style number.
+ *
+ * @return the styleNr
+ */
+ public int GetStyleNr() {
+ return styleNr;
+ }
+ /**
+ * Set this style number from the parsed value.
+ *
+ * @param styleNr the styleNr to set
+ */
+ public void SetStyleNr(int styleNr) {
+ this.styleNr = styleNr;
+ }
+ /**
+ * Get this style type.
+ * For example Style, Character Style, etc.
+ *
+ * @return the styleType
+ */
+ public int GetStyleType() {
+ return styleType;
+ }
+ /**
+ * Set the style type.
+ *
+ * @param styleType the styleType to set
+ */
+ public void SetStyleType(int styleType) {
+ this.styleType = styleType;
+ }
+ /* (non-Javadoc)
+ * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setToDefaults()
+ */
+ public override void SetToDefaults() {
+ styleName = "";
+ styleNr = 0;
+ alignment = Element.ALIGN_LEFT;
+ justificationPercentage = 0;
+ firstLineIndent = 0;
+ leftIndent = 0;
+ rightIndent = 0;
+ adustRightIndent = 0;
+ mirrorIndent = 0;
+ overrideWidowControl = -1;
+ AutoSpaceBetweenDBCEnglish = 0;
+ AutoSpaceBetweenDBCNumbers = 0;
+ noCharacterWrapping = 0;
+ noWordWrapping = 0;
+ noOverflowPeriodComma = 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/enumerations/RtfColorThemes.cs b/iTechSharp/iTextSharp/text/rtf/parser/enumerations/RtfColorThemes.cs
new file mode 100644
index 0000000..ef238cf
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/enumerations/RtfColorThemes.cs
@@ -0,0 +1,29 @@
+namespace iTextSharp.text.rtf.parser.enumerations {
+
+ /**
+ * Specifies the color theme values for use in Color Tables.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public sealed class RtfColorThemes {
+ public const int THEME_UNDEFINED = -1;
+ public const int THEME_MAINDARKONE = 0;
+ public const int THEME_MAINDARKTWO = 1;
+ public const int THEME_MAINLIGHTONE = 2;
+ public const int THEME_MAINLIGHTTWO = 3;
+ public const int THEME_ACCENTONE = 4;
+ public const int THEME_ACCENTTWO = 5;
+ public const int THEME_ACCENTTHREE = 6;
+ public const int THEME_ACCENTFOUR = 7;
+ public const int THEME_ACCENTFIVE = 8;
+ public const int THEME_ACCENTSIX = 9;
+ public const int THEME_HYPERLINK = 10;
+ public const int THEME_FOLLOWEDHYPERLINK = 11;
+ public const int THEME_BACKGROUNDONE = 12;
+ public const int THEME_TEXTONE = 13;
+ public const int THEME_BACKGROUNDTWO = 14;
+ public const int THEME_TEXTTWO = 15;
+ public const int THEME_MAX = 15;
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/exceptions/RtfParserException.cs b/iTechSharp/iTextSharp/text/rtf/parser/exceptions/RtfParserException.cs
new file mode 100644
index 0000000..88d9111
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/exceptions/RtfParserException.cs
@@ -0,0 +1,87 @@
+using System;
+/*
+ * $Id: RtfParserException.cs,v 1.2 2008/05/13 11:26:02 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.exceptions {
+
+ /*
+ * Signals that an error has occurred in a RtfParser
.
+ */
+ /**
+ * RtfParserException
is the exception object thrown by
+ * the parser
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public class RtfParserException : Exception {
+ /**
+ * Creates a RtfParserException object.
+ * @param ex an exception that has to be turned into a RtfParserException
+ */
+ public RtfParserException(Exception ex) : base("", ex) {
+ }
+
+ // constructors
+
+ /**
+ * Constructs a RtfParserException
whithout a message.
+ */
+ public RtfParserException() : base() {
+ }
+
+ /**
+ * Constructs a RtfParserException
with a message.
+ *
+ * @param message a message describing the exception
+ */
+ public RtfParserException(String message) : base(message) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/exceptions/RtfUnknownCtrlWordException.cs b/iTechSharp/iTextSharp/text/rtf/parser/exceptions/RtfUnknownCtrlWordException.cs
new file mode 100644
index 0000000..c1c3a65
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/exceptions/RtfUnknownCtrlWordException.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace iTextSharp.text.rtf.parser.exceptions {
+
+ public class RtfUnknownCtrlWordException : RtfParserException {
+
+ // constructors
+
+ /**
+ * Constructs a RtfParserException
whithout a message.
+ */
+ public RtfUnknownCtrlWordException() : base("Unknown control word.") {
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/properties/IRtfPropertyListener.cs b/iTechSharp/iTextSharp/text/rtf/parser/properties/IRtfPropertyListener.cs
new file mode 100644
index 0000000..c35d399
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/properties/IRtfPropertyListener.cs
@@ -0,0 +1,71 @@
+using System;
+using iTextSharp.text.rtf.parser;
+/*
+ * $Id: IRtfPropertyListener.cs,v 1.2 2008/05/13 11:26:03 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.properties {
+
+ /**
+ * RtfPropertyListener
interface for handling events.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ * @since 2.0.8
+ */
+ public interface IRtfPropertyListener : IEventListener {
+ /**
+ *
+ */
+ void BeforePropertyChange(String propertyName);
+ /**
+ *
+ */
+ void AfterPropertyChange(String propertyName);
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/properties/RtfCtrlWordPropertyType.cs b/iTechSharp/iTextSharp/text/rtf/parser/properties/RtfCtrlWordPropertyType.cs
new file mode 100644
index 0000000..8654dba
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/properties/RtfCtrlWordPropertyType.cs
@@ -0,0 +1,58 @@
+/* $Id: RtfCtrlWordPropertyType.cs,v 1.3 2008/05/13 11:26:03 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.properties {
+
+ public class RtfCtrlWordPropertyType {
+ public const int UNIDENTIFIED = -1;
+ public const int PROPERTY = 0;
+ public const int CHARACTER = 1;
+ public const int SPECIAL = 2;
+ public const int DESTINATION = 3;
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/rtf/parser/properties/RtfProperty.cs b/iTechSharp/iTextSharp/text/rtf/parser/properties/RtfProperty.cs
new file mode 100644
index 0000000..c604a5b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/parser/properties/RtfProperty.cs
@@ -0,0 +1,575 @@
+using System;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf.parser.ctrlwords;
+
+/* $Id: RtfProperty.cs,v 1.3 2008/05/13 11:26:03 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+namespace iTextSharp.text.rtf.parser.properties {
+
+ /**
+ * RtfProperty
handles document, paragraph, etc. property values
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public class RtfProperty {
+ public const int OFF = 0;
+ public const int ON = 1;
+
+ /* property groups */
+ public const String COLOR = "color.";
+ public const String CHARACTER = "character.";
+ public const String PARAGRAPH = "paragraph.";
+ public const String SECTION = "section.";
+ public const String DOCUMENT = "document.";
+
+ /* color properties */
+ public const String COLOR_FG = COLOR + "fg"; //Color Object
+ public const String COLOR_BG = COLOR + "bg"; //Color Object
+
+ /* character properties */
+ public const String CHARACTER_BOLD = CHARACTER + "bold";
+ public const String CHARACTER_UNDERLINE = CHARACTER + "underline";
+ public const String CHARACTER_ITALIC = CHARACTER + "italic";
+ public const String CHARACTER_SIZE = CHARACTER + "size";
+ public const String CHARACTER_FONT = CHARACTER + "font";
+ public const String CHARACTER_STYLE = CHARACTER + "style";
+
+ /* paragraph properties */
+ /** Justify left */
+ public const int JUSTIFY_LEFT = 0;
+ /** Justify right */
+ public const int JUSTIFY_RIGHT = 1;
+ /** Justify center */
+ public const int JUSTIFY_CENTER = 2;
+ /** Justify full */
+ public const int JUSTIFY_FULL = 3;
+
+ public const String PARAGRAPH_INDENT_LEFT = PARAGRAPH + "indentLeft"; // twips
+ public const String PARAGRAPH_INDENT_RIGHT = PARAGRAPH + "indentRight"; // twips
+ public const String PARAGRAPH_INDENT_FIRST_LINE = PARAGRAPH + "indentFirstLine"; // twips
+ public const String PARAGRAPH_JUSTIFICATION = PARAGRAPH + "justification";
+
+ public const String PARAGRAPH_BORDER = PARAGRAPH + "border";
+ public const String PARAGRAPH_BORDER_CELL = PARAGRAPH + "borderCell";
+
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_NIL = 0;
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_BOTTOM = 1;
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_TOP = 2;
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_LEFT = 4;
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_RIGHT = 8;
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_DIAGONAL_UL_LR = 16;
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_DIAGONAL_UR_LL = 32;
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_TABLE_HORIZONTAL = 64;
+ /** possible border settting */
+ public const int PARAGRAPH_BORDER_TABLE_VERTICAL = 128;
+
+ /* section properties */
+ /** Decimal number format */
+ public const int PGN_DECIMAL = 0;
+ /** Uppercase Roman Numeral */
+ public const int PGN_ROMAN_NUMERAL_UPPERCASE = 1;
+ /** Lowercase Roman Numeral */
+ public const int PGN_ROMAN_NUMERAL_LOWERCASE = 2;
+ /** Uppercase Letter */
+ public const int PGN_LETTER_UPPERCASE = 3;
+ /** Lowercase Letter */
+ public const int PGN_LETTER_LOWERCASE = 4;
+ /** Section Break None */
+ public const int SBK_NONE = 0;
+ /** Section Break Column break */
+ public const int SBK_COLUMN = 1;
+ /** Section Break Even page break */
+ public const int SBK_EVEN = 2;
+ /** Section Break Odd page break */
+ public const int SBK_ODD = 3;
+ /** Section Break Page break */
+ public const int SBK_PAGE = 4;
+
+ public const String SECTION_NUMBER_OF_COLUMNS = SECTION + "numberOfColumns";
+ public const String SECTION_BREAK_TYPE = SECTION + "SectionBreakType";
+ public const String SECTION_PAGE_NUMBER_POSITION_X = SECTION + "pageNumberPositionX";
+ public const String SECTION_PAGE_NUMBER_POSITION_Y = SECTION + "pageNumberPositionY";
+ public const String SECTION_PAGE_NUMBER_FORMAT = SECTION + "pageNumberFormat";
+
+ /* document properties */
+ /** Portrait orientation */
+ public const String PAGE_PORTRAIT = "0";
+ /** Landscape orientation */
+ public const String PAGE_LANDSCAPE = "1";
+
+ public const String DOCUMENT_PAGE_WIDTH_TWIPS = DOCUMENT + "pageWidthTwips";
+ public const String DOCUMENT_PAGE_HEIGHT_TWIPS = DOCUMENT + "pageHeightTwips";
+ public const String DOCUMENT_MARGIN_LEFT_TWIPS = DOCUMENT + "marginLeftTwips";
+ public const String DOCUMENT_MARGIN_TOP_TWIPS = DOCUMENT + "marginTopTwips";
+ public const String DOCUMENT_MARGIN_RIGHT_TWIPS = DOCUMENT + "marginRightTwips";
+ public const String DOCUMENT_MARGIN_BOTTOM_TWIPS = DOCUMENT + "marginBottomTwips";
+ public const String DOCUMENT_PAGE_NUMBER_START = DOCUMENT + "pageNumberStart";
+ public const String DOCUMENT_ENABLE_FACING_PAGES = DOCUMENT + "enableFacingPages";
+ public const String DOCUMENT_PAGE_ORIENTATION = DOCUMENT + "pageOrientation";
+ public const String DOCUMENT_DEFAULT_FONT_NUMER = DOCUMENT + "defaultFontNumber";
+
+ /** Properties for this RtfProperty object */
+ protected Hashtable properties = new Hashtable();
+
+ private bool modifiedCharacter = false;
+ private bool modifiedParagraph = false;
+ private bool modifiedSection = false;
+ private bool modifiedDocument = false;
+
+
+ /** The RtfPropertyListener
. */
+ private ArrayList listeners = new ArrayList();
+ /**
+ * Set all property objects to default values.
+ * @since 2.0.8
+ */
+ public void SetToDefault() {
+ SetToDefault(COLOR);
+ SetToDefault(CHARACTER);
+ SetToDefault(PARAGRAPH);
+ SetToDefault(SECTION);
+ SetToDefault(DOCUMENT);
+ }
+ /**
+ * Set individual property group to default values.
+ * @param propertyGroup String
name of the property group to set to default.
+ * @since 2.0.8
+ */
+ public void SetToDefault(String propertyGroup) {
+ if (COLOR.Equals(propertyGroup)) {
+ SetProperty(COLOR_FG, new Color(0,0,0));
+ SetProperty(COLOR_BG, new Color(255,255,255));
+ return;
+ }
+ if (CHARACTER.Equals(propertyGroup)) {
+ SetProperty(CHARACTER_BOLD, 0);
+ SetProperty(CHARACTER_UNDERLINE, 0);
+ SetProperty(CHARACTER_ITALIC, 0);
+ SetProperty(CHARACTER_SIZE, 24);// 1/2 pt sizes
+ SetProperty(CHARACTER_FONT, 0);
+ return;
+ }
+ if (PARAGRAPH.Equals(propertyGroup)) {
+ SetProperty(PARAGRAPH_INDENT_LEFT, 0);
+ SetProperty(PARAGRAPH_INDENT_RIGHT, 0);
+ SetProperty(PARAGRAPH_INDENT_FIRST_LINE, 0);
+ SetProperty(PARAGRAPH_JUSTIFICATION, JUSTIFY_LEFT);
+ SetProperty(PARAGRAPH_BORDER, PARAGRAPH_BORDER_NIL);
+ SetProperty(PARAGRAPH_BORDER_CELL, PARAGRAPH_BORDER_NIL);
+ return;
+ }
+ if (SECTION.Equals(propertyGroup)) {
+ SetProperty(SECTION_NUMBER_OF_COLUMNS, 0);
+ SetProperty(SECTION_BREAK_TYPE, SBK_NONE);
+ SetProperty(SECTION_PAGE_NUMBER_POSITION_X, 0);
+ SetProperty(SECTION_PAGE_NUMBER_POSITION_Y, 0);
+ SetProperty(SECTION_PAGE_NUMBER_FORMAT, PGN_DECIMAL);
+ return;
+ }
+ if (DOCUMENT.Equals(propertyGroup)) {
+ SetProperty(DOCUMENT_PAGE_WIDTH_TWIPS, 12240);
+ SetProperty(DOCUMENT_PAGE_HEIGHT_TWIPS, 15480);
+ SetProperty(DOCUMENT_MARGIN_LEFT_TWIPS, 1800);
+ SetProperty(DOCUMENT_MARGIN_TOP_TWIPS, 1440);
+ SetProperty(DOCUMENT_MARGIN_RIGHT_TWIPS, 1800);
+ SetProperty(DOCUMENT_MARGIN_BOTTOM_TWIPS, 1440);
+ SetProperty(DOCUMENT_PAGE_NUMBER_START, 1);
+ SetProperty(DOCUMENT_ENABLE_FACING_PAGES, 1);
+ SetProperty(DOCUMENT_PAGE_ORIENTATION, PAGE_PORTRAIT);
+ SetProperty(DOCUMENT_DEFAULT_FONT_NUMER, 0);
+ return;
+ }
+ }
+
+
+ /**
+ * Toggle the value of the property identified by the RtfCtrlWordData.specialHandler
parameter.
+ * Toggle values are assumed to be integer values per the RTF spec with a value of 0=off or 1=on.
+ *
+ * @param ctrlWordData The property name to set
+ * @return true
for handled or false
if propertyName
is null
or blank
+ */
+ public bool ToggleProperty(RtfCtrlWordData ctrlWordData) { //String propertyName) {
+
+ String propertyName = ctrlWordData.specialHandler;
+
+ if (propertyName == null || propertyName.Length == 0) return false;
+
+ Object propertyValue = GetProperty(propertyName);
+ if (propertyValue == null) {
+ propertyValue = RtfProperty.ON;
+ } else {
+ if (propertyValue is int) {
+ int value = (int)propertyValue;
+ if (value != 0) {
+ RemoveProperty(propertyName);
+ }
+ return true;
+ } else {
+ if (propertyValue is long) {
+ long value = (long)propertyValue;
+ if (value != 0) {
+ RemoveProperty(propertyName);
+ }
+ return true;
+ }
+ }
+ }
+ SetProperty(propertyName, propertyValue);
+ return true;
+ }
+ /**
+ * Set the value of the property identified by the parameter.
+ *
+ * @param ctrlWordData The controlword with the name to set
+ * @return true
for handled or false
if propertyName
or propertyValue
is null
+ */
+ public bool SetProperty(RtfCtrlWordData ctrlWordData) { //String propertyName, Object propertyValueNew) {
+ String propertyName = ctrlWordData.specialHandler;
+ Object propertyValueNew = ctrlWordData.param;
+ // depending on the control word, set mulitiple or reset settings, etc.
+ //if pard then reset settings
+ //
+ SetProperty(propertyName, propertyValueNew);
+ return true;
+ }
+ /**
+ * Set the value of the property identified by the parameter.
+ *
+ * @param propertyName The property name to set
+ * @param propertyValueNew The object to set the property value to
+ * @return true
for handled or false
if propertyName
or propertyValue
is null
+ */
+ private bool SetProperty(String propertyName, Object propertyValueNew) {
+ if (propertyName == null || propertyValueNew == null) return false;
+
+ Object propertyValueOld = GetProperty(propertyName);
+ if (propertyValueOld is int && propertyValueNew is int) {
+ int valueOld = (int)propertyValueOld;
+ int valueNew = (int)propertyValueNew;
+ if (valueOld==valueNew) return true;
+ } else {
+ if (propertyValueOld is long && propertyValueNew is long) {
+ long valueOld = (long)propertyValueOld;
+ long valueNew = (long)propertyValueNew;
+ if (valueOld==valueNew) return true;
+ }
+ }
+ BeforeChange(propertyName);
+ properties[propertyName] = propertyValueNew;
+ AfterChange(propertyName);
+ SetModified(propertyName, true);
+ return true;
+ }
+ /**
+ * Set the value of the property identified by the parameter.
+ *
+ * @param propertyName The property name to set
+ * @param propertyValue The object to set the property value to
+ * @return true
for handled or false
if propertyName
is null
+ */
+ private bool SetProperty(String propertyName, int propertyValueNew) {
+ if (propertyName == null) return false;
+ Object propertyValueOld = GetProperty(propertyName);
+ if (propertyValueOld is int) {
+ int valueOld = (int)propertyValueOld;
+ if (valueOld==propertyValueNew) return true;
+ }
+ BeforeChange(propertyName);
+ properties[propertyName] = propertyValueNew;
+ AfterChange(propertyName);
+ SetModified(propertyName, true);
+ return true;
+ }
+ /**
+ * Add the value of the property identified by the parameter.
+ *
+ * @param propertyName The property name to set
+ * @param propertyValue The object to set the property value to
+ * @return true
for handled or false
if propertyName
is null
+ */
+ private bool AddToProperty(String propertyName, int propertyValue) {
+ if (propertyName == null) return false;
+ int value = (int)properties[propertyName];
+ if ((value | propertyValue) == value) return true;
+ value |= propertyValue;
+ BeforeChange(propertyName);
+ properties[propertyName] = value;
+ AfterChange(propertyName);
+ SetModified(propertyName, true);
+ return true;
+ }
+ /**
+ * Set the value of the property identified by the parameter.
+ *
+ * @param propertyName The property name to set
+ * @param propertyValue The object to set the property value to
+ * @return true
for handled or false
if propertyName
is null
+ */
+ private bool SetProperty(String propertyName, long propertyValueNew) {
+ if (propertyName == null) return false;
+ Object propertyValueOld = GetProperty(propertyName);
+ if (propertyValueOld is long) {
+ long valueOld = (long)propertyValueOld;
+ if (valueOld==propertyValueNew) return true;
+ }
+ BeforeChange(propertyName);
+ properties[propertyName] = propertyValueNew;
+ AfterChange(propertyName);
+ SetModified(propertyName, true);
+ return true;
+ }
+ /**
+ * Add the value of the property identified by the parameter.
+ *
+ * @param propertyName The property name to set
+ * @param propertyValue The object to set the property value to
+ * @return true
for handled or false
if propertyName
is null
+ */
+ private bool AddToProperty(String propertyName, long propertyValue) {
+ if (propertyName == null) return false;
+ long value = (long)properties[propertyName];
+ if ((value | propertyValue) == value) return true;
+ value |= propertyValue;
+ BeforeChange(propertyName);
+ properties[propertyName] = value;
+ AfterChange(propertyName);
+ SetModified(propertyName, true);
+ return true;
+ }
+ private bool RemoveProperty(String propertyName) {
+ if (propertyName == null) return false;
+ if (properties.ContainsKey(propertyName)) {
+ BeforeChange(propertyName);
+ properties.Remove(propertyName);
+ AfterChange(propertyName);
+ SetModified(propertyName, true);
+ }
+ return true;
+ }
+ /**
+ * Get the value of the property identified by the parameter.
+ *
+ * @param propertyName String containing the property name to get
+ * @return Property Object requested or null if not found in map.
+ */
+ public Object GetProperty(String propertyName) {
+ return properties[propertyName];
+ }
+ /**
+ * Get a group of properties.
+ *
+ * @param propertyGroup The group name to obtain.
+ * @return Properties object with requested values.
+ */
+ public Hashtable GetProperties(String propertyGroup) {
+ Hashtable props = new Hashtable();
+ if (properties.Count != 0) {
+ //properties.get
+ foreach (String key in properties.Keys) {
+ if (key.StartsWith(propertyGroup)) {
+ props[key] = properties[key];
+ }
+ }
+ }
+ return props;
+ }
+
+ /**
+ * @return the modified
+ */
+ public bool IsModified() {
+ return modifiedCharacter || modifiedParagraph || modifiedSection || modifiedDocument;
+ }
+ /**
+ * @param propertyName the propertyName that is modified
+ * @param modified the modified to set
+ */
+ public void SetModified(String propertyName, bool modified) {
+ if (propertyName.StartsWith(CHARACTER)) {
+ this.SetModifiedCharacter(modified);
+ } else {
+ if (propertyName.StartsWith(PARAGRAPH)) {
+ this.SetModifiedParagraph(modified);
+ } else {
+ if (propertyName.StartsWith(SECTION)) {
+ this.SetModifiedSection(modified);
+ } else {
+ if (propertyName.StartsWith(DOCUMENT)) {
+ this.SetModifiedDocument(modified);
+ }
+ }
+ }
+ }
+ }
+ /**
+ * @return the modifiedCharacter
+ */
+ public bool IsModifiedCharacter() {
+ return modifiedCharacter;
+ }
+ /**
+ * @param modifiedCharacter the modifiedCharacter to set
+ */
+ public void SetModifiedCharacter(bool modifiedCharacter) {
+ this.modifiedCharacter = modifiedCharacter;
+ }
+ /**
+ * @return the modifiedParagraph
+ */
+ public bool IsModifiedParagraph() {
+ return modifiedParagraph;
+ }
+ /**
+ * @param modifiedParagraph the modifiedParagraph to set
+ */
+ public void SetModifiedParagraph(bool modifiedParagraph) {
+ this.modifiedParagraph = modifiedParagraph;
+ }
+ /**
+ * @return the modifiedSection
+ */
+ public bool IsModifiedSection() {
+ return modifiedSection;
+ }
+ /**
+ * @param modifiedSection the modifiedSection to set
+ */
+ public void SetModifiedSection(bool modifiedSection) {
+ this.modifiedSection = modifiedSection;
+ }
+ /**
+ * @return the modifiedDocument
+ */
+ public bool IsModifiedDocument() {
+ return modifiedDocument;
+ }
+ /**
+ * @param modifiedDocument the modifiedDocument to set
+ */
+ public void SetModifiedDocument(bool modifiedDocument) {
+ this.modifiedDocument = modifiedDocument;
+ }
+
+ /**
+ * Adds a RtfPropertyListener
to the RtfProperty
.
+ *
+ * @param listener
+ * the new RtfPropertyListener.
+ */
+ public void AddRtfPropertyListener(IRtfPropertyListener listener) {
+ listeners.Add(listener);
+ }
+ /**
+ * Removes a RtfPropertyListener
from the RtfProperty
.
+ *
+ * @param listener
+ * the new RtfPropertyListener.
+ */
+ public void RemoveRtfPropertyListener(IRtfPropertyListener listener) {
+ listeners.Remove(listener);
+ }
+
+ public void BeforeChange(String propertyName) {
+ // call listener for all
+ foreach (IRtfPropertyListener listener in listeners) {
+ listener.BeforePropertyChange(propertyName);
+ }
+
+ if (propertyName.StartsWith(CHARACTER)) {
+ // call listener for character chane
+ } else {
+ if (propertyName.StartsWith(PARAGRAPH)) {
+ // call listener for paragraph change
+ } else {
+ if (propertyName.StartsWith(SECTION)) {
+ // call listener for section change
+ } else {
+ if (propertyName.StartsWith(DOCUMENT)) {
+ // call listener for document change
+ }
+ }
+ }
+ }
+ }
+
+ public void AfterChange(String propertyName) {
+ // call listener for all
+ foreach (IRtfPropertyListener listener in listeners) {
+ listener.AfterPropertyChange(propertyName);
+ }
+
+ if (propertyName.StartsWith(CHARACTER)) {
+ // call listener for character chane
+ } else {
+ if (propertyName.StartsWith(PARAGRAPH)) {
+ // call listener for paragraph change
+ } else {
+ if (propertyName.StartsWith(SECTION)) {
+ // call listener for section change
+ } else {
+ if (propertyName.StartsWith(DOCUMENT)) {
+ // call listener for document change
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/style/RtfColor.cs b/iTechSharp/iTextSharp/text/rtf/style/RtfColor.cs
new file mode 100644
index 0000000..c942e99
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/style/RtfColor.cs
@@ -0,0 +1,285 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfColor.cs,v 1.6 2008/05/16 19:31:10 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.style {
+
+ /**
+ * The RtfColor stores one rtf color value for a rtf document
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfColor : RtfElement, IRtfExtendedElement {
+
+ /**
+ * Constant for RED value
+ */
+ private static byte[] COLOR_RED = DocWriter.GetISOBytes("\\red");
+ /**
+ * Constant for GREEN value
+ */
+ private static byte[] COLOR_GREEN = DocWriter.GetISOBytes("\\green");
+ /**
+ * Constant for BLUE value
+ */
+ private static byte[] COLOR_BLUE = DocWriter.GetISOBytes("\\blue");
+ /**
+ * Constant for the end of one color entry
+ */
+ private const byte COLON = (byte) ';';
+ /**
+ * Constant for the number of the colour in the list of colours
+ */
+ private static byte[] COLOR_NUMBER = DocWriter.GetISOBytes("\\cf");
+
+ /**
+ * The number of the colour in the list of colours
+ */
+ private int colorNumber = 0;
+ /**
+ * The red value
+ */
+ private int red = 0;
+ /**
+ * The green value
+ */
+ private int green = 0;
+ /**
+ * The blue value
+ */
+ private int blue = 0;
+
+ /**
+ * Constructor only for use when initializing the RtfColorList
+ *
+ * @param doc The RtfDocument this RtfColor belongs to
+ * @param red The red value to use
+ * @param green The green value to use
+ * @param blue The blue value to use
+ * @param colorNumber The number of the colour in the colour list
+ */
+ protected internal RtfColor(RtfDocument doc, int red, int green, int blue, int colorNumber) : base(doc) {
+ this.red = red;
+ this.blue = blue;
+ this.green = green;
+ this.colorNumber = colorNumber;
+ }
+
+ /**
+ * Constructs a RtfColor as a clone of an existing RtfColor
+ *
+ * @param doc The RtfDocument this RtfColor belongs to
+ * @param col The RtfColor to use as a base
+ */
+ public RtfColor(RtfDocument doc, RtfColor col) : base(doc) {
+ if (col != null) {
+ this.red = col.GetRed();
+ this.green = col.GetGreen();
+ this.blue = col.GetBlue();
+ }
+ if (this.document != null) {
+ this.colorNumber = this.document.GetDocumentHeader().GetColorNumber(this);
+ }
+ }
+
+ /**
+ * Constructs a RtfColor based on the Color
+ *
+ * @param doc The RtfDocument this RtfColor belongs to
+ * @param col The Color to base this RtfColor on
+ */
+ public RtfColor(RtfDocument doc, Color col) : base(doc) {
+ if (col != null) {
+ this.red = col.R;
+ this.blue = col.B;
+ this.green = col.G;
+ }
+ if (this.document != null) {
+ this.colorNumber = this.document.GetDocumentHeader().GetColorNumber(this);
+ }
+ }
+
+ /**
+ * Constructs a RtfColor based on the red/green/blue values
+ *
+ * @param doc The RtfDocument this RtfColor belongs to
+ * @param red The red value to use
+ * @param green The green value to use
+ * @param blue The blue value to use
+ */
+ public RtfColor(RtfDocument doc, int red, int green, int blue) : base(doc) {
+ this.red = red;
+ this.blue = blue;
+ this.green = green;
+ if (this.document != null) {
+ this.colorNumber = this.document.GetDocumentHeader().GetColorNumber(this);
+ }
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Write the definition part of this RtfColor.
+ */
+ public virtual void WriteDefinition(Stream result) {
+ byte[] t;
+ result.Write(COLOR_RED, 0, COLOR_RED.Length);
+ result.Write(t = IntToByteArray(red), 0, t.Length);
+ result.Write(COLOR_GREEN, 0, COLOR_GREEN.Length);
+ result.Write(t = IntToByteArray(green), 0, t.Length);
+ result.Write(COLOR_BLUE, 0, COLOR_BLUE.Length);
+ result.Write(t = IntToByteArray(blue), 0, t.Length);
+ result.WriteByte(COLON);
+ }
+
+ /**
+ * Writes the beginning of this RtfColor
+ *
+ */
+ public void WriteBegin(Stream result) {
+ byte[] t;
+ try {
+ result.Write(COLOR_NUMBER, 0, COLOR_NUMBER.Length);
+ result.Write(t = IntToByteArray(colorNumber), 0, t.Length);
+ } catch (IOException) {
+ }
+ }
+
+ /**
+ * Unused
+ *
+ */
+ public void WriteEnd(Stream result) {
+ }
+
+ /**
+ * Tests if this RtfColor is equal to another RtfColor.
+ *
+ * @param obj another RtfColor
+ * @return True
if red, green and blue values of the two colours match,
+ * false
otherwise.
+ */
+ public override bool Equals(Object obj) {
+ if (!(obj is RtfColor)) {
+ return false;
+ }
+ RtfColor color = (RtfColor) obj;
+ return (this.red == color.GetRed() && this.green == color.GetGreen() && this.blue == color.GetBlue());
+ }
+
+ /**
+ * Returns the hash code of this RtfColor. The hash code is
+ * an integer with the lowest three bytes containing the values
+ * of red, green and blue.
+ *
+ * @return The hash code of this RtfColor
+ */
+ public override int GetHashCode() {
+ return (this.red << 16) | (this.green << 8) | this.blue;
+ }
+
+ /**
+ * Get the blue value of this RtfColor
+ *
+ * @return The blue value
+ */
+ public int GetBlue() {
+ return blue;
+ }
+
+ /**
+ * Get the green value of this RtfColor
+ *
+ * @return The green value
+ */
+ public int GetGreen() {
+ return green;
+ }
+
+ /**
+ * Get the red value of this RtfColor
+ *
+ * @return The red value
+ */
+ public int GetRed() {
+ return red;
+ }
+
+ /**
+ * Gets the number of this RtfColor in the list of colours
+ *
+ * @return Returns the colorNumber.
+ */
+ public int GetColorNumber() {
+ return colorNumber;
+ }
+
+ /**
+ * Sets the RtfDocument this RtfColor belongs to
+ *
+ * @param doc The RtfDocument to use
+ */
+ public override void SetRtfDocument(RtfDocument doc) {
+ base.SetRtfDocument(doc);
+ if (document != null) {
+ this.colorNumber = document.GetDocumentHeader().GetColorNumber(this);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/style/RtfColorList.cs b/iTechSharp/iTextSharp/text/rtf/style/RtfColorList.cs
new file mode 100644
index 0000000..5852cad
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/style/RtfColorList.cs
@@ -0,0 +1,131 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfColorList.cs,v 1.5 2008/05/16 19:31:11 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.style {
+
+ /**
+ * The RtfColorList stores all colours that appear in the document. Black
+ * and White are always added
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfColorList : RtfElement, IRtfExtendedElement {
+
+ /**
+ * Constant for the beginning of the colour table
+ */
+ private static byte[] COLOR_TABLE = DocWriter.GetISOBytes("\\colortbl");
+
+ /**
+ * ArrayList containing all colours of this RtfColorList
+ */
+ ArrayList colorList = new ArrayList();
+
+ /**
+ * Constructs a new RtfColorList for the RtfDocument. Will add the default
+ * black and white colours.
+ *
+ * @param doc The RtfDocument this RtfColorList belongs to
+ */
+ public RtfColorList(RtfDocument doc) : base(doc) {
+ colorList.Add(new RtfColor(doc, 0, 0, 0, 0));
+ colorList.Add(new RtfColor(doc, 255, 255, 255, 1));
+ }
+
+ /**
+ * Returns the index of the given RtfColor in the colour list. If the RtfColor
+ * is not in the list of colours, then it is added.
+ *
+ * @param color The RtfColor for which to get the index
+ * @return The index of the RtfColor
+ */
+ public int GetColorNumber(RtfColor color) {
+ int colorIndex = -1;
+ for (int i = 0; i < colorList.Count; i++) {
+ if (colorList[i].Equals(color)) {
+ colorIndex = i;
+ }
+ }
+ if (colorIndex == -1) {
+ colorIndex = colorList.Count;
+ colorList.Add(color);
+ }
+ return colorIndex;
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Write the definition part of the colour list. Calls the writeDefinition
+ * methods of the RtfColors in the colour list.
+ */
+ public virtual void WriteDefinition(Stream result) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(COLOR_TABLE, 0, COLOR_TABLE.Length);
+ for (int i = 0; i < colorList.Count; i++) {
+ RtfColor color = (RtfColor) colorList[i];
+ color.WriteDefinition(result);
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/style/RtfFont.cs b/iTechSharp/iTextSharp/text/rtf/style/RtfFont.cs
new file mode 100644
index 0000000..55e3e5e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/style/RtfFont.cs
@@ -0,0 +1,730 @@
+using System;
+using System.IO;
+using System.util;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfFont.cs,v 1.13 2008/05/16 19:31:11 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.style {
+
+ /**
+ * The RtfFont class stores one font for an rtf document. It extends Font,
+ * so can be set as a font, to allow adding of fonts with arbitrary names.
+ * BaseFont fontname handling contributed by Craig Fleming. Various fixes
+ * Renaud Michel, Werner Daehn.
+ *
+ * Version: $Id: RtfFont.cs,v 1.13 2008/05/16 19:31:11 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Craig Fleming (rythos@rhana.dhs.org)
+ * @author Renaud Michel (r.michel@immedia.be)
+ * @author Werner Daehn (Werner.Daehn@BusinessObjects.com)
+ * @author Lidong Liu (tmslld@gmail.com)
+ */
+ public class RtfFont : Font, IRtfExtendedElement {
+ /**
+ * Constant for the font family to use ("froman")
+ */
+ private static byte[] FONT_FAMILY = DocWriter.GetISOBytes("\\froman");
+ /**
+ * Constant for the charset
+ */
+ private static byte[] FONT_CHARSET = DocWriter.GetISOBytes("\\fcharset");
+ /**
+ * Constant for the font size
+ */
+ public static byte[] FONT_SIZE = DocWriter.GetISOBytes("\\fs");
+ /**
+ * Constant for the bold flag
+ */
+ private static byte[] FONT_BOLD = DocWriter.GetISOBytes("\\b");
+ /**
+ * Constant for the italic flag
+ */
+ private static byte[] FONT_ITALIC = DocWriter.GetISOBytes("\\i");
+ /**
+ * Constant for the underline flag
+ */
+ private static byte[] FONT_UNDERLINE = DocWriter.GetISOBytes("\\ul");
+ /**
+ * Constant for the strikethrough flag
+ */
+ private static byte[] FONT_STRIKETHROUGH = DocWriter.GetISOBytes("\\strike");
+ /**
+ * Constant for the double strikethrough flag
+ */
+ private static byte[] FONT_DOUBLE_STRIKETHROUGH = DocWriter.GetISOBytes("\\striked");
+ /**
+ * Constant for the shadow flag
+ */
+ private static byte[] FONT_SHADOW = DocWriter.GetISOBytes("\\shad");
+ /**
+ * Constant for the outline flag
+ */
+ private static byte[] FONT_OUTLINE = DocWriter.GetISOBytes("\\outl");
+ /**
+ * Constant for the embossed flag
+ */
+ private static byte[] FONT_EMBOSSED = DocWriter.GetISOBytes("\\embo");
+ /**
+ * Constant for the engraved flag
+ */
+ private static byte[] FONT_ENGRAVED = DocWriter.GetISOBytes("\\impr");
+ /**
+ * Constant for hidden text flag
+ */
+ private static byte[] FONT_HIDDEN = DocWriter.GetISOBytes("\\v");
+
+ /**
+ * Constant for a plain font
+ */
+ public const int STYLE_NONE = 0;
+ /**
+ * Constant for a bold font
+ */
+ public const int STYLE_BOLD = 1;
+ /**
+ * Constant for an italic font
+ */
+ public const int STYLE_ITALIC = 2;
+ /**
+ * Constant for an underlined font
+ */
+ public const int STYLE_UNDERLINE = 4;
+ /**
+ * Constant for a strikethrough font
+ */
+ public const int STYLE_STRIKETHROUGH = 8;
+ /**
+ * Constant for a double strikethrough font
+ */
+ public const int STYLE_DOUBLE_STRIKETHROUGH = 16;
+ /**
+ * Constant for a shadowed font
+ */
+ public const int STYLE_SHADOW = 32;
+ /**
+ * Constant for an outlined font
+ */
+ public const int STYLE_OUTLINE = 64;
+ /**
+ * Constant for an embossed font
+ */
+ public const int STYLE_EMBOSSED = 128;
+ /**
+ * Constant for an engraved font
+ */
+ public const int STYLE_ENGRAVED = 256;
+ /**
+ * Constant for a font that hides the actual text.
+ */
+ public const int STYLE_HIDDEN = 512;
+
+ /**
+ * The font name. Defaults to "Times New Roman"
+ */
+ private String fontName = "Times New Roman";
+ /**
+ * The font size. Defaults to 10
+ */
+ private int fontSize = 10;
+ /**
+ * The font style. Defaults to STYLE_NONE
+ */
+ private int fontStyle = STYLE_NONE;
+ /**
+ * The number of this font
+ */
+ private int fontNumber = 0;
+ /**
+ * The colour of this font
+ */
+ private RtfColor color = null;
+ /**
+ * The character set to use for this font
+ */
+ private int charset = 0;
+ /**
+ * The RtfDocument this RtfFont belongs to.
+ */
+ protected RtfDocument document = null;
+
+ /**
+ * Constructs a RtfFont with the given font name and all other properties
+ * at their default values.
+ *
+ * @param fontName The font name to use
+ */
+ public RtfFont(String fontName) : base(Font.UNDEFINED, Font.UNDEFINED, Font.UNDEFINED, null) {
+ this.fontName = fontName;
+ }
+
+ /**
+ * Constructs a RtfFont with the given font name and font size and all other
+ * properties at their default values.
+ *
+ * @param fontName The font name to use
+ * @param size The font size to use
+ */
+ public RtfFont(String fontName, float size) : base(Font.UNDEFINED, size, Font.UNDEFINED, null) {
+ this.fontName = fontName;
+ }
+
+ /**
+ * Constructs a RtfFont with the given font name, font size and font style and the
+ * default color.
+ *
+ * @param fontName The font name to use
+ * @param size The font size to use
+ * @param style The font style to use
+ */
+ public RtfFont(String fontName, float size, int style) : base(Font.UNDEFINED, size, style, null) {
+ this.fontName = fontName;
+ }
+
+ /**
+ * Constructs a RtfFont with the given font name, font size, font style and
+ * color.
+ *
+ * @param fontName The font name to use
+ * @param size the font size to use
+ * @param style The font style to use
+ * @param color The font color to use
+ */
+ public RtfFont(String fontName, float size, int style, Color color) : base(Font.UNDEFINED, size, style, color) {
+ this.fontName = fontName;
+ }
+
+ /**
+ * Constructs a RtfFont with the given font name, font size, font style, colour
+ * and charset. This can be used when generating non latin-1 text.
+ *
+ * @param fontName The font name to use
+ * @param size the font size to use
+ * @param style The font style to use
+ * @param color The font color to use
+ * @param charset The charset of the font content
+ */
+ public RtfFont(String fontName, float size, int style, Color color, int charset) : this(fontName, size, style, color){
+ this.charset = charset;
+ }
+
+ /**
+ * Special constructor for the default font
+ *
+ * @param doc The RtfDocument this font appears in
+ * @param fontNumber The id of this font
+ */
+ protected internal RtfFont(RtfDocument doc, int fontNumber) {
+ this.document = doc;
+ this.fontNumber = fontNumber;
+ color = new RtfColor(doc, 0, 0, 0);
+ }
+
+ /**
+ * Constructs a RtfFont from a com.lowagie.text.Font
+ * @param doc The RtfDocument this font appears in
+ * @param font The Font to use as a base
+ */
+ public RtfFont(RtfDocument doc, Font font) {
+ this.document = doc;
+ if (font != null) {
+ if (font is RtfFont) {
+ this.fontName = ((RtfFont) font).GetFontName();
+ this.charset = ((RtfFont) font).GetCharset();
+ } else {
+ SetToDefaultFamily(font.Familyname);
+ }
+ if (font.BaseFont != null) {
+ String[][] fontNames = font.BaseFont.FullFontName;
+ for (int i = 0; i < fontNames.Length; i++) {
+ if (fontNames[i][2].Equals("0")) {
+ this.fontName = fontNames[i][3];
+ break;
+ } else if (fontNames[i][2].Equals("1033") || fontNames[i][2].Equals("")) {
+ this.fontName = fontNames[i][3];
+ }
+ }
+ }
+ Size = font.Size;
+ SetStyle(font.Style);
+ Color = font.Color;
+ }
+ if (Util.EqualsIgnoreCase(this.fontName, "unknown")) {
+ return;
+ }
+
+ if (document != null) {
+ SetRtfDocument(document);
+ }
+ }
+
+ /**
+ * Writes the font definition
+ */
+ public virtual void WriteDefinition(Stream result) {
+ byte[] t;
+ result.Write(FONT_FAMILY, 0, FONT_FAMILY.Length);
+ result.Write(FONT_CHARSET, 0, FONT_CHARSET.Length);
+ result.Write(t = IntToByteArray(charset), 0, t.Length);
+ result.Write(RtfElement.DELIMITER, 0, RtfElement.DELIMITER.Length);
+ document.FilterSpecialChar(result, fontName, true, false);
+ }
+
+ /**
+ * Writes the font beginning
+ *
+ * @return A byte array with the font start data
+ */
+ public virtual void WriteBegin(Stream result) {
+ byte[] t;
+ if(this.fontNumber != Font.UNDEFINED) {
+ result.Write(RtfFontList.FONT_NUMBER, 0, RtfFontList.FONT_NUMBER.Length);
+ result.Write(t = IntToByteArray(fontNumber), 0, t.Length);
+ }
+ if(this.fontSize != Font.UNDEFINED) {
+ result.Write(FONT_SIZE, 0, FONT_SIZE.Length);
+ result.Write(t = IntToByteArray(fontSize * 2), 0, t.Length);
+ }
+ if (this.fontStyle != UNDEFINED) {
+ if ((fontStyle & STYLE_BOLD) == STYLE_BOLD) {
+ result.Write(FONT_BOLD, 0, FONT_BOLD.Length);
+ }
+ if ((fontStyle & STYLE_ITALIC) == STYLE_ITALIC) {
+ result.Write(FONT_ITALIC, 0, FONT_ITALIC.Length);
+ }
+ if ((fontStyle & STYLE_UNDERLINE) == STYLE_UNDERLINE) {
+ result.Write(FONT_UNDERLINE, 0, FONT_UNDERLINE.Length);
+ }
+ if ((fontStyle & STYLE_STRIKETHROUGH) == STYLE_STRIKETHROUGH) {
+ result.Write(FONT_STRIKETHROUGH, 0, FONT_STRIKETHROUGH.Length);
+ }
+ if ((fontStyle & STYLE_HIDDEN) == STYLE_HIDDEN) {
+ result.Write(FONT_HIDDEN, 0, FONT_HIDDEN.Length);
+ }
+ if ((fontStyle & STYLE_DOUBLE_STRIKETHROUGH) == STYLE_DOUBLE_STRIKETHROUGH) {
+ result.Write(FONT_DOUBLE_STRIKETHROUGH, 0, FONT_DOUBLE_STRIKETHROUGH.Length);
+ result.Write(t = IntToByteArray(1), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_SHADOW) == STYLE_SHADOW) {
+ result.Write(FONT_SHADOW, 0, FONT_SHADOW.Length);
+ }
+ if ((fontStyle & STYLE_OUTLINE) == STYLE_OUTLINE) {
+ result.Write(FONT_OUTLINE, 0, FONT_OUTLINE.Length);
+ }
+ if ((fontStyle & STYLE_EMBOSSED) == STYLE_EMBOSSED) {
+ result.Write(FONT_EMBOSSED, 0, FONT_EMBOSSED.Length);
+ }
+ if ((fontStyle & STYLE_ENGRAVED) == STYLE_ENGRAVED) {
+ result.Write(FONT_ENGRAVED, 0, FONT_ENGRAVED.Length);
+ }
+ }
+ if(color != null) {
+ color.WriteBegin(result);
+ }
+ }
+
+ /**
+ * Write the font end
+ *
+ */
+ public virtual void WriteEnd(Stream result) {
+ byte[] t;
+ if (this.fontStyle != UNDEFINED) {
+ if ((fontStyle & STYLE_BOLD) == STYLE_BOLD) {
+ result.Write(FONT_BOLD, 0, FONT_BOLD.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_ITALIC) == STYLE_ITALIC) {
+ result.Write(FONT_ITALIC, 0, FONT_ITALIC.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_UNDERLINE) == STYLE_UNDERLINE) {
+ result.Write(FONT_UNDERLINE, 0, FONT_UNDERLINE.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_STRIKETHROUGH) == STYLE_STRIKETHROUGH) {
+ result.Write(FONT_STRIKETHROUGH, 0, FONT_STRIKETHROUGH.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_HIDDEN) == STYLE_HIDDEN) {
+ result.Write(FONT_HIDDEN, 0, FONT_HIDDEN.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_DOUBLE_STRIKETHROUGH) == STYLE_DOUBLE_STRIKETHROUGH) {
+ result.Write(FONT_DOUBLE_STRIKETHROUGH, 0, FONT_DOUBLE_STRIKETHROUGH.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_SHADOW) == STYLE_SHADOW) {
+ result.Write(FONT_SHADOW, 0, FONT_SHADOW.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_OUTLINE) == STYLE_OUTLINE) {
+ result.Write(FONT_OUTLINE, 0, FONT_OUTLINE.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_EMBOSSED) == STYLE_EMBOSSED) {
+ result.Write(FONT_EMBOSSED, 0, FONT_EMBOSSED.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ if ((fontStyle & STYLE_ENGRAVED) == STYLE_ENGRAVED) {
+ result.Write(FONT_ENGRAVED, 0, FONT_ENGRAVED.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ }
+ }
+ }
+
+ /**
+ * unused
+ */
+ public virtual void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Tests for equality of RtfFonts. RtfFonts are equal if their fontName,
+ * fontSize, fontStyle and fontSuperSubscript are equal
+ *
+ * @param obj The RtfFont to compare with this RtfFont
+ * @return True
if the RtfFonts are equal, false
otherwise
+ */
+ public override bool Equals(Object obj) {
+ if (!(obj is RtfFont)) {
+ return false;
+ }
+ RtfFont font = (RtfFont) obj;
+ bool result = true;
+ result = result & this.fontName.Equals(font.GetFontName());
+ return result;
+ }
+
+ /**
+ * Returns the hash code of this RtfFont. The hash code is the hash code of the
+ * string containing the font name + font size + "-" + the font style + "-" + the
+ * font super/supscript value.
+ *
+ * @return The hash code of this RtfFont
+ */
+ public override int GetHashCode() {
+ return (this.fontName + this.fontSize + "-" + this.fontStyle).GetHashCode();
+ }
+
+ /**
+ * Gets the font name of this RtfFont
+ *
+ * @return The font name
+ */
+ public String GetFontName() {
+ return this.fontName;
+ }
+
+ /**
+ * Sets the font name of this RtfFont.
+ *
+ * @param fontName The font name to use
+ */
+ public virtual void SetFontName(String fontName) {
+ this.fontName = fontName;
+ if(document != null) {
+ this.fontNumber = document.GetDocumentHeader().GetFontNumber(this);
+ }
+ }
+ /**
+ * @see com.lowagie.text.Font#getFamilyname()
+ */
+ public override String Familyname {
+ get {
+ return this.fontName;
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.Font#setFamily(String)
+ */
+ public override void SetFamily(String family){
+ base.SetFamily(family);
+ SetToDefaultFamily(family);
+ }
+
+ /**
+ * Sets the correct font name from the family name.
+ *
+ * @param familyname The family name to set the name to.
+ */
+ private void SetToDefaultFamily(String familyname){
+ switch (Font.GetFamilyIndex(familyname)) {
+ case Font.COURIER:
+ this.fontName = "Courier";
+ break;
+ case Font.HELVETICA:
+ this.fontName = "Arial";
+ break;
+ case Font.SYMBOL:
+ this.fontName = "Symbol";
+ this.charset = 2;
+ break;
+ case Font.TIMES_ROMAN:
+ this.fontName = "Times New Roman";
+ break;
+ case Font.ZAPFDINGBATS:
+ this.fontName = "Windings";
+ break;
+ default:
+ this.fontName = familyname;
+ break;
+ }
+ }
+
+ /**
+ * Gets the font size of this RtfFont
+ *
+ * @return The font size
+ */
+ public int GetFontSize() {
+ return this.fontSize;
+ }
+
+ /**
+ * @see com.lowagie.text.Font#setSize(float)
+ */
+ public override float Size {
+ set {
+ base.Size = value;
+ this.fontSize = (int)Size;
+ }
+ }
+
+ /**
+ * Gets the font style of this RtfFont
+ *
+ * @return The font style
+ */
+ public int GetFontStyle() {
+ return this.fontStyle;
+ }
+
+ /**
+ * @see com.lowagie.text.Font#setStyle(int)
+ */
+ public override void SetStyle(int style){
+ base.SetStyle(style);
+ this.fontStyle = Style;
+ }
+
+ /**
+ * @see com.lowagie.text.Font#setStyle(String)
+ */
+ public override void SetStyle(String style) {
+ base.SetStyle(style);
+ fontStyle = Style;
+ }
+
+ /**
+ * Gets the charset used for constructing this RtfFont.
+ *
+ * @return The charset of this RtfFont.
+ */
+ public int GetCharset() {
+ return charset;
+ }
+
+ /**
+ * Sets the charset used for constructing this RtfFont.
+ *
+ * @param charset The charset to use.
+ */
+ public void SetCharset(int charset) {
+ this.charset = charset;
+ }
+
+ /**
+ * Gets the font number of this RtfFont
+ *
+ * @return The font number
+ */
+ public int GetFontNumber() {
+ return fontNumber;
+ }
+
+ /**
+ * Sets the RtfDocument this RtfFont belongs to
+ *
+ * @param doc The RtfDocument to use
+ */
+ public void SetRtfDocument(RtfDocument doc) {
+ this.document = doc;
+ if (document != null) {
+ this.fontNumber = document.GetDocumentHeader().GetFontNumber(this);
+ }
+ if (this.color != null) {
+ this.color.SetRtfDocument(this.document);
+ }
+ }
+
+ /**
+ * Unused
+ * @param inTable
+ */
+ public void SetInTable(bool inTable) {
+ }
+
+ /**
+ * Unused
+ * @param inHeader
+ */
+ public void SetInHeader(bool inHeader) {
+ }
+
+ /**
+ * @see com.lowagie.text.Font#setColor(Color)
+ */
+ public override Color Color {
+ set {
+ base.Color = value;
+ if(value != null) {
+ this.color = new RtfColor(document, value);
+ } else {
+ this.color = null;
+ }
+ }
+ }
+
+ /**
+ * @see com.lowagie.text.Font#setColor(int, int, int)
+ */
+ public override void SetColor(int red, int green, int blue) {
+ base.SetColor(red,green,blue);
+ this.color = new RtfColor(document, red, green, blue);
+ }
+
+ /**
+ * Transforms an integer into its String representation and then returns the bytes
+ * of that string.
+ *
+ * @param i The integer to convert
+ * @return A byte array representing the integer
+ */
+ protected byte[] IntToByteArray(int i) {
+ return DocWriter.GetISOBytes(i.ToString());
+ }
+
+ /**
+ * Replaces the attributes that are equal to null with
+ * the attributes of a given font.
+ *
+ * @param font The surrounding font
+ * @return A RtfFont
+ */
+ public override Font Difference(Font font) {
+ String dFamilyname = font.Familyname;
+ if (dFamilyname == null || dFamilyname.Trim().Equals("") || Util.EqualsIgnoreCase(dFamilyname.Trim(), "unknown")) {
+ dFamilyname = this.fontName;
+ }
+
+ float dSize = font.Size;
+ if (dSize == Font.UNDEFINED) {
+ dSize = this.Size;
+ }
+
+ int dStyle = Font.UNDEFINED;
+ if (this.Style != Font.UNDEFINED && font.Style != Font.UNDEFINED) {
+ dStyle = this.Style | font.Style;
+ } else if (this.Style != Font.UNDEFINED) {
+ dStyle = this.Style;
+ } else if (font.Style != Font.UNDEFINED) {
+ dStyle = font.Style;
+ }
+
+ Color dColor = font.Color;
+ if (dColor == null) {
+ dColor = this.Color;
+ }
+
+ int dCharset = this.charset;
+ if(font is RtfFont) {
+ dCharset = ((RtfFont)font).GetCharset();
+ }
+
+ return new RtfFont(dFamilyname, dSize, dStyle, dColor, dCharset);
+ }
+
+ /**
+ * The RtfFont
is never a standard font.
+ *
+ * @since 2.1.0
+ */
+ public override bool IsStandardFont() {
+ return false;
+ }
+
+ /**
+ * Compares this RtfFont
to either a {@link com.lowagie.text.Font} or
+ * an RtfFont
.
+ *
+ * @since 2.1.0
+ */
+ public override int CompareTo(Object obj) {
+ if (obj == null) {
+ return -1;
+ }
+ if(obj is RtfFont) {
+ if(this.GetFontName().CompareTo(((RtfFont) obj).GetFontName()) != 0) {
+ return 1;
+ } else {
+ return base.CompareTo(obj);
+ }
+ } else if (obj is Font) {
+ return base.CompareTo(obj);
+ } else {
+ return -3;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/style/RtfFontList.cs b/iTechSharp/iTextSharp/text/rtf/style/RtfFontList.cs
new file mode 100644
index 0000000..6dd8901
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/style/RtfFontList.cs
@@ -0,0 +1,147 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfFontList.cs,v 1.6 2008/05/16 19:31:12 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.style {
+
+ /**
+ * The RtfFontList stores the list of fonts used in the rtf document. It also
+ * has methods for writing this list to the document
+ *
+ * Version: $Id: RtfFontList.cs,v 1.6 2008/05/16 19:31:12 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfFontList : RtfElement, IRtfExtendedElement {
+
+ /**
+ * Constant for the default font
+ */
+ private static byte[] DEFAULT_FONT = DocWriter.GetISOBytes("\\deff");
+ /**
+ * Constant for the font table
+ */
+ private static byte[] FONT_TABLE = DocWriter.GetISOBytes("\\fonttbl");
+ /**
+ * Constant for the font number
+ */
+ public static byte[] FONT_NUMBER = DocWriter.GetISOBytes("\\f");
+
+ /**
+ * The list of fonts
+ */
+ private ArrayList fontList = new ArrayList();
+
+ /**
+ * Creates a RtfFontList
+ *
+ * @param doc The RtfDocument this RtfFontList belongs to
+ */
+ public RtfFontList(RtfDocument doc) : base(doc) {
+ fontList.Add(new RtfFont(document, 0));
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Gets the index of the font in the list of fonts. If the font does not
+ * exist in the list, it is added.
+ *
+ * @param font The font to get the id for
+ * @return The index of the font
+ */
+ public int GetFontNumber(RtfFont font) {
+ if(font is RtfParagraphStyle) {
+ font = new RtfFont(this.document, (RtfParagraphStyle) font);
+ }
+ int fontIndex = -1;
+ for (int i = 0; i < fontList.Count; i++) {
+ if (fontList[i].Equals(font)) {
+ fontIndex = i;
+ }
+ }
+ if (fontIndex == -1) {
+ fontIndex = fontList.Count;
+ fontList.Add(font);
+ }
+ return fontIndex;
+ }
+
+ /**
+ * Writes the definition of the font list
+ */
+ public virtual void WriteDefinition(Stream result) {
+ byte[] t;
+ result.Write(DEFAULT_FONT, 0, DEFAULT_FONT.Length);
+ result.Write(t = IntToByteArray(0), 0, t.Length);
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(FONT_TABLE, 0, FONT_TABLE.Length);
+ for (int i = 0; i < fontList.Count; i++) {
+ result.Write(OPEN_GROUP, 0, OPEN_GROUP.Length);
+ result.Write(FONT_NUMBER, 0, FONT_NUMBER.Length);
+ result.Write(t = IntToByteArray(i), 0, t.Length);
+ RtfFont rf = (RtfFont) fontList[i];
+ rf.WriteDefinition(result);
+ result.Write(COMMA_DELIMITER, 0, COMMA_DELIMITER.Length);
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ }
+ result.Write(CLOSE_GROUP, 0, CLOSE_GROUP.Length);
+ result.WriteByte((byte)'\n');
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/style/RtfParagraphStyle.cs b/iTechSharp/iTextSharp/text/rtf/style/RtfParagraphStyle.cs
new file mode 100644
index 0000000..0bd9966
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/style/RtfParagraphStyle.cs
@@ -0,0 +1,675 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.text;
+
+namespace iTextSharp.text.rtf.style {
+
+ /**
+ * The RtfParagraphStyle stores all style/formatting attributes of a RtfParagraph.
+ * Additionally it also supports the style name system available in RTF. The RtfParagraphStyle
+ * is a Font and can thus be used as such. To use the stylesheet functionality
+ * it needs to be set as the font of a Paragraph. Otherwise it will work like a
+ * RtfFont. It also supports inheritance of styles.
+ *
+ * @version $Revision: 1.8 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfParagraphStyle : RtfFont {
+
+ /**
+ * Constant for left alignment
+ */
+ public static byte[] ALIGN_LEFT = DocWriter.GetISOBytes("\\ql");
+ /**
+ * Constant for right alignment
+ */
+ public static byte[] ALIGN_RIGHT = DocWriter.GetISOBytes("\\qr");
+ /**
+ * Constant for center alignment
+ */
+ public static byte[] ALIGN_CENTER = DocWriter.GetISOBytes("\\qc");
+ /**
+ * Constant for justified alignment
+ */
+ public static byte[] ALIGN_JUSTIFY = DocWriter.GetISOBytes("\\qj");
+ /**
+ * Constant for the first line indentation
+ */
+ public static byte[] FIRST_LINE_INDENT = DocWriter.GetISOBytes("\\fi");
+ /**
+ * Constant for left indentation
+ */
+ public static byte[] INDENT_LEFT = DocWriter.GetISOBytes("\\li");
+ /**
+ * Constant for right indentation
+ */
+ public static byte[] INDENT_RIGHT = DocWriter.GetISOBytes("\\ri");
+ /**
+ * Constant for keeping the paragraph together on one page
+ */
+ public static byte[] KEEP_TOGETHER = DocWriter.GetISOBytes("\\keep");
+ /**
+ * Constant for keeping the paragraph toghether with the next one on one page
+ */
+ public static byte[] KEEP_TOGETHER_WITH_NEXT = DocWriter.GetISOBytes("\\keepn");
+ /**
+ * Constant for the space after the paragraph.
+ */
+ public static byte[] SPACING_AFTER = DocWriter.GetISOBytes("\\sa");
+ /**
+ * Constant for the space before the paragraph.
+ */
+ public static byte[] SPACING_BEFORE = DocWriter.GetISOBytes("\\sb");
+
+ /**
+ * The NORMAL/STANDARD style.
+ */
+ public static RtfParagraphStyle STYLE_NORMAL = new RtfParagraphStyle("Normal", "Arial", 12, Font.NORMAL, Color.BLACK);
+ /**
+ * The style for level 1 headings.
+ */
+ public static RtfParagraphStyle STYLE_HEADING_1 = new RtfParagraphStyle("heading 1", "Normal");
+ /**
+ * The style for level 2 headings.
+ */
+ public static RtfParagraphStyle STYLE_HEADING_2 = new RtfParagraphStyle("heading 2", "Normal");
+ /**
+ * The style for level 3 headings.
+ */
+ public static RtfParagraphStyle STYLE_HEADING_3 = new RtfParagraphStyle("heading 3", "Normal");
+
+ /**
+ * Initialises the properties of the styles.
+ */
+ static RtfParagraphStyle() {
+ STYLE_HEADING_1.Size = 16;
+ STYLE_HEADING_1.SetStyle(Font.BOLD);
+ STYLE_HEADING_2.Size = 14;
+ STYLE_HEADING_2.SetStyle(Font.BOLDITALIC);
+ STYLE_HEADING_3.Size = 13;
+ STYLE_HEADING_3.SetStyle(Font.BOLD);
+ }
+
+ /**
+ * No modification has taken place when compared to the RtfParagraphStyle this RtfParagraphStyle
+ * is based on. These modification markers are used to determine what needs to be
+ * inherited and what not from the parent RtfParagraphStyle.
+ */
+ private const int MODIFIED_NONE = 0;
+ /**
+ * The alignment has been modified.
+ */
+ private const int MODIFIED_ALIGNMENT = 1;
+ /**
+ * The left indentation has been modified.
+ */
+ private const int MODIFIED_INDENT_LEFT = 2;
+ /**
+ * The right indentation has been modified.
+ */
+ private const int MODIFIED_INDENT_RIGHT = 4;
+ /**
+ * The spacing before a paragraph has been modified.
+ */
+ private const int MODIFIED_SPACING_BEFORE = 8;
+ /**
+ * The spacing after a paragraph has been modified.
+ */
+ private const int MODIFIED_SPACING_AFTER = 16;
+ /**
+ * The font name has been modified.
+ */
+ private const int MODIFIED_FONT_NAME = 32;
+ /**
+ * The font style has been modified.
+ */
+ private const int MODIFIED_FONT_SIZE = 64;
+ /**
+ * The font size has been modified.
+ */
+ private const int MODIFIED_FONT_STYLE = 128;
+ /**
+ * The font colour has been modified.
+ */
+ private const int MODIFIED_FONT_COLOR = 256;
+ /**
+ * The line leading has been modified.
+ */
+ private const int MODIFIED_LINE_LEADING = 512;
+ /**
+ * The paragraph keep together setting has been modified.
+ */
+ private const int MODIFIED_KEEP_TOGETHER = 1024;
+ /**
+ * The paragraph keep together with next setting has been modified.
+ */
+ private const int MODIFIED_KEEP_TOGETHER_WITH_NEXT = 2048;
+
+ /**
+ * The alignment of the paragraph.
+ */
+ private int alignment = Element.ALIGN_LEFT;
+ /**
+ * The indentation for the first line
+ */
+ private int firstLineIndent = 0;
+ /**
+ * The left indentation of the paragraph.
+ */
+ private int indentLeft = 0;
+ /**
+ * The right indentation of the paragraph.
+ */
+ private int indentRight = 0;
+ /**
+ * The spacing before a paragraph.
+ */
+ private int spacingBefore = 0;
+ /**
+ * The spacing after a paragraph.
+ */
+ private int spacingAfter = 0;
+ /**
+ * The line leading of the paragraph.
+ */
+ private int lineLeading = 0;
+ /**
+ * Whether this RtfParagraph must stay on one page.
+ */
+ private bool keepTogether = false;
+ /**
+ * Whether this RtfParagraph must stay on the same page as the next paragraph.
+ */
+ private bool keepTogetherWithNext = false;
+ /**
+ * The name of this RtfParagraphStyle.
+ */
+ private String styleName = "";
+ /**
+ * The name of the RtfParagraphStyle this RtfParagraphStyle is based on.
+ */
+ private String basedOnName = null;
+ /**
+ * The RtfParagraphStyle this RtfParagraphStyle is based on.
+ */
+ private RtfParagraphStyle baseStyle = null;
+ /**
+ * Which properties have been modified when compared to the base style.
+ */
+ private int modified = MODIFIED_NONE;
+ /**
+ * The number of this RtfParagraphStyle in the stylesheet list.
+ */
+ private int styleNumber = -1;
+
+ /**
+ * Constructs a new RtfParagraphStyle with the given attributes.
+ *
+ * @param styleName The name of this RtfParagraphStyle.
+ * @param fontName The name of the font to use for this RtfParagraphStyle.
+ * @param fontSize The size of the font to use for this RtfParagraphStyle.
+ * @param fontStyle The style of the font to use for this RtfParagraphStyle.
+ * @param fontColor The colour of the font to use for this RtfParagraphStyle.
+ */
+ public RtfParagraphStyle(String styleName, String fontName, int fontSize, int fontStyle, Color fontColor) : base(null, new RtfFont(fontName, fontSize, fontStyle, fontColor)) {
+ this.styleName = styleName;
+ }
+
+ /**
+ * Constructs a new RtfParagraphStyle that is based on an existing RtfParagraphStyle.
+ *
+ * @param styleName The name of this RtfParagraphStyle.
+ * @param basedOnName The name of the RtfParagraphStyle this RtfParagraphStyle is based on.
+ */
+ public RtfParagraphStyle(String styleName, String basedOnName) : base(null, new Font()) {
+ this.styleName = styleName;
+ this.basedOnName = basedOnName;
+ }
+
+ /**
+ * Constructs a RtfParagraphStyle from another RtfParagraphStyle.
+ *
+ * INTERNAL USE ONLY
+ *
+ * @param doc The RtfDocument this RtfParagraphStyle belongs to.
+ * @param style The RtfParagraphStyle to copy settings from.
+ */
+ public RtfParagraphStyle(RtfDocument doc, RtfParagraphStyle style) : base(doc, style) {
+ this.document = doc;
+ this.styleName = style.GetStyleName();
+ this.alignment = style.GetAlignment();
+ this.firstLineIndent = (int)(style.GetFirstLineIndent() * RtfElement.TWIPS_FACTOR);
+ this.indentLeft = (int) (style.GetIndentLeft() * RtfElement.TWIPS_FACTOR);
+ this.indentRight = (int) (style.GetIndentRight() * RtfElement.TWIPS_FACTOR);
+ this.spacingBefore = (int) (style.GetSpacingBefore() * RtfElement.TWIPS_FACTOR);
+ this.spacingAfter = (int) (style.GetSpacingAfter() * RtfElement.TWIPS_FACTOR);
+ this.lineLeading = (int) (style.GetLineLeading() * RtfElement.TWIPS_FACTOR);
+ this.keepTogether = style.GetKeepTogether();
+ this.keepTogetherWithNext = style.GetKeepTogetherWithNext();
+ this.basedOnName = style.basedOnName;
+ this.modified = style.modified;
+ this.styleNumber = style.GetStyleNumber();
+
+ if (this.document != null) {
+ SetRtfDocument(this.document);
+ }
+ }
+
+ /**
+ * Gets the name of this RtfParagraphStyle.
+ *
+ * @return The name of this RtfParagraphStyle.
+ */
+ public String GetStyleName() {
+ return this.styleName;
+ }
+
+ /**
+ * Gets the name of the RtfParagraphStyle this RtfParagraphStyle is based on.
+ *
+ * @return The name of the base RtfParagraphStyle.
+ */
+ public String GetBasedOnName() {
+ return this.basedOnName;
+ }
+
+ /**
+ * Gets the alignment of this RtfParagraphStyle.
+ *
+ * @return The alignment of this RtfParagraphStyle.
+ */
+ public int GetAlignment() {
+ return this.alignment;
+ }
+
+ /**
+ * Sets the alignment of this RtfParagraphStyle.
+ *
+ * @param alignment The alignment to use.
+ */
+ public void SetAlignment(int alignment) {
+ this.modified = this.modified | MODIFIED_ALIGNMENT;
+ this.alignment = alignment;
+ }
+
+ /**
+ * Gets the first line indentation of this RtfParagraphStyle.
+ *
+ * @return The first line indentation of this RtfParagraphStyle.
+ */
+ public int GetFirstLineIndent() {
+ return this.firstLineIndent;
+ }
+
+ /**
+ * Sets the first line indententation of this RtfParagraphStyle. It
+ * is relative to the left indentation.
+ *
+ * @param firstLineIndent The first line indentation to use.
+ */
+ public void SetFirstLineIndent(int firstLineIndent) {
+ this.firstLineIndent = firstLineIndent;
+ }
+
+ /**
+ * Gets the left indentation of this RtfParagraphStyle.
+ *
+ * @return The left indentation of this RtfParagraphStyle.
+ */
+ public int GetIndentLeft() {
+ return this.indentLeft;
+ }
+
+ /**
+ * Sets the left indentation of this RtfParagraphStyle.
+ *
+ * @param indentLeft The left indentation to use.
+ */
+ public void SetIndentLeft(int indentLeft) {
+ this.modified = this.modified | MODIFIED_INDENT_LEFT;
+ this.indentLeft = indentLeft;
+ }
+
+ /**
+ * Gets the right indentation of this RtfParagraphStyle.
+ *
+ * @return The right indentation of this RtfParagraphStyle.
+ */
+ public int GetIndentRight() {
+ return this.indentRight;
+ }
+
+ /**
+ * Sets the right indentation of this RtfParagraphStyle.
+ *
+ * @param indentRight The right indentation to use.
+ */
+ public void SetIndentRight(int indentRight) {
+ this.modified = this.modified | MODIFIED_INDENT_RIGHT;
+ this.indentRight = indentRight;
+ }
+
+ /**
+ * Gets the space before the paragraph of this RtfParagraphStyle..
+ *
+ * @return The space before the paragraph.
+ */
+ public int GetSpacingBefore() {
+ return this.spacingBefore;
+ }
+
+ /**
+ * Sets the space before the paragraph of this RtfParagraphStyle.
+ *
+ * @param spacingBefore The space before to use.
+ */
+ public void SetSpacingBefore(int spacingBefore) {
+ this.modified = this.modified | MODIFIED_SPACING_BEFORE;
+ this.spacingBefore = spacingBefore;
+ }
+
+ /**
+ * Gets the space after the paragraph of this RtfParagraphStyle.
+ *
+ * @return The space after the paragraph.
+ */
+ public int GetSpacingAfter() {
+ return this.spacingAfter;
+ }
+
+ /**
+ * Sets the space after the paragraph of this RtfParagraphStyle.
+ *
+ * @param spacingAfter The space after to use.
+ */
+ public void SetSpacingAfter(int spacingAfter) {
+ this.modified = this.modified | MODIFIED_SPACING_AFTER;
+ this.spacingAfter = spacingAfter;
+ }
+
+ /**
+ * Sets the font name of this RtfParagraphStyle.
+ *
+ * @param fontName The font name to use
+ */
+ public override void SetFontName(String fontName) {
+ this.modified = this.modified | MODIFIED_FONT_NAME;
+ base.SetFontName(fontName);
+ }
+
+ /**
+ * Sets the font size of this RtfParagraphStyle.
+ *
+ * @param fontSize The font size to use.
+ */
+ public override float Size {
+ set {
+ this.modified = this.modified | MODIFIED_FONT_SIZE;
+ base.Size = value;
+ }
+ }
+
+ /**
+ * Sets the font style of this RtfParagraphStyle.
+ *
+ * @param fontStyle The font style to use.
+ */
+ public override void SetStyle(int fontStyle) {
+ this.modified = this.modified | MODIFIED_FONT_STYLE;
+ base.SetStyle(fontStyle);
+ }
+
+ /**
+ * Sets the colour of this RtfParagraphStyle.
+ *
+ * @param color The Color to use.
+ */
+ public void SetColor(Color color) {
+ this.modified = this.modified | MODIFIED_FONT_COLOR;
+ base.Color = color;
+ }
+
+ /**
+ * Gets the line leading of this RtfParagraphStyle.
+ *
+ * @return The line leading of this RtfParagraphStyle.
+ */
+ public int GetLineLeading() {
+ return this.lineLeading;
+ }
+
+ /**
+ * Sets the line leading of this RtfParagraphStyle.
+ *
+ * @param lineLeading The line leading to use.
+ */
+ public void SetLineLeading(int lineLeading) {
+ this.lineLeading = lineLeading;
+ this.modified = this.modified | MODIFIED_LINE_LEADING;
+ }
+
+ /**
+ * Gets whether the lines in the paragraph should be kept together in
+ * this RtfParagraphStyle.
+ *
+ * @return Whether the lines in the paragraph should be kept together.
+ */
+ public bool GetKeepTogether() {
+ return this.keepTogether;
+ }
+
+ /**
+ * Sets whether the lines in the paragraph should be kept together in
+ * this RtfParagraphStyle.
+ *
+ * @param keepTogether Whether the lines in the paragraph should be kept together.
+ */
+ public void SetKeepTogether(bool keepTogether) {
+ this.keepTogether = keepTogether;
+ this.modified = this.modified | MODIFIED_KEEP_TOGETHER;
+ }
+
+ /**
+ * Gets whether the paragraph should be kept toggether with the next in
+ * this RtfParagraphStyle.
+ *
+ * @return Whether the paragraph should be kept together with the next.
+ */
+ public bool GetKeepTogetherWithNext() {
+ return this.keepTogetherWithNext;
+ }
+
+ /**
+ * Sets whether the paragraph should be kept together with the next in
+ * this RtfParagraphStyle.
+ *
+ * @param keepTogetherWithNext Whether the paragraph should be kept together with the next.
+ */
+ public void SetKeepTogetherWithNext(bool keepTogetherWithNext) {
+ this.keepTogetherWithNext = keepTogetherWithNext;
+ this.modified = this.modified | MODIFIED_KEEP_TOGETHER_WITH_NEXT;
+ }
+
+ /**
+ * Handles the inheritance of paragraph style settings. All settings that
+ * have not been modified will be inherited from the base RtfParagraphStyle.
+ * If this RtfParagraphStyle is not based on another one, then nothing happens.
+ */
+ public void HandleInheritance() {
+ if (this.basedOnName != null && this.document.GetDocumentHeader().GetRtfParagraphStyle(this.basedOnName) != null) {
+ this.baseStyle = this.document.GetDocumentHeader().GetRtfParagraphStyle(this.basedOnName);
+ this.baseStyle.HandleInheritance();
+ if (!((this.modified & MODIFIED_ALIGNMENT) == MODIFIED_ALIGNMENT)) {
+ this.alignment = this.baseStyle.GetAlignment();
+ }
+ if (!((this.modified & MODIFIED_INDENT_LEFT) == MODIFIED_INDENT_LEFT)) {
+ this.indentLeft = this.baseStyle.GetIndentLeft();
+ }
+ if (!((this.modified & MODIFIED_INDENT_RIGHT) == MODIFIED_INDENT_RIGHT)) {
+ this.indentRight = this.baseStyle.GetIndentRight();
+ }
+ if (!((this.modified & MODIFIED_SPACING_BEFORE) == MODIFIED_SPACING_BEFORE)) {
+ this.spacingBefore = this.baseStyle.GetSpacingBefore();
+ }
+ if (!((this.modified & MODIFIED_SPACING_AFTER) == MODIFIED_SPACING_AFTER)) {
+ this.spacingAfter = this.baseStyle.GetSpacingAfter();
+ }
+ if (!((this.modified & MODIFIED_FONT_NAME) == MODIFIED_FONT_NAME)) {
+ SetFontName(this.baseStyle.GetFontName());
+ }
+ if (!((this.modified & MODIFIED_FONT_SIZE) == MODIFIED_FONT_SIZE)) {
+ Size = this.baseStyle.GetFontSize();
+ }
+ if (!((this.modified & MODIFIED_FONT_STYLE) == MODIFIED_FONT_STYLE)) {
+ SetStyle(this.baseStyle.GetFontStyle());
+ }
+ if (!((this.modified & MODIFIED_FONT_COLOR) == MODIFIED_FONT_COLOR)) {
+ SetColor(this.baseStyle.Color);
+ }
+ if (!((this.modified & MODIFIED_LINE_LEADING) == MODIFIED_LINE_LEADING)) {
+ SetLineLeading(this.baseStyle.GetLineLeading());
+ }
+ if (!((this.modified & MODIFIED_KEEP_TOGETHER) == MODIFIED_KEEP_TOGETHER)) {
+ SetKeepTogether(this.baseStyle.GetKeepTogether());
+ }
+ if (!((this.modified & MODIFIED_KEEP_TOGETHER_WITH_NEXT) == MODIFIED_KEEP_TOGETHER_WITH_NEXT)) {
+ SetKeepTogetherWithNext(this.baseStyle.GetKeepTogetherWithNext());
+ }
+ }
+ }
+
+ /**
+ * Writes the settings of this RtfParagraphStyle.
+ *
+ */
+ private void WriteParagraphSettings(Stream result) {
+ byte[] t;
+ if (this.keepTogether) {
+ result.Write(t = RtfParagraphStyle.KEEP_TOGETHER, 0, t.Length);
+ }
+ if (this.keepTogetherWithNext) {
+ result.Write(t = RtfParagraphStyle.KEEP_TOGETHER_WITH_NEXT, 0, t.Length);
+ }
+ switch (alignment) {
+ case Element.ALIGN_LEFT:
+ result.Write(t = RtfParagraphStyle.ALIGN_LEFT, 0, t.Length);
+ break;
+ case Element.ALIGN_RIGHT:
+ result.Write(t = RtfParagraphStyle.ALIGN_RIGHT, 0, t.Length);
+ break;
+ case Element.ALIGN_CENTER:
+ result.Write(t = RtfParagraphStyle.ALIGN_CENTER, 0, t.Length);
+ break;
+ case Element.ALIGN_JUSTIFIED:
+ case Element.ALIGN_JUSTIFIED_ALL:
+ result.Write(t = RtfParagraphStyle.ALIGN_JUSTIFY, 0, t.Length);
+ break;
+ }
+ result.Write(t = FIRST_LINE_INDENT, 0, t.Length);
+ result.Write(t = IntToByteArray(this.firstLineIndent), 0, t.Length);
+ result.Write(t = RtfParagraphStyle.INDENT_LEFT, 0, t.Length);
+ result.Write(t = IntToByteArray(indentLeft), 0, t.Length);
+ result.Write(t = RtfParagraphStyle.INDENT_RIGHT, 0, t.Length);
+ result.Write(t = IntToByteArray(indentRight), 0, t.Length);
+ if (this.spacingBefore > 0) {
+ result.Write(t = RtfParagraphStyle.SPACING_BEFORE, 0, t.Length);
+ result.Write(t = IntToByteArray(this.spacingBefore), 0, t.Length);
+ }
+ if (this.spacingAfter > 0) {
+ result.Write(t = RtfParagraphStyle.SPACING_AFTER, 0, t.Length);
+ result.Write(t = IntToByteArray(this.spacingAfter), 0, t.Length);
+ }
+ if (this.lineLeading > 0) {
+ result.Write(t = RtfParagraph.LINE_SPACING, 0, t.Length);
+ result.Write(t = IntToByteArray(this.lineLeading), 0, t.Length);
+ }
+ }
+
+ /**
+ * Writes the definition of this RtfParagraphStyle for the stylesheet list.
+ */
+ public override void WriteDefinition(Stream result) {
+ byte[] t;
+ result.Write(t = DocWriter.GetISOBytes("{"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\style"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\s"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.styleNumber), 0, t.Length);
+ result.Write(t = RtfElement.DELIMITER, 0, t.Length);
+ WriteParagraphSettings(result);
+ base.WriteBegin(result);
+ result.Write(t = RtfElement.DELIMITER, 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes(this.styleName), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes(";"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("}"), 0, t.Length);
+ if (this.document.GetDocumentSettings().IsOutputDebugLineBreaks()) {
+ result.WriteByte((byte)'\n');
+ }
+ }
+
+ /**
+ * Writes the start information of this RtfParagraphStyle.
+ *
+ * @param result The OutputStream
to write to.
+ * @throws IOException On i/o errors.
+ */
+ public override void WriteBegin(Stream result) {
+ byte[] t;
+ result.Write(t = DocWriter.GetISOBytes("\\s"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.styleNumber), 0, t.Length);
+ WriteParagraphSettings(result);
+ }
+
+ /**
+ * Unused
+ */
+ public override void WriteEnd(Stream result) {
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Tests whether two RtfParagraphStyles are equal. Equality
+ * is determined via the name.
+ */
+ public override bool Equals(Object o) {
+ if (!(o is RtfParagraphStyle)) {
+ return false;
+ }
+ RtfParagraphStyle paragraphStyle = (RtfParagraphStyle) o;
+ bool result = this.GetStyleName().Equals(paragraphStyle.GetStyleName());
+ return result;
+ }
+
+ /**
+ * Gets the hash code of this RtfParagraphStyle.
+ */
+ public override int GetHashCode() {
+ return this.styleName.GetHashCode();
+ }
+
+ /**
+ * Gets the number of this RtfParagraphStyle in the stylesheet list.
+ *
+ * @return The number of this RtfParagraphStyle in the stylesheet list.
+ */
+ private int GetStyleNumber() {
+ return this.styleNumber;
+ }
+
+ /**
+ * Sets the number of this RtfParagraphStyle in the stylesheet list.
+ *
+ * @param styleNumber The number to use.
+ */
+ protected internal void SetStyleNumber(int styleNumber) {
+ this.styleNumber = styleNumber;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/style/RtfStyleTypes.cs b/iTechSharp/iTextSharp/text/rtf/style/RtfStyleTypes.cs
new file mode 100644
index 0000000..7ca93ff
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/style/RtfStyleTypes.cs
@@ -0,0 +1,81 @@
+using System;
+/*
+ * $Id: RtfStyleTypes.cs,v 1.1 2008/02/14 14:52:32 psoares33 Exp $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.style {
+ /**
+ * RtfStyleTypes
contains the different types of Stylesheet entries
+ * that exist in RTF.
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+ public sealed class RtfStyleTypes {
+ /**
+ * Indicates paragraph style.
+ */
+ public const int PARAGRAPH = 0;
+ /**
+ * Indicates character style.
+ */
+ public const int CHARACTER = 0;
+ /**
+ * Indicates section style.
+ */
+ public const int SECTION = 2;
+ /**
+ * Indicates Table style.
+ */
+ public const int TABLE = 3;
+ /**
+ * Indicates table definition style.
+ */
+ public const int TABLE_STYLE_DEFINITION = 4;
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/rtf/style/RtfStylesheetList.cs b/iTechSharp/iTextSharp/text/rtf/style/RtfStylesheetList.cs
new file mode 100644
index 0000000..e4be54e
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/style/RtfStylesheetList.cs
@@ -0,0 +1,110 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+
+namespace iTextSharp.text.rtf.style {
+
+ /**
+ * The RtfStylesheetList stores the RtfParagraphStyles that are used in the document.
+ *
+ * @version $Revision: 1.5 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfStylesheetList : RtfElement, IRtfExtendedElement {
+
+ /**
+ * The Hashtable containing the RtfParagraphStyles.
+ */
+ private Hashtable styleMap = null;
+ /**
+ * Whether the default settings have been loaded.
+ */
+ private bool defaultsLoaded = false;
+
+ /**
+ * Constructs a new RtfStylesheetList for the RtfDocument.
+ *
+ * @param doc The RtfDocument this RtfStylesheetList belongs to.
+ */
+ public RtfStylesheetList(RtfDocument doc) : base(doc) {
+ this.styleMap = new Hashtable();
+ }
+
+ /**
+ * unused
+ */
+ public override void WriteContent(Stream outp) {
+ }
+
+ /**
+ * Register a RtfParagraphStyle with this RtfStylesheetList.
+ *
+ * @param rtfParagraphStyle The RtfParagraphStyle to add.
+ */
+ public void RegisterParagraphStyle(RtfParagraphStyle rtfParagraphStyle) {
+ RtfParagraphStyle tempStyle = new RtfParagraphStyle(this.document, rtfParagraphStyle);
+ tempStyle.HandleInheritance();
+ tempStyle.SetStyleNumber(this.styleMap.Count);
+ this.styleMap[tempStyle.GetStyleName()] = tempStyle;
+ }
+
+ /**
+ * Registers all default styles. If styles with the given name have already been registered,
+ * then they are NOT overwritten.
+ */
+ private void RegisterDefaultStyles() {
+ defaultsLoaded = true;
+ if (!this.styleMap.ContainsKey(RtfParagraphStyle.STYLE_NORMAL.GetStyleName())) {
+ RegisterParagraphStyle(RtfParagraphStyle.STYLE_NORMAL);
+ }
+ if (!this.styleMap.ContainsKey(RtfParagraphStyle.STYLE_HEADING_1.GetStyleName())) {
+ RegisterParagraphStyle(RtfParagraphStyle.STYLE_HEADING_1);
+ }
+ if (!this.styleMap.ContainsKey(RtfParagraphStyle.STYLE_HEADING_2.GetStyleName())) {
+ RegisterParagraphStyle(RtfParagraphStyle.STYLE_HEADING_2);
+ }
+ if (!this.styleMap.ContainsKey(RtfParagraphStyle.STYLE_HEADING_3.GetStyleName())) {
+ RegisterParagraphStyle(RtfParagraphStyle.STYLE_HEADING_3);
+ }
+ }
+
+ /**
+ * Gets the RtfParagraphStyle with the given name. Makes sure that the defaults
+ * have been loaded.
+ *
+ * @param styleName The name of the RtfParagraphStyle to get.
+ * @return The RtfParagraphStyle with the given name or null.
+ */
+ public RtfParagraphStyle GetRtfParagraphStyle(String styleName) {
+ if (!defaultsLoaded) {
+ RegisterDefaultStyles();
+ }
+ if (this.styleMap.ContainsKey(styleName)) {
+ return (RtfParagraphStyle) this.styleMap[styleName];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Writes the definition of the stylesheet list.
+ */
+ public virtual void WriteDefinition(Stream result) {
+ byte[] t;
+ result.Write(t = DocWriter.GetISOBytes("{"), 0, t.Length);
+ result.Write(t = DocWriter.GetISOBytes("\\stylesheet"), 0, t.Length);
+ result.Write(t = RtfElement.DELIMITER, 0, t.Length);
+ if (this.document.GetDocumentSettings().IsOutputDebugLineBreaks()) {
+ result.Write(t = DocWriter.GetISOBytes("\n"), 0, t.Length);
+ }
+ foreach (RtfParagraphStyle rps in this.styleMap.Values)
+ rps.WriteDefinition(result);
+ result.Write(t = DocWriter.GetISOBytes("}"), 0, t.Length);
+ if (this.document.GetDocumentSettings().IsOutputDebugLineBreaks()) {
+ result.WriteByte((byte)'\n');
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/table/RtfBorder.cs b/iTechSharp/iTextSharp/text/rtf/table/RtfBorder.cs
new file mode 100644
index 0000000..1179ce2
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/table/RtfBorder.cs
@@ -0,0 +1,561 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.style;
+/*
+ * $Id: RtfBorder.cs,v 1.6 2008/05/16 19:31:18 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.table {
+
+ /**
+ * The RtfBorder handle one row or cell border.
+ * INTERNAL USE ONLY
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Unknown
+ */
+ public class RtfBorder : RtfElement {
+
+ /**
+ * Constant for the left row border
+ */
+ protected internal static byte[] ROW_BORDER_LEFT = DocWriter.GetISOBytes("\\trbrdrl");
+ /**
+ * Constant for the top row border
+ */
+ protected internal static byte[] ROW_BORDER_TOP = DocWriter.GetISOBytes("\\trbrdrt");
+ /**
+ * Constant for the right row border
+ */
+ protected internal static byte[] ROW_BORDER_RIGHT = DocWriter.GetISOBytes("\\trbrdrr");
+ /**
+ * Constant for the bottom row border
+ */
+ protected internal static byte[] ROW_BORDER_BOTTOM = DocWriter.GetISOBytes("\\trbrdrb");
+ /**
+ * Constant for the horizontal line
+ */
+ protected internal static byte[] ROW_BORDER_HORIZONTAL = DocWriter.GetISOBytes("\\trbrdrh");
+ /**
+ * Constant for the vertical line
+ */
+ protected internal static byte[] ROW_BORDER_VERTICAL = DocWriter.GetISOBytes("\\trbrdrv");
+ /**
+ * Constant for the left cell border
+ */
+ protected internal static byte[] CELL_BORDER_LEFT = DocWriter.GetISOBytes("\\clbrdrl");
+ /**
+ * Constant for the top cell border
+ */
+ protected internal static byte[] CELL_BORDER_TOP = DocWriter.GetISOBytes("\\clbrdrt");
+ /**
+ * Constant for the right cell border
+ */
+ protected internal static byte[] CELL_BORDER_RIGHT = DocWriter.GetISOBytes("\\clbrdrr");
+ /**
+ * Constant for the bottom cell border
+ */
+ protected internal static byte[] CELL_BORDER_BOTTOM = DocWriter.GetISOBytes("\\clbrdrb");
+ /**
+ * Constant for the border width
+ */
+ protected internal static byte[] BORDER_WIDTH = DocWriter.GetISOBytes("\\brdrw");
+ /**
+ * Constant for the border colour number
+ */
+ protected internal static byte[] BORDER_COLOR_NUMBER = DocWriter.GetISOBytes("\\brdrcf");
+ /**
+ * Constant for the single border style
+ */
+ protected internal static byte[] BORDER_STYLE_SINGLE = DocWriter.GetISOBytes("\\brdrs");
+ /**
+ * Constant for the double thick border style
+ */
+ protected internal static byte[] BORDER_STYLE_DOUBLE_THICK = DocWriter.GetISOBytes("\\brdrth");
+ /**
+ * Constant for the shadowed border style
+ */
+ protected internal static byte[] BORDER_STYLE_SHADOWED = DocWriter.GetISOBytes("\\brdrsh");
+ /**
+ * Constant for the dotted border style
+ */
+ protected internal static byte[] BORDER_STYLE_DOTTED = DocWriter.GetISOBytes("\\brdrdot");
+ /**
+ * Constant for the dashed border style
+ */
+ protected internal static byte[] BORDER_STYLE_DASHED = DocWriter.GetISOBytes("\\brdrdash");
+ /**
+ * Constant for the hairline border style
+ */
+ protected internal static byte[] BORDER_STYLE_HAIRLINE = DocWriter.GetISOBytes("\\brdrhair");
+ /**
+ * Constant for the double border style
+ */
+ protected internal static byte[] BORDER_STYLE_DOUBLE = DocWriter.GetISOBytes("\\brdrdb");
+ /**
+ * Constant for the dot dash border style
+ */
+ protected internal static byte[] BORDER_STYLE_DOT_DASH = DocWriter.GetISOBytes("\\brdrdashd");
+ /**
+ * Constant for the dot dot dash border style
+ */
+ protected internal static byte[] BORDER_STYLE_DOT_DOT_DASH = DocWriter.GetISOBytes("\\brdrdashdd");
+ /**
+ * Constant for the triple border style
+ */
+ protected internal static byte[] BORDER_STYLE_TRIPLE = DocWriter.GetISOBytes("\\brdrtriple");
+ /**
+ * Constant for the thick thin border style
+ */
+ protected internal static byte[] BORDER_STYLE_THICK_THIN = DocWriter.GetISOBytes("\\brdrtnthsg");
+ /**
+ * Constant for the thin thick border style
+ */
+ protected internal static byte[] BORDER_STYLE_THIN_THICK = DocWriter.GetISOBytes("\\brdrthtnsg");
+ /**
+ * Constant for the thin thick thin border style
+ */
+ protected internal static byte[] BORDER_STYLE_THIN_THICK_THIN = DocWriter.GetISOBytes("\\brdrtnthtnsg");
+ /**
+ * Constant for the thick thin medium border style
+ */
+ protected internal static byte[] BORDER_STYLE_THICK_THIN_MED = DocWriter.GetISOBytes("\\brdrtnthmg");
+ /**
+ * Constant for the thin thick medium border style
+ */
+ protected internal static byte[] BORDER_STYLE_THIN_THICK_MED = DocWriter.GetISOBytes("\\brdrthtnmg");
+ /**
+ * Constant for the thin thick thin medium border style
+ */
+ protected internal static byte[] BORDER_STYLE_THIN_THICK_THIN_MED = DocWriter.GetISOBytes("\\brdrtnthtnmg");
+ /**
+ * Constant for the thick thin large border style
+ */
+ protected internal static byte[] BORDER_STYLE_THICK_THIN_LARGE = DocWriter.GetISOBytes("\\brdrtnthlg");
+ /**
+ * Constant for the thin thick large border style
+ */
+ protected internal static byte[] BORDER_STYLE_THIN_THICK_LARGE = DocWriter.GetISOBytes("\\brdrthtnlg");
+ /**
+ * Constant for the thin thick thin large border style
+ */
+ protected internal static byte[] BORDER_STYLE_THIN_THICK_THIN_LARGE = DocWriter.GetISOBytes("\\brdrtnthtnlg");
+ /**
+ * Constant for the wavy border style
+ */
+ protected internal static byte[] BORDER_STYLE_WAVY = DocWriter.GetISOBytes("\\brdrwavy");
+ /**
+ * Constant for the double wavy border style
+ */
+ protected internal static byte[] BORDER_STYLE_DOUBLE_WAVY = DocWriter.GetISOBytes("\\brdrwavydb");
+ /**
+ * Constant for the striped border style
+ */
+ protected internal static byte[] BORDER_STYLE_STRIPED = DocWriter.GetISOBytes("\\brdrdashdotstr");
+ /**
+ * Constant for the embossed border style
+ */
+ protected internal static byte[] BORDER_STYLE_EMBOSS = DocWriter.GetISOBytes("\\brdremboss");
+ /**
+ * Constant for the engraved border style
+ */
+ protected internal static byte[] BORDER_STYLE_ENGRAVE = DocWriter.GetISOBytes("\\brdrengrave");
+
+ /**
+ * Constant for a row border
+ */
+ protected internal const int ROW_BORDER = 1;
+ /**
+ * Constant for a cell border
+ */
+ protected internal const int CELL_BORDER = 2;
+
+ /**
+ * This border is no border :-)
+ */
+ protected internal const int NO_BORDER = 0;
+ /**
+ * Constant for a left border
+ */
+ protected internal const int LEFT_BORDER = 1;
+ /**
+ * Constant for a top border
+ */
+ protected internal const int TOP_BORDER = 2;
+ /**
+ * Constant for a right border
+ */
+ protected internal const int RIGHT_BORDER = 4;
+ /**
+ * Constant for a bottom border
+ */
+ protected internal const int BOTTOM_BORDER = 8;
+ /**
+ * Constant for a box (left, top, right, bottom) border
+ */
+ protected internal const int BOX_BORDER = 15;
+ /**
+ * Constant for a vertical line
+ */
+ protected internal const int VERTICAL_BORDER = 16;
+ /**
+ * Constant for a horizontal line
+ */
+ protected internal const int HORIZONTAL_BORDER = 32;
+
+ /**
+ * Constant for a border with no border
+ */
+ public const int BORDER_NONE = 0;
+ /**
+ * Constant for a single border
+ */
+ public const int BORDER_SINGLE = 1;
+ /**
+ * Constant for a double thick border
+ */
+ public const int BORDER_DOUBLE_THICK = 2;
+ /**
+ * Constant for a shadowed border
+ */
+ public const int BORDER_SHADOWED = 3;
+ /**
+ * Constant for a dotted border
+ */
+ public const int BORDER_DOTTED = 4;
+ /**
+ * Constant for a dashed border
+ */
+ public const int BORDER_DASHED = 5;
+ /**
+ * Constant for a hairline border
+ */
+ public const int BORDER_HAIRLINE = 6;
+ /**
+ * Constant for a double border
+ */
+ public const int BORDER_DOUBLE = 7;
+ /**
+ * Constant for a dot dash border
+ */
+ public const int BORDER_DOT_DASH = 8;
+ /**
+ * Constant for a dot dot dash border
+ */
+ public const int BORDER_DOT_DOT_DASH = 9;
+ /**
+ * Constant for a triple border
+ */
+ public const int BORDER_TRIPLE = 10;
+ /**
+ * Constant for a thick thin border
+ */
+ public const int BORDER_THICK_THIN = 11;
+ /**
+ * Constant for a thin thick border
+ */
+ public const int BORDER_THIN_THICK = 12;
+ /**
+ * Constant for a thin thick thin border
+ */
+ public const int BORDER_THIN_THICK_THIN = 13;
+ /**
+ * Constant for a thick thin medium border
+ */
+ public const int BORDER_THICK_THIN_MED = 14;
+ /**
+ * Constant for a thin thick medium border
+ */
+ public const int BORDER_THIN_THICK_MED = 15;
+ /**
+ * Constant for a thin thick thin medium border
+ */
+ public const int BORDER_THIN_THICK_THIN_MED = 16;
+ /**
+ * Constant for a thick thin large border
+ */
+ public const int BORDER_THICK_THIN_LARGE = 17;
+ /**
+ * Constant for a thin thick large border
+ */
+ public const int BORDER_THIN_THICK_LARGE = 18;
+ /**
+ * Constant for a thin thick thin large border
+ */
+ public const int BORDER_THIN_THICK_THIN_LARGE = 19;
+ /**
+ * Constant for a wavy border
+ */
+ public const int BORDER_WAVY = 20;
+ /**
+ * Constant for a double wavy border
+ */
+ public const int BORDER_DOUBLE_WAVY = 21;
+ /**
+ * Constant for a striped border
+ */
+ public const int BORDER_STRIPED = 22;
+ /**
+ * Constant for an embossed border
+ */
+ public const int BORDER_EMBOSS = 23;
+ /**
+ * Constant for an engraved border
+ */
+ public const int BORDER_ENGRAVE = 24;
+
+ /**
+ * The type of this RtfBorder
+ */
+ private int borderType = ROW_BORDER;
+ /**
+ * The position of this RtfBorder
+ */
+ private int borderPosition = NO_BORDER;
+ /**
+ * The style of this RtfBorder
+ */
+ private int borderStyle = BORDER_NONE;
+ /**
+ * The width of this RtfBorder
+ */
+ private int borderWidth = 20;
+ /**
+ * The colour of this RtfBorder
+ */
+ private RtfColor borderColor = null;
+
+ /**
+ * Makes a copy of the given RtfBorder
+ *
+ * @param doc The RtfDocument this RtfBorder belongs to
+ * @param borderType The border type of this RtfBorder
+ * @param border The RtfBorder to copy
+ */
+ protected internal RtfBorder(RtfDocument doc, int borderType, RtfBorder border) : base(doc) {
+ this.borderType = borderType;
+ this.borderPosition = border.GetBorderPosition();
+ this.borderStyle = border.GetBorderStyle();
+ this.borderWidth = border.GetBorderWidth();
+ this.borderColor = new RtfColor(this.document, border.GetBorderColor());
+ }
+
+ /**
+ * Constructs a RtfBorder
+ *
+ * @param doc The RtfDocument this RtfBorder belongs to
+ * @param borderType The type of border this RtfBorder is
+ * @param borderPosition The position of this RtfBorder
+ * @param borderStyle The style of this RtfBorder
+ * @param borderWidth The width of this RtfBorder
+ * @param borderColor The colour of this RtfBorder
+ */
+ protected internal RtfBorder(RtfDocument doc, int borderType, int borderPosition, int borderStyle, float borderWidth, Color borderColor) : base(doc) {
+ this.borderType = borderType;
+ this.borderPosition = borderPosition;
+ this.borderStyle = borderStyle;
+ this.borderWidth = (int) Math.Min((borderWidth * TWIPS_FACTOR), 75);
+ if (this.borderWidth == 0) {
+ this.borderStyle = BORDER_NONE;
+ }
+ if (borderColor == null) {
+ this.borderColor = new RtfColor(this.document, new Color(0, 0, 0));
+ } else {
+ this.borderColor = new RtfColor(this.document, borderColor);
+ }
+ }
+
+ /**
+ * Writes the RtfBorder settings
+ */
+ public override void WriteContent(Stream result) {
+ if (this.borderStyle == BORDER_NONE || this.borderPosition == NO_BORDER || this.borderWidth == 0) {
+ return;
+ }
+ byte[] t;
+ if (this.borderType == ROW_BORDER) {
+ switch (this.borderPosition) {
+ case LEFT_BORDER:
+ result.Write(ROW_BORDER_LEFT, 0, ROW_BORDER_LEFT.Length);
+ break;
+ case TOP_BORDER:
+ result.Write(ROW_BORDER_TOP, 0, ROW_BORDER_TOP.Length);
+ break;
+ case RIGHT_BORDER:
+ result.Write(ROW_BORDER_RIGHT, 0, ROW_BORDER_RIGHT.Length);
+ break;
+ case BOTTOM_BORDER:
+ result.Write(ROW_BORDER_BOTTOM, 0, ROW_BORDER_BOTTOM.Length);
+ break;
+ case HORIZONTAL_BORDER:
+ result.Write(ROW_BORDER_HORIZONTAL, 0, ROW_BORDER_HORIZONTAL.Length);
+ break;
+ case VERTICAL_BORDER:
+ result.Write(ROW_BORDER_VERTICAL, 0, ROW_BORDER_VERTICAL.Length);
+ break;
+ default:
+ return;
+ }
+ result.Write(t = WriteBorderStyle(), 0, t.Length);
+ result.Write(BORDER_WIDTH, 0, BORDER_WIDTH.Length);
+ result.Write(t = IntToByteArray(this.borderWidth), 0, t.Length);
+ result.Write(BORDER_COLOR_NUMBER, 0, BORDER_COLOR_NUMBER.Length);
+ result.Write(t = IntToByteArray(this.borderColor.GetColorNumber()), 0, t.Length);
+ result.WriteByte((byte)'\n');
+ } else if (this.borderType == CELL_BORDER) {
+ switch (this.borderPosition) {
+ case LEFT_BORDER:
+ result.Write(CELL_BORDER_LEFT, 0, CELL_BORDER_LEFT.Length);
+ break;
+ case TOP_BORDER:
+ result.Write(CELL_BORDER_TOP, 0, CELL_BORDER_TOP.Length);
+ break;
+ case RIGHT_BORDER:
+ result.Write(CELL_BORDER_RIGHT, 0, CELL_BORDER_RIGHT.Length);
+ break;
+ case BOTTOM_BORDER:
+ result.Write(CELL_BORDER_BOTTOM, 0, CELL_BORDER_BOTTOM.Length);
+ break;
+ default:
+ return;
+ }
+ result.Write(t = WriteBorderStyle(), 0, t.Length);
+ result.Write(BORDER_WIDTH, 0, BORDER_WIDTH.Length);
+ result.Write(t = IntToByteArray(this.borderWidth), 0, t.Length);
+ result.Write(BORDER_COLOR_NUMBER, 0, BORDER_COLOR_NUMBER.Length);
+ result.Write(t = IntToByteArray(this.borderColor.GetColorNumber()), 0, t.Length);
+ result.WriteByte((byte)'\n');
+ }
+ }
+
+ /**
+ * Writes the style of this RtfBorder
+ *
+ * @return A byte array containing the style of this RtfBorder
+ */
+ private byte[] WriteBorderStyle() {
+ switch (this.borderStyle) {
+ case BORDER_NONE : return new byte[0];
+ case BORDER_SINGLE : return BORDER_STYLE_SINGLE;
+ case BORDER_DOUBLE_THICK : return BORDER_STYLE_DOUBLE_THICK;
+ case BORDER_SHADOWED : return BORDER_STYLE_SHADOWED;
+ case BORDER_DOTTED : return BORDER_STYLE_DOTTED;
+ case BORDER_DASHED : return BORDER_STYLE_DASHED;
+ case BORDER_HAIRLINE : return BORDER_STYLE_HAIRLINE;
+ case BORDER_DOUBLE : return BORDER_STYLE_DOUBLE;
+ case BORDER_DOT_DASH : return BORDER_STYLE_DOT_DASH;
+ case BORDER_DOT_DOT_DASH : return BORDER_STYLE_DOT_DOT_DASH;
+ case BORDER_TRIPLE : return BORDER_STYLE_TRIPLE;
+ case BORDER_THICK_THIN : return BORDER_STYLE_THICK_THIN;
+ case BORDER_THIN_THICK : return BORDER_STYLE_THIN_THICK;
+ case BORDER_THIN_THICK_THIN : return BORDER_STYLE_THIN_THICK_THIN;
+ case BORDER_THICK_THIN_MED : return BORDER_STYLE_THICK_THIN_MED;
+ case BORDER_THIN_THICK_MED : return BORDER_STYLE_THIN_THICK_MED;
+ case BORDER_THIN_THICK_THIN_MED : return BORDER_STYLE_THIN_THICK_THIN_MED;
+ case BORDER_THICK_THIN_LARGE : return BORDER_STYLE_THICK_THIN_LARGE;
+ case BORDER_THIN_THICK_LARGE : return BORDER_STYLE_THIN_THICK_LARGE;
+ case BORDER_THIN_THICK_THIN_LARGE : return BORDER_STYLE_THIN_THICK_THIN_LARGE;
+ case BORDER_WAVY : return BORDER_STYLE_WAVY;
+ case BORDER_DOUBLE_WAVY : return BORDER_STYLE_DOUBLE_WAVY;
+ case BORDER_STRIPED : return BORDER_STYLE_STRIPED;
+ case BORDER_EMBOSS : return BORDER_STYLE_EMBOSS;
+ case BORDER_ENGRAVE : return BORDER_STYLE_ENGRAVE;
+ default : return BORDER_STYLE_SINGLE;
+ }
+ }
+
+ /**
+ * Gets the colour of this RtfBorder
+ *
+ * @return Returns RtfColor of this RtfBorder
+ */
+ protected RtfColor GetBorderColor() {
+ return borderColor;
+ }
+
+ /**
+ * Gets the position of this RtfBorder
+ * @return Returns the position of this RtfBorder
+ */
+ protected int GetBorderPosition() {
+ return borderPosition;
+ }
+
+ /**
+ * Gets the style of this RtfBorder
+ *
+ * @return Returns the style of this RtfBorder
+ */
+ protected int GetBorderStyle() {
+ return borderStyle;
+ }
+
+ /**
+ * Gets the type of this RtfBorder
+ *
+ * @return Returns the type of this RtfBorder
+ */
+ protected int GetBorderType() {
+ return borderType;
+ }
+
+ /**
+ * Gets the width of this RtfBorder
+ *
+ * @return Returns the width of this RtfBorder
+ */
+ protected int GetBorderWidth() {
+ return borderWidth;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/table/RtfBorderGroup.cs b/iTechSharp/iTextSharp/text/rtf/table/RtfBorderGroup.cs
new file mode 100644
index 0000000..d3a7f5d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/table/RtfBorderGroup.cs
@@ -0,0 +1,213 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfBorderGroup.cs,v 1.5 2008/05/16 19:31:18 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.table {
+
+ /**
+ * The RtfBorderGroup represents a collection of RtfBorders to use in a RtfCell
+ * or RtfTable.
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfBorderGroup : RtfElement {
+ /**
+ * The type of borders this RtfBorderGroup contains.
+ * RtfBorder.ROW_BORDER or RtfBorder.CELL_BORDER
+ */
+ private int borderType = RtfBorder.ROW_BORDER;
+ /**
+ * The borders in this RtfBorderGroup
+ */
+ private Hashtable borders = null;
+
+ /**
+ * Constructs an empty RtfBorderGroup.
+ */
+ public RtfBorderGroup() : base(null) {
+ this.borders = new Hashtable();
+ }
+
+ /**
+ * Constructs a RtfBorderGroup with on border style for multiple borders.
+ *
+ * @param bordersToAdd The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX)
+ * @param borderStyle The style of border to add (from RtfBorder)
+ * @param borderWidth The border width to use
+ * @param borderColor The border color to use
+ */
+ public RtfBorderGroup(int bordersToAdd, int borderStyle, float borderWidth, Color borderColor) : base(null) {
+ this.borders = new Hashtable();
+ AddBorder(bordersToAdd, borderStyle, borderWidth, borderColor);
+ }
+
+ /**
+ * Constructs a RtfBorderGroup based on another RtfBorderGroup.
+ *
+ * @param doc The RtfDocument this RtfBorderGroup belongs to
+ * @param borderType The type of borders this RtfBorderGroup contains
+ * @param borderGroup The RtfBorderGroup to use as a base
+ */
+ protected internal RtfBorderGroup(RtfDocument doc, int borderType, RtfBorderGroup borderGroup) : base(doc) {
+ this.borders = new Hashtable();
+ this.borderType = borderType;
+ if (borderGroup != null) {
+ foreach (DictionaryEntry entry in borderGroup.GetBorders()) {
+ int borderPos = (int)entry.Key;
+ RtfBorder border = (RtfBorder)entry.Value;
+ this.borders[borderPos] = new RtfBorder(this.document, this.borderType, border);
+ }
+ }
+ }
+
+ /**
+ * Constructs a RtfBorderGroup with certain borders
+ *
+ * @param doc The RtfDocument this RtfBorderGroup belongs to
+ * @param borderType The type of borders this RtfBorderGroup contains
+ * @param bordersToUse The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX)
+ * @param borderWidth The border width to use
+ * @param borderColor The border color to use
+ */
+ protected internal RtfBorderGroup(RtfDocument doc, int borderType, int bordersToUse, float borderWidth, Color borderColor) : base(doc) {
+ this.borderType = borderType;
+ this.borders = new Hashtable();
+ AddBorder(bordersToUse, RtfBorder.BORDER_SINGLE, borderWidth, borderColor);
+ }
+
+ /**
+ * Sets a border in the Hashtable of borders
+ *
+ * @param borderPosition The position of this RtfBorder
+ * @param borderStyle The type of borders this RtfBorderGroup contains
+ * @param borderWidth The border width to use
+ * @param borderColor The border color to use
+ */
+ private void SetBorder(int borderPosition, int borderStyle, float borderWidth, Color borderColor) {
+ RtfBorder border = new RtfBorder(this.document, this.borderType, borderPosition, borderStyle, borderWidth, borderColor);
+ this.borders[borderPosition] = border;
+ }
+
+ /**
+ * Adds borders to the RtfBorderGroup
+ *
+ * @param bordersToAdd The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX)
+ * @param borderStyle The style of border to add (from RtfBorder)
+ * @param borderWidth The border width to use
+ * @param borderColor The border color to use
+ */
+ public void AddBorder(int bordersToAdd, int borderStyle, float borderWidth, Color borderColor) {
+ if ((bordersToAdd & Rectangle.LEFT_BORDER) == Rectangle.LEFT_BORDER) {
+ SetBorder(RtfBorder.LEFT_BORDER, borderStyle, borderWidth, borderColor);
+ }
+ if ((bordersToAdd & Rectangle.TOP_BORDER) == Rectangle.TOP_BORDER) {
+ SetBorder(RtfBorder.TOP_BORDER, borderStyle, borderWidth, borderColor);
+ }
+ if ((bordersToAdd & Rectangle.RIGHT_BORDER) == Rectangle.RIGHT_BORDER) {
+ SetBorder(RtfBorder.RIGHT_BORDER, borderStyle, borderWidth, borderColor);
+ }
+ if ((bordersToAdd & Rectangle.BOTTOM_BORDER) == Rectangle.BOTTOM_BORDER) {
+ SetBorder(RtfBorder.BOTTOM_BORDER, borderStyle, borderWidth, borderColor);
+ }
+ if ((bordersToAdd & Rectangle.BOX) == Rectangle.BOX && this.borderType == RtfBorder.ROW_BORDER) {
+ SetBorder(RtfBorder.VERTICAL_BORDER, borderStyle, borderWidth, borderColor);
+ SetBorder(RtfBorder.HORIZONTAL_BORDER, borderStyle, borderWidth, borderColor);
+ }
+ }
+
+ /**
+ * Removes borders from the list of borders
+ *
+ * @param bordersToRemove The borders to remove (from Rectangle)
+ */
+ public void RemoveBorder(int bordersToRemove) {
+ if ((bordersToRemove & Rectangle.LEFT_BORDER) == Rectangle.LEFT_BORDER) {
+ this.borders.Remove(RtfBorder.LEFT_BORDER);
+ }
+ if ((bordersToRemove & Rectangle.TOP_BORDER) == Rectangle.TOP_BORDER) {
+ this.borders.Remove(RtfBorder.TOP_BORDER);
+ }
+ if ((bordersToRemove & Rectangle.RIGHT_BORDER) == Rectangle.RIGHT_BORDER) {
+ this.borders.Remove(RtfBorder.RIGHT_BORDER);
+ }
+ if ((bordersToRemove & Rectangle.BOTTOM_BORDER) == Rectangle.BOTTOM_BORDER) {
+ this.borders.Remove(RtfBorder.BOTTOM_BORDER);
+ }
+ if ((bordersToRemove & Rectangle.BOX) == Rectangle.BOX && this.borderType == RtfBorder.ROW_BORDER) {
+ this.borders.Remove(RtfBorder.VERTICAL_BORDER);
+ this.borders.Remove(RtfBorder.HORIZONTAL_BORDER);
+ }
+ }
+
+ /**
+ * Writes the borders of this RtfBorderGroup
+ */
+ public override void WriteContent(Stream result) {
+ foreach (RtfBorder rb in this.borders.Values) {
+ rb.WriteContent(result);
+ }
+ }
+
+ /**
+ * Gets the RtfBorders of this RtfBorderGroup
+ *
+ * @return The RtfBorders of this RtfBorderGroup
+ */
+ protected internal Hashtable GetBorders() {
+ return this.borders;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/table/RtfCell.cs b/iTechSharp/iTextSharp/text/rtf/table/RtfCell.cs
new file mode 100644
index 0000000..f597586
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/table/RtfCell.cs
@@ -0,0 +1,493 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.util;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.style;
+using iTextSharp.text.rtf.text;
+/*
+ * $Id: RtfCell.cs,v 1.14 2008/05/16 19:31:18 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.table {
+
+ /**
+ * The RtfCell wraps a Cell, but can also be added directly to a Table.
+ * The RtfCell is an extension of Cell, that supports a multitude of different
+ * borderstyles.
+ *
+ * @version $Id: RtfCell.cs,v 1.14 2008/05/16 19:31:18 psoares33 Exp $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen Stundzig
+ * @author Benoit WIART True
if this RtfCell is in a header, false
otherwise
+ */
+ public void SetInHeader(bool inHeader) {
+ this.inHeader = inHeader;
+ for (int i = 0; i < this.content.Count; i++) {
+ ((IRtfBasicElement) this.content[i]).SetInHeader(inHeader);
+ }
+ }
+
+ /**
+ * Gets whether this RtfCell
is in a header
+ *
+ * @return True
if this RtfCell
is in a header, false
otherwise
+ */
+ public bool IsInHeader() {
+ return this.inHeader;
+ }
+
+ /**
+ * Transforms an integer into its String representation and then returns the bytes
+ * of that string.
+ *
+ * @param i The integer to convert
+ * @return A byte array representing the integer
+ */
+ private byte[] IntToByteArray(int i) {
+ return DocWriter.GetISOBytes(i.ToString());
+ }
+
+ /**
+ * Checks whether this RtfCell is a placeholder for
+ * a table cell that has been removed due to col/row spanning.
+ *
+ * @return True
if this RtfCell is deleted, false
otherwise.
+ */
+ public bool IsDeleted() {
+ return this.deleted;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/table/RtfRow.cs b/iTechSharp/iTextSharp/text/rtf/table/RtfRow.cs
new file mode 100644
index 0000000..8c41d6c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/table/RtfRow.cs
@@ -0,0 +1,377 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+/*
+ * $Id: RtfRow.cs,v 1.10 2008/05/16 19:31:19 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.table {
+
+ /**
+ * The RtfRow wraps one Row for a RtfTable.
+ * INTERNAL USE ONLY
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen Stundzig
+ * @author Lorenz Maierhofer OutputStream
to write the definitions to.
+ */
+ private void WriteRowDefinition(Stream result) {
+ byte[] t;
+ result.Write(ROW_BEGIN, 0, ROW_BEGIN.Length);
+ result.WriteByte((byte)'\n');
+ result.Write(ROW_WIDTH_STYLE, 0, ROW_WIDTH_STYLE.Length);
+ result.Write(ROW_WIDTH, 0, ROW_WIDTH.Length);
+ result.Write(t = IntToByteArray(this.width), 0, t.Length);
+ if (this.parentTable.GetCellsFitToPage()) {
+ result.Write(ROW_KEEP_TOGETHER, 0, ROW_KEEP_TOGETHER.Length);
+ }
+ if (this.rowNumber <= this.parentTable.GetHeaderRows()) {
+ result.Write(ROW_HEADER_ROW, 0, ROW_HEADER_ROW.Length);
+ }
+ switch (this.parentTable.GetAlignment()) {
+ case Element.ALIGN_LEFT:
+ result.Write(ROW_ALIGN_LEFT, 0, ROW_ALIGN_LEFT.Length);
+ break;
+ case Element.ALIGN_RIGHT:
+ result.Write(ROW_ALIGN_RIGHT, 0, ROW_ALIGN_RIGHT.Length);
+ break;
+ case Element.ALIGN_CENTER:
+ result.Write(ROW_ALIGN_CENTER, 0, ROW_ALIGN_CENTER.Length);
+ break;
+ case Element.ALIGN_JUSTIFIED:
+ case Element.ALIGN_JUSTIFIED_ALL:
+ result.Write(ROW_ALIGN_JUSTIFIED, 0, ROW_ALIGN_JUSTIFIED.Length);
+ break;
+ }
+ result.Write(ROW_GRAPH, 0, ROW_GRAPH.Length);
+
+ this.parentTable.GetBorders().WriteContent(result);
+
+ if (this.parentTable.GetCellSpacing() > 0) {
+ result.Write(ROW_CELL_SPACING_LEFT, 0, ROW_CELL_SPACING_LEFT.Length);
+ result.Write(t = IntToByteArray((int) (this.parentTable.GetCellSpacing() / 2)), 0, t.Length);
+ result.Write(ROW_CELL_SPACING_LEFT_STYLE, 0, ROW_CELL_SPACING_LEFT_STYLE.Length);
+ result.Write(ROW_CELL_SPACING_TOP, 0, ROW_CELL_SPACING_TOP.Length);
+ result.Write(t = IntToByteArray((int) (this.parentTable.GetCellSpacing() / 2)), 0, t.Length);
+ result.Write(ROW_CELL_SPACING_TOP_STYLE, 0, ROW_CELL_SPACING_TOP_STYLE.Length);
+ result.Write(ROW_CELL_SPACING_RIGHT, 0, ROW_CELL_SPACING_RIGHT.Length);
+ result.Write(t = IntToByteArray((int) (this.parentTable.GetCellSpacing() / 2)), 0, t.Length);
+ result.Write(ROW_CELL_SPACING_RIGHT_STYLE, 0, ROW_CELL_SPACING_RIGHT_STYLE.Length);
+ result.Write(ROW_CELL_SPACING_BOTTOM, 0, ROW_CELL_SPACING_BOTTOM.Length);
+ result.Write(t = IntToByteArray((int) (this.parentTable.GetCellSpacing() / 2)), 0, t.Length);
+ result.Write(ROW_CELL_SPACING_BOTTOM_STYLE, 0, ROW_CELL_SPACING_BOTTOM_STYLE.Length);
+ }
+
+ result.Write(ROW_CELL_PADDING_LEFT, 0, ROW_CELL_PADDING_LEFT.Length);
+ result.Write(t = IntToByteArray((int) (this.parentTable.GetCellPadding() / 2)), 0, t.Length);
+ result.Write(ROW_CELL_PADDING_RIGHT, 0, ROW_CELL_PADDING_RIGHT.Length);
+ result.Write(t = IntToByteArray((int) (this.parentTable.GetCellPadding() / 2)), 0, t.Length);
+ result.Write(ROW_CELL_PADDING_LEFT_STYLE, 0, ROW_CELL_PADDING_LEFT_STYLE.Length);
+ result.Write(ROW_CELL_PADDING_RIGHT_STYLE, 0, ROW_CELL_PADDING_RIGHT_STYLE.Length);
+
+ result.WriteByte((byte)'\n');
+
+ for (int i = 0; i < this.cells.Count; i++) {
+ RtfCell rtfCell = (RtfCell) this.cells[i];
+ rtfCell.WriteDefinition(result);
+ }
+ }
+
+ /**
+ * Writes the content of this RtfRow
+ */
+ public override void WriteContent(Stream result) {
+ WriteRowDefinition(result);
+
+ for (int i = 0; i < this.cells.Count; i++) {
+ RtfCell rtfCell = (RtfCell) this.cells[i];
+ rtfCell.WriteContent(result);
+ }
+
+ result.Write(DELIMITER, 0, DELIMITER.Length);
+
+ if (this.document.GetDocumentSettings().IsOutputTableRowDefinitionAfter()) {
+ WriteRowDefinition(result);
+ }
+
+ result.Write(ROW_END, 0, ROW_END.Length);
+ result.WriteByte((byte)'\n');
+ }
+
+ /**
+ * Gets the parent RtfTable of this RtfRow
+ *
+ * @return The parent RtfTable of this RtfRow
+ */
+ protected internal RtfTable GetParentTable() {
+ return this.parentTable;
+ }
+
+ /**
+ * Gets the cells of this RtfRow
+ *
+ * @return The cells of this RtfRow
+ */
+ protected internal ArrayList GetCells() {
+ return this.cells;
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/table/RtfTable.cs b/iTechSharp/iTextSharp/text/rtf/table/RtfTable.cs
new file mode 100644
index 0000000..f6a8589
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/table/RtfTable.cs
@@ -0,0 +1,271 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.text;
+using iTextSharp.text.rtf.style;
+/*
+ * $Id: RtfTable.cs,v 1.9 2008/05/23 17:24:29 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.table {
+
+ /**
+ * The RtfTable wraps a Table.
+ * INTERNAL USE ONLY
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen Stundzig
+ * @author Benoit WIART True
if this RtfPhrase is in a table, false
otherwise
+ */
+ public override void SetInTable(bool inTable) {
+ base.SetInTable(inTable);
+ for (int i = 0; i < this.chunks.Count; i++) {
+ ((IRtfBasicElement) this.chunks[i]).SetInTable(inTable);
+ }
+ }
+
+ /**
+ * Sets whether this RtfPhrase is in a header. Sets the correct inTable setting for all
+ * child elements.
+ *
+ * @param inHeader True
if this RtfPhrase is in a header, false
otherwise
+ */
+ public override void SetInHeader(bool inHeader) {
+ base.SetInHeader(inHeader);
+ for (int i = 0; i < this.chunks.Count; i++) {
+ ((IRtfBasicElement) this.chunks[i]).SetInHeader(inHeader);
+ }
+ }
+
+ /**
+ * Sets the RtfDocument this RtfPhrase belongs to. Also sets the RtfDocument for all child
+ * elements.
+ *
+ * @param doc The RtfDocument to use
+ */
+ public override void SetRtfDocument(RtfDocument doc) {
+ base.SetRtfDocument(doc);
+ for (int i = 0; i < this.chunks.Count; i++) {
+ ((IRtfBasicElement) this.chunks[i]).SetRtfDocument(this.document);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/text/RtfSection.cs b/iTechSharp/iTextSharp/text/rtf/text/RtfSection.cs
new file mode 100644
index 0000000..e6c2f9d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/text/RtfSection.cs
@@ -0,0 +1,183 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Text;
+using iTextSharp.text;
+using iTextSharp.text.rtf.document;
+using iTextSharp.text.rtf.field;
+using FD = iTextSharp.text.rtf.field;
+using iTextSharp.text.rtf;
+/*
+ * $Id: RtfSection.cs,v 1.9 2008/05/16 19:31:24 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.text {
+
+ /**
+ * The RtfSection wraps a Section element.
+ * INTERNAL CLASS
+ *
+ * @version $Version:$
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfSection : RtfElement {
+
+ /**
+ * The title paragraph of this RtfSection
+ */
+ protected RtfParagraph title = null;
+ /**
+ * The sub-items of this RtfSection
+ */
+ protected ArrayList items = null;
+
+ /**
+ * Constructs a RtfSection for a given Section. If the autogenerateTOCEntries
+ * property of the RtfDocument is set and the title is not empty then a TOC entry
+ * is generated for the title.
+ *
+ * @param doc The RtfDocument this RtfSection belongs to
+ * @param section The Section this RtfSection is based on
+ */
+ public RtfSection(RtfDocument doc, Section section) : base(doc) {
+ items = new ArrayList();
+ try {
+ if (section.Title != null) {
+ this.title = (RtfParagraph) doc.GetMapper().MapElement(section.Title)[0];
+ }
+ if (document.GetAutogenerateTOCEntries()) {
+ StringBuilder titleText = new StringBuilder();
+ foreach (IElement element in section.Title) {
+ if (element.Type == Element.CHUNK) {
+ titleText.Append(((Chunk) element).Content);
+ }
+ }
+ if (titleText.ToString().Trim().Length > 0) {
+ FD.RtfTOCEntry tocEntry = new FD.RtfTOCEntry(titleText.ToString());
+ tocEntry.SetRtfDocument(this.document);
+ this.items.Add(tocEntry);
+ }
+ }
+ foreach (IElement element in section) {
+ IRtfBasicElement[] rtfElements = doc.GetMapper().MapElement(element);
+ for (int i = 0; i < rtfElements.Length; i++) {
+ if (rtfElements[i] != null) {
+ items.Add(rtfElements[i]);
+ }
+ }
+ }
+ UpdateIndentation(section.IndentationLeft, section.IndentationRight, section.Indentation);
+ } catch (DocumentException) {
+ }
+ }
+
+ /**
+ * Write this RtfSection and its contents
+ */
+ public override void WriteContent(Stream result) {
+ result.Write(RtfParagraph.PARAGRAPH, 0, RtfParagraph.PARAGRAPH.Length);
+ if (this.title != null) {
+ this.title.WriteContent(result);
+ }
+ foreach (IRtfBasicElement rbe in items) {
+ rbe.WriteContent(result);
+ }
+ }
+
+ /**
+ * Sets whether this RtfSection is in a table. Sets the correct inTable setting for all
+ * child elements.
+ *
+ * @param inTable True
if this RtfSection is in a table, false
otherwise
+ */
+ public override void SetInTable(bool inTable) {
+ base.SetInTable(inTable);
+ for (int i = 0; i < this.items.Count; i++) {
+ ((IRtfBasicElement) this.items[i]).SetInTable(inTable);
+ }
+ }
+
+ /**
+ * Sets whether this RtfSection is in a header. Sets the correct inTable setting for all
+ * child elements.
+ *
+ * @param inHeader True
if this RtfSection is in a header, false
otherwise
+ */
+ public override void SetInHeader(bool inHeader) {
+ base.SetInHeader(inHeader);
+ for (int i = 0; i < this.items.Count; i++) {
+ ((IRtfBasicElement) this.items[i]).SetInHeader(inHeader);
+ }
+ }
+
+ /**
+ * Updates the left, right and content indentation of all RtfParagraph and RtfSection
+ * elements that this RtfSection contains.
+ *
+ * @param indentLeft The left indentation to add.
+ * @param indentRight The right indentation to add.
+ * @param indentContent The content indentation to add.
+ */
+ private void UpdateIndentation(float indentLeft, float indentRight, float indentContent) {
+ if(this.title != null) {
+ this.title.SetIndentLeft((int) (this.title.GetIndentLeft() + indentLeft * RtfElement.TWIPS_FACTOR));
+ this.title.SetIndentRight((int) (this.title.GetIndentRight() + indentRight * RtfElement.TWIPS_FACTOR));
+ }
+ for(int i = 0; i < this.items.Count; i++) {
+ IRtfBasicElement rtfElement = (IRtfBasicElement) this.items[i];
+ if(rtfElement is RtfSection) {
+ ((RtfSection) rtfElement).UpdateIndentation(indentLeft + indentContent, indentRight, 0);
+ } else if(rtfElement is RtfParagraph) {
+ ((RtfParagraph) rtfElement).SetIndentLeft((int) (((RtfParagraph) rtfElement).GetIndentLeft() + (indentLeft + indentContent) * RtfElement.TWIPS_FACTOR));
+ ((RtfParagraph) rtfElement).SetIndentRight((int) (((RtfParagraph) rtfElement).GetIndentRight() + indentRight * RtfElement.TWIPS_FACTOR));
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/text/RtfTab.cs b/iTechSharp/iTextSharp/text/rtf/text/RtfTab.cs
new file mode 100644
index 0000000..1f5a196
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/text/RtfTab.cs
@@ -0,0 +1,135 @@
+using System;
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/*
+ * $Id: RtfTab.cs,v 1.5 2008/05/23 17:24:29 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are
+ * Copyright (C) 2006 by Mark Hall. All Rights Reserved
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.text {
+
+ /**
+ * The RtfTab encapsulates a tab position and tab type in a paragraph.
+ * To add tabs to a paragraph construct new RtfTab objects with the desired
+ * tab position and alignment and then add them to the paragraph. In the actual
+ * text the tabs are then defined as standard \t characters.
+ *
+ * RtfTab tab = new RtfTab(300, RtfTab.TAB_LEFT_ALIGN);
+ *
+ * @version $Revision: 1.5 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfTab : RtfAddableElement {
+
+ /**
+ * A tab where the text is left aligned.
+ */
+ public const int TAB_LEFT_ALIGN = 0;
+ /**
+ * A tab where the text is centre aligned.
+ */
+ public const int TAB_CENTER_ALIGN = 1;
+ /**
+ * A tab where the text is right aligned.
+ */
+ public const int TAB_RIGHT_ALIGN = 2;
+ /**
+ * A tab where the text is aligned on the decimal character. Which
+ * character that is depends on the language settings of the viewer.
+ */
+ public const int TAB_DECIMAL_ALIGN = 3;
+
+ /**
+ * The tab position in twips.
+ */
+ private int position = 0;
+ /**
+ * The tab alignment.
+ */
+ private int type = TAB_LEFT_ALIGN;
+
+ /**
+ * Constructs a new RtfTab with the given position and type. The position
+ * is in standard iText points. The type is one of the tab alignment
+ * constants defined in the RtfTab.
+ *
+ * @param position The position of the tab in points.
+ * @param type The tab type constant.
+ */
+ public RtfTab(float position, int type) {
+ this.position = (int) Math.Round(position * RtfElement.TWIPS_FACTOR);
+ switch (type) {
+ case TAB_LEFT_ALIGN: this.type = TAB_LEFT_ALIGN; break;
+ case TAB_CENTER_ALIGN: this.type = TAB_CENTER_ALIGN; break;
+ case TAB_RIGHT_ALIGN: this.type = TAB_RIGHT_ALIGN; break;
+ case TAB_DECIMAL_ALIGN: this.type = TAB_DECIMAL_ALIGN; break;
+ default: this.type = TAB_LEFT_ALIGN; break;
+ }
+ }
+
+ /**
+ * Writes the tab settings.
+ */
+ public override void WriteContent(Stream result) {
+ byte[] t;
+ switch (this.type) {
+ case TAB_CENTER_ALIGN: result.Write(t = DocWriter.GetISOBytes("\\tqc"), 0, t.Length); break;
+ case TAB_RIGHT_ALIGN: result.Write(t = DocWriter.GetISOBytes("\\tqr"), 0, t.Length); break;
+ case TAB_DECIMAL_ALIGN: result.Write(t = DocWriter.GetISOBytes("\\tqdec"), 0, t.Length); break;
+ }
+ result.Write(t = DocWriter.GetISOBytes("\\tx"), 0, t.Length);
+ result.Write(t = IntToByteArray(this.position), 0, t.Length);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/rtf/text/RtfTabGroup.cs b/iTechSharp/iTextSharp/text/rtf/text/RtfTabGroup.cs
new file mode 100644
index 0000000..c51689d
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/rtf/text/RtfTabGroup.cs
@@ -0,0 +1,121 @@
+using System;
+using System.IO;
+using System.Collections;
+using iTextSharp.text;
+using iTextSharp.text.rtf;
+/*
+ * $Id: RtfTabGroup.cs,v 1.5 2008/05/23 17:24:29 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are
+ * Copyright (C) 2006 by Mark Hall. All Rights Reserved
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.rtf.text {
+
+ /**
+ * The RtfTabGroup is a convenience class if the same tabs are to be added
+ * to multiple paragraphs.
+ * Paragraph para = new Paragraph();
+ * para.Add(tab);
+ * para.Add("This paragraph has a\ttab defined.");
+ *
+ * RtfTabGroup tabs = new RtfTabGroup();
+ *
+ * @version $Revision: 1.5 $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+ public class RtfTabGroup : RtfAddableElement {
+ /**
+ * The tabs to add.
+ */
+ private ArrayList tabs = null;
+
+ /**
+ * Constructs an empty RtfTabGroup.
+ */
+ public RtfTabGroup() {
+ this.tabs = new ArrayList();
+ }
+
+ /**
+ * Constructs a RtfTabGroup with a set of tabs.
+ *
+ * @param tabs An ArrayList with the RtfTabs to group in this RtfTabGroup.
+ */
+ public RtfTabGroup(ArrayList tabs) {
+ this.tabs = new ArrayList();
+ for (int i = 0; i < tabs.Count; i++) {
+ if (tabs[i] is RtfTab) {
+ this.tabs.Add(tabs[i]);
+ }
+ }
+ }
+
+ /**
+ * Adds a RtfTab to the list of grouped tabs.
+ *
+ * @param tab The RtfTab to add.
+ */
+ public void Add(RtfTab tab) {
+ this.tabs.Add(tab);
+ }
+
+ /**
+ * Combines the tab output form all grouped tabs.
+ */
+ public override void WriteContent(Stream result) {
+ foreach (RtfTab rt in tabs) {
+ rt.WriteContent(result);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/xml/ITextHandler.cs b/iTechSharp/iTextSharp/text/xml/ITextHandler.cs
new file mode 100644
index 0000000..eb7d80c
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/xml/ITextHandler.cs
@@ -0,0 +1,872 @@
+using System;
+using System.Collections;
+using System.util;
+using System.Text;
+using System.Xml;
+
+using iTextSharp.text;
+using iTextSharp.text.pdf;
+using iTextSharp.text.pdf.draw;
+using iTextSharp.text.xml.simpleparser;
+using iTextSharp.text.html;
+using iTextSharp.text.factories;
+
+/*
+ * $Id: ITextHandler.cs,v 1.21 2008/05/13 11:26:11 psoares33 Exp $
+ *
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.xml {
+
+ ///
+ * tabs.Add(new RtfTab(70, RtfTab.TAB_LEFT_ALIGN));
+ * tabs.Add(new RtfTab(160, RtfTab.TAB_CENTER_ALIGN));
+ * tabs.Add(new RtfTab(250, RtfTab.TAB_DECIMAL_ALIGN));
+ * tabs.Add(new RtfTab(500, RtfTab.TAB_RIGHT_ALIGN));
+ * Paragraph para = new Paragraph();
+ * para.Add(tabs);
+ * para.Add("\tLeft aligned\tCentre aligned\t12,45\tRight aligned");iTextHandler
-class maps several XHTML-tags to iText-objects.
+ /// Stack
of objects, waiting to be added to the document. Document
-object.
+ /// true
or false
true
or false
true
if tag equals itext
, false
otherwise.iTextmyHandler
-class maps several XHTML-tags to iText-objects.
+ /// Document
-object.
+ /// ParserBase
-class provides XML document parsing.
+ /// TagMap
-class maps several XHTML-tags to iText-objects.
+ /// Document
-object.
+ /// SimpleXMLParser
.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public interface ISimpleXMLDocHandler {
+ /**
+ * Called when a start tag is found.
+ * @param tag the tag name
+ * @param h the tag's attributes
+ */
+ void StartElement(String tag, Hashtable h);
+ /**
+ * Called when an end tag is found.
+ * @param tag the tag name
+ */
+ void EndElement(String tag);
+ /**
+ * Called when the document starts to be parsed.
+ */
+ void StartDocument();
+ /**
+ * Called after the document is parsed.
+ */
+ void EndDocument();
+ /**
+ * Called when a text element is found.
+ * @param str the text element, probably a fragment.
+ */
+ void Text(String str);
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/xml/simpleparser/ISimpleXMLDocHandlerComment.cs b/iTechSharp/iTextSharp/text/xml/simpleparser/ISimpleXMLDocHandlerComment.cs
new file mode 100644
index 0000000..e4042e7
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/xml/simpleparser/ISimpleXMLDocHandlerComment.cs
@@ -0,0 +1,61 @@
+using System;
+/*
+ * Copyright 2003 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.xml.simpleparser {
+ /**
+ * The handler for the events fired by SimpleXMLParser
.
+ * @author Paulo Soares (psoares@consiste.pt)
+ */
+ public interface ISimpleXMLDocHandlerComment {
+ /**
+ * Called when a comment is found.
+ * @param text the comment text
+ */
+ void Comment(String text);
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/xml/simpleparser/IanaEncodings.cs b/iTechSharp/iTextSharp/text/xml/simpleparser/IanaEncodings.cs
new file mode 100644
index 0000000..c4fda86
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/xml/simpleparser/IanaEncodings.cs
@@ -0,0 +1,551 @@
+using System;
+using System.Collections;
+using System.Text;
+/*
+ * $Id: IanaEncodings.cs,v 1.4 2008/05/13 11:26:14 psoares33 Exp $
+ *
+ *
+ * Copyright 2003-2007 Paulo Soares and Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ *
+ * The values used in this class are based on class org.apache.xercis.util.EncodingMap
+ * http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xerces/util/EncodingMap.java?view=markup
+ * This class was originally published under the following license:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace iTextSharp.text.xml.simpleparser {
+
+ /**
+ * Translates a IANA encoding name to a Java encoding.
+ */
+
+ public class IanaEncodings {
+
+ /** The object that maps IANA to Java encodings. */
+ private static readonly Hashtable map = new Hashtable();
+
+ static IanaEncodings() {
+ // add IANA to .NET encoding mappings.
+ map["CP037"] = 37;
+ map["CSIBM037"] = 37;
+ map["EBCDIC-CP-CA"] = 37;
+ map["EBCDIC-CP-NL"] = 37;
+ map["EBCDIC-CP-US"] = 37;
+ map["EBCDIC-CP-WT"] = 37;
+ map["IBM037"] = 37;
+ map["CP437"] = 437;
+ map["CSPC8CODEPAGE437"] = 437;
+ map["IBM437"] = 437;
+ map["CP500"] = 500;
+ map["CSIBM500"] = 500;
+ map["EBCDIC-CP-BE"] = 500;
+ map["EBCDIC-CP-CH"] = 500;
+ map["IBM500"] = 500;
+ map["ASMO-708"] = 708;
+ map["DOS-720"] = 720;
+ map["IBM737"] = 737;
+ map["IBM775"] = 775;
+ map["CP850"] = 850;
+ map["IBM850"] = 850;
+ map["CP852"] = 852;
+ map["IBM852"] = 852;
+ map["CP855"] = 855;
+ map["IBM855"] = 855;
+ map["CP857"] = 857;
+ map["IBM857"] = 857;
+ map["CCSID00858"] = 858;
+ map["CP00858"] = 858;
+ map["CP858"] = 858;
+ map["IBM00858"] = 858;
+ map["PC-MULTILINGUAL-850+EURO"] = 858;
+ map["CP860"] = 860;
+ map["IBM860"] = 860;
+ map["CP861"] = 861;
+ map["IBM861"] = 861;
+ map["CP862"] = 862;
+ map["DOS-862"] = 862;
+ map["IBM862"] = 862;
+ map["CP863"] = 863;
+ map["IBM863"] = 863;
+ map["CP864"] = 864;
+ map["IBM864"] = 864;
+ map["CP865"] = 865;
+ map["IBM865"] = 865;
+ map["CP866"] = 866;
+ map["IBM866"] = 866;
+ map["CP869"] = 869;
+ map["IBM869"] = 869;
+ map["CP870"] = 870;
+ map["CSIBM870"] = 870;
+ map["EBCDIC-CP-ROECE"] = 870;
+ map["EBCDIC-CP-YU"] = 870;
+ map["IBM870"] = 870;
+ map["DOS-874"] = 874;
+ map["ISO-8859-11"] = 874;
+ map["MS874"] = 874;
+ map["TIS620"] = 874;
+ map["TIS-620"] = 874;
+ map["WINDOWS-874"] = 874;
+ map["CP875"] = 875;
+ map["CSSHIFTJIS"] = 932;
+ map["CSWINDOWS31J"] = 932;
+ map["MS932"] = 932;
+ map["MS_KANJI"] = 932;
+ map["SHIFT-JIS"] = 932;
+ map["SHIFT_JIS"] = 932;
+ map["SJIS"] = 932;
+ map["X-MS-CP932"] = 932;
+ map["X-SJIS"] = 932;
+ map["CHINESE"] = 936;
+ map["CN-GB"] = 936;
+ map["CSGB2312"] = 936;
+ map["CSGB231280"] = 936;
+ map["CSISO58GB231280"] = 936;
+ map["GB2312"] = 936;
+ map["GB2312-80"] = 936;
+ map["GB231280"] = 936;
+ map["GB_2312-80"] = 936;
+ map["GBK"] = 936;
+ map["ISO-IR-58"] = 936;
+ map["MS936"] = 936;
+ map["CSKSC56011987"] = 949;
+ map["ISO-IR-149"] = 949;
+ map["KOREAN"] = 949;
+ map["KS-C-5601"] = 949;
+ map["KS-C5601"] = 949;
+ map["KS_C_5601"] = 949;
+ map["KS_C_5601-1987"] = 949;
+ map["KS_C_5601-1989"] = 949;
+ map["KS_C_5601_1987"] = 949;
+ map["KSC5601"] = 949;
+ map["KSC_5601"] = 949;
+ map["MS949"] = 949;
+ map["BIG5"] = 950;
+ map["BIG5-HKSCS"] = 950;
+ map["CN-BIG5"] = 950;
+ map["CSBIG5"] = 950;
+ map["MS950"] = 950;
+ map["X-X-BIG5"] = 950;
+ map["CP1026"] = 1026;
+ map["CSIBM1026"] = 1026;
+ map["IBM1026"] = 1026;
+ map["IBM01047"] = 1047;
+ map["CCSID01140"] = 1140;
+ map["CP01140"] = 1140;
+ map["EBCDIC-US-37+EURO"] = 1140;
+ map["IBM01140"] = 1140;
+ map["CCSID01141"] = 1141;
+ map["CP01141"] = 1141;
+ map["EBCDIC-DE-273+EURO"] = 1141;
+ map["IBM01141"] = 1141;
+ map["CCSID01142"] = 1142;
+ map["CP01142"] = 1142;
+ map["EBCDIC-DK-277+EURO"] = 1142;
+ map["EBCDIC-NO-277+EURO"] = 1142;
+ map["IBM01142"] = 1142;
+ map["CCSID01143"] = 1143;
+ map["CP01143"] = 1143;
+ map["EBCDIC-FI-278+EURO"] = 1143;
+ map["EBCDIC-SE-278+EURO"] = 1143;
+ map["IBM01143"] = 1143;
+ map["CCSID01144"] = 1144;
+ map["CP01144"] = 1144;
+ map["EBCDIC-IT-280+EURO"] = 1144;
+ map["IBM01144"] = 1144;
+ map["CCSID01145"] = 1145;
+ map["CP01145"] = 1145;
+ map["EBCDIC-ES-284+EURO"] = 1145;
+ map["IBM01145"] = 1145;
+ map["CCSID01146"] = 1146;
+ map["CP01146"] = 1146;
+ map["EBCDIC-GB-285+EURO"] = 1146;
+ map["IBM01146"] = 1146;
+ map["CCSID01147"] = 1147;
+ map["CP01147"] = 1147;
+ map["EBCDIC-FR-297+EURO"] = 1147;
+ map["IBM01147"] = 1147;
+ map["CCSID01148"] = 1148;
+ map["CP01148"] = 1148;
+ map["EBCDIC-INTERNATIONAL-500+EURO"] = 1148;
+ map["IBM01148"] = 1148;
+ map["CCSID01149"] = 1149;
+ map["CP01149"] = 1149;
+ map["EBCDIC-IS-871+EURO"] = 1149;
+ map["IBM01149"] = 1149;
+ map["ISO-10646-UCS-2"] = 1200;
+ map["UCS-2"] = 1200;
+ map["UNICODE"] = 1200;
+ map["UTF-16"] = 1200;
+ map["UTF-16LE"] = 1200;
+ map["UNICODELITTLEUNMARKED"] = 1200;
+ map["UNICODELITTLE"] = 1200;
+ map["UNICODEFFFE"] = 1201;
+ map["UTF-16BE"] = 1201;
+ map["UNICODEBIGUNMARKED"] = 1201;
+ map["UNICODEBIG"] = 1201;
+ map["CP1250"] = 1250;
+ map["WINDOWS-1250"] = 1250;
+ map["X-CP1250"] = 1250;
+ map["CP1251"] = 1251;
+ map["WINDOWS-1251"] = 1251;
+ map["X-CP1251"] = 1251;
+ map["CP1252"] = 1252;
+ map["WINDOWS-1252"] = 1252;
+ map["X-ANSI"] = 1252;
+ map["CP1253"] = 1253;
+ map["WINDOWS-1253"] = 1253;
+ map["CP1254"] = 1254;
+ map["WINDOWS-1254"] = 1254;
+ map["CP1255"] = 1255;
+ map["WINDOWS-1255"] = 1255;
+ map["CP1256"] = 1256;
+ map["WINDOWS-1256"] = 1256;
+ map["CP1257"] = 1257;
+ map["WINDOWS-1257"] = 1257;
+ map["CP1258"] = 1258;
+ map["WINDOWS-1258"] = 1258;
+ map["JOHAB"] = 1361;
+ map["MACINTOSH"] = 10000;
+ map["MACROMAN"] = 10000;
+ map["X-MAC-JAPANESE"] = 10001;
+ map["X-MAC-CHINESETRAD"] = 10002;
+ map["X-MAC-KOREAN"] = 10003;
+ map["MACARABIC"] = 10004;
+ map["X-MAC-ARABIC"] = 10004;
+ map["MACHEBREW"] = 10005;
+ map["X-MAC-HEBREW"] = 10005;
+ map["MACGREEK"] = 10006;
+ map["X-MAC-GREEK"] = 10006;
+ map["MACCYRILLIC"] = 10007;
+ map["X-MAC-CYRILLIC"] = 10007;
+ map["X-MAC-CHINESESIMP"] = 10008;
+ map["MACROMANIA"] = 10010;
+ map["MACROMANIAN"] = 10010;
+ map["X-MAC-ROMANIAN"] = 10010;
+ map["MACUKRAINE"] = 10017;
+ map["MACUKRAINIAN"] = 10017;
+ map["X-MAC-UKRAINIAN"] = 10017;
+ map["MACTHAI"] = 10021;
+ map["X-MAC-THAI"] = 10021;
+ map["MACCENTRALEUROPE"] = 10029;
+ map["X-MAC-CE"] = 10029;
+ map["MACICELANDIC"] = 10079;
+ map["MACICELAND"] = 10079;
+ map["X-MAC-ICELANDIC"] = 10079;
+ map["MACTURKISH"] = 10081;
+ map["X-MAC-TURKISH"] = 10081;
+ map["MACCROATIAN"] = 10082;
+ map["X-MAC-CROATIAN"] = 10082;
+ map["X-CHINESE-CNS"] = 20000;
+ map["X-CP20001"] = 20001;
+ map["X-CHINESE-ETEN"] = 20002;
+ map["X-CP20003"] = 20003;
+ map["X-CP20004"] = 20004;
+ map["X-CP20005"] = 20005;
+ map["IRV"] = 20105;
+ map["X-IA5"] = 20105;
+ map["DIN_66003"] = 20106;
+ map["GERMAN"] = 20106;
+ map["X-IA5-GERMAN"] = 20106;
+ map["SEN_850200_B"] = 20107;
+ map["SWEDISH"] = 20107;
+ map["X-IA5-SWEDISH"] = 20107;
+ map["NORWEGIAN"] = 20108;
+ map["NS_4551-1"] = 20108;
+ map["X-IA5-NORWEGIAN"] = 20108;
+ map["ANSI_X3.4-1968"] = 20127;
+ map["ANSI_X3.4-1986"] = 20127;
+ map["ASCII"] = 20127;
+ map["CP367"] = 20127;
+ map["CSASCII"] = 20127;
+ map["IBM367"] = 20127;
+ map["ISO-IR-6"] = 20127;
+ map["ISO646-US"] = 20127;
+ map["ISO_646.IRV:1991"] = 20127;
+ map["US"] = 20127;
+ map["US-ASCII"] = 20127;
+ map["X-CP20261"] = 20261;
+ map["X-CP20269"] = 20269;
+ map["CP273"] = 20273;
+ map["CSIBM273"] = 20273;
+ map["IBM273"] = 20273;
+ map["CSIBM277"] = 20277;
+ map["EBCDIC-CP-DK"] = 20277;
+ map["EBCDIC-CP-NO"] = 20277;
+ map["IBM277"] = 20277;
+ map["CP278"] = 20278;
+ map["CSIBM278"] = 20278;
+ map["EBCDIC-CP-FI"] = 20278;
+ map["EBCDIC-CP-SE"] = 20278;
+ map["IBM278"] = 20278;
+ map["CP280"] = 20280;
+ map["CSIBM280"] = 20280;
+ map["EBCDIC-CP-IT"] = 20280;
+ map["IBM280"] = 20280;
+ map["CP284"] = 20284;
+ map["CSIBM284"] = 20284;
+ map["EBCDIC-CP-ES"] = 20284;
+ map["IBM284"] = 20284;
+ map["CP285"] = 20285;
+ map["CSIBM285"] = 20285;
+ map["EBCDIC-CP-GB"] = 20285;
+ map["IBM285"] = 20285;
+ map["CP290"] = 20290;
+ map["CSIBM290"] = 20290;
+ map["EBCDIC-JP-KANA"] = 20290;
+ map["IBM290"] = 20290;
+ map["CP297"] = 20297;
+ map["CSIBM297"] = 20297;
+ map["EBCDIC-CP-FR"] = 20297;
+ map["IBM297"] = 20297;
+ map["CP420"] = 20420;
+ map["CSIBM420"] = 20420;
+ map["EBCDIC-CP-AR1"] = 20420;
+ map["IBM420"] = 20420;
+ map["CP423"] = 20423;
+ map["CSIBM423"] = 20423;
+ map["EBCDIC-CP-GR"] = 20423;
+ map["IBM423"] = 20423;
+ map["CP424"] = 20424;
+ map["CSIBM424"] = 20424;
+ map["EBCDIC-CP-HE"] = 20424;
+ map["IBM424"] = 20424;
+ map["X-EBCDIC-KOREANEXTENDED"] = 20833;
+ map["CSIBMTHAI"] = 20838;
+ map["IBM-THAI"] = 20838;
+ map["CSKOI8R"] = 20866;
+ map["KOI"] = 20866;
+ map["KOI8"] = 20866;
+ map["KOI8-R"] = 20866;
+ map["KOI8R"] = 20866;
+ map["CP871"] = 20871;
+ map["CSIBM871"] = 20871;
+ map["EBCDIC-CP-IS"] = 20871;
+ map["IBM871"] = 20871;
+ map["CP880"] = 20880;
+ map["CSIBM880"] = 20880;
+ map["EBCDIC-CYRILLIC"] = 20880;
+ map["IBM880"] = 20880;
+ map["CP905"] = 20905;
+ map["CSIBM905"] = 20905;
+ map["EBCDIC-CP-TR"] = 20905;
+ map["IBM905"] = 20905;
+ map["CCSID00924"] = 20924;
+ map["CP00924"] = 20924;
+ map["EBCDIC-LATIN9--EURO"] = 20924;
+ map["IBM00924"] = 20924;
+ map["X-CP20936"] = 20936;
+ map["X-CP20949"] = 20949;
+ map["CP1025"] = 21025;
+ map["X-CP21027"] = 21027;
+ map["KOI8-RU"] = 21866;
+ map["KOI8-U"] = 21866;
+ map["CP819"] = 28591;
+ map["CSISOLATIN1"] = 28591;
+ map["IBM819"] = 28591;
+ map["ISO-8859-1"] = 28591;
+ map["ISO-IR-100"] = 28591;
+ map["ISO8859-1"] = 28591;
+ map["ISO_8859-1"] = 28591;
+ map["ISO_8859-1:1987"] = 28591;
+ map["L1"] = 28591;
+ map["LATIN1"] = 28591;
+ map["CSISOLATIN2"] = 28592;
+ map["ISO-8859-2"] = 28592;
+ map["ISO-IR-101"] = 28592;
+ map["ISO8859-2"] = 28592;
+ map["ISO_8859-2"] = 28592;
+ map["ISO_8859-2:1987"] = 28592;
+ map["L2"] = 28592;
+ map["LATIN2"] = 28592;
+ map["CSISOLATIN3"] = 28593;
+ map["ISO-8859-3"] = 28593;
+ map["ISO-IR-109"] = 28593;
+ map["ISO_8859-3"] = 28593;
+ map["ISO_8859-3:1988"] = 28593;
+ map["L3"] = 28593;
+ map["LATIN3"] = 28593;
+ map["CSISOLATIN4"] = 28594;
+ map["ISO-8859-4"] = 28594;
+ map["ISO-IR-110"] = 28594;
+ map["ISO_8859-4"] = 28594;
+ map["ISO_8859-4:1988"] = 28594;
+ map["L4"] = 28594;
+ map["LATIN4"] = 28594;
+ map["CSISOLATINCYRILLIC"] = 28595;
+ map["CYRILLIC"] = 28595;
+ map["ISO-8859-5"] = 28595;
+ map["ISO-IR-144"] = 28595;
+ map["ISO_8859-5"] = 28595;
+ map["ISO_8859-5:1988"] = 28595;
+ map["ARABIC"] = 28596;
+ map["CSISOLATINARABIC"] = 28596;
+ map["ECMA-114"] = 28596;
+ map["ISO-8859-6"] = 28596;
+ map["ISO-IR-127"] = 28596;
+ map["ISO_8859-6"] = 28596;
+ map["ISO_8859-6:1987"] = 28596;
+ map["CSISOLATINGREEK"] = 28597;
+ map["ECMA-118"] = 28597;
+ map["ELOT_928"] = 28597;
+ map["GREEK"] = 28597;
+ map["GREEK8"] = 28597;
+ map["ISO-8859-7"] = 28597;
+ map["ISO-IR-126"] = 28597;
+ map["ISO_8859-7"] = 28597;
+ map["ISO_8859-7:1987"] = 28597;
+ map["CSISOLATINHEBREW"] = 28598;
+ map["HEBREW"] = 28598;
+ map["ISO-8859-8"] = 28598;
+ map["ISO-IR-138"] = 28598;
+ map["ISO_8859-8"] = 28598;
+ map["ISO_8859-8:1988"] = 28598;
+ map["LOGICAL"] = 28598;
+ map["VISUAL"] = 28598;
+ map["CSISOLATIN5"] = 28599;
+ map["ISO-8859-9"] = 28599;
+ map["ISO-IR-148"] = 28599;
+ map["ISO_8859-9"] = 28599;
+ map["ISO_8859-9:1989"] = 28599;
+ map["L5"] = 28599;
+ map["LATIN5"] = 28599;
+ map["ISO-8859-13"] = 28603;
+ map["CSISOLATIN9"] = 28605;
+ map["ISO-8859-15"] = 28605;
+ map["ISO_8859-15"] = 28605;
+ map["L9"] = 28605;
+ map["LATIN9"] = 28605;
+ map["X-EUROPA"] = 29001;
+ map["ISO-8859-8-I"] = 38598;
+ map["ISO-2022-JP"] = 50220;
+ map["CSISO2022JP"] = 50221;
+ map["CSISO2022KR"] = 50225;
+ map["ISO-2022-KR"] = 50225;
+ map["ISO-2022-KR-7"] = 50225;
+ map["ISO-2022-KR-7BIT"] = 50225;
+ map["CP50227"] = 50227;
+ map["X-CP50227"] = 50227;
+ map["CP930"] = 50930;
+ map["X-EBCDIC-JAPANESEANDUSCANADA"] = 50931;
+ map["CP933"] = 50933;
+ map["CP935"] = 50935;
+ map["CP937"] = 50937;
+ map["CP939"] = 50939;
+ map["CSEUCPKDFMTJAPANESE"] = 51932;
+ map["EUC-JP"] = 51932;
+ map["EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE"] = 51932;
+ map["ISO-2022-JPEUC"] = 51932;
+ map["X-EUC"] = 51932;
+ map["X-EUC-JP"] = 51932;
+ map["EUC-CN"] = 51936;
+ map["X-EUC-CN"] = 51936;
+ map["CSEUCKR"] = 51949;
+ map["EUC-KR"] = 51949;
+ map["ISO-2022-KR-8"] = 51949;
+ map["ISO-2022-KR-8BIT"] = 51949;
+ map["HZ-GB-2312"] = 52936;
+ map["GB18030"] = 54936;
+ map["X-ISCII-DE"] = 57002;
+ map["X-ISCII-BE"] = 57003;
+ map["X-ISCII-TA"] = 57004;
+ map["X-ISCII-TE"] = 57005;
+ map["X-ISCII-AS"] = 57006;
+ map["X-ISCII-OR"] = 57007;
+ map["X-ISCII-KA"] = 57008;
+ map["X-ISCII-MA"] = 57009;
+ map["X-ISCII-GU"] = 57010;
+ map["X-ISCII-PA"] = 57011;
+ map["CSUNICODE11UTF7"] = 65000;
+ map["UNICODE-1-1-UTF-7"] = 65000;
+ map["UNICODE-2-0-UTF-7"] = 65000;
+ map["UTF-7"] = 65000;
+ map["X-UNICODE-1-1-UTF-7"] = 65000;
+ map["X-UNICODE-2-0-UTF-7"] = 65000;
+ map["UNICODE-1-1-UTF-8"] = 65001;
+ map["UNICODE-2-0-UTF-8"] = 65001;
+ map["UTF-8"] = 65001;
+ map["X-UNICODE-1-1-UTF-8"] = 65001;
+ map["X-UNICODE-2-0-UTF-8"] = 65001;
+ }
+
+ public static int GetEncodingNumber(string name) {
+ object n = map[name.ToUpper(System.Globalization.CultureInfo.InvariantCulture)];
+ if (n == null)
+ return 0;
+ return (int)n;
+ }
+
+ public static Encoding GetEncodingEncoding(string name) {
+ String nameU = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
+ if (nameU.Equals("UNICODEBIGUNMARKED"))
+ return new UnicodeEncoding(true, false);
+ if (nameU.Equals("UNICODEBIG"))
+ return new UnicodeEncoding(true, true);
+ if (nameU.Equals("UNICODELITTLEUNMARKED"))
+ return new UnicodeEncoding(false, false);
+ if (nameU.Equals("UNICODELITTLE"))
+ return new UnicodeEncoding(false, true);
+ if (map.ContainsKey(nameU))
+ return Encoding.GetEncoding((int)map[nameU]);
+ else
+ return Encoding.GetEncoding(name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/xml/simpleparser/SimpleXMLParser.cs b/iTechSharp/iTextSharp/text/xml/simpleparser/SimpleXMLParser.cs
new file mode 100644
index 0000000..93ac6db
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/xml/simpleparser/SimpleXMLParser.cs
@@ -0,0 +1,740 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+/*
+ * Copyright 2003 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ *
+ * The code to recognize the encoding in this class and in the convenience class IanaEncodings was taken from Apache Xerces published under the following license:
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Part of this code is based on the Quick-and-Dirty XML parser by Steven Brandt.
+ * The code for the Quick-and-Dirty parser was published in JavaWorld (java tip 128).
+ * Steven Brandt and JavaWorld gave permission to use the code for free.
+ * (Bruno Lowagie and Paulo Soares chose to use it under the MPL/LGPL in
+ * conformance with the rest of the code).
+ * The original code can be found on this url: http://www.javaworld.com/javatips/jw-javatip128_p.html.
+ * It was substantially refactored by Bruno Lowagie.
+ *
+ * The method 'private static String getEncodingName(byte[] b4)' was found
+ * in org.apache.xerces.impl.XMLEntityManager, originaly published by the
+ * Apache Software Foundation under the Apache Software License; now being
+ * used in iText under the MPL.
+ */
+
+namespace iTextSharp.text.xml.simpleparser {
+ /**
+ * A simple XML and HTML parser. This parser is, like the SAX parser,
+ * an event based parser, but with much less functionality.
+ *
+ *
+ * <[CDATA[ ... ]]>
construct
+ * \r\n
and \r
to \n
on input, in accordance with the XML Specification, Section 2.11
+ * true
+ * @return the escaped string
+ */
+ public static String EscapeXML(String s, bool onlyASCII) {
+ char[] cc = s.ToCharArray();
+ int len = cc.Length;
+ StringBuilder sb = new StringBuilder();
+ for (int k = 0; k < len; ++k) {
+ int c = cc[k];
+ switch (c) {
+ case '<':
+ sb.Append("<");
+ break;
+ case '>':
+ sb.Append(">");
+ break;
+ case '&':
+ sb.Append("&");
+ break;
+ case '"':
+ sb.Append(""");
+ break;
+ case '\'':
+ sb.Append("'");
+ break;
+ default:
+ if (onlyASCII && c > 127)
+ sb.Append("").Append(c).Append(';');
+ else
+ sb.Append((char)c);
+ break;
+ }
+ }
+ return sb.ToString();
+ }
+
+ /**
+ * Returns the IANA encoding name that is auto-detected from
+ * the bytes specified, with the endian-ness of that encoding where appropriate.
+ * (method found in org.apache.xerces.impl.XMLEntityManager, originaly published
+ * by the Apache Software Foundation under the Apache Software License; now being
+ * used in iText under the MPL)
+ * @param b4 The first four bytes of the input.
+ * @return an IANA-encoding string
+ */
+ private static String GetEncodingName(byte[] b4) {
+ // UTF-16, with BOM
+ int b0 = b4[0] & 0xFF;
+ int b1 = b4[1] & 0xFF;
+ if (b0 == 0xFE && b1 == 0xFF) {
+ // UTF-16, big-endian
+ return "UTF-16BE";
+ }
+ if (b0 == 0xFF && b1 == 0xFE) {
+ // UTF-16, little-endian
+ return "UTF-16LE";
+ }
+
+ // UTF-8 with a BOM
+ int b2 = b4[2] & 0xFF;
+ if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) {
+ return "UTF-8";
+ }
+
+ // other encodings
+ int b3 = b4[3] & 0xFF;
+ if (b0 == 0x00 && b1 == 0x00 && b2 == 0x00 && b3 == 0x3C) {
+ // UCS-4, big endian (1234)
+ return "ISO-10646-UCS-4";
+ }
+ if (b0 == 0x3C && b1 == 0x00 && b2 == 0x00 && b3 == 0x00) {
+ // UCS-4, little endian (4321)
+ return "ISO-10646-UCS-4";
+ }
+ if (b0 == 0x00 && b1 == 0x00 && b2 == 0x3C && b3 == 0x00) {
+ // UCS-4, unusual octet order (2143)
+ // REVISIT: What should this be?
+ return "ISO-10646-UCS-4";
+ }
+ if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x00) {
+ // UCS-4, unusual octect order (3412)
+ // REVISIT: What should this be?
+ return "ISO-10646-UCS-4";
+ }
+ if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) {
+ // UTF-16, big-endian, no BOM
+ // (or could turn out to be UCS-2...
+ // REVISIT: What should this be?
+ return "UTF-16BE";
+ }
+ if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) {
+ // UTF-16, little-endian, no BOM
+ // (or could turn out to be UCS-2...
+ return "UTF-16LE";
+ }
+ if (b0 == 0x4C && b1 == 0x6F && b2 == 0xA7 && b3 == 0x94) {
+ // EBCDIC
+ // a la xerces1, return CP037 instead of EBCDIC here
+ return "CP037";
+ }
+
+ // default encoding
+ return "UTF-8";
+ }
+ }
+}
diff --git a/iTechSharp/iTextSharp/text/xml/xmp/DublinCoreSchema.cs b/iTechSharp/iTextSharp/text/xml/xmp/DublinCoreSchema.cs
new file mode 100644
index 0000000..ebfc82b
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/xml/xmp/DublinCoreSchema.cs
@@ -0,0 +1,185 @@
+using System;
+/*
+ * $Id: DublinCoreSchema.cs,v 1.3 2008/05/13 11:26:16 psoares33 Exp $
+ *
+ *
+ * Copyright 2005 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.xml.xmp {
+
+ /**
+ * An implementation of an XmpSchema.
+ */
+ public class DublinCoreSchema : XmpSchema {
+
+ /** default namespace identifier*/
+ public const String DEFAULT_XPATH_ID = "dc";
+ /** default namespace uri*/
+ public const String DEFAULT_XPATH_URI = "http://purl.org/dc/elements/1.1/";
+ /** External Contributors to the resource (other than the authors). */
+ public const String CONTRIBUTOR = "dc:contributor";
+ /** The extent or scope of the resource. */
+ public const String COVERAGE = "dc:coverage";
+ /** The authors of the resource (listed in order of precedence, if significant). */
+ public const String CREATOR = "dc:creator";
+ /** Date(s) that something interesting happened to the resource. */
+ public const String DATE = "dc:date";
+ /** A textual description of the content of the resource. Multiple values may be present for different languages. */
+ public const String DESCRIPTION = "dc:description";
+ /** The file format used when saving the resource. Tools and applications should set this property to the save format of the data. It may include appropriate qualifiers. */
+ public const String FORMAT = "dc:format";
+ /** Unique identifier of the resource. */
+ public const String IDENTIFIER = "dc:identifier";
+ /** An unordered array specifying the languages used in the resource. */
+ public const String LANGUAGE = "dc:language";
+ /** Publishers. */
+ public const String PUBLISHER = "dc:publisher";
+ /** Relationships to other documents. */
+ public const String RELATION = "dc:relation";
+ /** Informal rights statement, selected by language. */
+ public const String RIGHTS = "dc:rights";
+ /** Unique identifier of the work from which this resource was derived. */
+ public const String SOURCE = "dc:source";
+ /** An unordered array of descriptive phrases or keywords that specify the topic of the content of the resource. */
+ public const String SUBJECT = "dc:subject";
+ /** The title of the document, or the name given to the resource. Typically, it will be a name by which the resource is formally known. */
+ public const String TITLE = "dc:title";
+ /** A document type; for example, novel, poem, or working paper. */
+ public const String TYPE = "dc:type";
+
+ /**
+ * @param shorthand
+ * @throws IOException
+ */
+ public DublinCoreSchema() : base("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\"") {
+ this[FORMAT] = "application/pdf";
+ }
+
+ /**
+ * Adds a title.
+ * @param title
+ */
+ public void AddTitle(String title) {
+ this[TITLE] = title;
+ }
+
+ /**
+ * Adds a description.
+ * @param desc
+ */
+ public void AddDescription(String desc) {
+ this[DESCRIPTION] = desc;
+ }
+
+ /**
+ * Adds a subject.
+ * @param subject
+ */
+ public void AddSubject(String subject) {
+ XmpArray array = new XmpArray(XmpArray.UNORDERED);
+ array.Add(subject);
+ SetProperty(SUBJECT, array);
+ }
+
+
+ /**
+ * Adds a subject.
+ * @param subject array of subjects
+ */
+ public void addSubject(String[] subject) {
+ XmpArray array = new XmpArray(XmpArray.UNORDERED);
+ for (int i = 0; i < subject.Length; i++) {
+ array.Add(subject[i]);
+ }
+ SetProperty(SUBJECT, array);
+ }
+
+ /**
+ * Adds a single author.
+ * @param author
+ */
+ public void AddAuthor(String author) {
+ XmpArray array = new XmpArray(XmpArray.ORDERED);
+ array.Add(author);
+ SetProperty(CREATOR, array);
+ }
+
+ /**
+ * Adds an array of authors.
+ * @param author
+ */
+ public void AddAuthor(String[] author) {
+ XmpArray array = new XmpArray(XmpArray.ORDERED);
+ for (int i = 0; i < author.Length; i++) {
+ array.Add(author[i]);
+ }
+ SetProperty(CREATOR, array);
+ }
+
+ /**
+ * Adds a single publisher.
+ * @param publisher
+ */
+ public void AddPublisher(String publisher) {
+ XmpArray array = new XmpArray(XmpArray.ORDERED);
+ array.Add(publisher);
+ SetProperty(PUBLISHER, array);
+ }
+
+ /**
+ * Adds an array of publishers.
+ * @param publisher
+ */
+ public void AddPublisher(String[] publisher) {
+ XmpArray array = new XmpArray(XmpArray.ORDERED);
+ for (int i = 0; i < publisher.Length; i++) {
+ array.Add(publisher[i]);
+ }
+ SetProperty(PUBLISHER, array);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/iTextSharp/text/xml/xmp/EncodingNoPreamble.cs b/iTechSharp/iTextSharp/text/xml/xmp/EncodingNoPreamble.cs
new file mode 100644
index 0000000..3aa75d8
--- /dev/null
+++ b/iTechSharp/iTextSharp/text/xml/xmp/EncodingNoPreamble.cs
@@ -0,0 +1,163 @@
+using System;
+using System.Text;
+/*
+ * $Id: EncodingNoPreamble.cs,v 1.2 2008/05/13 11:26:16 psoares33 Exp $
+ *
+ *
+ * Copyright 2007 Paulo Soares.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library 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 LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+namespace iTextSharp.text.xml.xmp {
+
+ ///
+ * dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ *
+ * To read in the time and Get a date which is compatible with our local
+ * time zone.
+ * dateF = new SimpleDateFormat("yyMMddHHmmssz");
+ *
+ * To read in the time and Get a date which is compatible with our local
+ * time zone.
+ * PKIFailureInfo ::= BIT STRING {
+ * badAlg (0),
+ * -- unrecognized or unsupported Algorithm Identifier
+ * badMessageCheck (1), -- integrity check failed (e.g., signature did not verify)
+ * badRequest (2),
+ * -- transaction not permitted or supported
+ * badTime (3), -- messageTime was not sufficiently close to the system time, as defined by local policy
+ * badCertId (4), -- no certificate could be found matching the provided criteria
+ * badDataFormat (5),
+ * -- the data submitted has the wrong format
+ * wrongAuthority (6), -- the authority indicated in the request is different from the one creating the response token
+ * incorrectData (7), -- the requester's data is incorrect (for notary services)
+ * missingTimeStamp (8), -- when the timestamp is missing but should be there (by policy)
+ * badPOP (9) -- the proof-of-possession failed
+ * timeNotAvailable (14),
+ * -- the TSA's time source is not available
+ * unacceptedPolicy (15),
+ * -- the requested TSA policy is not supported by the TSA
+ * unacceptedExtension (16),
+ * -- the requested extension is not supported by the TSA
+ * addInfoNotAvailable (17)
+ * -- the additional information requested could not be understood
+ * -- or is not available
+ * systemFailure (25)
+ * -- the request cannot be handled due to system failure
+ *
+ */
+ public class PkiFailureInfo
+ : DerBitString
+ {
+ public const int BadAlg = (1 << 7); // unrecognized or unsupported Algorithm Identifier
+ public const int BadMessageCheck = (1 << 6); // integrity check failed (e.g., signature did not verify)
+ public const int BadRequest = (1 << 5);
+ public const int BadTime = (1 << 4); // -- messageTime was not sufficiently close to the system time, as defined by local policy
+ public const int BadCertId = (1 << 3); // no certificate could be found matching the provided criteria
+ public const int BadDataFormat = (1 << 2);
+ public const int WrongAuthority = (1 << 1); // the authority indicated in the request is different from the one creating the response token
+ public const int IncorrectData = 1; // the requester's data is incorrect (for notary services)
+ public const int MissingTimeStamp = (1 << 15); // when the timestamp is missing but should be there (by policy)
+ public const int BadPop = (1 << 14); // the proof-of-possession failed
+ public const int TimeNotAvailable = (1 << 9); // the TSA's time source is not available
+ public const int UnacceptedPolicy = (1 << 8); // the requested TSA policy is not supported by the TSA
+ public const int UnacceptedExtension = (1 << 23); //the requested extension is not supported by the TSA
+ public const int AddInfoNotAvailable = (1 << 22); //the additional information requested could not be understood or is not available
+ public const int SystemFailure = (1 << 30); //the request cannot be handled due to system failure
+
+ /**
+ * Basic constructor.
+ */
+ public PkiFailureInfo(
+ int info)
+ : base(GetBytes(info), GetPadBits(info))
+ {
+ }
+
+ public PkiFailureInfo(
+ DerBitString info)
+ : base(info.GetBytes(), info.PadBits)
+ {
+ }
+
+ public override string ToString()
+ {
+ return "PkiFailureInfo: 0x" + this.IntValue.ToString("X");
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cmp/PKIFreeText.cs b/iTechSharp/srcbc/asn1/cmp/PKIFreeText.cs
new file mode 100644
index 0000000..571c8d9
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cmp/PKIFreeText.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public class PkiFreeText
+ : Asn1Encodable
+ {
+ internal Asn1Sequence strings;
+
+ public static PkiFreeText GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+ }
+
+ public static PkiFreeText GetInstance(
+ object obj)
+ {
+ if (obj is PkiFreeText)
+ {
+ return (PkiFreeText)obj;
+ }
+ else if (obj is Asn1Sequence)
+ {
+ return new PkiFreeText((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public PkiFreeText(
+ Asn1Sequence seq)
+ {
+ foreach (object o in seq)
+ {
+ if (!(o is DerUtf8String))
+ {
+ throw new ArgumentException("attempt to insert non UTF8 STRING into PkiFreeText");
+ }
+ }
+
+ this.strings = seq;
+ }
+
+ public PkiFreeText(
+ DerUtf8String p)
+ {
+ strings = new DerSequence(p);
+ }
+
+ /**
+ * Return the number of string elements present.
+ *
+ * @return number of elements present.
+ */
+ [Obsolete("Use 'Count' property instead")]
+ public int Size
+ {
+ get { return strings.Count; }
+ }
+
+ public int Count
+ {
+ get { return strings.Count; }
+ }
+
+ /**
+ * Return the UTF8STRING at index.
+ *
+ * @param index index of the string of interest
+ * @return the string at index.
+ */
+ public DerUtf8String this[int index]
+ {
+ get { return (DerUtf8String) strings[index]; }
+ }
+
+ [Obsolete("Use 'object[index]' syntax instead")]
+ public DerUtf8String GetStringAt(
+ int index)
+ {
+ return this[index];
+ }
+
+ /**
+ *
+ * PkiFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return strings;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cmp/PKIStatus.cs b/iTechSharp/srcbc/asn1/cmp/PKIStatus.cs
new file mode 100644
index 0000000..c56380f
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cmp/PKIStatus.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public enum PkiStatus
+ {
+ Granted = 0,
+ GrantedWithMods = 1,
+ Rejection = 2,
+ Waiting = 3,
+ RevocationWarning = 4,
+ RevocationNotification = 5,
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cmp/PKIStatusInfo.cs b/iTechSharp/srcbc/asn1/cmp/PKIStatusInfo.cs
new file mode 100644
index 0000000..2463e00
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cmp/PKIStatusInfo.cs
@@ -0,0 +1,165 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public class PkiStatusInfo
+ : Asn1Encodable
+ {
+ DerInteger status;
+ PkiFreeText statusString;
+ DerBitString failInfo;
+
+ public static PkiStatusInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+ }
+
+ public static PkiStatusInfo GetInstance(
+ object obj)
+ {
+ if (obj is PkiStatusInfo)
+ {
+ return (PkiStatusInfo)obj;
+ }
+ else if (obj is Asn1Sequence)
+ {
+ return new PkiStatusInfo((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public PkiStatusInfo(
+ Asn1Sequence seq)
+ {
+ this.status = DerInteger.GetInstance(seq[0]);
+
+ this.statusString = null;
+ this.failInfo = null;
+
+ if (seq.Count > 2)
+ {
+ this.statusString = PkiFreeText.GetInstance(seq[1]);
+ this.failInfo = DerBitString.GetInstance(seq[2]);
+ }
+ else if (seq.Count > 1)
+ {
+ object obj = seq[1];
+ if (obj is DerBitString)
+ {
+ this.failInfo = DerBitString.GetInstance(obj);
+ }
+ else
+ {
+ this.statusString = PkiFreeText.GetInstance(obj);
+ }
+ }
+ }
+
+ /**
+ * @param status
+ */
+ public PkiStatusInfo(int status)
+ {
+ this.status = new DerInteger(status);
+ }
+
+ /**
+ * @param status
+ * @param statusString
+ */
+ public PkiStatusInfo(
+ int status,
+ PkiFreeText statusString)
+ {
+ this.status = new DerInteger(status);
+ this.statusString = statusString;
+ }
+
+ public PkiStatusInfo(
+ int status,
+ PkiFreeText statusString,
+ PkiFailureInfo failInfo)
+ {
+ this.status = new DerInteger(status);
+ this.statusString = statusString;
+ this.failInfo = failInfo;
+ }
+
+ public BigInteger Status
+ {
+ get
+ {
+ return status.Value;
+ }
+ }
+
+ public PkiFreeText StatusString
+ {
+ get
+ {
+ return statusString;
+ }
+ }
+
+ public DerBitString FailInfo
+ {
+ get
+ {
+ return failInfo;
+ }
+ }
+
+ /**
+ *
+ * PkiStatusInfo ::= SEQUENCE {
+ * status PKIStatus, (INTEGER)
+ * statusString PkiFreeText OPTIONAL,
+ * failInfo PkiFailureInfo OPTIONAL (BIT STRING)
+ * }
+ *
+ * PKIStatus:
+ * granted (0), -- you got exactly what you asked for
+ * grantedWithMods (1), -- you got something like what you asked for
+ * rejection (2), -- you don't get it, more information elsewhere in the message
+ * waiting (3), -- the request body part has not yet been processed, expect to hear more later
+ * revocationWarning (4), -- this message contains a warning that a revocation is imminent
+ * revocationNotification (5), -- notification that a revocation has occurred
+ * keyUpdateWarning (6) -- update already done for the oldCertId specified in CertReqMsg
+ *
+ * PkiFailureInfo:
+ * badAlg (0), -- unrecognized or unsupported Algorithm Identifier
+ * badMessageCheck (1), -- integrity check failed (e.g., signature did not verify)
+ * badRequest (2), -- transaction not permitted or supported
+ * badTime (3), -- messageTime was not sufficiently close to the system time, as defined by local policy
+ * badCertId (4), -- no certificate could be found matching the provided criteria
+ * badDataFormat (5), -- the data submitted has the wrong format
+ * wrongAuthority (6), -- the authority indicated in the request is different from the one creating the response token
+ * incorrectData (7), -- the requester's data is incorrect (for notary services)
+ * missingTimeStamp (8), -- when the timestamp is missing but should be there (by policy)
+ * badPOP (9) -- the proof-of-possession failed
+ *
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(status);
+
+ if (statusString != null)
+ {
+ v.Add(statusString);
+ }
+
+ if (failInfo!= null)
+ {
+ v.Add(failInfo);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/Attribute.cs b/iTechSharp/srcbc/asn1/cms/Attribute.cs
new file mode 100644
index 0000000..bfdd1d4
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/Attribute.cs
@@ -0,0 +1,68 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class Attribute
+ : Asn1Encodable
+ {
+ private DerObjectIdentifier attrType;
+ private Asn1Set attrValues;
+
+ /**
+ * return an Attribute object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static Attribute GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is Attribute)
+ {
+ return (Attribute) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Attribute((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public Attribute(
+ Asn1Sequence seq)
+ {
+ attrType = (DerObjectIdentifier)seq[0];
+ attrValues = (Asn1Set)seq[1];
+ }
+
+ public Attribute(
+ DerObjectIdentifier attrType,
+ Asn1Set attrValues)
+ {
+ this.attrType = attrType;
+ this.attrValues = attrValues;
+ }
+
+ public DerObjectIdentifier AttrType { get { return attrType; } }
+
+ public Asn1Set AttrValues { get { return attrValues; } }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Attribute ::= SEQUENCE {
+ * attrType OBJECT IDENTIFIER,
+ * attrValues SET OF AttributeValue
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(attrType, attrValues);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/AttributeTable.cs b/iTechSharp/srcbc/asn1/cms/AttributeTable.cs
new file mode 100644
index 0000000..614372f
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/AttributeTable.cs
@@ -0,0 +1,155 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class AttributeTable
+ {
+ private readonly Hashtable attributes;
+
+ public AttributeTable(
+ Hashtable attrs)
+ {
+ this.attributes = new Hashtable(attrs);
+ }
+
+ public AttributeTable(
+ Asn1EncodableVector v)
+ {
+ this.attributes = new Hashtable(v.Count);
+
+ foreach (Asn1Encodable o in v)
+ {
+ Attribute a = Attribute.GetInstance(o);
+
+ AddAttribute(a);
+ }
+ }
+
+ public AttributeTable(
+ Asn1Set s)
+ {
+ this.attributes = new Hashtable(s.Count);
+
+ for (int i = 0; i != s.Count; i++)
+ {
+ Attribute a = Attribute.GetInstance(s[i]);
+
+ AddAttribute(a);
+ }
+ }
+
+ private void AddAttribute(
+ Attribute a)
+ {
+ DerObjectIdentifier oid = a.AttrType;
+ object obj = attributes[oid];
+
+ if (obj == null)
+ {
+ attributes[oid] = a;
+ }
+ else
+ {
+ ArrayList v;
+
+ if (obj is Attribute)
+ {
+ v = new ArrayList();
+
+ v.Add(obj);
+ v.Add(a);
+ }
+ else
+ {
+ v = (ArrayList) obj;
+
+ v.Add(a);
+ }
+
+ attributes[oid] = v;
+ }
+ }
+
+ ///
+ * CompressedData ::= Sequence {
+ * version CMSVersion,
+ * compressionAlgorithm CompressionAlgorithmIdentifier,
+ * encapContentInfo EncapsulatedContentInfo
+ * }
+ *
+ */
+ public class CompressedData
+ : Asn1Encodable
+ {
+ private DerInteger version;
+ private AlgorithmIdentifier compressionAlgorithm;
+ private ContentInfo encapContentInfo;
+
+ public CompressedData(
+ AlgorithmIdentifier compressionAlgorithm,
+ ContentInfo encapContentInfo)
+ {
+ this.version = new DerInteger(0);
+ this.compressionAlgorithm = compressionAlgorithm;
+ this.encapContentInfo = encapContentInfo;
+ }
+
+ public CompressedData(
+ Asn1Sequence seq)
+ {
+ this.version = (DerInteger) seq[0];
+ this.compressionAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]);
+ this.encapContentInfo = ContentInfo.GetInstance(seq[2]);
+ }
+
+ /**
+ * return a CompressedData object from a tagged object.
+ *
+ * @param ato the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static CompressedData GetInstance(
+ Asn1TaggedObject ato,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(ato, explicitly));
+ }
+
+ /**
+ * return a CompressedData object from the given object.
+ *
+ * @param _obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static CompressedData GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is CompressedData)
+ {
+ return (CompressedData)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new CompressedData((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid CompressedData: " + obj.GetType().Name);
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public AlgorithmIdentifier CompressionAlgorithmIdentifier
+ {
+ get { return compressionAlgorithm; }
+ }
+
+ public ContentInfo EncapContentInfo
+ {
+ get { return encapContentInfo; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new BerSequence(version, compressionAlgorithm, encapContentInfo);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/CompressedDataParser.cs b/iTechSharp/srcbc/asn1/cms/CompressedDataParser.cs
new file mode 100644
index 0000000..7c53453
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/CompressedDataParser.cs
@@ -0,0 +1,47 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ /**
+ * RFC 3274 - CMS Compressed Data.
+ *
+ * CompressedData ::= SEQUENCE {
+ * version CMSVersion,
+ * compressionAlgorithm CompressionAlgorithmIdentifier,
+ * encapContentInfo EncapsulatedContentInfo
+ * }
+ *
+ */
+ public class CompressedDataParser
+ {
+ private DerInteger _version;
+ private AlgorithmIdentifier _compressionAlgorithm;
+ private ContentInfoParser _encapContentInfo;
+
+ public CompressedDataParser(
+ Asn1SequenceParser seq)
+ {
+ this._version = (DerInteger)seq.ReadObject();
+ this._compressionAlgorithm = AlgorithmIdentifier.GetInstance(seq.ReadObject().ToAsn1Object());
+ this._encapContentInfo = new ContentInfoParser((Asn1SequenceParser)seq.ReadObject());
+ }
+
+ public DerInteger Version
+ {
+ get { return _version; }
+ }
+
+ public AlgorithmIdentifier CompressionAlgorithmIdentifier
+ {
+ get { return _compressionAlgorithm; }
+ }
+
+ public ContentInfoParser GetEncapContentInfo()
+ {
+ return _encapContentInfo;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/ContentInfo.cs b/iTechSharp/srcbc/asn1/cms/ContentInfo.cs
new file mode 100644
index 0000000..4521c2f
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/ContentInfo.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class ContentInfo
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier contentType;
+ private readonly Asn1Encodable content;
+
+ public static ContentInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ContentInfo)
+ {
+ return (ContentInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ContentInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name);
+ }
+
+ private ContentInfo(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+ contentType = (DerObjectIdentifier) seq[0];
+
+ if (seq.Count > 1)
+ {
+ Asn1TaggedObject optOcts = (Asn1TaggedObject) seq[1];
+ if (optOcts.TagNo != 0)
+ throw new ArgumentException("Tag number for 'content' must be 0");
+
+ content = optOcts.GetObject();
+ }
+ }
+
+ public ContentInfo(
+ DerObjectIdentifier contentType,
+ Asn1Encodable content)
+ {
+ this.contentType = contentType;
+ this.content = content;
+ }
+
+ public DerObjectIdentifier ContentType
+ {
+ get { return contentType; }
+ }
+
+ public Asn1Encodable Content
+ {
+ get { return content; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * ContentInfo ::= Sequence {
+ * contentType ContentType,
+ * content
+ * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(contentType);
+
+ if (content != null)
+ {
+ v.Add(new BerTaggedObject(0, content));
+ }
+
+ return new BerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/ContentInfoParser.cs b/iTechSharp/srcbc/asn1/cms/ContentInfoParser.cs
new file mode 100644
index 0000000..541cc0f
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/ContentInfoParser.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * ContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * content
+ * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+ *
+ */
+ public class ContentInfoParser
+ {
+ private DerObjectIdentifier contentType;
+ private Asn1TaggedObjectParser content;
+
+ public ContentInfoParser(
+ Asn1SequenceParser seq)
+ {
+ contentType = (DerObjectIdentifier)seq.ReadObject();
+ content = (Asn1TaggedObjectParser)seq.ReadObject();
+ }
+
+ public DerObjectIdentifier ContentType
+ {
+ get { return contentType; }
+ }
+
+ public IAsn1Convertible GetContent(
+ int tag)
+ {
+ if (content == null)
+ return null;
+
+ return content.GetObjectParser(tag, true);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/EncryptedContentInfo.cs b/iTechSharp/srcbc/asn1/cms/EncryptedContentInfo.cs
new file mode 100644
index 0000000..f76f51c
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/EncryptedContentInfo.cs
@@ -0,0 +1,98 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class EncryptedContentInfo
+ : Asn1Encodable
+ {
+ private DerObjectIdentifier contentType;
+ private AlgorithmIdentifier contentEncryptionAlgorithm;
+ private Asn1OctetString encryptedContent;
+
+ public EncryptedContentInfo(
+ DerObjectIdentifier contentType,
+ AlgorithmIdentifier contentEncryptionAlgorithm,
+ Asn1OctetString encryptedContent)
+ {
+ this.contentType = contentType;
+ this.contentEncryptionAlgorithm = contentEncryptionAlgorithm;
+ this.encryptedContent = encryptedContent;
+ }
+
+ public EncryptedContentInfo(
+ Asn1Sequence seq)
+ {
+ contentType = (DerObjectIdentifier) seq[0];
+ contentEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]);
+
+ if (seq.Count > 2)
+ {
+ encryptedContent = Asn1OctetString.GetInstance(
+ (Asn1TaggedObject) seq[2], false);
+ }
+ }
+
+ /**
+ * return an EncryptedContentInfo object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static EncryptedContentInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is EncryptedContentInfo)
+ {
+ return (EncryptedContentInfo)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new EncryptedContentInfo((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Invalid EncryptedContentInfo: " + obj.GetType().Name);
+ }
+
+ public DerObjectIdentifier ContentType
+ {
+ get { return contentType; }
+ }
+
+ public AlgorithmIdentifier ContentEncryptionAlgorithm
+ {
+ get { return contentEncryptionAlgorithm; }
+ }
+
+ public Asn1OctetString EncryptedContent
+ {
+ get { return encryptedContent; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * EncryptedContentInfo ::= Sequence {
+ * contentType ContentType,
+ * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ contentType, contentEncryptionAlgorithm);
+
+ if (encryptedContent != null)
+ {
+ v.Add(new BerTaggedObject(false, 0, encryptedContent));
+ }
+
+ return new BerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/EncryptedContentInfoParser.cs b/iTechSharp/srcbc/asn1/cms/EncryptedContentInfoParser.cs
new file mode 100644
index 0000000..af748b1
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/EncryptedContentInfoParser.cs
@@ -0,0 +1,46 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ /**
+ *
+ * EncryptedContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+ * }
+ *
+ */
+ public class EncryptedContentInfoParser
+ {
+ private DerObjectIdentifier _contentType;
+ private AlgorithmIdentifier _contentEncryptionAlgorithm;
+ private Asn1TaggedObjectParser _encryptedContent;
+
+ public EncryptedContentInfoParser(
+ Asn1SequenceParser seq)
+ {
+ _contentType = (DerObjectIdentifier)seq.ReadObject();
+ _contentEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq.ReadObject().ToAsn1Object());
+ _encryptedContent = (Asn1TaggedObjectParser)seq.ReadObject();
+ }
+
+ public DerObjectIdentifier ContentType
+ {
+ get { return _contentType; }
+ }
+
+ public AlgorithmIdentifier ContentEncryptionAlgorithm
+ {
+ get { return _contentEncryptionAlgorithm; }
+ }
+
+ public IAsn1Convertible GetEncryptedContent(
+ int tag)
+ {
+ return _encryptedContent.GetObjectParser(tag, false);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/EncryptedData.cs b/iTechSharp/srcbc/asn1/cms/EncryptedData.cs
new file mode 100644
index 0000000..5b83782
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/EncryptedData.cs
@@ -0,0 +1,95 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class EncryptedData
+ : Asn1Encodable
+ {
+ private readonly DerInteger version;
+ private readonly EncryptedContentInfo encryptedContentInfo;
+ private readonly Asn1Set unprotectedAttrs;
+
+ public static EncryptedData GetInstance(
+ object obj)
+ {
+ if (obj is EncryptedData)
+ return (EncryptedData) obj;
+
+ if (obj is Asn1Sequence)
+ return new EncryptedData((Asn1Sequence) obj);
+
+ throw new ArgumentException("Invalid EncryptedData: " + obj.GetType().Name);
+ }
+
+ public EncryptedData(
+ EncryptedContentInfo encInfo)
+ : this(encInfo, null)
+ {
+ }
+
+ public EncryptedData(
+ EncryptedContentInfo encInfo,
+ Asn1Set unprotectedAttrs)
+ {
+ if (encInfo == null)
+ throw new ArgumentNullException("encInfo");
+
+ this.version = new DerInteger((unprotectedAttrs == null) ? 0 : 2);
+ this.encryptedContentInfo = encInfo;
+ this.unprotectedAttrs = unprotectedAttrs;
+ }
+
+ private EncryptedData(
+ Asn1Sequence seq)
+ {
+ if (seq == null)
+ throw new ArgumentNullException("seq");
+ if (seq.Count < 2 || seq.Count > 3)
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+ this.version = DerInteger.GetInstance(seq[0]);
+ this.encryptedContentInfo = EncryptedContentInfo.GetInstance(seq[1]);
+
+ if (seq.Count > 2)
+ {
+ this.unprotectedAttrs = Asn1Set.GetInstance(seq[2]);
+ }
+ }
+
+ public virtual DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public virtual EncryptedContentInfo EncryptedContentInfo
+ {
+ get { return encryptedContentInfo; }
+ }
+
+ public virtual Asn1Set UnprotectedAttrs
+ {
+ get { return unprotectedAttrs; }
+ }
+
+ /**
+ *
+ * EncryptedData ::= SEQUENCE {
+ * version CMSVersion,
+ * encryptedContentInfo EncryptedContentInfo,
+ * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
+ *
+ * @return a basic ASN.1 object representation.
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(version, encryptedContentInfo);
+
+ if (unprotectedAttrs != null)
+ {
+ v.Add(new BerTaggedObject(false, 1, unprotectedAttrs));
+ }
+
+ return new BerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/EnvelopedData.cs b/iTechSharp/srcbc/asn1/cms/EnvelopedData.cs
new file mode 100644
index 0000000..0e18bd8
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/EnvelopedData.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class EnvelopedData
+ : Asn1Encodable
+ {
+ private DerInteger version;
+ private OriginatorInfo originatorInfo;
+ private Asn1Set recipientInfos;
+ private EncryptedContentInfo encryptedContentInfo;
+ private Asn1Set unprotectedAttrs;
+
+ public EnvelopedData(
+ OriginatorInfo originatorInfo,
+ Asn1Set recipientInfos,
+ EncryptedContentInfo encryptedContentInfo,
+ Asn1Set unprotectedAttrs)
+ {
+ if (originatorInfo != null || unprotectedAttrs != null)
+ {
+ version = new DerInteger(2);
+ }
+ else
+ {
+ version = new DerInteger(0);
+
+ foreach (object o in recipientInfos)
+ {
+ RecipientInfo ri = RecipientInfo.GetInstance(o);
+
+ if (!ri.Version.Equals(version))
+ {
+ version = new DerInteger(2);
+ break;
+ }
+ }
+ }
+
+ this.originatorInfo = originatorInfo;
+ this.recipientInfos = recipientInfos;
+ this.encryptedContentInfo = encryptedContentInfo;
+ this.unprotectedAttrs = unprotectedAttrs;
+ }
+
+ public EnvelopedData(
+ Asn1Sequence seq)
+ {
+ int index = 0;
+
+ version = (DerInteger) seq[index++];
+
+ object tmp = seq[index++];
+
+ if (tmp is Asn1TaggedObject)
+ {
+ originatorInfo = OriginatorInfo.GetInstance((Asn1TaggedObject) tmp, false);
+ tmp = seq[index++];
+ }
+
+ recipientInfos = Asn1Set.GetInstance(tmp);
+ encryptedContentInfo = EncryptedContentInfo.GetInstance(seq[index++]);
+
+ if (seq.Count > index)
+ {
+ unprotectedAttrs = Asn1Set.GetInstance((Asn1TaggedObject) seq[index], false);
+ }
+ }
+
+ /**
+ * return an EnvelopedData object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static EnvelopedData GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ /**
+ * return an EnvelopedData object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static EnvelopedData GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is EnvelopedData)
+ {
+ return (EnvelopedData)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new EnvelopedData((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Invalid EnvelopedData: " + obj.GetType().Name);
+ }
+
+ public DerInteger Version { get { return version; } }
+
+ public OriginatorInfo OriginatorInfo { get { return originatorInfo; } }
+
+ public Asn1Set RecipientInfos { get { return recipientInfos; } }
+
+ public EncryptedContentInfo EncryptedContentInfo { get { return encryptedContentInfo; } }
+
+ public Asn1Set UnprotectedAttrs { get { return unprotectedAttrs; } }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * EnvelopedData ::= Sequence {
+ * version CMSVersion,
+ * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ * recipientInfos RecipientInfos,
+ * encryptedContentInfo EncryptedContentInfo,
+ * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(version);
+
+ if (originatorInfo != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, originatorInfo));
+ }
+
+ v.Add(recipientInfos, encryptedContentInfo);
+
+ if (unprotectedAttrs != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, unprotectedAttrs));
+ }
+
+ return new BerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/EnvelopedDataParser.cs b/iTechSharp/srcbc/asn1/cms/EnvelopedDataParser.cs
new file mode 100644
index 0000000..877696e
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/EnvelopedDataParser.cs
@@ -0,0 +1,106 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ /**
+ *
+ * EnvelopedData ::= SEQUENCE {
+ * version CMSVersion,
+ * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+ * recipientInfos RecipientInfos,
+ * encryptedContentInfo EncryptedContentInfo,
+ * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
+ * }
+ *
+ */
+ public class EnvelopedDataParser
+ {
+ private Asn1SequenceParser _seq;
+ private DerInteger _version;
+ private IAsn1Convertible _nextObject;
+ private bool _originatorInfoCalled;
+
+ public EnvelopedDataParser(
+ Asn1SequenceParser seq)
+ {
+ this._seq = seq;
+ this._version = (DerInteger)seq.ReadObject();
+ }
+
+ public DerInteger Version
+ {
+ get { return _version; }
+ }
+
+ public OriginatorInfo GetOriginatorInfo()
+ {
+ _originatorInfoCalled = true;
+
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.ReadObject();
+ }
+
+ if (_nextObject is Asn1TaggedObjectParser && ((Asn1TaggedObjectParser)_nextObject).TagNo == 0)
+ {
+ Asn1SequenceParser originatorInfo = (Asn1SequenceParser)
+ ((Asn1TaggedObjectParser)_nextObject).GetObjectParser(Asn1Tags.Sequence, false);
+ _nextObject = null;
+ return OriginatorInfo.GetInstance(originatorInfo.ToAsn1Object());
+ }
+
+ return null;
+ }
+
+ public Asn1SetParser GetRecipientInfos()
+ {
+ if (!_originatorInfoCalled)
+ {
+ GetOriginatorInfo();
+ }
+
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.ReadObject();
+ }
+
+ Asn1SetParser recipientInfos = (Asn1SetParser)_nextObject;
+ _nextObject = null;
+ return recipientInfos;
+ }
+
+ public EncryptedContentInfoParser GetEncryptedContentInfo()
+ {
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.ReadObject();
+ }
+
+ if (_nextObject != null)
+ {
+ Asn1SequenceParser o = (Asn1SequenceParser) _nextObject;
+ _nextObject = null;
+ return new EncryptedContentInfoParser(o);
+ }
+
+ return null;
+ }
+
+ public Asn1SetParser GetUnprotectedAttrs()
+ {
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.ReadObject();
+ }
+
+ if (_nextObject != null)
+ {
+ IAsn1Convertible o = _nextObject;
+ _nextObject = null;
+ return (Asn1SetParser)((Asn1TaggedObjectParser)o).GetObjectParser(Asn1Tags.Set, false);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/IssuerAndSerialNumber.cs b/iTechSharp/srcbc/asn1/cms/IssuerAndSerialNumber.cs
new file mode 100644
index 0000000..5f8e8c2
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/IssuerAndSerialNumber.cs
@@ -0,0 +1,70 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class IssuerAndSerialNumber
+ : Asn1Encodable
+ {
+ X509Name name;
+ DerInteger serialNumber;
+
+ public static IssuerAndSerialNumber GetInstance(
+ object obj)
+ {
+ if (obj is IssuerAndSerialNumber)
+ {
+ return (IssuerAndSerialNumber)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new IssuerAndSerialNumber((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException(
+ "Illegal object in IssuerAndSerialNumber: " + obj.GetType().Name);
+ }
+
+ public IssuerAndSerialNumber(
+ Asn1Sequence seq)
+ {
+ this.name = X509Name.GetInstance(seq[0]);
+ this.serialNumber = (DerInteger) seq[1];
+ }
+
+ public IssuerAndSerialNumber(
+ X509Name name,
+ BigInteger serialNumber)
+ {
+ this.name = name;
+ this.serialNumber = new DerInteger(serialNumber);
+ }
+
+ public IssuerAndSerialNumber(
+ X509Name name,
+ DerInteger serialNumber)
+ {
+ this.name = name;
+ this.serialNumber = serialNumber;
+ }
+
+ public X509Name Name
+ {
+ get { return name; }
+ }
+
+ public DerInteger SerialNumber
+ {
+ get { return serialNumber; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(name, serialNumber);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/KEKIdentifier.cs b/iTechSharp/srcbc/asn1/cms/KEKIdentifier.cs
new file mode 100644
index 0000000..b438ea9
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/KEKIdentifier.cs
@@ -0,0 +1,133 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class KekIdentifier
+ : Asn1Encodable
+ {
+ private Asn1OctetString keyIdentifier;
+ private DerGeneralizedTime date;
+ private OtherKeyAttribute other;
+
+ public KekIdentifier(
+ byte[] keyIdentifier,
+ DerGeneralizedTime date,
+ OtherKeyAttribute other)
+ {
+ this.keyIdentifier = new DerOctetString(keyIdentifier);
+ this.date = date;
+ this.other = other;
+ }
+
+ public KekIdentifier(
+ Asn1Sequence seq)
+ {
+ keyIdentifier = (Asn1OctetString) seq[0];
+
+ switch (seq.Count)
+ {
+ case 1:
+ break;
+ case 2:
+ if (seq[1] is DerGeneralizedTime)
+ {
+ date = (DerGeneralizedTime) seq[1];
+ }
+ else
+ {
+ other = OtherKeyAttribute.GetInstance(seq[2]);
+ }
+ break;
+ case 3:
+ date = (DerGeneralizedTime) seq[1];
+ other = OtherKeyAttribute.GetInstance(seq[2]);
+ break;
+ default:
+ throw new ArgumentException("Invalid KekIdentifier");
+ }
+ }
+
+ /**
+ * return a KekIdentifier object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static KekIdentifier GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ /**
+ * return a KekIdentifier object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static KekIdentifier GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is KekIdentifier)
+ {
+ return (KekIdentifier)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new KekIdentifier((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Invalid KekIdentifier: " + obj.GetType().Name);
+ }
+
+ public Asn1OctetString KeyIdentifier
+ {
+ get { return keyIdentifier; }
+ }
+
+ public DerGeneralizedTime Date
+ {
+ get { return date; }
+ }
+
+ public OtherKeyAttribute Other
+ {
+ get { return other; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * KekIdentifier ::= Sequence {
+ * keyIdentifier OCTET STRING,
+ * date GeneralizedTime OPTIONAL,
+ * other OtherKeyAttribute OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(keyIdentifier);
+
+ if (date != null)
+ {
+ v.Add(date);
+ }
+
+ if (other != null)
+ {
+ v.Add(other);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
+
diff --git a/iTechSharp/srcbc/asn1/cms/KEKRecipientInfo.cs b/iTechSharp/srcbc/asn1/cms/KEKRecipientInfo.cs
new file mode 100644
index 0000000..88b8b07
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/KEKRecipientInfo.cs
@@ -0,0 +1,110 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class KekRecipientInfo
+ : Asn1Encodable
+ {
+ private DerInteger version;
+ private KekIdentifier kekID;
+ private AlgorithmIdentifier keyEncryptionAlgorithm;
+ private Asn1OctetString encryptedKey;
+
+ public KekRecipientInfo(
+ KekIdentifier kekID,
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ Asn1OctetString encryptedKey)
+ {
+ this.version = new DerInteger(4);
+ this.kekID = kekID;
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.encryptedKey = encryptedKey;
+ }
+
+ public KekRecipientInfo(
+ Asn1Sequence seq)
+ {
+ version = (DerInteger) seq[0];
+ kekID = KekIdentifier.GetInstance(seq[1]);
+ keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[2]);
+ encryptedKey = (Asn1OctetString) seq[3];
+ }
+
+ /**
+ * return a KekRecipientInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static KekRecipientInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ /**
+ * return a KekRecipientInfo object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static KekRecipientInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is KekRecipientInfo)
+ {
+ return (KekRecipientInfo)obj;
+ }
+
+ if(obj is Asn1Sequence)
+ {
+ return new KekRecipientInfo((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Invalid KekRecipientInfo: " + obj.GetType().Name);
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public KekIdentifier KekID
+ {
+ get { return kekID; }
+ }
+
+ public AlgorithmIdentifier KeyEncryptionAlgorithm
+ {
+ get { return keyEncryptionAlgorithm; }
+ }
+
+ public Asn1OctetString EncryptedKey
+ {
+ get { return encryptedKey; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * KekRecipientInfo ::= Sequence {
+ * version CMSVersion, -- always set to 4
+ * kekID KekIdentifier,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * encryptedKey EncryptedKey
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(version, kekID, keyEncryptionAlgorithm, encryptedKey);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/KeyAgreeRecipientIdentifier.cs b/iTechSharp/srcbc/asn1/cms/KeyAgreeRecipientIdentifier.cs
new file mode 100644
index 0000000..1f8b8db
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/KeyAgreeRecipientIdentifier.cs
@@ -0,0 +1,90 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class KeyAgreeRecipientIdentifier
+ : Asn1Encodable
+ {
+ /**
+ * return an KeyAgreeRecipientIdentifier object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param isExplicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static KeyAgreeRecipientIdentifier GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+ }
+
+ /**
+ * return an KeyAgreeRecipientIdentifier object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static KeyAgreeRecipientIdentifier GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is KeyAgreeRecipientIdentifier)
+ {
+ return (KeyAgreeRecipientIdentifier)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new KeyAgreeRecipientIdentifier((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Invalid KeyAgreeRecipientIdentifier: " + obj.GetType().FullName, "obj");
+ }
+
+ private readonly IssuerAndSerialNumber issuerSerial;
+ private const RecipientKeyIdentifier rKeyID = null;
+
+ public KeyAgreeRecipientIdentifier(
+ IssuerAndSerialNumber issuerSerial)
+ {
+ this.issuerSerial = issuerSerial;
+ }
+
+ private KeyAgreeRecipientIdentifier(
+ Asn1Sequence seq)
+ {
+ this.issuerSerial = IssuerAndSerialNumber.GetInstance(seq);
+ }
+
+ public IssuerAndSerialNumber IssuerAndSerialNumber
+ {
+ get { return issuerSerial; }
+ }
+
+ public RecipientKeyIdentifier RKeyID
+ {
+ get { return rKeyID; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * KeyAgreeRecipientIdentifier ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * rKeyId [0] IMPLICIT RecipientKeyIdentifier
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ if (issuerSerial != null)
+ {
+ return issuerSerial.ToAsn1Object();
+ }
+
+ return new DerTaggedObject(false, 0, rKeyID);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/KeyAgreeRecipientInfo.cs b/iTechSharp/srcbc/asn1/cms/KeyAgreeRecipientInfo.cs
new file mode 100644
index 0000000..a0191ac
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/KeyAgreeRecipientInfo.cs
@@ -0,0 +1,143 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class KeyAgreeRecipientInfo
+ : Asn1Encodable
+ {
+ private DerInteger version;
+ private OriginatorIdentifierOrKey originator;
+ private Asn1OctetString ukm;
+ private AlgorithmIdentifier keyEncryptionAlgorithm;
+ private Asn1Sequence recipientEncryptedKeys;
+
+ public KeyAgreeRecipientInfo(
+ OriginatorIdentifierOrKey originator,
+ Asn1OctetString ukm,
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ Asn1Sequence recipientEncryptedKeys)
+ {
+ this.version = new DerInteger(3);
+ this.originator = originator;
+ this.ukm = ukm;
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.recipientEncryptedKeys = recipientEncryptedKeys;
+ }
+
+ public KeyAgreeRecipientInfo(
+ Asn1Sequence seq)
+ {
+ int index = 0;
+
+ version = (DerInteger) seq[index++];
+ originator = OriginatorIdentifierOrKey.GetInstance(
+ (Asn1TaggedObject) seq[index++], true);
+
+ if (seq[index] is Asn1TaggedObject)
+ {
+ ukm = Asn1OctetString.GetInstance(
+ (Asn1TaggedObject) seq[index++], true);
+ }
+
+ keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(
+ seq[index++]);
+
+ recipientEncryptedKeys = (Asn1Sequence) seq[index++];
+ }
+
+ /**
+ * return a KeyAgreeRecipientInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static KeyAgreeRecipientInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ /**
+ * return a KeyAgreeRecipientInfo object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static KeyAgreeRecipientInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is KeyAgreeRecipientInfo)
+ {
+ return (KeyAgreeRecipientInfo)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new KeyAgreeRecipientInfo((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException(
+ "Illegal object in KeyAgreeRecipientInfo: " + obj.GetType().Name);
+
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public OriginatorIdentifierOrKey Originator
+ {
+ get { return originator; }
+ }
+
+ public Asn1OctetString UserKeyingMaterial
+ {
+ get { return ukm; }
+ }
+
+ public AlgorithmIdentifier KeyEncryptionAlgorithm
+ {
+ get { return keyEncryptionAlgorithm; }
+ }
+
+ public Asn1Sequence RecipientEncryptedKeys
+ {
+ get { return recipientEncryptedKeys; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * KeyAgreeRecipientInfo ::= Sequence {
+ * version CMSVersion, -- always set to 3
+ * originator [0] EXPLICIT OriginatorIdentifierOrKey,
+ * ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * recipientEncryptedKeys RecipientEncryptedKeys
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, new DerTaggedObject(true, 0, originator));
+
+ if (ukm != null)
+ {
+ v.Add(new DerTaggedObject(true, 1, ukm));
+ }
+
+ v.Add(keyEncryptionAlgorithm, recipientEncryptedKeys);
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/KeyTransRecipientInfo.cs b/iTechSharp/srcbc/asn1/cms/KeyTransRecipientInfo.cs
new file mode 100644
index 0000000..01611e0
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/KeyTransRecipientInfo.cs
@@ -0,0 +1,103 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class KeyTransRecipientInfo
+ : Asn1Encodable
+ {
+ private DerInteger version;
+ private RecipientIdentifier rid;
+ private AlgorithmIdentifier keyEncryptionAlgorithm;
+ private Asn1OctetString encryptedKey;
+
+ public KeyTransRecipientInfo(
+ RecipientIdentifier rid,
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ Asn1OctetString encryptedKey)
+ {
+ if (rid.ToAsn1Object() is Asn1TaggedObject)
+ {
+ this.version = new DerInteger(2);
+ }
+ else
+ {
+ this.version = new DerInteger(0);
+ }
+
+ this.rid = rid;
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.encryptedKey = encryptedKey;
+ }
+
+ public KeyTransRecipientInfo(
+ Asn1Sequence seq)
+ {
+ this.version = (DerInteger) seq[0];
+ this.rid = RecipientIdentifier.GetInstance(seq[1]);
+ this.keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[2]);
+ this.encryptedKey = (Asn1OctetString) seq[3];
+ }
+
+ /**
+ * return a KeyTransRecipientInfo object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static KeyTransRecipientInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is KeyTransRecipientInfo)
+ {
+ return (KeyTransRecipientInfo) obj;
+ }
+
+ if(obj is Asn1Sequence)
+ {
+ return new KeyTransRecipientInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException(
+ "Illegal object in KeyTransRecipientInfo: " + obj.GetType().Name);
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public RecipientIdentifier RecipientIdentifier
+ {
+ get { return rid; }
+ }
+
+ public AlgorithmIdentifier KeyEncryptionAlgorithm
+ {
+ get { return keyEncryptionAlgorithm; }
+ }
+
+ public Asn1OctetString EncryptedKey
+ {
+ get { return encryptedKey; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * KeyTransRecipientInfo ::= Sequence {
+ * version CMSVersion, -- always set to 0 or 2
+ * rid RecipientIdentifier,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * encryptedKey EncryptedKey
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(version, rid, keyEncryptionAlgorithm, encryptedKey);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/OriginatorIdentifierOrKey.cs b/iTechSharp/srcbc/asn1/cms/OriginatorIdentifierOrKey.cs
new file mode 100644
index 0000000..6eeb1a3
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/OriginatorIdentifierOrKey.cs
@@ -0,0 +1,115 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class OriginatorIdentifierOrKey
+ : Asn1Encodable
+ {
+ private Asn1Encodable id;
+
+ public OriginatorIdentifierOrKey(
+ IssuerAndSerialNumber id)
+ {
+ this.id = id;
+ }
+
+ public OriginatorIdentifierOrKey(
+ Asn1OctetString id)
+ {
+ this.id = new DerTaggedObject(false, 0, id);
+ }
+
+ public OriginatorIdentifierOrKey(
+ OriginatorPublicKey id)
+ {
+ this.id = new DerTaggedObject(false, 1, id);
+ }
+
+ public OriginatorIdentifierOrKey(
+ Asn1Object id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * return an OriginatorIdentifierOrKey object from a tagged object.
+ *
+ * @param o the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OriginatorIdentifierOrKey GetInstance(
+ Asn1TaggedObject o,
+ bool explicitly)
+ {
+ if (!explicitly)
+ {
+ throw new ArgumentException(
+ "Can't implicitly tag OriginatorIdentifierOrKey");
+ }
+
+ return GetInstance(o.GetObject());
+ }
+
+ /**
+ * return an OriginatorIdentifierOrKey object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static OriginatorIdentifierOrKey GetInstance(
+ object o)
+ {
+ if (o == null || o is OriginatorIdentifierOrKey)
+ {
+ return (OriginatorIdentifierOrKey)o;
+ }
+
+ if (o is Asn1Object)
+ {
+ return new OriginatorIdentifierOrKey((Asn1Object)o);
+ }
+
+ throw new ArgumentException("Invalid OriginatorIdentifierOrKey: " + o.GetType().Name);
+ }
+
+ public Asn1Encodable ID
+ {
+ get { return id; }
+ }
+
+ public OriginatorPublicKey OriginatorKey
+ {
+ get
+ {
+ if (id is Asn1TaggedObject && ((Asn1TaggedObject)id).TagNo == 1)
+ {
+ return OriginatorPublicKey.GetInstance((Asn1TaggedObject)id, false);
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * OriginatorIdentifierOrKey ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * subjectKeyIdentifier [0] SubjectKeyIdentifier,
+ * originatorKey [1] OriginatorPublicKey
+ * }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return id.ToAsn1Object();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/OriginatorInfo.cs b/iTechSharp/srcbc/asn1/cms/OriginatorInfo.cs
new file mode 100644
index 0000000..829b85c
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/OriginatorInfo.cs
@@ -0,0 +1,125 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class OriginatorInfo
+ : Asn1Encodable
+ {
+ private Asn1Set certs;
+ private Asn1Set crls;
+
+ public OriginatorInfo(
+ Asn1Set certs,
+ Asn1Set crls)
+ {
+ this.certs = certs;
+ this.crls = crls;
+ }
+
+ public OriginatorInfo(
+ Asn1Sequence seq)
+ {
+ switch (seq.Count)
+ {
+ case 0: // empty
+ break;
+ case 1:
+ Asn1TaggedObject o = (Asn1TaggedObject) seq[0];
+ switch (o.TagNo)
+ {
+ case 0 :
+ certs = Asn1Set.GetInstance(o, false);
+ break;
+ case 1 :
+ crls = Asn1Set.GetInstance(o, false);
+ break;
+ default:
+ throw new ArgumentException("Bad tag in OriginatorInfo: " + o.TagNo);
+ }
+ break;
+ case 2:
+ certs = Asn1Set.GetInstance((Asn1TaggedObject) seq[0], false);
+ crls = Asn1Set.GetInstance((Asn1TaggedObject) seq[1], false);
+ break;
+ default:
+ throw new ArgumentException("OriginatorInfo too big");
+ }
+ }
+
+ /**
+ * return an OriginatorInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OriginatorInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ /**
+ * return an OriginatorInfo object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static OriginatorInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is OriginatorInfo)
+ {
+ return (OriginatorInfo)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new OriginatorInfo((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Invalid OriginatorInfo: " + obj.GetType().Name);
+ }
+
+ public Asn1Set Certificates
+ {
+ get { return certs; }
+ }
+
+ public Asn1Set Crls
+ {
+ get { return crls; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * OriginatorInfo ::= Sequence {
+ * certs [0] IMPLICIT CertificateSet OPTIONAL,
+ * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (certs != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, certs));
+ }
+
+ if (crls != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, crls));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/OriginatorPublicKey.cs b/iTechSharp/srcbc/asn1/cms/OriginatorPublicKey.cs
new file mode 100644
index 0000000..4e6be3b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/OriginatorPublicKey.cs
@@ -0,0 +1,91 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class OriginatorPublicKey
+ : Asn1Encodable
+ {
+ private AlgorithmIdentifier algorithm;
+ private DerBitString publicKey;
+
+ public OriginatorPublicKey(
+ AlgorithmIdentifier algorithm,
+ byte[] publicKey)
+ {
+ this.algorithm = algorithm;
+ this.publicKey = new DerBitString(publicKey);
+ }
+
+ public OriginatorPublicKey(
+ Asn1Sequence seq)
+ {
+ algorithm = AlgorithmIdentifier.GetInstance(seq[0]);
+ publicKey = (DerBitString) seq[1];
+ }
+
+ /**
+ * return an OriginatorPublicKey object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OriginatorPublicKey GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ /**
+ * return an OriginatorPublicKey object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static OriginatorPublicKey GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is OriginatorPublicKey)
+ {
+ return (OriginatorPublicKey)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new OriginatorPublicKey((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid OriginatorPublicKey: " + obj.GetType().Name);
+ }
+
+ public AlgorithmIdentifier Algorithm
+ {
+ get { return algorithm; }
+ }
+
+ public DerBitString PublicKey
+ {
+ get { return publicKey; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * OriginatorPublicKey ::= Sequence {
+ * algorithm AlgorithmIdentifier,
+ * publicKey BIT STRING
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(algorithm, publicKey);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/OtherKeyAttribute.cs b/iTechSharp/srcbc/asn1/cms/OtherKeyAttribute.cs
new file mode 100644
index 0000000..4366cf8
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/OtherKeyAttribute.cs
@@ -0,0 +1,74 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class OtherKeyAttribute
+ : Asn1Encodable
+ {
+ private DerObjectIdentifier keyAttrId;
+ private Asn1Encodable keyAttr;
+
+ /**
+ * return an OtherKeyAttribute object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static OtherKeyAttribute GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is OtherKeyAttribute)
+ {
+ return (OtherKeyAttribute) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new OtherKeyAttribute((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public OtherKeyAttribute(
+ Asn1Sequence seq)
+ {
+ keyAttrId = (DerObjectIdentifier) seq[0];
+ keyAttr = seq[1];
+ }
+
+ public OtherKeyAttribute(
+ DerObjectIdentifier keyAttrId,
+ Asn1Encodable keyAttr)
+ {
+ this.keyAttrId = keyAttrId;
+ this.keyAttr = keyAttr;
+ }
+
+ public DerObjectIdentifier KeyAttrId
+ {
+ get { return keyAttrId; }
+ }
+
+ public Asn1Encodable KeyAttr
+ {
+ get { return keyAttr; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * OtherKeyAttribute ::= Sequence {
+ * keyAttrId OBJECT IDENTIFIER,
+ * keyAttr ANY DEFINED BY keyAttrId OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(keyAttrId, keyAttr);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/OtherRecipientInfo.cs b/iTechSharp/srcbc/asn1/cms/OtherRecipientInfo.cs
new file mode 100644
index 0000000..153d2ac
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/OtherRecipientInfo.cs
@@ -0,0 +1,89 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class OtherRecipientInfo
+ : Asn1Encodable
+ {
+ private DerObjectIdentifier oriType;
+ private Asn1Encodable oriValue;
+
+ public OtherRecipientInfo(
+ DerObjectIdentifier oriType,
+ Asn1Encodable oriValue)
+ {
+ this.oriType = oriType;
+ this.oriValue = oriValue;
+ }
+
+ public OtherRecipientInfo(
+ Asn1Sequence seq)
+ {
+ oriType = DerObjectIdentifier.GetInstance(seq[0]);
+ oriValue = seq[1];
+ }
+
+ /**
+ * return a OtherRecipientInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static OtherRecipientInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ /**
+ * return a OtherRecipientInfo object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static OtherRecipientInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is OtherRecipientInfo)
+ {
+ return (OtherRecipientInfo)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new OtherRecipientInfo((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Invalid OtherRecipientInfo: " + obj.GetType().Name);
+ }
+
+ public DerObjectIdentifier OriType
+ {
+ get { return oriType; }
+ }
+
+ public Asn1Encodable OriValue
+ {
+ get { return oriValue; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * OtherRecipientInfo ::= Sequence {
+ * oriType OBJECT IDENTIFIER,
+ * oriValue ANY DEFINED BY oriType }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(oriType, oriValue);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/PasswordRecipientInfo.cs b/iTechSharp/srcbc/asn1/cms/PasswordRecipientInfo.cs
new file mode 100644
index 0000000..55e3a04
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/PasswordRecipientInfo.cs
@@ -0,0 +1,137 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class PasswordRecipientInfo
+ : Asn1Encodable
+ {
+ private readonly DerInteger version;
+ private readonly AlgorithmIdentifier keyDerivationAlgorithm;
+ private readonly AlgorithmIdentifier keyEncryptionAlgorithm;
+ private readonly Asn1OctetString encryptedKey;
+
+ public PasswordRecipientInfo(
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ Asn1OctetString encryptedKey)
+ {
+ this.version = new DerInteger(0);
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.encryptedKey = encryptedKey;
+ }
+
+ public PasswordRecipientInfo(
+ AlgorithmIdentifier keyDerivationAlgorithm,
+ AlgorithmIdentifier keyEncryptionAlgorithm,
+ Asn1OctetString encryptedKey)
+ {
+ this.version = new DerInteger(0);
+ this.keyDerivationAlgorithm = keyDerivationAlgorithm;
+ this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+ this.encryptedKey = encryptedKey;
+ }
+
+ public PasswordRecipientInfo(
+ Asn1Sequence seq)
+ {
+ version = (DerInteger) seq[0];
+
+ if (seq[1] is Asn1TaggedObject)
+ {
+ keyDerivationAlgorithm = AlgorithmIdentifier.GetInstance((Asn1TaggedObject) seq[1], false);
+ keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[2]);
+ encryptedKey = (Asn1OctetString) seq[3];
+ }
+ else
+ {
+ keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]);
+ encryptedKey = (Asn1OctetString) seq[2];
+ }
+ }
+
+ /**
+ * return a PasswordRecipientInfo object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicitly true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static PasswordRecipientInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ /**
+ * return a PasswordRecipientInfo object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static PasswordRecipientInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is PasswordRecipientInfo)
+ {
+ return (PasswordRecipientInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new PasswordRecipientInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid PasswordRecipientInfo: " + obj.GetType().Name);
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public AlgorithmIdentifier KeyDerivationAlgorithm
+ {
+ get { return keyDerivationAlgorithm; }
+ }
+
+ public AlgorithmIdentifier KeyEncryptionAlgorithm
+ {
+ get { return keyEncryptionAlgorithm; }
+ }
+
+ public Asn1OctetString EncryptedKey
+ {
+ get { return encryptedKey; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * PasswordRecipientInfo ::= Sequence {
+ * version CMSVersion, -- Always set to 0
+ * keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier
+ * OPTIONAL,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * encryptedKey EncryptedKey }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(version);
+
+ if (keyDerivationAlgorithm != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, keyDerivationAlgorithm));
+ }
+
+ v.Add(keyEncryptionAlgorithm, encryptedKey);
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/RecipientEncryptedKey.cs b/iTechSharp/srcbc/asn1/cms/RecipientEncryptedKey.cs
new file mode 100644
index 0000000..5ba25a7
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/RecipientEncryptedKey.cs
@@ -0,0 +1,88 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class RecipientEncryptedKey
+ : Asn1Encodable
+ {
+ private readonly KeyAgreeRecipientIdentifier identifier;
+ private readonly Asn1OctetString encryptedKey;
+
+ private RecipientEncryptedKey(
+ Asn1Sequence seq)
+ {
+ identifier = KeyAgreeRecipientIdentifier.GetInstance(seq[0]);
+ encryptedKey = (Asn1OctetString) seq[1];
+ }
+
+ /**
+ * return an RecipientEncryptedKey object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param isExplicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static RecipientEncryptedKey GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+ }
+
+ /**
+ * return a RecipientEncryptedKey object from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static RecipientEncryptedKey GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is RecipientEncryptedKey)
+ {
+ return (RecipientEncryptedKey) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new RecipientEncryptedKey((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid RecipientEncryptedKey: " + obj.GetType().FullName, "obj");
+ }
+
+ public RecipientEncryptedKey(
+ KeyAgreeRecipientIdentifier id,
+ Asn1OctetString encryptedKey)
+ {
+ this.identifier = id;
+ this.encryptedKey = encryptedKey;
+ }
+
+ public KeyAgreeRecipientIdentifier Identifier
+ {
+ get { return identifier; }
+ }
+
+ public Asn1OctetString EncryptedKey
+ {
+ get { return encryptedKey; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * RecipientEncryptedKey ::= SEQUENCE {
+ * rid KeyAgreeRecipientIdentifier,
+ * encryptedKey EncryptedKey
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(identifier, encryptedKey);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/RecipientIdentifier.cs b/iTechSharp/srcbc/asn1/cms/RecipientIdentifier.cs
new file mode 100644
index 0000000..e8f2724
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/RecipientIdentifier.cs
@@ -0,0 +1,94 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class RecipientIdentifier
+ : Asn1Encodable
+ {
+ private Asn1Encodable id;
+
+ public RecipientIdentifier(
+ IssuerAndSerialNumber id)
+ {
+ this.id = id;
+ }
+
+ public RecipientIdentifier(
+ Asn1OctetString id)
+ {
+ this.id = new DerTaggedObject(false, 0, id);
+ }
+
+ public RecipientIdentifier(
+ Asn1Object id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * return a RecipientIdentifier object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static RecipientIdentifier GetInstance(
+ object o)
+ {
+ if (o == null || o is RecipientIdentifier)
+ {
+ return (RecipientIdentifier)o;
+ }
+
+ if (o is IssuerAndSerialNumber)
+ {
+ return new RecipientIdentifier((IssuerAndSerialNumber) o);
+ }
+
+ if (o is Asn1OctetString)
+ {
+ return new RecipientIdentifier((Asn1OctetString) o);
+ }
+
+ if (o is Asn1Object)
+ {
+ return new RecipientIdentifier((Asn1Object) o);
+ }
+
+ throw new ArgumentException(
+ "Illegal object in RecipientIdentifier: " + o.GetType().Name);
+ }
+
+ public bool IsTagged { get { return (id is Asn1TaggedObject); } }
+
+ public Asn1Encodable ID
+ {
+ get
+ {
+ if (id is Asn1TaggedObject)
+ {
+ return Asn1OctetString.GetInstance((Asn1TaggedObject) id, false);
+ }
+
+ return IssuerAndSerialNumber.GetInstance(id);
+ }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * RecipientIdentifier ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * subjectKeyIdentifier [0] SubjectKeyIdentifier
+ * }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return id.ToAsn1Object();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/RecipientInfo.cs b/iTechSharp/srcbc/asn1/cms/RecipientInfo.cs
new file mode 100644
index 0000000..a9b171f
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/RecipientInfo.cs
@@ -0,0 +1,151 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class RecipientInfo
+ : Asn1Encodable
+ {
+ internal Asn1Encodable info;
+
+ public RecipientInfo(
+ KeyTransRecipientInfo info)
+ {
+ this.info = info;
+ }
+
+ public RecipientInfo(
+ KeyAgreeRecipientInfo info)
+ {
+ this.info = new DerTaggedObject(false, 1, info);
+ }
+
+ public RecipientInfo(
+ KekRecipientInfo info)
+ {
+ this.info = new DerTaggedObject(false, 2, info);
+ }
+
+ public RecipientInfo(
+ PasswordRecipientInfo info)
+ {
+ this.info = new DerTaggedObject(false, 3, info);
+ }
+
+ public RecipientInfo(
+ OtherRecipientInfo info)
+ {
+ this.info = new DerTaggedObject(false, 4, info);
+ }
+
+ public RecipientInfo(
+ Asn1Object info)
+ {
+ this.info = info;
+ }
+
+ public static RecipientInfo GetInstance(
+ object o)
+ {
+ if (o == null || o is RecipientInfo)
+ {
+ return (RecipientInfo) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new RecipientInfo((Asn1Sequence) o);
+ }
+
+ if (o is Asn1TaggedObject)
+ {
+ return new RecipientInfo((Asn1TaggedObject) o);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + o.GetType().Name);
+ }
+
+ public DerInteger Version
+ {
+ get
+ {
+ if (info is Asn1TaggedObject)
+ {
+ Asn1TaggedObject o = (Asn1TaggedObject) info;
+
+ switch (o.TagNo)
+ {
+ case 1:
+ return KeyAgreeRecipientInfo.GetInstance(o, false).Version;
+ case 2:
+ return GetKekInfo(o).Version;
+ case 3:
+ return PasswordRecipientInfo.GetInstance(o, false).Version;
+ case 4:
+ return new DerInteger(0); // no syntax version for OtherRecipientInfo
+ default:
+ throw new InvalidOperationException("unknown tag");
+ }
+ }
+
+ return KeyTransRecipientInfo.GetInstance(info).Version;
+ }
+ }
+
+ public bool IsTagged
+ {
+ get { return info is Asn1TaggedObject; }
+ }
+
+ public Asn1Encodable Info
+ {
+ get
+ {
+ if (info is Asn1TaggedObject)
+ {
+ Asn1TaggedObject o = (Asn1TaggedObject) info;
+
+ switch (o.TagNo)
+ {
+ case 1:
+ return KeyAgreeRecipientInfo.GetInstance(o, false);
+ case 2:
+ return GetKekInfo(o);
+ case 3:
+ return PasswordRecipientInfo.GetInstance(o, false);
+ case 4:
+ return OtherRecipientInfo.GetInstance(o, false);
+ default:
+ throw new InvalidOperationException("unknown tag");
+ }
+ }
+
+ return KeyTransRecipientInfo.GetInstance(info);
+ }
+ }
+
+ private KekRecipientInfo GetKekInfo(
+ Asn1TaggedObject o)
+ {
+ // For compatibility with erroneous version, we don't always pass 'false' here
+ return KekRecipientInfo.GetInstance(o, o.IsExplicit());
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * RecipientInfo ::= CHOICE {
+ * ktri KeyTransRecipientInfo,
+ * kari [1] KeyAgreeRecipientInfo,
+ * kekri [2] KekRecipientInfo,
+ * pwri [3] PasswordRecipientInfo,
+ * ori [4] OtherRecipientInfo }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return info.ToAsn1Object();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/RecipientKeyIdentifier.cs b/iTechSharp/srcbc/asn1/cms/RecipientKeyIdentifier.cs
new file mode 100644
index 0000000..05ce8bf
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/RecipientKeyIdentifier.cs
@@ -0,0 +1,135 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class RecipientKeyIdentifier
+ : Asn1Encodable
+ {
+ private Asn1OctetString subjectKeyIdentifier;
+ private DerGeneralizedTime date;
+ private OtherKeyAttribute other;
+
+ public RecipientKeyIdentifier(
+ Asn1OctetString subjectKeyIdentifier,
+ DerGeneralizedTime date,
+ OtherKeyAttribute other)
+ {
+ this.subjectKeyIdentifier = subjectKeyIdentifier;
+ this.date = date;
+ this.other = other;
+ }
+
+ public RecipientKeyIdentifier(
+ Asn1Sequence seq)
+ {
+ subjectKeyIdentifier = Asn1OctetString.GetInstance(
+ seq[0]);
+
+ switch(seq.Count)
+ {
+ case 1:
+ break;
+ case 2:
+ if (seq[1] is DerGeneralizedTime)
+ {
+ date = (DerGeneralizedTime) seq[1];
+ }
+ else
+ {
+ other = OtherKeyAttribute.GetInstance(seq[2]);
+ }
+ break;
+ case 3:
+ date = (DerGeneralizedTime) seq[1];
+ other = OtherKeyAttribute.GetInstance(seq[2]);
+ break;
+ default:
+ throw new ArgumentException("Invalid KekIdentifier");
+ }
+ }
+
+ /**
+ * return a RecipientKeyIdentifier object from a tagged object.
+ *
+ * @param _ato the tagged object holding the object we want.
+ * @param _explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception ArgumentException if the object held by the
+ * tagged object cannot be converted.
+ */
+ public static RecipientKeyIdentifier GetInstance(
+ Asn1TaggedObject ato,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(ato, explicitly));
+ }
+
+ /**
+ * return a RecipientKeyIdentifier object from the given object.
+ *
+ * @param _obj the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static RecipientKeyIdentifier GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is RecipientKeyIdentifier)
+ {
+ return (RecipientKeyIdentifier) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new RecipientKeyIdentifier((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid RecipientKeyIdentifier: " + obj.GetType().Name);
+ }
+
+ public Asn1OctetString SubjectKeyIdentifier
+ {
+ get { return subjectKeyIdentifier; }
+ }
+
+ public DerGeneralizedTime Date
+ {
+ get { return date; }
+ }
+
+ public OtherKeyAttribute OtherKeyAttribute
+ {
+ get { return other; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * RecipientKeyIdentifier ::= Sequence {
+ * subjectKeyIdentifier SubjectKeyIdentifier,
+ * date GeneralizedTime OPTIONAL,
+ * other OtherKeyAttribute OPTIONAL
+ * }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(subjectKeyIdentifier);
+
+ if (date != null)
+ {
+ v.Add(date);
+ }
+
+ if (other != null)
+ {
+ v.Add(other);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/SignedData.cs b/iTechSharp/srcbc/asn1/cms/SignedData.cs
new file mode 100644
index 0000000..e2d5bd3
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/SignedData.cs
@@ -0,0 +1,292 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ /**
+ * a signed data object.
+ */
+ public class SignedData
+ : Asn1Encodable
+ {
+ private readonly DerInteger version;
+ private readonly Asn1Set digestAlgorithms;
+ private readonly ContentInfo contentInfo;
+ private readonly Asn1Set certificates;
+ private readonly Asn1Set crls;
+ private readonly Asn1Set signerInfos;
+ private readonly bool certsBer;
+ private readonly bool crlsBer;
+
+ public static SignedData GetInstance(
+ object obj)
+ {
+ if (obj is SignedData)
+ {
+ return (SignedData) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SignedData((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public SignedData(
+ Asn1Set digestAlgorithms,
+ ContentInfo contentInfo,
+ Asn1Set certificates,
+ Asn1Set crls,
+ Asn1Set signerInfos)
+ {
+ this.version = CalculateVersion(contentInfo.ContentType, certificates, crls, signerInfos);
+ this.digestAlgorithms = digestAlgorithms;
+ this.contentInfo = contentInfo;
+ this.certificates = certificates;
+ this.crls = crls;
+ this.signerInfos = signerInfos;
+ this.crlsBer = crls is BerSet;
+ this.certsBer = certificates is BerSet;
+ }
+
+ // RFC3852, section 5.1:
+ // IF ((certificates is present) AND
+ // (any certificates with a type of other are present)) OR
+ // ((crls is present) AND
+ // (any crls with a type of other are present))
+ // THEN version MUST be 5
+ // ELSE
+ // IF (certificates is present) AND
+ // (any version 2 attribute certificates are present)
+ // THEN version MUST be 4
+ // ELSE
+ // IF ((certificates is present) AND
+ // (any version 1 attribute certificates are present)) OR
+ // (any SignerInfo structures are version 3) OR
+ // (encapContentInfo eContentType is other than id-data)
+ // THEN version MUST be 3
+ // ELSE version MUST be 1
+ //
+ private DerInteger CalculateVersion(
+ DerObjectIdentifier contentOid,
+ Asn1Set certs,
+ Asn1Set crls,
+ Asn1Set signerInfs)
+ {
+ bool otherCert = false;
+ bool otherCrl = false;
+ bool attrCertV1Found = false;
+ bool attrCertV2Found = false;
+
+ if (certs != null)
+ {
+ foreach (object obj in certs)
+ {
+ if (obj is Asn1TaggedObject)
+ {
+ Asn1TaggedObject tagged = (Asn1TaggedObject)obj;
+
+ if (tagged.TagNo == 1)
+ {
+ attrCertV1Found = true;
+ }
+ else if (tagged.TagNo == 2)
+ {
+ attrCertV2Found = true;
+ }
+ else if (tagged.TagNo == 3)
+ {
+ otherCert = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (otherCert)
+ {
+ return new DerInteger(5);
+ }
+
+ if (crls != null)
+ {
+ foreach (object obj in crls)
+ {
+ if (obj is Asn1TaggedObject)
+ {
+ otherCrl = true;
+ break;
+ }
+ }
+ }
+
+ if (otherCrl)
+ {
+ return new DerInteger(5);
+ }
+
+ if (attrCertV2Found)
+ {
+ return new DerInteger(4);
+ }
+
+ if (attrCertV1Found)
+ {
+ return new DerInteger(3);
+ }
+
+ if (contentOid.Equals(CmsObjectIdentifiers.Data)
+ && !CheckForVersion3(signerInfs))
+ {
+ return new DerInteger(1);
+ }
+
+ return new DerInteger(3);
+ }
+
+ private bool CheckForVersion3(
+ Asn1Set signerInfs)
+ {
+ foreach (object obj in signerInfs)
+ {
+ SignerInfo s = SignerInfo.GetInstance(obj);
+
+ if (s.Version.Value.IntValue == 3)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private SignedData(
+ Asn1Sequence seq)
+ {
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ version = (DerInteger)e.Current;
+
+ e.MoveNext();
+ digestAlgorithms = ((Asn1Set)e.Current);
+
+ e.MoveNext();
+ contentInfo = ContentInfo.GetInstance(e.Current);
+
+ while (e.MoveNext())
+ {
+ Asn1Object o = (Asn1Object)e.Current;
+
+ //
+ // an interesting feature of SignedData is that there appear
+ // to be varying implementations...
+ // for the moment we ignore anything which doesn't fit.
+ //
+ if (o is Asn1TaggedObject)
+ {
+ Asn1TaggedObject tagged = (Asn1TaggedObject)o;
+
+ switch (tagged.TagNo)
+ {
+ case 0:
+ certsBer = tagged is BerTaggedObject;
+ certificates = Asn1Set.GetInstance(tagged, false);
+ break;
+ case 1:
+ crlsBer = tagged is BerTaggedObject;
+ crls = Asn1Set.GetInstance(tagged, false);
+ break;
+ default:
+ throw new ArgumentException("unknown tag value " + tagged.TagNo);
+ }
+ }
+ else
+ {
+ signerInfos = (Asn1Set) o;
+ }
+ }
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public Asn1Set DigestAlgorithms
+ {
+ get { return digestAlgorithms; }
+ }
+
+ public ContentInfo EncapContentInfo
+ {
+ get { return contentInfo; }
+ }
+
+ public Asn1Set Certificates
+ {
+ get { return certificates; }
+ }
+
+ public Asn1Set CRLs
+ {
+ get { return crls; }
+ }
+
+ public Asn1Set SignerInfos
+ {
+ get { return signerInfos; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * SignedData ::= Sequence {
+ * version CMSVersion,
+ * digestAlgorithms DigestAlgorithmIdentifiers,
+ * encapContentInfo EncapsulatedContentInfo,
+ * certificates [0] IMPLICIT CertificateSet OPTIONAL,
+ * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ * signerInfos SignerInfos
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, digestAlgorithms, contentInfo);
+
+ if (certificates != null)
+ {
+ if (certsBer)
+ {
+ v.Add(new BerTaggedObject(false, 0, certificates));
+ }
+ else
+ {
+ v.Add(new DerTaggedObject(false, 0, certificates));
+ }
+ }
+
+ if (crls != null)
+ {
+ if (crlsBer)
+ {
+ v.Add(new BerTaggedObject(false, 1, crls));
+ }
+ else
+ {
+ v.Add(new DerTaggedObject(false, 1, crls));
+ }
+ }
+
+ v.Add(signerInfos);
+
+ return new BerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/SignedDataParser.cs b/iTechSharp/srcbc/asn1/cms/SignedDataParser.cs
new file mode 100644
index 0000000..3413092
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/SignedDataParser.cs
@@ -0,0 +1,112 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ /**
+ *
+ * SignedData ::= SEQUENCE {
+ * version CMSVersion,
+ * digestAlgorithms DigestAlgorithmIdentifiers,
+ * encapContentInfo EncapsulatedContentInfo,
+ * certificates [0] IMPLICIT CertificateSet OPTIONAL,
+ * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ * signerInfos SignerInfos
+ * }
+ *
+ */
+ public class SignedDataParser
+ {
+ private Asn1SequenceParser _seq;
+ private DerInteger _version;
+ private object _nextObject;
+ private bool _certsCalled;
+ private bool _crlsCalled;
+
+ public static SignedDataParser GetInstance(
+ object o)
+ {
+ if (o is Asn1Sequence)
+ return new SignedDataParser(((Asn1Sequence)o).Parser);
+
+ if (o is Asn1SequenceParser)
+ return new SignedDataParser((Asn1SequenceParser)o);
+
+ throw new IOException("unknown object encountered: " + o.GetType().Name);
+ }
+
+ public SignedDataParser(
+ Asn1SequenceParser seq)
+ {
+ this._seq = seq;
+ this._version = (DerInteger)seq.ReadObject();
+ }
+
+ public DerInteger Version
+ {
+ get { return _version; }
+ }
+
+ public Asn1SetParser GetDigestAlgorithms()
+ {
+ return (Asn1SetParser)_seq.ReadObject();
+ }
+
+ public ContentInfoParser GetEncapContentInfo()
+ {
+ return new ContentInfoParser((Asn1SequenceParser)_seq.ReadObject());
+ }
+
+ public Asn1SetParser GetCertificates()
+ {
+ _certsCalled = true;
+ _nextObject = _seq.ReadObject();
+
+ if (_nextObject is Asn1TaggedObjectParser && ((Asn1TaggedObjectParser)_nextObject).TagNo == 0)
+ {
+ Asn1SetParser certs = (Asn1SetParser)((Asn1TaggedObjectParser)_nextObject).GetObjectParser(Asn1Tags.Set, false);
+ _nextObject = null;
+
+ return certs;
+ }
+
+ return null;
+ }
+
+ public Asn1SetParser GetCrls()
+ {
+ if (!_certsCalled)
+ throw new IOException("GetCerts() has not been called.");
+
+ _crlsCalled = true;
+
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.ReadObject();
+ }
+
+ if (_nextObject is Asn1TaggedObjectParser && ((Asn1TaggedObjectParser)_nextObject).TagNo == 1)
+ {
+ Asn1SetParser crls = (Asn1SetParser)((Asn1TaggedObjectParser)_nextObject).GetObjectParser(Asn1Tags.Set, false);
+ _nextObject = null;
+
+ return crls;
+ }
+
+ return null;
+ }
+
+ public Asn1SetParser GetSignerInfos()
+ {
+ if (!_certsCalled || !_crlsCalled)
+ throw new IOException("GetCerts() and/or GetCrls() has not been called.");
+
+ if (_nextObject == null)
+ {
+ _nextObject = _seq.ReadObject();
+ }
+
+ return (Asn1SetParser)_nextObject;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/SignerIdentifier.cs b/iTechSharp/srcbc/asn1/cms/SignerIdentifier.cs
new file mode 100644
index 0000000..07c24c0
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/SignerIdentifier.cs
@@ -0,0 +1,94 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class SignerIdentifier
+ : Asn1Encodable
+ {
+ private Asn1Encodable id;
+
+ public SignerIdentifier(
+ IssuerAndSerialNumber id)
+ {
+ this.id = id;
+ }
+
+ public SignerIdentifier(
+ Asn1OctetString id)
+ {
+ this.id = new DerTaggedObject(false, 0, id);
+ }
+
+ public SignerIdentifier(
+ Asn1Object id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * return a SignerIdentifier object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static SignerIdentifier GetInstance(
+ object o)
+ {
+ if (o == null || o is SignerIdentifier)
+ {
+ return (SignerIdentifier) o;
+ }
+
+ if (o is IssuerAndSerialNumber)
+ {
+ return new SignerIdentifier((IssuerAndSerialNumber) o);
+ }
+
+ if (o is Asn1OctetString)
+ {
+ return new SignerIdentifier((Asn1OctetString) o);
+ }
+
+ if (o is Asn1Object)
+ {
+ return new SignerIdentifier((Asn1Object) o);
+ }
+
+ throw new ArgumentException(
+ "Illegal object in SignerIdentifier: " + o.GetType().Name);
+ }
+
+ public bool IsTagged { get { return (id is Asn1TaggedObject); } }
+
+ public Asn1Encodable ID
+ {
+ get
+ {
+ if (id is Asn1TaggedObject)
+ {
+ return Asn1OctetString.GetInstance((Asn1TaggedObject)id, false);
+ }
+
+ return id;
+ }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * SignerIdentifier ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * subjectKeyIdentifier [0] SubjectKeyIdentifier
+ * }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return id.ToAsn1Object();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/SignerInfo.cs b/iTechSharp/srcbc/asn1/cms/SignerInfo.cs
new file mode 100644
index 0000000..d478507
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/SignerInfo.cs
@@ -0,0 +1,158 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class SignerInfo
+ : Asn1Encodable
+ {
+ private DerInteger version;
+ private SignerIdentifier sid;
+ private AlgorithmIdentifier digAlgorithm;
+ private Asn1Set authenticatedAttributes;
+ private AlgorithmIdentifier digEncryptionAlgorithm;
+ private Asn1OctetString encryptedDigest;
+ private Asn1Set unauthenticatedAttributes;
+
+ public static SignerInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is SignerInfo)
+ {
+ return (SignerInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SignerInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public SignerInfo(
+ SignerIdentifier sid,
+ AlgorithmIdentifier digAlgorithm,
+ Asn1Set authenticatedAttributes,
+ AlgorithmIdentifier digEncryptionAlgorithm,
+ Asn1OctetString encryptedDigest,
+ Asn1Set unauthenticatedAttributes)
+ {
+ if (sid.IsTagged)
+ {
+ this.version = new DerInteger(3);
+ }
+ else
+ {
+ this.version = new DerInteger(1);
+ }
+
+ this.sid = sid;
+ this.digAlgorithm = digAlgorithm;
+ this.authenticatedAttributes = authenticatedAttributes;
+ this.digEncryptionAlgorithm = digEncryptionAlgorithm;
+ this.encryptedDigest = encryptedDigest;
+ this.unauthenticatedAttributes = unauthenticatedAttributes;
+ }
+
+ public SignerInfo(
+ Asn1Sequence seq)
+ {
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ version = (DerInteger) e.Current;
+
+ e.MoveNext();
+ sid = SignerIdentifier.GetInstance(e.Current);
+
+ e.MoveNext();
+ digAlgorithm = AlgorithmIdentifier.GetInstance(e.Current);
+
+ e.MoveNext();
+ object obj = e.Current;
+
+ if (obj is Asn1TaggedObject)
+ {
+ authenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject) obj, false);
+
+ e.MoveNext();
+ digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(e.Current);
+ }
+ else
+ {
+ authenticatedAttributes = null;
+ digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(obj);
+ }
+
+ e.MoveNext();
+ encryptedDigest = DerOctetString.GetInstance(e.Current);
+
+ if (e.MoveNext())
+ {
+ unauthenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false);
+ }
+ else
+ {
+ unauthenticatedAttributes = null;
+ }
+ }
+
+ public DerInteger Version { get { return version; } }
+
+ public SignerIdentifier SignerID { get { return sid; } }
+
+ public Asn1Set AuthenticatedAttributes { get { return authenticatedAttributes; } }
+
+ public AlgorithmIdentifier DigestAlgorithm { get { return digAlgorithm; } }
+
+ public Asn1OctetString EncryptedDigest { get { return encryptedDigest; } }
+
+ public AlgorithmIdentifier DigestEncryptionAlgorithm { get { return digEncryptionAlgorithm; } }
+
+ public Asn1Set UnauthenticatedAttributes { get { return unauthenticatedAttributes; } }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * SignerInfo ::= Sequence {
+ * version Version,
+ * SignerIdentifier sid,
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
+ * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+ * encryptedDigest EncryptedDigest,
+ * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+ * }
+ *
+ * EncryptedDigest ::= OCTET STRING
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, sid, digAlgorithm);
+
+ if (authenticatedAttributes != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, authenticatedAttributes));
+ }
+
+ v.Add(digEncryptionAlgorithm, encryptedDigest);
+
+ if (unauthenticatedAttributes != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, unauthenticatedAttributes));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cms/Time.cs b/iTechSharp/srcbc/asn1/cms/Time.cs
new file mode 100644
index 0000000..3fad3b9
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cms/Time.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Globalization;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+ public class Time
+ : Asn1Encodable
+ {
+ private readonly Asn1Object time;
+
+ public static Time GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(obj.GetObject());
+ }
+
+ public Time(
+ Asn1Object time)
+ {
+ if (!(time is DerUtcTime)
+ && !(time is DerGeneralizedTime))
+ {
+ throw new ArgumentException("unknown object passed to Time");
+ }
+
+ this.time = time;
+ }
+
+ /**
+ * creates a time object from a given date - if the date is between 1950
+ * and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime
+ * is used.
+ */
+ public Time(
+ DateTime date)
+ {
+ string d = date.ToString("yyyyMMddHHmmss") + "Z";
+
+ int year = int.Parse(d.Substring(0, 4));
+
+ if (year < 1950 || year > 2049)
+ {
+ time = new DerGeneralizedTime(d);
+ }
+ else
+ {
+ time = new DerUtcTime(d.Substring(2));
+ }
+ }
+
+ public static Time GetInstance(
+ object obj)
+ {
+ if (obj is Time)
+ {
+ return (Time)obj;
+ }
+
+ if (obj is DerUtcTime)
+ {
+ return new Time((DerUtcTime)obj);
+ }
+
+ if (obj is DerGeneralizedTime)
+ {
+ return new Time((DerGeneralizedTime)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public string TimeString
+ {
+ get
+ {
+ if (time is DerUtcTime)
+ {
+ return ((DerUtcTime)time).AdjustedTimeString;
+ }
+ else
+ {
+ return ((DerGeneralizedTime)time).GetTime();
+ }
+ }
+ }
+
+ public DateTime Date
+ {
+ get
+ {
+ try
+ {
+ if (time is DerUtcTime)
+ {
+ return ((DerUtcTime)time).ToAdjustedDateTime();
+ }
+
+ return ((DerGeneralizedTime)time).ToDateTime();
+ }
+ catch (FormatException e)
+ {
+ // this should never happen
+ throw new InvalidOperationException("invalid date string: " + e.Message);
+ }
+ }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return time;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cryptopro/CryptoProObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/cryptopro/CryptoProObjectIdentifiers.cs
new file mode 100644
index 0000000..6e0e023
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cryptopro/CryptoProObjectIdentifiers.cs
@@ -0,0 +1,48 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.CryptoPro
+{
+ public abstract class CryptoProObjectIdentifiers
+ {
+ // GOST Algorithms OBJECT IDENTIFIERS :
+ // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2)}
+ public const string GostID = "1.2.643.2.2";
+
+ public static readonly DerObjectIdentifier GostR3411 = new DerObjectIdentifier(GostID + ".9");
+
+ public static readonly DerObjectIdentifier GostR28147Cbc = new DerObjectIdentifier(GostID + ".21");
+
+ public static readonly DerObjectIdentifier GostR3410x94 = new DerObjectIdentifier(GostID + ".20");
+ public static readonly DerObjectIdentifier GostR3410x2001 = new DerObjectIdentifier(GostID + ".19");
+ public static readonly DerObjectIdentifier GostR3411x94WithGostR3410x94 = new DerObjectIdentifier(GostID + ".4");
+ public static readonly DerObjectIdentifier GostR3411x94WithGostR3410x2001 = new DerObjectIdentifier(GostID + ".3");
+
+ // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) hashes(30) }
+ public static readonly DerObjectIdentifier GostR3411x94CryptoProParamSet = new DerObjectIdentifier(GostID + ".30.1");
+
+ // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) signs(32) }
+ public static readonly DerObjectIdentifier GostR3410x94CryptoProA = new DerObjectIdentifier(GostID + ".32.2");
+ public static readonly DerObjectIdentifier GostR3410x94CryptoProB = new DerObjectIdentifier(GostID + ".32.3");
+ public static readonly DerObjectIdentifier GostR3410x94CryptoProC = new DerObjectIdentifier(GostID + ".32.4");
+ public static readonly DerObjectIdentifier GostR3410x94CryptoProD = new DerObjectIdentifier(GostID + ".32.5");
+
+ // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) exchanges(33) }
+ public static readonly DerObjectIdentifier GostR3410x94CryptoProXchA = new DerObjectIdentifier(GostID + ".33.1");
+ public static readonly DerObjectIdentifier GostR3410x94CryptoProXchB = new DerObjectIdentifier(GostID + ".33.2");
+ public static readonly DerObjectIdentifier GostR3410x94CryptoProXchC = new DerObjectIdentifier(GostID + ".33.3");
+
+ //{ iso(1) member-body(2)ru(643) rans(2) cryptopro(2) ecc-signs(35) }
+ public static readonly DerObjectIdentifier GostR3410x2001CryptoProA = new DerObjectIdentifier(GostID + ".35.1");
+ public static readonly DerObjectIdentifier GostR3410x2001CryptoProB = new DerObjectIdentifier(GostID + ".35.2");
+ public static readonly DerObjectIdentifier GostR3410x2001CryptoProC = new DerObjectIdentifier(GostID + ".35.3");
+
+ // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) ecc-exchanges(36) }
+ public static readonly DerObjectIdentifier GostR3410x2001CryptoProXchA = new DerObjectIdentifier(GostID + ".36.0");
+ public static readonly DerObjectIdentifier GostR3410x2001CryptoProXchB = new DerObjectIdentifier(GostID + ".36.1");
+
+ public static readonly DerObjectIdentifier GostElSgDH3410Default = new DerObjectIdentifier(GostID + ".36.0");
+ public static readonly DerObjectIdentifier GostElSgDH3410x1 = new DerObjectIdentifier(GostID + ".36.1");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cryptopro/ECGOST3410NamedCurves.cs b/iTechSharp/srcbc/asn1/cryptopro/ECGOST3410NamedCurves.cs
new file mode 100644
index 0000000..76b95bf
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cryptopro/ECGOST3410NamedCurves.cs
@@ -0,0 +1,178 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.CryptoPro
+{
+ /**
+ * table of the available named parameters for GOST 3410-2001.
+ */
+ public sealed class ECGost3410NamedCurves
+ {
+ private ECGost3410NamedCurves()
+ {
+ }
+
+ internal static readonly Hashtable objIds = new Hashtable();
+ internal static readonly Hashtable parameters = new Hashtable();
+ internal static readonly Hashtable names = new Hashtable();
+
+ static ECGost3410NamedCurves()
+ {
+ BigInteger mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319");
+ BigInteger mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323");
+
+ FpCurve curve = new FpCurve(
+ mod_p, // p
+ new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a
+ new BigInteger("166")); // b
+
+ ECDomainParameters ecParams = new ECDomainParameters(
+ curve,
+ curve.CreatePoint(
+ BigInteger.One, // x
+ new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"), // y
+ false),
+ mod_q);
+
+ parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = ecParams;
+
+ mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319");
+ mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323");
+
+ curve = new FpCurve(
+ mod_p, // p
+ new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"),
+ new BigInteger("166"));
+
+ ecParams = new ECDomainParameters(
+ curve,
+ curve.CreatePoint(
+ BigInteger.One, // x
+ new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"), // y
+ false),
+ mod_q);
+
+ parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA] = ecParams;
+
+ mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823193"); //p
+ mod_q = new BigInteger("57896044618658097711785492504343953927102133160255826820068844496087732066703"); //q
+
+ curve = new FpCurve(
+ mod_p, // p
+ new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a
+ new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595")); // b
+
+ ecParams = new ECDomainParameters(
+ curve,
+ curve.CreatePoint(
+ BigInteger.One, // x
+ new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124"), // y
+ false),
+ mod_q); // q
+
+ parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProB] = ecParams;
+
+ mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619");
+ mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601");
+
+ curve = new FpCurve(
+ mod_p, // p
+ new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"),
+ new BigInteger("32858"));
+
+ ecParams = new ECDomainParameters(
+ curve,
+ curve.CreatePoint(
+ BigInteger.Zero, // x
+ new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"), // y
+ false),
+ mod_q);
+
+ parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB] = ecParams;
+
+ mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); //p
+ mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); //q
+ curve = new FpCurve(
+ mod_p, // p
+ new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a
+ new BigInteger("32858")); // b
+
+ ecParams = new ECDomainParameters(
+ curve,
+ curve.CreatePoint(
+ BigInteger.Zero, // x
+ new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"), // y
+ false),
+ mod_q); // q
+
+ parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = ecParams;
+
+ objIds["GostR3410-2001-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProA;
+ objIds["GostR3410-2001-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProB;
+ objIds["GostR3410-2001-CryptoPro-C"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProC;
+ objIds["GostR3410-2001-CryptoPro-XchA"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA;
+ objIds["GostR3410-2001-CryptoPro-XchB"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB;
+
+ names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = "GostR3410-2001-CryptoPro-A";
+ names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProB] = "GostR3410-2001-CryptoPro-B";
+ names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = "GostR3410-2001-CryptoPro-C";
+ names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA] = "GostR3410-2001-CryptoPro-XchA";
+ names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB] = "GostR3410-2001-CryptoPro-XchB";
+ }
+
+ /**
+ * return the ECDomainParameters object for the given OID, null if it
+ * isn't present.
+ *
+ * @param oid an object identifier representing a named parameters, if present.
+ */
+ public static ECDomainParameters GetByOid(
+ DerObjectIdentifier oid)
+ {
+ return (ECDomainParameters) parameters[oid];
+ }
+
+ /**
+ * returns an enumeration containing the name strings for curves
+ * contained in this structure.
+ */
+ public static IEnumerable Names
+ {
+ get { return new EnumerableProxy(objIds.Keys); }
+ }
+
+ public static ECDomainParameters GetByName(
+ string name)
+ {
+ DerObjectIdentifier oid = (DerObjectIdentifier) objIds[name];
+
+ if (oid != null)
+ {
+ return (ECDomainParameters) parameters[oid];
+ }
+
+ return null;
+ }
+
+ /**
+ * return the named curve name represented by the given object identifier.
+ */
+ public static string GetName(
+ DerObjectIdentifier oid)
+ {
+ return (string) names[oid];
+ }
+
+ public static DerObjectIdentifier GetOid(
+ string name)
+ {
+ return (DerObjectIdentifier) objIds[name];
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cryptopro/ECGOST3410ParamSetParameters.cs b/iTechSharp/srcbc/asn1/cryptopro/ECGOST3410ParamSetParameters.cs
new file mode 100644
index 0000000..6f4435d
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cryptopro/ECGOST3410ParamSetParameters.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.CryptoPro
+{
+ public class ECGost3410ParamSetParameters
+ : Asn1Encodable
+ {
+ internal readonly DerInteger p, q, a, b, x, y;
+
+ public static ECGost3410ParamSetParameters GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static ECGost3410ParamSetParameters GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ECGost3410ParamSetParameters)
+ {
+ return (ECGost3410ParamSetParameters) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ECGost3410ParamSetParameters((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid GOST3410Parameter: " + obj.GetType().Name);
+ }
+
+ public ECGost3410ParamSetParameters(
+ BigInteger a,
+ BigInteger b,
+ BigInteger p,
+ BigInteger q,
+ int x,
+ BigInteger y)
+ {
+ this.a = new DerInteger(a);
+ this.b = new DerInteger(b);
+ this.p = new DerInteger(p);
+ this.q = new DerInteger(q);
+ this.x = new DerInteger(x);
+ this.y = new DerInteger(y);
+ }
+
+ public ECGost3410ParamSetParameters(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 6)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.a = DerInteger.GetInstance(seq[0]);
+ this.b = DerInteger.GetInstance(seq[1]);
+ this.p = DerInteger.GetInstance(seq[2]);
+ this.q = DerInteger.GetInstance(seq[3]);
+ this.x = DerInteger.GetInstance(seq[4]);
+ this.y = DerInteger.GetInstance(seq[5]);
+ }
+
+ public BigInteger P
+ {
+ get { return p.PositiveValue; }
+ }
+
+ public BigInteger Q
+ {
+ get { return q.PositiveValue; }
+ }
+
+ public BigInteger A
+ {
+ get { return a.PositiveValue; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(a, b, p, q, x, y);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cryptopro/GOST28147Parameters.cs b/iTechSharp/srcbc/asn1/cryptopro/GOST28147Parameters.cs
new file mode 100644
index 0000000..eb7e0e3
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cryptopro/GOST28147Parameters.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.CryptoPro
+{
+ public class Gost28147Parameters
+ : Asn1Encodable
+ {
+ private readonly Asn1OctetString iv;
+ private readonly DerObjectIdentifier paramSet;
+
+ public static Gost28147Parameters GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static Gost28147Parameters GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is Gost28147Parameters)
+ {
+ return (Gost28147Parameters) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Gost28147Parameters((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid GOST3410Parameter: " + obj.GetType().Name);
+ }
+
+ private Gost28147Parameters(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.iv = Asn1OctetString.GetInstance(seq[0]);
+ this.paramSet = DerObjectIdentifier.GetInstance(seq[1]);
+ }
+
+ /**
+ *
+ * Gost28147-89-Parameters ::=
+ * SEQUENCE {
+ * iv Gost28147-89-IV,
+ * encryptionParamSet OBJECT IDENTIFIER
+ * }
+ *
+ * Gost28147-89-IV ::= OCTET STRING (SIZE (8))
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(iv, paramSet);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cryptopro/GOST3410NamedParameters.cs b/iTechSharp/srcbc/asn1/cryptopro/GOST3410NamedParameters.cs
new file mode 100644
index 0000000..19ade03
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cryptopro/GOST3410NamedParameters.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.CryptoPro
+{
+ /**
+ * table of the available named parameters for GOST 3410-94.
+ */
+ public sealed class Gost3410NamedParameters
+ {
+ private Gost3410NamedParameters()
+ {
+ }
+
+ private static readonly Hashtable objIds = new Hashtable();
+ private static readonly Hashtable parameters = new Hashtable();
+
+ private static readonly Gost3410ParamSetParameters cryptoProA = new Gost3410ParamSetParameters(
+ 1024,
+ new BigInteger("127021248288932417465907042777176443525787653508916535812817507265705031260985098497423188333483401180925999995120988934130659205614996724254121049274349357074920312769561451689224110579311248812610229678534638401693520013288995000362260684222750813532307004517341633685004541062586971416883686778842537820383"),
+ new BigInteger("68363196144955700784444165611827252895102170888761442055095051287550314083023"),
+ new BigInteger("100997906755055304772081815535925224869841082572053457874823515875577147990529272777244152852699298796483356699682842027972896052747173175480590485607134746852141928680912561502802222185647539190902656116367847270145019066794290930185446216399730872221732889830323194097355403213400972588322876850946740663962")
+ // validationAlgorithm {
+ // algorithm
+ // id-GostR3410-94-bBis,
+ // parameters
+ // GostR3410-94-ValidationBisParameters: {
+ // x0 1376285941,
+ // c 3996757427
+ // }
+ // }
+
+ );
+
+ private static readonly Gost3410ParamSetParameters cryptoProB = new Gost3410ParamSetParameters(
+ 1024,
+ new BigInteger("139454871199115825601409655107690713107041707059928031797758001454375765357722984094124368522288239833039114681648076688236921220737322672160740747771700911134550432053804647694904686120113087816240740184800477047157336662926249423571248823968542221753660143391485680840520336859458494803187341288580489525163"),
+ new BigInteger("79885141663410976897627118935756323747307951916507639758300472692338873533959"),
+ new BigInteger("42941826148615804143873447737955502392672345968607143066798112994089471231420027060385216699563848719957657284814898909770759462613437669456364882730370838934791080835932647976778601915343474400961034231316672578686920482194932878633360203384797092684342247621055760235016132614780652761028509445403338652341")
+ // validationAlgorithm {
+ // algorithm
+ // id-GostR3410-94-bBis,
+ // parameters
+ // GostR3410-94-ValidationBisParameters: {
+ // x0 1536654555,
+ // c 1855361757,
+ // d 14408629386140014567655
+ //4902939282056547857802241461782996702017713059974755104394739915140
+ //6115284791024439062735788342744854120601660303926203867703556828005
+ //8957203818114895398976594425537561271800850306
+ // }
+ // }
+ //}
+ );
+
+ private static readonly Gost3410ParamSetParameters cryptoProXchA = new Gost3410ParamSetParameters(
+ 1024,
+ new BigInteger("142011741597563481196368286022318089743276138395243738762872573441927459393512718973631166078467600360848946623567625795282774719212241929071046134208380636394084512691828894000571524625445295769349356752728956831541775441763139384457191755096847107846595662547942312293338483924514339614727760681880609734239"),
+ new BigInteger("91771529896554605945588149018382750217296858393520724172743325725474374979801"),
+ new BigInteger("133531813272720673433859519948319001217942375967847486899482359599369642528734712461590403327731821410328012529253871914788598993103310567744136196364803064721377826656898686468463277710150809401182608770201615324990468332931294920912776241137878030224355746606283971659376426832674269780880061631528163475887")
+ );
+
+ static Gost3410NamedParameters()
+ {
+ parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProA] = cryptoProA;
+ parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProB] = cryptoProB;
+ //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProC] = cryptoProC;
+ //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProD] = cryptoProD;
+ parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA] = cryptoProXchA;
+ //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchB] = cryptoProXchA;
+ //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchC] = cryptoProXchA;
+
+ objIds["GostR3410-94-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProA;
+ objIds["GostR3410-94-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProB;
+ objIds["GostR3410-94-CryptoPro-XchA"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA;
+ }
+
+ /**
+ * return the GOST3410ParamSetParameters object for the given OID, null if it
+ * isn't present.
+ *
+ * @param oid an object identifier representing a named parameters, if present.
+ */
+ public static Gost3410ParamSetParameters GetByOid(
+ DerObjectIdentifier oid)
+ {
+ return (Gost3410ParamSetParameters) parameters[oid];
+ }
+
+ /**
+ * returns an enumeration containing the name strings for parameters
+ * contained in this structure.
+ */
+ public static IEnumerable Names
+ {
+ get { return new EnumerableProxy(objIds.Keys); }
+ }
+
+ public static Gost3410ParamSetParameters GetByName(
+ string name)
+ {
+ DerObjectIdentifier oid = (DerObjectIdentifier) objIds[name];
+
+ if (oid != null)
+ {
+ return (Gost3410ParamSetParameters) parameters[oid];
+ }
+
+ return null;
+ }
+
+ public static DerObjectIdentifier GetOid(
+ string name)
+ {
+ return (DerObjectIdentifier) objIds[name];
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cryptopro/GOST3410ParamSetParameters.cs b/iTechSharp/srcbc/asn1/cryptopro/GOST3410ParamSetParameters.cs
new file mode 100644
index 0000000..f133cdf
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cryptopro/GOST3410ParamSetParameters.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.CryptoPro
+{
+ public class Gost3410ParamSetParameters
+ : Asn1Encodable
+ {
+ private readonly int keySize;
+ private readonly DerInteger p, q, a;
+
+ public static Gost3410ParamSetParameters GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static Gost3410ParamSetParameters GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is Gost3410ParamSetParameters)
+ {
+ return (Gost3410ParamSetParameters) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Gost3410ParamSetParameters((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid GOST3410Parameter: " + obj.GetType().Name);
+ }
+
+ public Gost3410ParamSetParameters(
+ int keySize,
+ BigInteger p,
+ BigInteger q,
+ BigInteger a)
+ {
+ this.keySize = keySize;
+ this.p = new DerInteger(p);
+ this.q = new DerInteger(q);
+ this.a = new DerInteger(a);
+ }
+
+ private Gost3410ParamSetParameters(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 4)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.keySize = DerInteger.GetInstance(seq[0]).Value.IntValue;
+ this.p = DerInteger.GetInstance(seq[1]);
+ this.q = DerInteger.GetInstance(seq[2]);
+ this.a = DerInteger.GetInstance(seq[3]);
+ }
+
+ public int KeySize
+ {
+ get { return keySize; }
+ }
+
+ public BigInteger P
+ {
+ get { return p.PositiveValue; }
+ }
+
+ public BigInteger Q
+ {
+ get { return q.PositiveValue; }
+ }
+
+ public BigInteger A
+ {
+ get { return a.PositiveValue; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(new DerInteger(keySize), p, q, a);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs b/iTechSharp/srcbc/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs
new file mode 100644
index 0000000..8bc1460
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs
@@ -0,0 +1,99 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.CryptoPro
+{
+ public class Gost3410PublicKeyAlgParameters
+ : Asn1Encodable
+ {
+ private DerObjectIdentifier publicKeyParamSet;
+ private DerObjectIdentifier digestParamSet;
+ private DerObjectIdentifier encryptionParamSet;
+
+ public static Gost3410PublicKeyAlgParameters GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static Gost3410PublicKeyAlgParameters GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is Gost3410PublicKeyAlgParameters)
+ {
+ return (Gost3410PublicKeyAlgParameters) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Gost3410PublicKeyAlgParameters((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid GOST3410Parameter: " + obj.GetType().Name);
+ }
+
+ public Gost3410PublicKeyAlgParameters(
+ DerObjectIdentifier publicKeyParamSet,
+ DerObjectIdentifier digestParamSet)
+ : this (publicKeyParamSet, digestParamSet, null)
+ {
+ }
+
+ public Gost3410PublicKeyAlgParameters(
+ DerObjectIdentifier publicKeyParamSet,
+ DerObjectIdentifier digestParamSet,
+ DerObjectIdentifier encryptionParamSet)
+ {
+ if (publicKeyParamSet == null)
+ throw new ArgumentNullException("publicKeyParamSet");
+ if (digestParamSet == null)
+ throw new ArgumentNullException("digestParamSet");
+
+ this.publicKeyParamSet = publicKeyParamSet;
+ this.digestParamSet = digestParamSet;
+ this.encryptionParamSet = encryptionParamSet;
+ }
+
+ public Gost3410PublicKeyAlgParameters(
+ Asn1Sequence seq)
+ {
+ this.publicKeyParamSet = (DerObjectIdentifier) seq[0];
+ this.digestParamSet = (DerObjectIdentifier) seq[1];
+
+ if (seq.Count > 2)
+ {
+ this.encryptionParamSet = (DerObjectIdentifier) seq[2];
+ }
+ }
+
+ public DerObjectIdentifier PublicKeyParamSet
+ {
+ get { return publicKeyParamSet; }
+ }
+
+ public DerObjectIdentifier DigestParamSet
+ {
+ get { return digestParamSet; }
+ }
+
+ public DerObjectIdentifier EncryptionParamSet
+ {
+ get { return encryptionParamSet; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ publicKeyParamSet, digestParamSet);
+
+ if (encryptionParamSet != null)
+ {
+ v.Add(encryptionParamSet);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/esf/CertificateValues.cs b/iTechSharp/srcbc/asn1/esf/CertificateValues.cs
new file mode 100644
index 0000000..e0fb39b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/esf/CertificateValues.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.Esf
+{
+ ///
+ /// CertificateValues ::= SEQUENCE OF Certificate
+ ///
+ ///
+ * CommitmentTypeIndication ::= SEQUENCE {
+ * commitmentTypeId CommitmentTypeIdentifier,
+ * commitmentTypeQualifier SEQUENCE SIZE (1..MAX) OF
+ * CommitmentTypeQualifier OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(commitmentTypeId);
+
+ if (commitmentTypeQualifier != null)
+ {
+ v.Add(commitmentTypeQualifier);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/esf/CommitmentTypeQualifier.cs b/iTechSharp/srcbc/asn1/esf/CommitmentTypeQualifier.cs
new file mode 100644
index 0000000..09ff707
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/esf/CommitmentTypeQualifier.cs
@@ -0,0 +1,119 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Esf
+{
+ /**
+ * Commitment type qualifiers, used in the Commitment-Type-Indication attribute (RFC3126).
+ *
+ *
+ * CommitmentTypeQualifier ::= SEQUENCE {
+ * commitmentTypeIdentifier CommitmentTypeIdentifier,
+ * qualifier ANY DEFINED BY commitmentTypeIdentifier OPTIONAL }
+ *
+ */
+ public class CommitmentTypeQualifier
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier commitmentTypeIdentifier;
+ private readonly Asn1Object qualifier;
+
+ /**
+ * Creates a new CommitmentTypeQualifier
instance.
+ *
+ * @param commitmentTypeIdentifier a CommitmentTypeIdentifier
value
+ */
+ public CommitmentTypeQualifier(
+ DerObjectIdentifier commitmentTypeIdentifier)
+ : this(commitmentTypeIdentifier, null)
+ {
+ }
+
+ /**
+ * Creates a new CommitmentTypeQualifier
instance.
+ *
+ * @param commitmentTypeIdentifier a CommitmentTypeIdentifier
value
+ * @param qualifier the qualifier, defined by the above field.
+ */
+ public CommitmentTypeQualifier(
+ DerObjectIdentifier commitmentTypeIdentifier,
+ Asn1Encodable qualifier)
+ {
+ if (commitmentTypeIdentifier == null)
+ throw new ArgumentNullException("commitmentTypeIdentifier");
+
+ this.commitmentTypeIdentifier = commitmentTypeIdentifier;
+
+ if (qualifier != null)
+ {
+ this.qualifier = qualifier.ToAsn1Object();
+ }
+ }
+
+ /**
+ * Creates a new CommitmentTypeQualifier
instance.
+ *
+ * @param as CommitmentTypeQualifier
structure
+ * encoded as an Asn1Sequence.
+ */
+ public CommitmentTypeQualifier(
+ Asn1Sequence seq)
+ {
+ if (seq == null)
+ throw new ArgumentNullException("seq");
+ if (seq.Count < 1 || seq.Count > 2)
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+ commitmentTypeIdentifier = (DerObjectIdentifier) seq[0].ToAsn1Object();
+
+ if (seq.Count > 1)
+ {
+ qualifier = seq[1].ToAsn1Object();
+ }
+ }
+
+ public static CommitmentTypeQualifier GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is CommitmentTypeQualifier)
+ return (CommitmentTypeQualifier) obj;
+
+ if (obj is Asn1Sequence)
+ return new CommitmentTypeQualifier((Asn1Sequence) obj);
+
+ throw new ArgumentException(
+ "Unknown object in 'CommitmentTypeQualifier' factory: "
+ + obj.GetType().Name,
+ "obj");
+ }
+
+ public DerObjectIdentifier CommitmentTypeIdentifier
+ {
+ get { return commitmentTypeIdentifier; }
+ }
+
+ public Asn1Object Qualifier
+ {
+ get { return qualifier; }
+ }
+
+ /**
+ * Returns a DER-encodable representation of this instance.
+ *
+ * @return a Asn1Object
value
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ commitmentTypeIdentifier);
+
+ if (qualifier != null)
+ {
+ v.Add(qualifier);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/esf/CompleteCertificateRefs.cs b/iTechSharp/srcbc/asn1/esf/CompleteCertificateRefs.cs
new file mode 100644
index 0000000..7f1c835
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/esf/CompleteCertificateRefs.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.Esf
+{
+ ///
+ /// CompleteCertificateRefs ::= SEQUENCE OF OtherCertID
+ ///
+ ///
+ /// CompleteRevocationRefs ::= SEQUENCE OF CrlOcspRef
+ ///
+ ///
+ /// CrlIdentifier ::= SEQUENCE
+ /// {
+ /// crlissuer Name,
+ /// crlIssuedTime UTCTime,
+ /// crlNumber INTEGER OPTIONAL
+ /// }
+ ///
+ ///
+ /// CRLListID ::= SEQUENCE
+ /// {
+ /// crls SEQUENCE OF CrlValidatedID
+ /// }
+ ///
+ ///
+ /// CrlOcspRef ::= SEQUENCE {
+ /// crlids [0] CRLListID OPTIONAL,
+ /// ocspids [1] OcspListID OPTIONAL,
+ /// otherRev [2] OtherRevRefs OPTIONAL
+ /// }
+ ///
+ ///
+ /// CrlValidatedID ::= SEQUENCE {
+ /// crlHash OtherHash,
+ /// crlIdentifier CrlIdentifier OPTIONAL}
+ ///
+ ///
+ /// OcspIdentifier ::= SEQUENCE {
+ /// ocspResponderID ResponderID,
+ /// -- As in OCSP response data
+ /// producedAt GeneralizedTime
+ /// -- As in OCSP response data
+ /// }
+ ///
+ ///
+ /// OcspListID ::= SEQUENCE {
+ /// ocspResponses SEQUENCE OF OcspResponsesID
+ /// }
+ ///
+ ///
+ /// OcspResponsesID ::= SEQUENCE {
+ /// ocspIdentifier OcspIdentifier,
+ /// ocspRepHash OtherHash OPTIONAL
+ /// }
+ ///
+ ///
+ /// OtherCertID ::= SEQUENCE {
+ /// otherCertHash OtherHash,
+ /// issuerSerial IssuerSerial OPTIONAL
+ /// }
+ ///
+ ///
+ /// OtherHash ::= CHOICE {
+ /// sha1Hash OtherHashValue, -- This contains a SHA-1 hash
+ /// otherHash OtherHashAlgAndValue
+ /// }
+ ///
+ /// OtherHashValue ::= OCTET STRING
+ ///
+ ///
+ /// OtherHashAlgAndValue ::= SEQUENCE {
+ /// hashAlgorithm AlgorithmIdentifier,
+ /// hashValue OtherHashValue
+ /// }
+ ///
+ /// OtherHashValue ::= OCTET STRING
+ ///
+ ///
+ /// OtherRevRefs ::= SEQUENCE
+ /// {
+ /// otherRevRefType OtherRevRefType,
+ /// otherRevRefs ANY DEFINED BY otherRevRefType
+ /// }
+ ///
+ /// OtherRevRefType ::= OBJECT IDENTIFIER
+ ///
+ ///
+ /// OtherRevVals ::= SEQUENCE
+ /// {
+ /// otherRevValType OtherRevValType,
+ /// otherRevVals ANY DEFINED BY otherRevValType
+ /// }
+ ///
+ /// OtherRevValType ::= OBJECT IDENTIFIER
+ ///
+ ///
+ /// OtherSigningCertificate ::= SEQUENCE {
+ /// certs SEQUENCE OF OtherCertID,
+ /// policies SEQUENCE OF PolicyInformation OPTIONAL
+ /// }
+ ///
+ ///
+ /// RevocationValues ::= SEQUENCE {
+ /// crlVals [0] SEQUENCE OF CertificateList OPTIONAL,
+ /// ocspVals [1] SEQUENCE OF BasicOCSPResponse OPTIONAL,
+ /// otherRevVals [2] OtherRevVals
+ /// }
+ ///
+ ///
+ /// SigPolicyQualifierInfo ::= SEQUENCE {
+ /// sigPolicyQualifierId SigPolicyQualifierId,
+ /// sigQualifier ANY DEFINED BY sigPolicyQualifierId
+ /// }
+ ///
+ /// SigPolicyQualifierId ::= OBJECT IDENTIFIER
+ ///
+ ///
+ /// SignaturePolicyId ::= SEQUENCE {
+ /// sigPolicyIdentifier SigPolicyId,
+ /// sigPolicyHash SigPolicyHash,
+ /// sigPolicyQualifiers SEQUENCE SIZE (1..MAX) OF SigPolicyQualifierInfo OPTIONAL
+ /// }
+ ///
+ /// SigPolicyId ::= OBJECT IDENTIFIER
+ ///
+ /// SigPolicyHash ::= OtherHashAlgAndValue
+ ///
+ ///
+ /// SignaturePolicyIdentifier ::= CHOICE {
+ /// SignaturePolicyId SignaturePolicyId,
+ /// SignaturePolicyImplied SignaturePolicyImplied
+ /// }
+ ///
+ /// SignaturePolicyImplied ::= NULL
+ ///
+ ///
+ * SignerLocation ::= SEQUENCE {
+ * countryName [0] DirectoryString OPTIONAL,
+ * localityName [1] DirectoryString OPTIONAL,
+ * postalAddress [2] PostalAddress OPTIONAL }
+ *
+ * PostalAddress ::= SEQUENCE SIZE(1..6) OF DirectoryString
+ *
+ */
+ public class SignerLocation
+ : Asn1Encodable
+ {
+ // TODO Should these be using DirectoryString?
+ private DerUtf8String countryName;
+ private DerUtf8String localityName;
+ private Asn1Sequence postalAddress;
+
+ public SignerLocation(
+ Asn1Sequence seq)
+ {
+ foreach (Asn1TaggedObject obj in seq)
+ {
+ switch (obj.TagNo)
+ {
+ case 0:
+ this.countryName = DerUtf8String.GetInstance(obj, true);
+ break;
+ case 1:
+ this.localityName = DerUtf8String.GetInstance(obj, true);
+ break;
+ case 2:
+ bool isExplicit = obj.IsExplicit(); // handle erroneous implicitly tagged sequences
+ this.postalAddress = Asn1Sequence.GetInstance(obj, isExplicit);
+ if (postalAddress != null && postalAddress.Count > 6)
+ throw new ArgumentException("postal address must contain less than 6 strings");
+ break;
+ default:
+ throw new ArgumentException("illegal tag");
+ }
+ }
+ }
+
+ public SignerLocation(
+ DerUtf8String countryName,
+ DerUtf8String localityName,
+ Asn1Sequence postalAddress)
+ {
+ if (postalAddress != null && postalAddress.Count > 6)
+ {
+ throw new ArgumentException("postal address must contain less than 6 strings");
+ }
+
+ if (countryName != null)
+ {
+ this.countryName = DerUtf8String.GetInstance(countryName.ToAsn1Object());
+ }
+
+ if (localityName != null)
+ {
+ this.localityName = DerUtf8String.GetInstance(localityName.ToAsn1Object());
+ }
+
+ if (postalAddress != null)
+ {
+ this.postalAddress = (Asn1Sequence) postalAddress.ToAsn1Object();
+ }
+ }
+
+ public static SignerLocation GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is SignerLocation)
+ {
+ return (SignerLocation) obj;
+ }
+
+ return new SignerLocation(Asn1Sequence.GetInstance(obj));
+ }
+
+ public DerUtf8String CountryName
+ {
+ get { return countryName; }
+ }
+
+ public DerUtf8String LocalityName
+ {
+ get { return localityName; }
+ }
+
+ public Asn1Sequence PostalAddress
+ {
+ get { return postalAddress; }
+ }
+
+ /**
+ *
+ * SignerLocation ::= SEQUENCE {
+ * countryName [0] DirectoryString OPTIONAL,
+ * localityName [1] DirectoryString OPTIONAL,
+ * postalAddress [2] PostalAddress OPTIONAL }
+ *
+ * PostalAddress ::= SEQUENCE SIZE(1..6) OF DirectoryString
+ *
+ * DirectoryString ::= CHOICE {
+ * teletexString TeletexString (SIZE (1..MAX)),
+ * printableString PrintableString (SIZE (1..MAX)),
+ * universalString UniversalString (SIZE (1..MAX)),
+ * utf8String UTF8String (SIZE (1.. MAX)),
+ * bmpString BMPString (SIZE (1..MAX)) }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (countryName != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, countryName));
+ }
+
+ if (localityName != null)
+ {
+ v.Add(new DerTaggedObject(true, 1, localityName));
+ }
+
+ if (postalAddress != null)
+ {
+ v.Add(new DerTaggedObject(true, 2, postalAddress));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ess/ContentHints.cs b/iTechSharp/srcbc/asn1/ess/ContentHints.cs
new file mode 100644
index 0000000..a430fea
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ess/ContentHints.cs
@@ -0,0 +1,92 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+ public class ContentHints
+ : Asn1Encodable
+ {
+ private readonly DerUtf8String contentDescription;
+ private readonly DerObjectIdentifier contentType;
+
+ public static ContentHints GetInstance(
+ object o)
+ {
+ if (o == null || o is ContentHints)
+ {
+ return (ContentHints)o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new ContentHints((Asn1Sequence)o);
+ }
+
+ throw new ArgumentException("unknown object in 'ContentHints' factory : "
+ + o.GetType().Name + ".");
+ }
+
+ /**
+ * constructor
+ */
+ private ContentHints(
+ Asn1Sequence seq)
+ {
+ IAsn1Convertible field = seq[0];
+ if (field.ToAsn1Object() is DerUtf8String)
+ {
+ contentDescription = DerUtf8String.GetInstance(field);
+ contentType = DerObjectIdentifier.GetInstance(seq[1]);
+ }
+ else
+ {
+ contentType = DerObjectIdentifier.GetInstance(seq[0]);
+ }
+ }
+
+ public ContentHints(
+ DerObjectIdentifier contentType)
+ {
+ this.contentType = contentType;
+ this.contentDescription = null;
+ }
+
+ public ContentHints(
+ DerObjectIdentifier contentType,
+ DerUtf8String contentDescription)
+ {
+ this.contentType = contentType;
+ this.contentDescription = contentDescription;
+ }
+
+ public DerObjectIdentifier ContentType
+ {
+ get { return contentType; }
+ }
+
+ public DerUtf8String ContentDescription
+ {
+ get { return contentDescription; }
+ }
+
+ /**
+ *
+ * ContentHints ::= SEQUENCE {
+ * contentDescription UTF8String (SIZE (1..MAX)) OPTIONAL,
+ * contentType ContentType }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (contentDescription != null)
+ {
+ v.Add(contentDescription);
+ }
+
+ v.Add(contentType);
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ess/ContentIdentifier.cs b/iTechSharp/srcbc/asn1/ess/ContentIdentifier.cs
new file mode 100644
index 0000000..8058dcc
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ess/ContentIdentifier.cs
@@ -0,0 +1,65 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+ public class ContentIdentifier
+ : Asn1Encodable
+ {
+ private Asn1OctetString value;
+
+ public static ContentIdentifier GetInstance(
+ object o)
+ {
+ if (o == null || o is ContentIdentifier)
+ {
+ return (ContentIdentifier) o;
+ }
+
+ if (o is Asn1OctetString)
+ {
+ return new ContentIdentifier((Asn1OctetString) o);
+ }
+
+ throw new ArgumentException(
+ "unknown object in 'ContentIdentifier' factory : "
+ + o.GetType().Name + ".");
+ }
+
+ /**
+ * Create from OCTET STRING whose octets represent the identifier.
+ */
+ public ContentIdentifier(
+ Asn1OctetString value)
+ {
+ this.value = value;
+ }
+
+ /**
+ * Create from byte array representing the identifier.
+ */
+ public ContentIdentifier(
+ byte[] value)
+ : this(new DerOctetString(value))
+ {
+ }
+
+ public Asn1OctetString Value
+ {
+ get { return value; }
+ }
+
+ /**
+ * The definition of ContentIdentifier is
+ *
+ * ContentIdentifier ::= OCTET STRING
+ *
+ * id-aa-contentIdentifier OBJECT IDENTIFIER ::= { iso(1)
+ * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+ * smime(16) id-aa(2) 7 }
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return value;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ess/ESSCertID.cs b/iTechSharp/srcbc/asn1/ess/ESSCertID.cs
new file mode 100644
index 0000000..4d449a7
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ess/ESSCertID.cs
@@ -0,0 +1,93 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+ public class EssCertID
+ : Asn1Encodable
+ {
+ private Asn1OctetString certHash;
+ private IssuerSerial issuerSerial;
+
+ public static EssCertID GetInstance(
+ object o)
+ {
+ if (o == null || o is EssCertID)
+ {
+ return (EssCertID) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new EssCertID((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException(
+ "unknown object in 'EssCertID' factory : "
+ + o.GetType().Name + ".");
+ }
+
+ /**
+ * constructor
+ */
+ public EssCertID(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ this.certHash = Asn1OctetString.GetInstance(seq[0]);
+
+ if (seq.Count > 1)
+ {
+ issuerSerial = IssuerSerial.GetInstance(seq[1]);
+ }
+ }
+
+ public EssCertID(
+ byte[] hash)
+ {
+ certHash = new DerOctetString(hash);
+ }
+
+ public EssCertID(
+ byte[] hash,
+ IssuerSerial issuerSerial)
+ {
+ this.certHash = new DerOctetString(hash);
+ this.issuerSerial = issuerSerial;
+ }
+
+ public byte[] GetCertHash()
+ {
+ return certHash.GetOctets();
+ }
+
+ public IssuerSerial IssuerSerial
+ {
+ get { return issuerSerial; }
+ }
+
+ /**
+ *
+ * EssCertID ::= SEQUENCE {
+ * certHash Hash,
+ * issuerSerial IssuerSerial OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(certHash);
+
+ if (issuerSerial != null)
+ {
+ v.Add(issuerSerial);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ess/ESSCertIDv2.cs b/iTechSharp/srcbc/asn1/ess/ESSCertIDv2.cs
new file mode 100644
index 0000000..ca22456
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ess/ESSCertIDv2.cs
@@ -0,0 +1,138 @@
+using System;
+
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+ public class EssCertIDv2
+ : Asn1Encodable
+ {
+ private readonly AlgorithmIdentifier hashAlgorithm;
+ private readonly byte[] certHash;
+ private readonly IssuerSerial issuerSerial;
+
+ private static readonly AlgorithmIdentifier DefaultAlgID = new AlgorithmIdentifier(
+ NistObjectIdentifiers.IdSha256, DerNull.Instance);
+
+ public static EssCertIDv2 GetInstance(
+ object o)
+ {
+ if (o == null || o is EssCertIDv2)
+ return (EssCertIDv2) o;
+
+ if (o is Asn1Sequence)
+ return new EssCertIDv2((Asn1Sequence) o);
+
+ throw new ArgumentException(
+ "unknown object in 'EssCertIDv2' factory : "
+ + o.GetType().Name + ".");
+ }
+
+ private EssCertIDv2(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2 && seq.Count != 3)
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+ int count = 0;
+
+ if (seq[0] is Asn1OctetString)
+ {
+ // Default value
+ this.hashAlgorithm = DefaultAlgID;
+ }
+ else
+ {
+ this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[count++].ToAsn1Object());
+ }
+
+ this.certHash = Asn1OctetString.GetInstance(seq[count++].ToAsn1Object()).GetOctets();
+
+ if (seq.Count > count)
+ {
+ this.issuerSerial = IssuerSerial.GetInstance(
+ Asn1Sequence.GetInstance(seq[count].ToAsn1Object()));
+ }
+ }
+
+ public EssCertIDv2(
+ AlgorithmIdentifier algId,
+ byte[] certHash)
+ : this(algId, certHash, null)
+ {
+ }
+
+ public EssCertIDv2(
+ AlgorithmIdentifier algId,
+ byte[] certHash,
+ IssuerSerial issuerSerial)
+ {
+ if (algId == null)
+ {
+ // Default value
+ this.hashAlgorithm = DefaultAlgID;
+ }
+ else
+ {
+ this.hashAlgorithm = algId;
+ }
+
+ this.certHash = certHash;
+ this.issuerSerial = issuerSerial;
+ }
+
+ public AlgorithmIdentifier HashAlgorithm
+ {
+ get { return this.hashAlgorithm; }
+ }
+
+ public byte[] GetCertHash()
+ {
+ return Arrays.Clone(certHash);
+ }
+
+ public IssuerSerial IssuerSerial
+ {
+ get { return issuerSerial; }
+ }
+
+ /**
+ *
+ * EssCertIDv2 ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier
+ * DEFAULT {algorithm id-sha256 parameters NULL},
+ * certHash Hash,
+ * issuerSerial IssuerSerial OPTIONAL
+ * }
+ *
+ * Hash ::= OCTET STRING
+ *
+ * IssuerSerial ::= SEQUENCE {
+ * issuer GeneralNames,
+ * serialNumber CertificateSerialNumber
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (!hashAlgorithm.Equals(DefaultAlgID))
+ {
+ v.Add(hashAlgorithm);
+ }
+
+ v.Add(new DerOctetString(certHash).ToAsn1Object());
+
+ if (issuerSerial != null)
+ {
+ v.Add(issuerSerial);
+ }
+
+ return new DerSequence(v);
+ }
+
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ess/OtherCertID.cs b/iTechSharp/srcbc/asn1/ess/OtherCertID.cs
new file mode 100644
index 0000000..972ef8c
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ess/OtherCertID.cs
@@ -0,0 +1,132 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+ [Obsolete("Use version in Asn1.Esf instead")]
+ public class OtherCertID
+ : Asn1Encodable
+ {
+ private Asn1Encodable otherCertHash;
+ private IssuerSerial issuerSerial;
+
+ public static OtherCertID GetInstance(
+ object o)
+ {
+ if (o == null || o is OtherCertID)
+ {
+ return (OtherCertID) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new OtherCertID((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException(
+ "unknown object in 'OtherCertID' factory : "
+ + o.GetType().Name + ".");
+ }
+
+ /**
+ * constructor
+ */
+ public OtherCertID(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ if (seq[0].ToAsn1Object() is Asn1OctetString)
+ {
+ otherCertHash = Asn1OctetString.GetInstance(seq[0]);
+ }
+ else
+ {
+ otherCertHash = DigestInfo.GetInstance(seq[0]);
+ }
+
+ if (seq.Count > 1)
+ {
+ issuerSerial = IssuerSerial.GetInstance(Asn1Sequence.GetInstance(seq[1]));
+ }
+ }
+
+ public OtherCertID(
+ AlgorithmIdentifier algId,
+ byte[] digest)
+ {
+ this.otherCertHash = new DigestInfo(algId, digest);
+ }
+
+ public OtherCertID(
+ AlgorithmIdentifier algId,
+ byte[] digest,
+ IssuerSerial issuerSerial)
+ {
+ this.otherCertHash = new DigestInfo(algId, digest);
+ this.issuerSerial = issuerSerial;
+ }
+
+ public AlgorithmIdentifier AlgorithmHash
+ {
+ get
+ {
+ if (otherCertHash.ToAsn1Object() is Asn1OctetString)
+ {
+ // SHA-1
+ return new AlgorithmIdentifier("1.3.14.3.2.26");
+ }
+
+ return DigestInfo.GetInstance(otherCertHash).AlgorithmID;
+ }
+ }
+
+ public byte[] GetCertHash()
+ {
+ if (otherCertHash.ToAsn1Object() is Asn1OctetString)
+ {
+ // SHA-1
+ return ((Asn1OctetString) otherCertHash.ToAsn1Object()).GetOctets();
+ }
+
+ return DigestInfo.GetInstance(otherCertHash).GetDigest();
+ }
+
+ public IssuerSerial IssuerSerial
+ {
+ get { return issuerSerial; }
+ }
+
+ /**
+ *
+ * OtherCertID ::= SEQUENCE {
+ * otherCertHash OtherHash,
+ * issuerSerial IssuerSerial OPTIONAL }
+ *
+ * OtherHash ::= CHOICE {
+ * sha1Hash OCTET STRING,
+ * otherHash OtherHashAlgAndValue }
+ *
+ * OtherHashAlgAndValue ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * hashValue OCTET STRING }
+ *
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(otherCertHash);
+
+ if (issuerSerial != null)
+ {
+ v.Add(issuerSerial);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ess/OtherSigningCertificate.cs b/iTechSharp/srcbc/asn1/ess/OtherSigningCertificate.cs
new file mode 100644
index 0000000..c165fec
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ess/OtherSigningCertificate.cs
@@ -0,0 +1,109 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+ [Obsolete("Use version in Asn1.Esf instead")]
+ public class OtherSigningCertificate
+ : Asn1Encodable
+ {
+ private Asn1Sequence certs, policies;
+
+ public static OtherSigningCertificate GetInstance(
+ object o)
+ {
+ if (o == null || o is OtherSigningCertificate)
+ {
+ return (OtherSigningCertificate) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new OtherSigningCertificate((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException(
+ "unknown object in 'OtherSigningCertificate' factory : "
+ + o.GetType().Name + ".");
+ }
+
+ /**
+ * constructors
+ */
+ public OtherSigningCertificate(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ this.certs = Asn1Sequence.GetInstance(seq[0]);
+
+ if (seq.Count > 1)
+ {
+ this.policies = Asn1Sequence.GetInstance(seq[1]);
+ }
+ }
+
+ public OtherSigningCertificate(
+ OtherCertID otherCertID)
+ {
+ certs = new DerSequence(otherCertID);
+ }
+
+ public OtherCertID[] GetCerts()
+ {
+ OtherCertID[] cs = new OtherCertID[certs.Count];
+
+ for (int i = 0; i != certs.Count; ++i)
+ {
+ cs[i] = OtherCertID.GetInstance(certs[i]);
+ }
+
+ return cs;
+ }
+
+ public PolicyInformation[] GetPolicies()
+ {
+ if (policies == null)
+ {
+ return null;
+ }
+
+ PolicyInformation[] ps = new PolicyInformation[policies.Count];
+
+ for (int i = 0; i != policies.Count; i++)
+ {
+ ps[i] = PolicyInformation.GetInstance(policies[i]);
+ }
+
+ return ps;
+ }
+
+ /**
+ * The definition of OtherSigningCertificate is
+ *
+ * OtherSigningCertificate ::= SEQUENCE {
+ * certs SEQUENCE OF OtherCertID,
+ * policies SEQUENCE OF PolicyInformation OPTIONAL
+ * }
+ *
+ * id-aa-ets-otherSigCert OBJECT IDENTIFIER ::= { iso(1)
+ * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+ * smime(16) id-aa(2) 19 }
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(certs);
+
+ if (policies != null)
+ {
+ v.Add(policies);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ess/SigningCertificate.cs b/iTechSharp/srcbc/asn1/ess/SigningCertificate.cs
new file mode 100644
index 0000000..366749b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ess/SigningCertificate.cs
@@ -0,0 +1,108 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+ public class SigningCertificate
+ : Asn1Encodable
+ {
+ private Asn1Sequence certs, policies;
+
+ public static SigningCertificate GetInstance(
+ object o)
+ {
+ if (o == null || o is SigningCertificate)
+ {
+ return (SigningCertificate) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new SigningCertificate((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException(
+ "unknown object in 'SigningCertificate' factory : "
+ + o.GetType().Name + ".");
+ }
+
+ /**
+ * constructors
+ */
+ public SigningCertificate(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ this.certs = Asn1Sequence.GetInstance(seq[0]);
+
+ if (seq.Count > 1)
+ {
+ this.policies = Asn1Sequence.GetInstance(seq[1]);
+ }
+ }
+
+ public SigningCertificate(
+ EssCertID essCertID)
+ {
+ certs = new DerSequence(essCertID);
+ }
+
+ public EssCertID[] GetCerts()
+ {
+ EssCertID[] cs = new EssCertID[certs.Count];
+
+ for (int i = 0; i != certs.Count; i++)
+ {
+ cs[i] = EssCertID.GetInstance(certs[i]);
+ }
+
+ return cs;
+ }
+
+ public PolicyInformation[] GetPolicies()
+ {
+ if (policies == null)
+ {
+ return null;
+ }
+
+ PolicyInformation[] ps = new PolicyInformation[policies.Count];
+
+ for (int i = 0; i != policies.Count; i++)
+ {
+ ps[i] = PolicyInformation.GetInstance(policies[i]);
+ }
+
+ return ps;
+ }
+
+ /**
+ * The definition of SigningCertificate is
+ *
+ * SigningCertificate ::= SEQUENCE {
+ * certs SEQUENCE OF EssCertID,
+ * policies SEQUENCE OF PolicyInformation OPTIONAL
+ * }
+ *
+ * id-aa-signingCertificate OBJECT IDENTIFIER ::= { iso(1)
+ * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+ * smime(16) id-aa(2) 12 }
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(certs);
+
+ if (policies != null)
+ {
+ v.Add(policies);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ess/SigningCertificateV2.cs b/iTechSharp/srcbc/asn1/ess/SigningCertificateV2.cs
new file mode 100644
index 0000000..a2aff48
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ess/SigningCertificateV2.cs
@@ -0,0 +1,106 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+ public class SigningCertificateV2
+ : Asn1Encodable
+ {
+ private readonly Asn1Sequence certs;
+ private readonly Asn1Sequence policies;
+
+ public static SigningCertificateV2 GetInstance(
+ object o)
+ {
+ if (o == null || o is SigningCertificateV2)
+ return (SigningCertificateV2) o;
+
+ if (o is Asn1Sequence)
+ return new SigningCertificateV2((Asn1Sequence) o);
+
+ throw new ArgumentException(
+ "unknown object in 'SigningCertificateV2' factory : "
+ + o.GetType().Name + ".");
+ }
+
+ private SigningCertificateV2(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+ this.certs = Asn1Sequence.GetInstance(seq[0].ToAsn1Object());
+
+ if (seq.Count > 1)
+ {
+ this.policies = Asn1Sequence.GetInstance(seq[1].ToAsn1Object());
+ }
+ }
+
+ public SigningCertificateV2(
+ EssCertIDv2[] certs)
+ {
+ this.certs = new DerSequence(certs);
+ }
+
+ public SigningCertificateV2(
+ EssCertIDv2[] certs,
+ PolicyInformation[] policies)
+ {
+ this.certs = new DerSequence(certs);
+
+ if (policies != null)
+ {
+ this.policies = new DerSequence(policies);
+ }
+ }
+
+ public EssCertIDv2[] GetCerts()
+ {
+ EssCertIDv2[] certIds = new EssCertIDv2[certs.Count];
+ for (int i = 0; i != certs.Count; i++)
+ {
+ certIds[i] = EssCertIDv2.GetInstance(certs[i]);
+ }
+ return certIds;
+ }
+
+ public PolicyInformation[] GetPolicies()
+ {
+ if (policies == null)
+ return null;
+
+ PolicyInformation[] policyInformations = new PolicyInformation[policies.Count];
+ for (int i = 0; i != policies.Count; i++)
+ {
+ policyInformations[i] = PolicyInformation.GetInstance(policies[i]);
+ }
+ return policyInformations;
+ }
+
+ /**
+ * The definition of SigningCertificateV2 is
+ *
+ * SigningCertificateV2 ::= SEQUENCE {
+ * certs SEQUENCE OF EssCertIDv2,
+ * policies SEQUENCE OF PolicyInformation OPTIONAL
+ * }
+ *
+ * id-aa-signingCertificateV2 OBJECT IDENTIFIER ::= { iso(1)
+ * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+ * smime(16) id-aa(2) 47 }
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(certs);
+
+ if (policies != null)
+ {
+ v.Add(policies);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/gnu/GNUObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/gnu/GNUObjectIdentifiers.cs
new file mode 100644
index 0000000..9311a3a
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/gnu/GNUObjectIdentifiers.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Gnu
+{
+ public abstract class GnuObjectIdentifiers
+ {
+ public static readonly DerObjectIdentifier Gnu = new DerObjectIdentifier("1.3.6.1.4.1.11591.1"); // GNU Radius
+ public static readonly DerObjectIdentifier GnuPG = new DerObjectIdentifier("1.3.6.1.4.1.11591.2"); // GnuPG (Ägypten)
+ public static readonly DerObjectIdentifier Notation = new DerObjectIdentifier("1.3.6.1.4.1.11591.2.1"); // notation
+ public static readonly DerObjectIdentifier PkaAddress = new DerObjectIdentifier("1.3.6.1.4.1.11591.2.1.1"); // pkaAddress
+ public static readonly DerObjectIdentifier GnuRadar = new DerObjectIdentifier("1.3.6.1.4.1.11591.3"); // GNU Radar
+ public static readonly DerObjectIdentifier DigestAlgorithm = new DerObjectIdentifier("1.3.6.1.4.1.11591.12"); // digestAlgorithm
+ public static readonly DerObjectIdentifier Tiger192 = new DerObjectIdentifier("1.3.6.1.4.1.11591.12.2"); // TIGER/192
+ public static readonly DerObjectIdentifier EncryptionAlgorithm = new DerObjectIdentifier("1.3.6.1.4.1.11591.13"); // encryptionAlgorithm
+ public static readonly DerObjectIdentifier Serpent = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2"); // Serpent
+ public static readonly DerObjectIdentifier Serpent128Ecb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.1"); // Serpent-128-ECB
+ public static readonly DerObjectIdentifier Serpent128Cbc = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.2"); // Serpent-128-CBC
+ public static readonly DerObjectIdentifier Serpent128Ofb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.3"); // Serpent-128-OFB
+ public static readonly DerObjectIdentifier Serpent128Cfb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.4"); // Serpent-128-CFB
+ public static readonly DerObjectIdentifier Serpent192Ecb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.21"); // Serpent-192-ECB
+ public static readonly DerObjectIdentifier Serpent192Cbc = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.22"); // Serpent-192-CBC
+ public static readonly DerObjectIdentifier Serpent192Ofb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.23"); // Serpent-192-OFB
+ public static readonly DerObjectIdentifier Serpent192Cfb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.24"); // Serpent-192-CFB
+ public static readonly DerObjectIdentifier Serpent256Ecb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.41"); // Serpent-256-ECB
+ public static readonly DerObjectIdentifier Serpent256Cbc = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.42"); // Serpent-256-CBC
+ public static readonly DerObjectIdentifier Serpent256Ofb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.43"); // Serpent-256-OFB
+ public static readonly DerObjectIdentifier Serpent256Cfb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.44"); // Serpent-256-CFB
+ public static readonly DerObjectIdentifier Crc = new DerObjectIdentifier("1.3.6.1.4.1.11591.14"); // CRC algorithms
+ public static readonly DerObjectIdentifier Crc32 = new DerObjectIdentifier("1.3.6.1.4.1.11591.14.1"); // CRC 32
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/iana/IANAObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/iana/IANAObjectIdentifiers.cs
new file mode 100644
index 0000000..63343f5
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/iana/IANAObjectIdentifiers.cs
@@ -0,0 +1,18 @@
+namespace Org.BouncyCastle.Asn1.Iana
+{
+ public abstract class IanaObjectIdentifiers
+ {
+ // id-SHA1 OBJECT IDENTIFIER ::=
+ // {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1)}
+ //
+
+ public static readonly DerObjectIdentifier IsakmpOakley = new DerObjectIdentifier("1.3.6.1.5.5.8.1");
+
+ public static readonly DerObjectIdentifier HmacMD5 = new DerObjectIdentifier(IsakmpOakley + ".1");
+ public static readonly DerObjectIdentifier HmacSha1 = new DerObjectIdentifier(IsakmpOakley + ".2");
+
+ public static readonly DerObjectIdentifier HmacTiger = new DerObjectIdentifier(IsakmpOakley + ".3");
+
+ public static readonly DerObjectIdentifier HmacRipeMD160 = new DerObjectIdentifier(IsakmpOakley + ".4");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/icao/DataGroupHash.cs b/iTechSharp/srcbc/asn1/icao/DataGroupHash.cs
new file mode 100644
index 0000000..91e46ca
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/icao/DataGroupHash.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Icao
+{
+ /**
+ * The DataGroupHash object.
+ *
+ * DataGroupHash ::= SEQUENCE {
+ * dataGroupNumber DataGroupNumber,
+ * dataGroupHashValue OCTET STRING }
+ *
+ * DataGroupNumber ::= INTEGER {
+ * dataGroup1 (1),
+ * dataGroup1 (2),
+ * dataGroup1 (3),
+ * dataGroup1 (4),
+ * dataGroup1 (5),
+ * dataGroup1 (6),
+ * dataGroup1 (7),
+ * dataGroup1 (8),
+ * dataGroup1 (9),
+ * dataGroup1 (10),
+ * dataGroup1 (11),
+ * dataGroup1 (12),
+ * dataGroup1 (13),
+ * dataGroup1 (14),
+ * dataGroup1 (15),
+ * dataGroup1 (16) }
+ *
+ *
+ */
+ public class DataGroupHash
+ : Asn1Encodable
+ {
+ private readonly DerInteger dataGroupNumber;
+ private readonly Asn1OctetString dataGroupHashValue;
+
+ public static DataGroupHash GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is DataGroupHash)
+ {
+ return (DataGroupHash) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new DataGroupHash(Asn1Sequence.GetInstance(obj));
+ }
+
+ throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName);
+ }
+
+ private DataGroupHash(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.dataGroupNumber = DerInteger.GetInstance(seq[0]);
+ this.dataGroupHashValue = Asn1OctetString.GetInstance(seq[1]);
+ }
+
+ public DataGroupHash(
+ int dataGroupNumber,
+ Asn1OctetString dataGroupHashValue)
+ {
+ this.dataGroupNumber = new DerInteger(dataGroupNumber);
+ this.dataGroupHashValue = dataGroupHashValue;
+ }
+
+ public int DataGroupNumber
+ {
+ get { return dataGroupNumber.Value.IntValue; }
+ }
+
+ public Asn1OctetString DataGroupHashValue
+ {
+ get { return dataGroupHashValue; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(dataGroupNumber, dataGroupHashValue);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/icao/ICAOObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/icao/ICAOObjectIdentifiers.cs
new file mode 100644
index 0000000..0ed9f2b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/icao/ICAOObjectIdentifiers.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Icao
+{
+ public abstract class IcaoObjectIdentifiers
+ {
+ //
+ // base id
+ //
+ public const string IdIcao = "1.3.27";
+
+ public static readonly DerObjectIdentifier IdIcaoMrtd = new DerObjectIdentifier(IdIcao + ".1");
+ public static readonly DerObjectIdentifier IdIcaoMrtdSecurity = new DerObjectIdentifier(IdIcaoMrtd + ".1");
+ public static readonly DerObjectIdentifier IdIcaoLdsSecurityObject = new DerObjectIdentifier(IdIcaoMrtdSecurity + ".1");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/icao/LDSSecurityObject.cs b/iTechSharp/srcbc/asn1/icao/LDSSecurityObject.cs
new file mode 100644
index 0000000..0973c34
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/icao/LDSSecurityObject.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Icao
+{
+ /**
+ * The LDSSecurityObject object.
+ *
+ * LDSSecurityObject ::= SEQUENCE {
+ * version LDSSecurityObjectVersion,
+ * hashAlgorithm DigestAlgorithmIdentifier,
+ * dataGroupHashValues SEQUENCE SIZE (2..ub-DataGroups) OF DataHashGroup}
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier,
+ *
+ * LDSSecurityObjectVersion :: INTEGER {V0(0)}
+ *
+ */
+
+ public class LdsSecurityObject
+ : Asn1Encodable
+ {
+ public const int UBDataGroups = 16;
+
+ internal DerInteger version = new DerInteger(0);
+ internal AlgorithmIdentifier digestAlgorithmIdentifier;
+ internal DataGroupHash[] datagroupHash;
+
+ public static LdsSecurityObject GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is LdsSecurityObject)
+ {
+ return (LdsSecurityObject) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new LdsSecurityObject(Asn1Sequence.GetInstance(obj));
+ }
+
+ throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName);
+ }
+
+ public LdsSecurityObject(
+ Asn1Sequence seq)
+ {
+ if (seq == null || seq.Count == 0)
+ {
+ throw new ArgumentException("null or empty sequence passed.");
+ }
+
+ IEnumerator e = seq.GetEnumerator();
+
+ // version
+ e.MoveNext();
+ version = DerInteger.GetInstance(e.Current);
+ // digestAlgorithmIdentifier
+ e.MoveNext();
+ digestAlgorithmIdentifier = AlgorithmIdentifier.GetInstance(e.Current);
+
+ e.MoveNext();
+ Asn1Sequence datagroupHashSeq = Asn1Sequence.GetInstance(e.Current);
+
+ CheckDatagroupHashSeqSize(datagroupHashSeq.Count);
+
+ datagroupHash = new DataGroupHash[datagroupHashSeq.Count];
+ for (int i= 0; i< datagroupHashSeq.Count; i++)
+ {
+ datagroupHash[i] = DataGroupHash.GetInstance(datagroupHashSeq[i]);
+ }
+ }
+
+ public LdsSecurityObject(
+ AlgorithmIdentifier digestAlgorithmIdentifier,
+ DataGroupHash[] datagroupHash)
+ {
+ this.digestAlgorithmIdentifier = digestAlgorithmIdentifier;
+ this.datagroupHash = datagroupHash;
+
+ CheckDatagroupHashSeqSize(datagroupHash.Length);
+ }
+
+ private void CheckDatagroupHashSeqSize(int size)
+ {
+ if (size < 2 || size > UBDataGroups)
+ {
+ throw new ArgumentException("wrong size in DataGroupHashValues : not in (2.."+ UBDataGroups +")");
+ }
+ }
+
+ public AlgorithmIdentifier DigestAlgorithmIdentifier
+ {
+ get { return digestAlgorithmIdentifier; }
+ }
+
+ public DataGroupHash[] GetDatagroupHash()
+ {
+ return datagroupHash;
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(
+ version,
+ digestAlgorithmIdentifier,
+ new DerSequence(datagroupHash));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/ISISMTTObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/isismtt/ISISMTTObjectIdentifiers.cs
new file mode 100644
index 0000000..af60b03
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/ISISMTTObjectIdentifiers.cs
@@ -0,0 +1,177 @@
+namespace Org.BouncyCastle.Asn1.IsisMtt
+{
+ public abstract class IsisMttObjectIdentifiers
+ {
+ public static readonly DerObjectIdentifier IdIsisMtt = new DerObjectIdentifier("1.3.36.8");
+
+ public static readonly DerObjectIdentifier IdIsisMttCP = new DerObjectIdentifier(IdIsisMtt + ".1");
+
+ /**
+ * The id-isismtt-cp-accredited OID indicates that the certificate is a
+ * qualified certificate according to Directive 1999/93/EC of the European
+ * Parliament and of the Council of 13 December 1999 on a Community
+ * Framework for Electronic Signatures, which additionally conforms the
+ * special requirements of the SigG and has been issued by an accredited CA.
+ */
+ public static readonly DerObjectIdentifier IdIsisMttCPAccredited = new DerObjectIdentifier(IdIsisMttCP + ".1");
+
+ public static readonly DerObjectIdentifier IdIsisMttAT = new DerObjectIdentifier(IdIsisMtt + ".3");
+
+ /**
+ * Certificate extensionDate of certificate generation
+ *
+ *
+ * DateOfCertGenSyntax ::= GeneralizedTime
+ *
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATDateOfCertGen = new DerObjectIdentifier(IdIsisMttAT + ".1");
+
+ /**
+ * Attribute to indicate that the certificate holder may sign in the name of
+ * a third person. May also be used as extension in a certificate.
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATProcuration = new DerObjectIdentifier(IdIsisMttAT + ".2");
+
+ /**
+ * Attribute to indicate admissions to certain professions. May be used as
+ * attribute in attribute certificate or as extension in a certificate
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATAdmission = new DerObjectIdentifier(IdIsisMttAT + ".3");
+
+ /**
+ * Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST
+ * be used in new certificates in place of the extension/attribute
+ * MonetaryLimit since January 1, 2004. For the sake of backward
+ * compatibility with certificates already in use, SigG conforming
+ * components MUST support MonetaryLimit (as well as QcEuLimitValue).
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATMonetaryLimit = new DerObjectIdentifier(IdIsisMttAT + ".4");
+
+ /**
+ * A declaration of majority. May be used as attribute in attribute
+ * certificate or as extension in a certificate
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATDeclarationOfMajority = new DerObjectIdentifier(IdIsisMttAT + ".5");
+
+ /**
+ *
+ * Serial number of the smart card containing the corresponding private key
+ *
+ *
+ * ICCSNSyntax ::= OCTET STRING (SIZE(8..20))
+ *
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATIccsn = new DerObjectIdentifier(IdIsisMttAT + ".6");
+
+ /**
+ *
+ * Reference for a file of a smartcard that stores the public key of this
+ * certificate and that is used as �security anchor�.
+ *
+ *
+ * PKReferenceSyntax ::= OCTET STRING (SIZE(20))
+ *
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATPKReference = new DerObjectIdentifier(IdIsisMttAT + ".7");
+
+ /**
+ * Some other restriction regarding the usage of this certificate. May be
+ * used as attribute in attribute certificate or as extension in a
+ * certificate.
+ *
+ *
+ * RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+ *
+ *
+ * @see Org.BouncyCastle.Asn1.IsisMtt.X509.Restriction
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATRestriction = new DerObjectIdentifier(IdIsisMttAT + ".8");
+
+ /**
+ *
+ * (Single)Request extension: Clients may include this extension in a
+ * (single) Request to request the responder to send the certificate in the
+ * response message along with the status information. Besides the LDAP
+ * service, this extension provides another mechanism for the distribution
+ * of certificates, which MAY optionally be provided by certificate
+ * repositories.
+ *
+ *
+ * RetrieveIfAllowed ::= BOOLEAN
+ *
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATRetrieveIfAllowed = new DerObjectIdentifier(IdIsisMttAT + ".9");
+
+ /**
+ * SingleOCSPResponse extension: The certificate requested by the client by
+ * inserting the RetrieveIfAllowed extension in the request, will be
+ * returned in this extension.
+ *
+ * @see Org.BouncyCastle.Asn1.IsisMtt.Ocsp.RequestedCertificate
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATRequestedCertificate = new DerObjectIdentifier(IdIsisMttAT + ".10");
+
+ /**
+ * Base ObjectIdentifier for naming authorities
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATNamingAuthorities = new DerObjectIdentifier(IdIsisMttAT + ".11");
+
+ /**
+ * SingleOCSPResponse extension: Date, when certificate has been published
+ * in the directory and status information has become available. Currently,
+ * accrediting authorities enforce that SigG-conforming OCSP servers include
+ * this extension in the responses.
+ *
+ *
+ * CertInDirSince ::= GeneralizedTime
+ *
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATCertInDirSince = new DerObjectIdentifier(IdIsisMttAT + ".12");
+
+ /**
+ * Hash of a certificate in OCSP.
+ *
+ * @see Org.BouncyCastle.Asn1.IsisMtt.Ocsp.CertHash
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATCertHash = new DerObjectIdentifier(IdIsisMttAT + ".13");
+
+ /**
+ *
+ * NameAtBirth ::= DirectoryString(SIZE(1..64)
+ *
+ *
+ * Used in
+ * {@link Org.BouncyCastle.Asn1.X509.SubjectDirectoryAttributes SubjectDirectoryAttributes}
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATNameAtBirth = new DerObjectIdentifier(IdIsisMttAT + ".14");
+
+ /**
+ * Some other information of non-restrictive nature regarding the usage of
+ * this certificate. May be used as attribute in atribute certificate or as
+ * extension in a certificate.
+ *
+ *
+ * AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+ *
+ *
+ * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdditionalInformationSyntax
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATAdditionalInformation = new DerObjectIdentifier(IdIsisMttAT + ".15");
+
+ /**
+ * Indicates that an attribute certificate exists, which limits the
+ * usability of this public key certificate. Whenever verifying a signature
+ * with the help of this certificate, the content of the corresponding
+ * attribute certificate should be concerned. This extension MUST be
+ * included in a PKC, if a corresponding attribute certificate (having the
+ * PKC as base certificate) contains some attribute that restricts the
+ * usability of the PKC too. Attribute certificates with restricting content
+ * MUST always be included in the signed document.
+ *
+ *
+ * LiabilityLimitationFlagSyntax ::= BOOLEAN
+ *
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATLiabilityLimitationFlag = new DerObjectIdentifier("0.2.262.1.10.12.0");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/ocsp/CertHash.cs b/iTechSharp/srcbc/asn1/isismtt/ocsp/CertHash.cs
new file mode 100644
index 0000000..da5b530
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/ocsp/CertHash.cs
@@ -0,0 +1,121 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.Ocsp
+{
+ /**
+ * ISIS-MTT PROFILE: The responder may include this extension in a response to
+ * send the hash of the requested certificate to the responder. This hash is
+ * cryptographically bound to the certificate and serves as evidence that the
+ * certificate is known to the responder (i.e. it has been issued and is present
+ * in the directory). Hence, this extension is a means to provide a positive
+ * statement of availability as described in T8.[8]. As explained in T13.[1],
+ * clients may rely on this information to be able to validate signatures after
+ * the expiry of the corresponding certificate. Hence, clients MUST support this
+ * extension. If a positive statement of availability is to be delivered, this
+ * extension syntax and OID MUST be used.
+ *
+ *
+ *
+ * CertHash ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * certificateHash OCTET STRING
+ * }
+ *
+ */
+ public class CertHash
+ : Asn1Encodable
+ {
+ private readonly AlgorithmIdentifier hashAlgorithm;
+ private readonly byte[] certificateHash;
+
+ public static CertHash GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is CertHash)
+ {
+ return (CertHash) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new CertHash((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor from Asn1Sequence.
+ *
+ * The sequence is of type CertHash:
+ *
+ *
+ * CertHash ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * certificateHash OCTET STRING
+ * }
+ *
+ *
+ * @param seq The ASN.1 sequence.
+ */
+ private CertHash(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]);
+ this.certificateHash = DerOctetString.GetInstance(seq[1]).GetOctets();
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * @param hashAlgorithm The hash algorithm identifier.
+ * @param certificateHash The hash of the whole DER encoding of the certificate.
+ */
+ public CertHash(
+ AlgorithmIdentifier hashAlgorithm,
+ byte[] certificateHash)
+ {
+ if (hashAlgorithm == null)
+ throw new ArgumentNullException("hashAlgorithm");
+ if (certificateHash == null)
+ throw new ArgumentNullException("certificateHash");
+
+ this.hashAlgorithm = hashAlgorithm;
+ this.certificateHash = (byte[]) certificateHash.Clone();
+ }
+
+ public AlgorithmIdentifier HashAlgorithm
+ {
+ get { return hashAlgorithm; }
+ }
+
+ public byte[] CertificateHash
+ {
+ get { return (byte[]) certificateHash.Clone(); }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * CertHash ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * certificateHash OCTET STRING
+ * }
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(hashAlgorithm, new DerOctetString(certificateHash));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/ocsp/RequestedCertificate.cs b/iTechSharp/srcbc/asn1/isismtt/ocsp/RequestedCertificate.cs
new file mode 100644
index 0000000..62657fe
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/ocsp/RequestedCertificate.cs
@@ -0,0 +1,187 @@
+using System;
+using System.IO;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.Ocsp
+{
+ /**
+ * ISIS-MTT-Optional: The certificate requested by the client by inserting the
+ * RetrieveIfAllowed extension in the request, will be returned in this
+ * extension.
+ *
+ * ISIS-MTT-SigG: The signature act allows publishing certificates only then,
+ * when the certificate owner gives his isExplicit permission. Accordingly, there
+ * may be �nondownloadable� certificates, about which the responder must provide
+ * status information, but MUST NOT include them in the response. Clients may
+ * get therefore the following three kind of answers on a single request
+ * including the RetrieveIfAllowed extension:
+ *
+ *
+ * Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If
+ * any of the OCTET STRING options is used, it MUST contain the DER encoding of
+ * the requested certificate.
+ *
+ *
+ * RequestedCertificate ::= CHOICE {
+ * Certificate Certificate,
+ * publicKeyCertificate [0] EXPLICIT OCTET STRING,
+ * attributeCertificate [1] EXPLICIT OCTET STRING
+ * }
+ *
+ */
+ public class RequestedCertificate
+ : Asn1Encodable
+ //, ASN1Choice
+ {
+ public enum Choice
+ {
+ Certificate = -1,
+ PublicKeyCertificate = 0,
+ AttributeCertificate = 1
+ }
+
+ private readonly X509CertificateStructure cert;
+ private readonly byte[] publicKeyCert;
+ private readonly byte[] attributeCert;
+
+ public static RequestedCertificate GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is RequestedCertificate)
+ {
+ return (RequestedCertificate) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new RequestedCertificate(X509CertificateStructure.GetInstance(obj));
+ }
+
+ if (obj is Asn1TaggedObject)
+ {
+ return new RequestedCertificate((Asn1TaggedObject) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public static RequestedCertificate GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ if (!isExplicit)
+ throw new ArgumentException("choice item must be explicitly tagged");
+
+ return GetInstance(obj.GetObject());
+ }
+
+ private RequestedCertificate(
+ Asn1TaggedObject tagged)
+ {
+ switch ((Choice) tagged.TagNo)
+ {
+ case Choice.AttributeCertificate:
+ this.attributeCert = Asn1OctetString.GetInstance(tagged, true).GetOctets();
+ break;
+ case Choice.PublicKeyCertificate:
+ this.publicKeyCert = Asn1OctetString.GetInstance(tagged, true).GetOctets();
+ break;
+ default:
+ throw new ArgumentException("unknown tag number: " + tagged.TagNo);
+ }
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * Only one parameter can be given. All other must be null
.
+ *
+ * @param certificate Given as Certificate
+ */
+ public RequestedCertificate(
+ X509CertificateStructure certificate)
+ {
+ this.cert = certificate;
+ }
+
+ public RequestedCertificate(
+ Choice type,
+ byte[] certificateOctets)
+ : this(new DerTaggedObject((int) type, new DerOctetString(certificateOctets)))
+ {
+ }
+
+ public Choice Type
+ {
+ get
+ {
+ if (cert != null)
+ return Choice.Certificate;
+
+ if (publicKeyCert != null)
+ return Choice.PublicKeyCertificate;
+
+ return Choice.AttributeCertificate;
+ }
+ }
+
+ public byte[] GetCertificateBytes()
+ {
+ if (cert != null)
+ {
+ try
+ {
+ return cert.GetEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new InvalidOperationException("can't decode certificate: " + e);
+ }
+ }
+
+ if (publicKeyCert != null)
+ return publicKeyCert;
+
+ return attributeCert;
+ }
+
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * RequestedCertificate ::= CHOICE {
+ * Certificate Certificate,
+ * publicKeyCertificate [0] EXPLICIT OCTET STRING,
+ * attributeCertificate [1] EXPLICIT OCTET STRING
+ * }
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ if (publicKeyCert != null)
+ {
+ return new DerTaggedObject(0, new DerOctetString(publicKeyCert));
+ }
+
+ if (attributeCert != null)
+ {
+ return new DerTaggedObject(1, new DerOctetString(attributeCert));
+ }
+
+ return cert.ToAsn1Object();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/AdditionalInformationSyntax.cs b/iTechSharp/srcbc/asn1/isismtt/x509/AdditionalInformationSyntax.cs
new file mode 100644
index 0000000..11af9b9
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/x509/AdditionalInformationSyntax.cs
@@ -0,0 +1,74 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+ /**
+ * Some other information of non-restrictive nature regarding the usage of this
+ * certificate.
+ *
+ *
+ * AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+ *
+ */
+ public class AdditionalInformationSyntax
+ : Asn1Encodable
+ {
+ private readonly DirectoryString information;
+
+ public static AdditionalInformationSyntax GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is AdditionalInformationSyntax)
+ {
+ return (AdditionalInformationSyntax) obj;
+ }
+
+ if (obj is IAsn1String)
+ {
+ return new AdditionalInformationSyntax(DirectoryString.GetInstance(obj));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private AdditionalInformationSyntax(
+ DirectoryString information)
+ {
+ this.information = information;
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * @param information The describtion of the information.
+ */
+ public AdditionalInformationSyntax(
+ string information)
+ {
+ this.information = new DirectoryString(information);
+ }
+
+ public virtual DirectoryString Information
+ {
+ get { return information; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return information.ToAsn1Object();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/AdmissionSyntax.cs b/iTechSharp/srcbc/asn1/isismtt/x509/AdmissionSyntax.cs
new file mode 100644
index 0000000..6c4a628
Binary files /dev/null and b/iTechSharp/srcbc/asn1/isismtt/x509/AdmissionSyntax.cs differ
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/Admissions.cs b/iTechSharp/srcbc/asn1/isismtt/x509/Admissions.cs
new file mode 100644
index 0000000..40290c6
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/x509/Admissions.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+ /**
+ * An Admissions structure.
+ *
+ *
+ * Admissions ::= SEQUENCE
+ * {
+ * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+ * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+ * professionInfos SEQUENCE OF ProfessionInfo
+ * }
+ *
+ *
+ *
+ * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax
+ * @see Org.BouncyCastle.Asn1.IsisMtt.X509.ProfessionInfo
+ * @see Org.BouncyCastle.Asn1.IsisMtt.X509.NamingAuthority
+ */
+ public class Admissions
+ : Asn1Encodable
+ {
+ private readonly GeneralName admissionAuthority;
+ private readonly NamingAuthority namingAuthority;
+ private readonly Asn1Sequence professionInfos;
+
+ public static Admissions GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is Admissions)
+ {
+ return (Admissions) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Admissions((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor from Asn1Sequence.
+ *
+ * The sequence is of type ProcurationSyntax:
+ *
+ *
+ * Admissions ::= SEQUENCE
+ * {
+ * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+ * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+ * professionInfos SEQUENCE OF ProfessionInfo
+ * }
+ *
+ *
+ * @param seq The ASN.1 sequence.
+ */
+ private Admissions(
+ Asn1Sequence seq)
+ {
+ if (seq.Count > 3)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ Asn1Encodable o = (Asn1Encodable) e.Current;
+ if (o is Asn1TaggedObject)
+ {
+ switch (((Asn1TaggedObject)o).TagNo)
+ {
+ case 0:
+ admissionAuthority = GeneralName.GetInstance((Asn1TaggedObject)o, true);
+ break;
+ case 1:
+ namingAuthority = NamingAuthority.GetInstance((Asn1TaggedObject)o, true);
+ break;
+ default:
+ throw new ArgumentException("Bad tag number: " + ((Asn1TaggedObject)o).TagNo);
+ }
+ e.MoveNext();
+ o = (Asn1Encodable) e.Current;
+ }
+ if (o is Asn1TaggedObject)
+ {
+ switch (((Asn1TaggedObject)o).TagNo)
+ {
+ case 1:
+ namingAuthority = NamingAuthority.GetInstance((Asn1TaggedObject)o, true);
+ break;
+ default:
+ throw new ArgumentException("Bad tag number: " + ((Asn1TaggedObject)o).TagNo);
+ }
+ e.MoveNext();
+ o = (Asn1Encodable) e.Current;
+ }
+ professionInfos = Asn1Sequence.GetInstance(o);
+ if (e.MoveNext())
+ {
+ throw new ArgumentException("Bad object encountered: " + e.Current.GetType().Name);
+ }
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * Parameter professionInfos
is mandatory.
+ *
+ * @param admissionAuthority The admission authority.
+ * @param namingAuthority The naming authority.
+ * @param professionInfos The profession infos.
+ */
+ public Admissions(
+ GeneralName admissionAuthority,
+ NamingAuthority namingAuthority,
+ ProfessionInfo[] professionInfos)
+ {
+ this.admissionAuthority = admissionAuthority;
+ this.namingAuthority = namingAuthority;
+ this.professionInfos = new DerSequence(professionInfos);
+ }
+
+ public virtual GeneralName AdmissionAuthority
+ {
+ get { return admissionAuthority; }
+ }
+
+ public virtual NamingAuthority NamingAuthority
+ {
+ get { return namingAuthority; }
+ }
+
+ public ProfessionInfo[] GetProfessionInfos()
+ {
+ ProfessionInfo[] infos = new ProfessionInfo[professionInfos.Count];
+ int count = 0;
+ foreach (Asn1Encodable ae in professionInfos)
+ {
+ infos[count++] = ProfessionInfo.GetInstance(ae);
+ }
+ return infos;
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * Admissions ::= SEQUENCE
+ * {
+ * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+ * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+ * professionInfos SEQUENCE OF ProfessionInfo
+ * }
+ *
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector vec = new Asn1EncodableVector();
+
+ if (admissionAuthority != null)
+ {
+ vec.Add(new DerTaggedObject(true, 0, admissionAuthority));
+ }
+
+ if (namingAuthority != null)
+ {
+ vec.Add(new DerTaggedObject(true, 1, namingAuthority));
+ }
+
+ vec.Add(professionInfos);
+
+ return new DerSequence(vec);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/DeclarationOfMajority.cs b/iTechSharp/srcbc/asn1/isismtt/x509/DeclarationOfMajority.cs
new file mode 100644
index 0000000..581b4b3
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/x509/DeclarationOfMajority.cs
@@ -0,0 +1,171 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+ /**
+ * A declaration of majority.
+ *
+ *
+ * DeclarationOfMajoritySyntax ::= CHOICE
+ * {
+ * notYoungerThan [0] IMPLICIT INTEGER,
+ * fullAgeAtCountry [1] IMPLICIT SEQUENCE
+ * {
+ * fullAge BOOLEAN DEFAULT TRUE,
+ * country PrintableString (SIZE(2))
+ * }
+ * dateOfBirth [2] IMPLICIT GeneralizedTime
+ * }
+ *
+ *
+ * fullAgeAtCountry indicates the majority of the owner with respect to the laws
+ * of a specific country.
+ */
+ public class DeclarationOfMajority
+ : Asn1Encodable
+ //, ASN1Choice
+ {
+ public enum Choice
+ {
+ NotYoungerThan = 0,
+ FullAgeAtCountry = 1,
+ DateOfBirth = 2
+ };
+
+ private readonly Asn1TaggedObject declaration;
+
+ public DeclarationOfMajority(
+ int notYoungerThan)
+ {
+ declaration = new DerTaggedObject(false, 0, new DerInteger(notYoungerThan));
+ }
+
+ public DeclarationOfMajority(
+ bool fullAge,
+ string country)
+ {
+ if (country.Length > 2)
+ throw new ArgumentException("country can only be 2 characters");
+
+ DerPrintableString countryString = new DerPrintableString(country, true);
+
+ DerSequence seq;
+ if (fullAge)
+ {
+ seq = new DerSequence(countryString);
+ }
+ else
+ {
+ seq = new DerSequence(DerBoolean.False, countryString);
+ }
+
+ this.declaration = new DerTaggedObject(false, 1, seq);
+ }
+
+ public DeclarationOfMajority(
+ DerGeneralizedTime dateOfBirth)
+ {
+ this.declaration = new DerTaggedObject(false, 2, dateOfBirth);
+ }
+
+ public static DeclarationOfMajority GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is DeclarationOfMajority)
+ {
+ return (DeclarationOfMajority) obj;
+ }
+
+ if (obj is Asn1TaggedObject)
+ {
+ return new DeclarationOfMajority((Asn1TaggedObject) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private DeclarationOfMajority(
+ Asn1TaggedObject o)
+ {
+ if (o.TagNo > 2)
+ throw new ArgumentException("Bad tag number: " + o.TagNo);
+
+ this.declaration = o;
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * DeclarationOfMajoritySyntax ::= CHOICE
+ * {
+ * notYoungerThan [0] IMPLICIT INTEGER,
+ * fullAgeAtCountry [1] IMPLICIT SEQUENCE
+ * {
+ * fullAge BOOLEAN DEFAULT TRUE,
+ * country PrintableString (SIZE(2))
+ * }
+ * dateOfBirth [2] IMPLICIT GeneralizedTime
+ * }
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return declaration;
+ }
+
+ public Choice Type
+ {
+ get { return (Choice) declaration.TagNo; }
+ }
+
+ /**
+ * @return notYoungerThan if that's what we are, -1 otherwise
+ */
+ public virtual int NotYoungerThan
+ {
+ get
+ {
+ switch ((Choice) declaration.TagNo)
+ {
+ case Choice.NotYoungerThan:
+ return DerInteger.GetInstance(declaration, false).Value.IntValue;
+ default:
+ return -1;
+ }
+ }
+ }
+
+ public virtual Asn1Sequence FullAgeAtCountry
+ {
+ get
+ {
+ switch ((Choice) declaration.TagNo)
+ {
+ case Choice.FullAgeAtCountry:
+ return Asn1Sequence.GetInstance(declaration, false);
+ default:
+ return null;
+ }
+ }
+ }
+
+ public virtual DerGeneralizedTime DateOfBirth
+ {
+ get
+ {
+ switch ((Choice) declaration.TagNo)
+ {
+ case Choice.DateOfBirth:
+ return DerGeneralizedTime.GetInstance(declaration, false);
+ default:
+ return null;
+ }
+ }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/MonetaryLimit.cs b/iTechSharp/srcbc/asn1/isismtt/x509/MonetaryLimit.cs
new file mode 100644
index 0000000..f70ae34
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/x509/MonetaryLimit.cs
@@ -0,0 +1,122 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+ /**
+ * Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST be
+ * used in new certificates in place of the extension/attribute MonetaryLimit
+ * since January 1, 2004. For the sake of backward compatibility with
+ * certificates already in use, components SHOULD support MonetaryLimit (as well
+ * as QcEuLimitValue).
+ *
+ * Indicates a monetary limit within which the certificate holder is authorized
+ * to act. (This value DOES NOT express a limit on the liability of the
+ * certification authority).
+ *
+ *
+ * MonetaryLimitSyntax ::= SEQUENCE
+ * {
+ * currency PrintableString (SIZE(3)),
+ * amount INTEGER,
+ * exponent INTEGER
+ * }
+ *
+ *
+ * currency must be the ISO code.
+ *
+ * value = amount�10*exponent
+ */
+ public class MonetaryLimit
+ : Asn1Encodable
+ {
+ private readonly DerPrintableString currency;
+ private readonly DerInteger amount;
+ private readonly DerInteger exponent;
+
+ public static MonetaryLimit GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is MonetaryLimit)
+ {
+ return (MonetaryLimit) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new MonetaryLimit(Asn1Sequence.GetInstance(obj));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private MonetaryLimit(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 3)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ currency = DerPrintableString.GetInstance(seq[0]);
+ amount = DerInteger.GetInstance(seq[1]);
+ exponent = DerInteger.GetInstance(seq[2]);
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ *
+ * value = amount�10^exponent
+ *
+ * @param currency The currency. Must be the ISO code.
+ * @param amount The amount
+ * @param exponent The exponent
+ */
+ public MonetaryLimit(
+ string currency,
+ int amount,
+ int exponent)
+ {
+ this.currency = new DerPrintableString(currency, true);
+ this.amount = new DerInteger(amount);
+ this.exponent = new DerInteger(exponent);
+ }
+
+ public virtual string Currency
+ {
+ get { return currency.GetString(); }
+ }
+
+ public virtual BigInteger Amount
+ {
+ get { return amount.Value; }
+ }
+
+ public virtual BigInteger Exponent
+ {
+ get { return exponent.Value; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * MonetaryLimitSyntax ::= SEQUENCE
+ * {
+ * currency PrintableString (SIZE(3)),
+ * amount INTEGER,
+ * exponent INTEGER
+ * }
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(currency, amount, exponent);
+ }
+
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/NamingAuthority.cs b/iTechSharp/srcbc/asn1/isismtt/x509/NamingAuthority.cs
new file mode 100644
index 0000000..4262fd0
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/x509/NamingAuthority.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+ /**
+ * Names of authorities which are responsible for the administration of title
+ * registers.
+ *
+ *
+ * NamingAuthority ::= SEQUENCE
+ * {
+ * namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+ * namingAuthorityUrl IA5String OPTIONAL,
+ * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+ * }
+ *
+ * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax
+ *
+ */
+ public class NamingAuthority
+ : Asn1Encodable
+ {
+ /**
+ * Profession OIDs should always be defined under the OID branch of the
+ * responsible naming authority. At the time of this writing, the work group
+ * �Recht, Wirtschaft, Steuern� (�Law, Economy, Taxes�) is registered as the
+ * first naming authority under the OID id-isismtt-at-namingAuthorities.
+ */
+ public static readonly DerObjectIdentifier IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern
+ = new DerObjectIdentifier(IsisMttObjectIdentifiers.IdIsisMttATNamingAuthorities + ".1");
+
+ private readonly DerObjectIdentifier namingAuthorityID;
+ private readonly string namingAuthorityUrl;
+ private readonly DirectoryString namingAuthorityText;
+
+ public static NamingAuthority GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is NamingAuthority)
+ {
+ return (NamingAuthority) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new NamingAuthority((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public static NamingAuthority GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+ }
+
+ /**
+ * Constructor from Asn1Sequence.
+ *
+ *
+ *
+ * NamingAuthority ::= SEQUENCE
+ * {
+ * namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+ * namingAuthorityUrl IA5String OPTIONAL,
+ * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+ * }
+ *
+ *
+ * @param seq The ASN.1 sequence.
+ */
+ private NamingAuthority(
+ Asn1Sequence seq)
+ {
+ if (seq.Count > 3)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ IEnumerator e = seq.GetEnumerator();
+
+ if (e.MoveNext())
+ {
+ Asn1Encodable o = (Asn1Encodable) e.Current;
+ if (o is DerObjectIdentifier)
+ {
+ namingAuthorityID = (DerObjectIdentifier) o;
+ }
+ else if (o is DerIA5String)
+ {
+ namingAuthorityUrl = DerIA5String.GetInstance(o).GetString();
+ }
+ else if (o is IAsn1String)
+ {
+ namingAuthorityText = DirectoryString.GetInstance(o);
+ }
+ else
+ {
+ throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+ }
+ }
+
+ if (e.MoveNext())
+ {
+ Asn1Encodable o = (Asn1Encodable) e.Current;
+ if (o is DerIA5String)
+ {
+ namingAuthorityUrl = DerIA5String.GetInstance(o).GetString();
+ }
+ else if (o is IAsn1String)
+ {
+ namingAuthorityText = DirectoryString.GetInstance(o);
+ }
+ else
+ {
+ throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+ }
+ }
+
+ if (e.MoveNext())
+ {
+ Asn1Encodable o = (Asn1Encodable) e.Current;
+ if (o is IAsn1String)
+ {
+ namingAuthorityText = DirectoryString.GetInstance(o);
+ }
+ else
+ {
+ throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+ }
+ }
+ }
+
+ /**
+ * @return Returns the namingAuthorityID.
+ */
+ public virtual DerObjectIdentifier NamingAuthorityID
+ {
+ get { return namingAuthorityID; }
+ }
+
+ /**
+ * @return Returns the namingAuthorityText.
+ */
+ public virtual DirectoryString NamingAuthorityText
+ {
+ get { return namingAuthorityText; }
+ }
+
+ /**
+ * @return Returns the namingAuthorityUrl.
+ */
+ public virtual string NamingAuthorityUrl
+ {
+ get { return namingAuthorityUrl; }
+ }
+
+ /**
+ * Constructor from given details.
+ *
+ * All parameters can be combined.
+ *
+ * @param namingAuthorityID ObjectIdentifier for naming authority.
+ * @param namingAuthorityUrl URL for naming authority.
+ * @param namingAuthorityText Textual representation of naming authority.
+ */
+ public NamingAuthority(
+ DerObjectIdentifier namingAuthorityID,
+ string namingAuthorityUrl,
+ DirectoryString namingAuthorityText)
+ {
+ this.namingAuthorityID = namingAuthorityID;
+ this.namingAuthorityUrl = namingAuthorityUrl;
+ this.namingAuthorityText = namingAuthorityText;
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * NamingAuthority ::= SEQUENCE
+ * {
+ * namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+ * namingAuthorityUrl IA5String OPTIONAL,
+ * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+ * }
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector vec = new Asn1EncodableVector();
+ if (namingAuthorityID != null)
+ {
+ vec.Add(namingAuthorityID);
+ }
+ if (namingAuthorityUrl != null)
+ {
+ vec.Add(new DerIA5String(namingAuthorityUrl, true));
+ }
+ if (namingAuthorityText != null)
+ {
+ vec.Add(namingAuthorityText);
+ }
+ return new DerSequence(vec);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/ProcurationSyntax.cs b/iTechSharp/srcbc/asn1/isismtt/x509/ProcurationSyntax.cs
new file mode 100644
index 0000000..a25df22
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/x509/ProcurationSyntax.cs
@@ -0,0 +1,232 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X500;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+ /**
+ * Attribute to indicate that the certificate holder may sign in the name of a
+ * third person.
+ *
+ * ProcurationSyntax ::= SEQUENCE {
+ * country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+ * typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+ * signingFor [3] EXPLICIT SigningFor
+ * }
+ *
+ * SigningFor ::= CHOICE
+ * {
+ * thirdPerson GeneralName,
+ * certRef IssuerSerial
+ * }
+ *
+ *
+ */
+ public class ProcurationSyntax
+ : Asn1Encodable
+ {
+ private readonly string country;
+ private readonly DirectoryString typeOfSubstitution;
+ private readonly GeneralName thirdPerson;
+ private readonly IssuerSerial certRef;
+
+ public static ProcurationSyntax GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ProcurationSyntax)
+ {
+ return (ProcurationSyntax) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ProcurationSyntax((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor from Asn1Sequence.
+ *
+ * The sequence is of type ProcurationSyntax:
+ *
+ *
+ * ProcurationSyntax ::= SEQUENCE {
+ * country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+ * typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+ * signingFor [3] EXPLICIT SigningFor
+ * }
+ *
+ * SigningFor ::= CHOICE
+ * {
+ * thirdPerson GeneralName,
+ * certRef IssuerSerial
+ * }
+ *
+ *
+ * @param seq The ASN.1 sequence.
+ */
+ private ProcurationSyntax(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 3)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ IEnumerator e = seq.GetEnumerator();
+
+ while (e.MoveNext())
+ {
+ Asn1TaggedObject o = Asn1TaggedObject.GetInstance(e.Current);
+ switch (o.TagNo)
+ {
+ case 1:
+ country = DerPrintableString.GetInstance(o, true).GetString();
+ break;
+ case 2:
+ typeOfSubstitution = DirectoryString.GetInstance(o, true);
+ break;
+ case 3:
+ Asn1Object signingFor = o.GetObject();
+ if (signingFor is Asn1TaggedObject)
+ {
+ thirdPerson = GeneralName.GetInstance(signingFor);
+ }
+ else
+ {
+ certRef = IssuerSerial.GetInstance(signingFor);
+ }
+ break;
+ default:
+ throw new ArgumentException("Bad tag number: " + o.TagNo);
+ }
+ }
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ *
+ * Either generalName
or certRef
MUST be
+ * null
.
+ *
+ * @param country The country code whose laws apply.
+ * @param typeOfSubstitution The type of procuration.
+ * @param certRef Reference to certificate of the person who is represented.
+ */
+ public ProcurationSyntax(
+ string country,
+ DirectoryString typeOfSubstitution,
+ IssuerSerial certRef)
+ {
+ this.country = country;
+ this.typeOfSubstitution = typeOfSubstitution;
+ this.thirdPerson = null;
+ this.certRef = certRef;
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ *
+ * Either generalName
or certRef
MUST be
+ * null
.
+ *
+ * @param country The country code whose laws apply.
+ * @param typeOfSubstitution The type of procuration.
+ * @param thirdPerson The GeneralName of the person who is represented.
+ */
+ public ProcurationSyntax(
+ string country,
+ DirectoryString typeOfSubstitution,
+ GeneralName thirdPerson)
+ {
+ this.country = country;
+ this.typeOfSubstitution = typeOfSubstitution;
+ this.thirdPerson = thirdPerson;
+ this.certRef = null;
+ }
+
+ public virtual string Country
+ {
+ get { return country; }
+ }
+
+ public virtual DirectoryString TypeOfSubstitution
+ {
+ get { return typeOfSubstitution; }
+ }
+
+ public virtual GeneralName ThirdPerson
+ {
+ get { return thirdPerson; }
+ }
+
+ public virtual IssuerSerial CertRef
+ {
+ get { return certRef; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * ProcurationSyntax ::= SEQUENCE {
+ * country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+ * typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+ * signingFor [3] EXPLICIT SigningFor
+ * }
+ *
+ * SigningFor ::= CHOICE
+ * {
+ * thirdPerson GeneralName,
+ * certRef IssuerSerial
+ * }
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector vec = new Asn1EncodableVector();
+ if (country != null)
+ {
+ vec.Add(new DerTaggedObject(true, 1, new DerPrintableString(country, true)));
+ }
+ if (typeOfSubstitution != null)
+ {
+ vec.Add(new DerTaggedObject(true, 2, typeOfSubstitution));
+ }
+ if (thirdPerson != null)
+ {
+ vec.Add(new DerTaggedObject(true, 3, thirdPerson));
+ }
+ else
+ {
+ vec.Add(new DerTaggedObject(true, 3, certRef));
+ }
+
+ return new DerSequence(vec);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/ProfessionInfo.cs b/iTechSharp/srcbc/asn1/isismtt/x509/ProfessionInfo.cs
new file mode 100644
index 0000000..3bad2cb
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/x509/ProfessionInfo.cs
@@ -0,0 +1,386 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+ /**
+ * Professions, specializations, disciplines, fields of activity, etc.
+ *
+ *
+ * ProfessionInfo ::= SEQUENCE
+ * {
+ * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+ * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+ * professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+ * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+ * addProfessionInfo OCTET STRING OPTIONAL
+ * }
+ *
+ *
+ * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax
+ */
+ public class ProfessionInfo
+ : Asn1Encodable
+ {
+ /**
+ * Rechtsanw�ltin
+ */
+ public static readonly DerObjectIdentifier Rechtsanwltin = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".1");
+
+ /**
+ * Rechtsanwalt
+ */
+ public static readonly DerObjectIdentifier Rechtsanwalt = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".2");
+
+ /**
+ * Rechtsbeistand
+ */
+ public static readonly DerObjectIdentifier Rechtsbeistand = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".3");
+
+ /**
+ * Steuerberaterin
+ */
+ public static readonly DerObjectIdentifier Steuerberaterin = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".4");
+
+ /**
+ * Steuerberater
+ */
+ public static readonly DerObjectIdentifier Steuerberater = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".5");
+
+ /**
+ * Steuerbevollm�chtigte
+ */
+ public static readonly DerObjectIdentifier Steuerbevollmchtigte = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".6");
+
+ /**
+ * Steuerbevollm�chtigter
+ */
+ public static readonly DerObjectIdentifier Steuerbevollmchtigter = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".7");
+
+ /**
+ * Notarin
+ */
+ public static readonly DerObjectIdentifier Notarin = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".8");
+
+ /**
+ * Notar
+ */
+ public static readonly DerObjectIdentifier Notar = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".9");
+
+ /**
+ * Notarvertreterin
+ */
+ public static readonly DerObjectIdentifier Notarvertreterin = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".10");
+
+ /**
+ * Notarvertreter
+ */
+ public static readonly DerObjectIdentifier Notarvertreter = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".11");
+
+ /**
+ * Notariatsverwalterin
+ */
+ public static readonly DerObjectIdentifier Notariatsverwalterin = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".12");
+
+ /**
+ * Notariatsverwalter
+ */
+ public static readonly DerObjectIdentifier Notariatsverwalter = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".13");
+
+ /**
+ * Wirtschaftspr�ferin
+ */
+ public static readonly DerObjectIdentifier Wirtschaftsprferin = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".14");
+
+ /**
+ * Wirtschaftspr�fer
+ */
+ public static readonly DerObjectIdentifier Wirtschaftsprfer = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".15");
+
+ /**
+ * Vereidigte Buchpr�ferin
+ */
+ public static readonly DerObjectIdentifier VereidigteBuchprferin = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".16");
+
+ /**
+ * Vereidigter Buchpr�fer
+ */
+ public static readonly DerObjectIdentifier VereidigterBuchprfer = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".17");
+
+ /**
+ * Patentanw�ltin
+ */
+ public static readonly DerObjectIdentifier Patentanwltin = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".18");
+
+ /**
+ * Patentanwalt
+ */
+ public static readonly DerObjectIdentifier Patentanwalt = new DerObjectIdentifier(
+ NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".19");
+
+ private readonly NamingAuthority namingAuthority;
+ private readonly Asn1Sequence professionItems;
+ private readonly Asn1Sequence professionOids;
+ private readonly string registrationNumber;
+ private readonly Asn1OctetString addProfessionInfo;
+
+ public static ProfessionInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ProfessionInfo)
+ {
+ return (ProfessionInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ProfessionInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor from Asn1Sequence.
+ *
+ *
+ *
+ * ProfessionInfo ::= SEQUENCE
+ * {
+ * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+ * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+ * professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+ * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+ * addProfessionInfo OCTET STRING OPTIONAL
+ * }
+ *
+ *
+ * @param seq The ASN.1 sequence.
+ */
+ private ProfessionInfo(
+ Asn1Sequence seq)
+ {
+ if (seq.Count > 5)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ Asn1Encodable o = (Asn1Encodable) e.Current;
+
+ if (o is Asn1TaggedObject)
+ {
+ Asn1TaggedObject ato = (Asn1TaggedObject) o;
+ if (ato.TagNo != 0)
+ throw new ArgumentException("Bad tag number: " + ato.TagNo);
+
+ namingAuthority = NamingAuthority.GetInstance(ato, true);
+ e.MoveNext();
+ o = (Asn1Encodable) e.Current;
+ }
+
+ professionItems = Asn1Sequence.GetInstance(o);
+
+ if (e.MoveNext())
+ {
+ o = (Asn1Encodable) e.Current;
+ if (o is Asn1Sequence)
+ {
+ professionOids = Asn1Sequence.GetInstance(o);
+ }
+ else if (o is DerPrintableString)
+ {
+ registrationNumber = DerPrintableString.GetInstance(o).GetString();
+ }
+ else if (o is Asn1OctetString)
+ {
+ addProfessionInfo = Asn1OctetString.GetInstance(o);
+ }
+ else
+ {
+ throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+ }
+ }
+
+ if (e.MoveNext())
+ {
+ o = (Asn1Encodable) e.Current;
+ if (o is DerPrintableString)
+ {
+ registrationNumber = DerPrintableString.GetInstance(o).GetString();
+ }
+ else if (o is DerOctetString)
+ {
+ addProfessionInfo = (DerOctetString) o;
+ }
+ else
+ {
+ throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+ }
+ }
+
+ if (e.MoveNext())
+ {
+ o = (Asn1Encodable) e.Current;
+ if (o is DerOctetString)
+ {
+ addProfessionInfo = (DerOctetString) o;
+ }
+ else
+ {
+ throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+ }
+ }
+ }
+
+ /**
+ * Constructor from given details.
+ *
+ * professionItems
is mandatory, all other parameters are
+ * optional.
+ *
+ * @param namingAuthority The naming authority.
+ * @param professionItems Directory strings of the profession.
+ * @param professionOids DERObjectIdentfier objects for the
+ * profession.
+ * @param registrationNumber Registration number.
+ * @param addProfessionInfo Additional infos in encoded form.
+ */
+ public ProfessionInfo(
+ NamingAuthority namingAuthority,
+ DirectoryString[] professionItems,
+ DerObjectIdentifier[] professionOids,
+ string registrationNumber,
+ Asn1OctetString addProfessionInfo)
+ {
+ this.namingAuthority = namingAuthority;
+ this.professionItems = new DerSequence(professionItems);
+ if (professionOids != null)
+ {
+ this.professionOids = new DerSequence(professionOids);
+ }
+ this.registrationNumber = registrationNumber;
+ this.addProfessionInfo = addProfessionInfo;
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * ProfessionInfo ::= SEQUENCE
+ * {
+ * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+ * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+ * professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+ * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+ * addProfessionInfo OCTET STRING OPTIONAL
+ * }
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector vec = new Asn1EncodableVector();
+ if (namingAuthority != null)
+ {
+ vec.Add(new DerTaggedObject(true, 0, namingAuthority));
+ }
+ vec.Add(professionItems);
+ if (professionOids != null)
+ {
+ vec.Add(professionOids);
+ }
+ if (registrationNumber != null)
+ {
+ vec.Add(new DerPrintableString(registrationNumber, true));
+ }
+ if (addProfessionInfo != null)
+ {
+ vec.Add(addProfessionInfo);
+ }
+ return new DerSequence(vec);
+ }
+
+ /**
+ * @return Returns the addProfessionInfo.
+ */
+ public virtual Asn1OctetString AddProfessionInfo
+ {
+ get { return addProfessionInfo; }
+ }
+
+ /**
+ * @return Returns the namingAuthority.
+ */
+ public virtual NamingAuthority NamingAuthority
+ {
+ get { return namingAuthority; }
+ }
+
+ /**
+ * @return Returns the professionItems.
+ */
+ public virtual DirectoryString[] GetProfessionItems()
+ {
+ DirectoryString[] result = new DirectoryString[professionItems.Count];
+
+ for (int i = 0; i < professionItems.Count; ++i)
+ {
+ result[i] = DirectoryString.GetInstance(professionItems[i]);
+ }
+
+ return result;
+ }
+
+ /**
+ * @return Returns the professionOids.
+ */
+ public virtual DerObjectIdentifier[] GetProfessionOids()
+ {
+ if (professionOids == null)
+ {
+ return new DerObjectIdentifier[0];
+ }
+
+ DerObjectIdentifier[] result = new DerObjectIdentifier[professionOids.Count];
+
+ for (int i = 0; i < professionOids.Count; ++i)
+ {
+ result[i] = DerObjectIdentifier.GetInstance(professionOids[i]);
+ }
+
+ return result;
+ }
+
+ /**
+ * @return Returns the registrationNumber.
+ */
+ public virtual string RegistrationNumber
+ {
+ get { return registrationNumber; }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/isismtt/x509/Restriction.cs b/iTechSharp/srcbc/asn1/isismtt/x509/Restriction.cs
new file mode 100644
index 0000000..087c4cb
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/isismtt/x509/Restriction.cs
@@ -0,0 +1,85 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+ /**
+ * Some other restriction regarding the usage of this certificate.
+ *
+ *
+ * RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+ *
+ */
+ public class Restriction
+ : Asn1Encodable
+ {
+ private readonly DirectoryString restriction;
+
+ public static Restriction GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is Restriction)
+ {
+ return (Restriction) obj;
+ }
+
+ if (obj is IAsn1String)
+ {
+ return new Restriction(DirectoryString.GetInstance(obj));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor from DirectoryString.
+ *
+ * The DirectoryString is of type RestrictionSyntax:
+ *
+ *
+ * RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+ *
+ *
+ * @param restriction A IAsn1String.
+ */
+ private Restriction(
+ DirectoryString restriction)
+ {
+ this.restriction = restriction;
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * @param restriction The description of the restriction.
+ */
+ public Restriction(
+ string restriction)
+ {
+ this.restriction = new DirectoryString(restriction);
+ }
+
+ public virtual DirectoryString RestrictionString
+ {
+ get { return restriction; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+ *
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return restriction.ToAsn1Object();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/kisa/KISAObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/kisa/KISAObjectIdentifiers.cs
new file mode 100644
index 0000000..05351ec
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/kisa/KISAObjectIdentifiers.cs
@@ -0,0 +1,8 @@
+namespace Org.BouncyCastle.Asn1.Kisa
+{
+ public abstract class KisaObjectIdentifiers
+ {
+ public static readonly DerObjectIdentifier IdSeedCbc = new DerObjectIdentifier("1.2.410.200004.1.4");
+ public static readonly DerObjectIdentifier IdNpkiAppCmsSeedWrap = new DerObjectIdentifier("1.2.410.200004.7.1.1.1");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/microsoft/MicrosoftObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/microsoft/MicrosoftObjectIdentifiers.cs
new file mode 100644
index 0000000..b8aba7e
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/microsoft/MicrosoftObjectIdentifiers.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Microsoft
+{
+ public abstract class MicrosoftObjectIdentifiers
+ {
+ //
+ // Microsoft
+ // iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) Microsoft(311)
+ //
+ public static readonly DerObjectIdentifier Microsoft = new DerObjectIdentifier("1.3.6.1.4.1.311");
+ public static readonly DerObjectIdentifier MicrosoftCertTemplateV1 = new DerObjectIdentifier(Microsoft + ".20.2");
+ public static readonly DerObjectIdentifier MicrosoftCAVersion = new DerObjectIdentifier(Microsoft + ".21.1");
+ public static readonly DerObjectIdentifier MicrosoftPrevCACertHash = new DerObjectIdentifier(Microsoft + ".21.2");
+ public static readonly DerObjectIdentifier MicrosoftCertTemplateV2 = new DerObjectIdentifier(Microsoft + ".21.7");
+ public static readonly DerObjectIdentifier MicrosoftAppPolicies = new DerObjectIdentifier(Microsoft + ".21.10");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/misc/CAST5CBCParameters.cs b/iTechSharp/srcbc/asn1/misc/CAST5CBCParameters.cs
new file mode 100644
index 0000000..51fd660
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/misc/CAST5CBCParameters.cs
@@ -0,0 +1,74 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.Misc
+{
+ public class Cast5CbcParameters
+ : Asn1Encodable
+ {
+ private readonly DerInteger keyLength;
+ private readonly Asn1OctetString iv;
+
+ public static Cast5CbcParameters GetInstance(
+ object o)
+ {
+ if (o is Cast5CbcParameters)
+ {
+ return (Cast5CbcParameters) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new Cast5CbcParameters((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException("unknown object in Cast5CbcParameters factory");
+ }
+
+ public Cast5CbcParameters(
+ byte[] iv,
+ int keyLength)
+ {
+ this.iv = new DerOctetString(iv);
+ this.keyLength = new DerInteger(keyLength);
+ }
+
+ private Cast5CbcParameters(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ iv = (Asn1OctetString) seq[0];
+ keyLength = (DerInteger) seq[1];
+ }
+
+ public byte[] GetIV()
+ {
+ return Arrays.Clone(iv.GetOctets());
+ }
+
+ public int KeyLength
+ {
+ get { return keyLength.Value.IntValue; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * cast5CBCParameters ::= Sequence {
+ * iv OCTET STRING DEFAULT 0,
+ * -- Initialization vector
+ * keyLength Integer
+ * -- Key length, in bits
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(iv, keyLength);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/misc/IDEACBCPar.cs b/iTechSharp/srcbc/asn1/misc/IDEACBCPar.cs
new file mode 100644
index 0000000..72a60b9
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/misc/IDEACBCPar.cs
@@ -0,0 +1,68 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Misc
+{
+ public class IdeaCbcPar
+ : Asn1Encodable
+ {
+ internal Asn1OctetString iv;
+
+ public static IdeaCbcPar GetInstance(
+ object o)
+ {
+ if (o is IdeaCbcPar)
+ {
+ return (IdeaCbcPar) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new IdeaCbcPar((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException("unknown object in IDEACBCPar factory");
+ }
+
+ public IdeaCbcPar(
+ byte[] iv)
+ {
+ this.iv = new DerOctetString(iv);
+ }
+
+ private IdeaCbcPar(
+ Asn1Sequence seq)
+ {
+ if (seq.Count == 1)
+ {
+ iv = (Asn1OctetString) seq[0];
+ }
+ }
+
+ public byte[] GetIV()
+ {
+ return iv == null ? null : iv.GetOctets();
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * IDEA-CBCPar ::= Sequence {
+ * iv OCTET STRING OPTIONAL -- exactly 8 octets
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (iv != null)
+ {
+ v.Add(iv);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/misc/MiscObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/misc/MiscObjectIdentifiers.cs
new file mode 100644
index 0000000..01004d8
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/misc/MiscObjectIdentifiers.cs
@@ -0,0 +1,48 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Misc
+{
+ public abstract class MiscObjectIdentifiers
+ {
+ //
+ // Netscape
+ // iso/itu(2) joint-assign(16) us(840) uscompany(1) Netscape(113730) cert-extensions(1) }
+ //
+ public static readonly DerObjectIdentifier Netscape = new DerObjectIdentifier("2.16.840.1.113730.1");
+ public static readonly DerObjectIdentifier NetscapeCertType = new DerObjectIdentifier(Netscape + ".1");
+ public static readonly DerObjectIdentifier NetscapeBaseUrl = new DerObjectIdentifier(Netscape + ".2");
+ public static readonly DerObjectIdentifier NetscapeRevocationUrl = new DerObjectIdentifier(Netscape + ".3");
+ public static readonly DerObjectIdentifier NetscapeCARevocationUrl = new DerObjectIdentifier(Netscape + ".4");
+ public static readonly DerObjectIdentifier NetscapeRenewalUrl = new DerObjectIdentifier(Netscape + ".7");
+ public static readonly DerObjectIdentifier NetscapeCAPolicyUrl = new DerObjectIdentifier(Netscape + ".8");
+ public static readonly DerObjectIdentifier NetscapeSslServerName = new DerObjectIdentifier(Netscape + ".12");
+ public static readonly DerObjectIdentifier NetscapeCertComment = new DerObjectIdentifier(Netscape + ".13");
+ //
+ // Verisign
+ // iso/itu(2) joint-assign(16) us(840) uscompany(1) verisign(113733) cert-extensions(1) }
+ //
+ internal const string Verisign = "2.16.840.1.113733.1";
+
+ //
+ // CZAG - country, zip, age, and gender
+ //
+ public static readonly DerObjectIdentifier VerisignCzagExtension = new DerObjectIdentifier(Verisign + ".6.3");
+
+ // D&B D-U-N-S number
+ public static readonly DerObjectIdentifier VerisignDnbDunsNumber = new DerObjectIdentifier(Verisign + ".6.15");
+
+ //
+ // Novell
+ // iso/itu(2) country(16) us(840) organization(1) novell(113719)
+ //
+ public static readonly string Novell = "2.16.840.1.113719";
+ public static readonly DerObjectIdentifier NovellSecurityAttribs = new DerObjectIdentifier(Novell + ".1.9.4.1");
+
+ //
+ // Entrust
+ // iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7)
+ //
+ public static readonly string Entrust = "1.2.840.113533.7";
+ public static readonly DerObjectIdentifier EntrustVersionExtension = new DerObjectIdentifier(Entrust + ".65.0");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/misc/NetscapeCertType.cs b/iTechSharp/srcbc/asn1/misc/NetscapeCertType.cs
new file mode 100644
index 0000000..d5db652
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/misc/NetscapeCertType.cs
@@ -0,0 +1,54 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Misc
+{
+ /**
+ * The NetscapeCertType object.
+ *
+ * NetscapeCertType ::= BIT STRING {
+ * SSLClient (0),
+ * SSLServer (1),
+ * S/MIME (2),
+ * Object Signing (3),
+ * Reserved (4),
+ * SSL CA (5),
+ * S/MIME CA (6),
+ * Object Signing CA (7) }
+ *
+ */
+ public class NetscapeCertType
+ : DerBitString
+ {
+ public const int SslClient = (1 << 7);
+ public const int SslServer = (1 << 6);
+ public const int Smime = (1 << 5);
+ public const int ObjectSigning = (1 << 4);
+ public const int Reserved = (1 << 3);
+ public const int SslCA = (1 << 2);
+ public const int SmimeCA = (1 << 1);
+ public const int ObjectSigningCA = (1 << 0);
+
+ /**
+ * Basic constructor.
+ *
+ * @param usage - the bitwise OR of the Key Usage flags giving the
+ * allowed uses for the key.
+ * e.g. (X509NetscapeCertType.sslCA | X509NetscapeCertType.smimeCA)
+ */
+ public NetscapeCertType(int usage)
+ : base(GetBytes(usage), GetPadBits(usage))
+ {
+ }
+
+ public NetscapeCertType(DerBitString usage)
+ : base(usage.GetBytes(), usage.PadBits)
+ {
+ }
+
+ public override string ToString()
+ {
+ byte[] data = GetBytes();
+ return "NetscapeCertType: 0x" + (data[0] & 0xff).ToString("X");
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/misc/NetscapeRevocationURL.cs b/iTechSharp/srcbc/asn1/misc/NetscapeRevocationURL.cs
new file mode 100644
index 0000000..6cac031
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/misc/NetscapeRevocationURL.cs
@@ -0,0 +1,18 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Misc
+{
+ public class NetscapeRevocationUrl
+ : DerIA5String
+ {
+ public NetscapeRevocationUrl(DerIA5String str)
+ : base(str.GetString())
+ {
+ }
+
+ public override string ToString()
+ {
+ return "NetscapeRevocationUrl: " + this.GetString();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/misc/VerisignCzagExtension.cs b/iTechSharp/srcbc/asn1/misc/VerisignCzagExtension.cs
new file mode 100644
index 0000000..1c3054b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/misc/VerisignCzagExtension.cs
@@ -0,0 +1,18 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Misc
+{
+ public class VerisignCzagExtension
+ : DerIA5String
+ {
+ public VerisignCzagExtension(DerIA5String str)
+ : base(str.GetString())
+ {
+ }
+
+ public override string ToString()
+ {
+ return "VerisignCzagExtension: " + this.GetString();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/mozilla/PublicKeyAndChallenge.cs b/iTechSharp/srcbc/asn1/mozilla/PublicKeyAndChallenge.cs
new file mode 100644
index 0000000..1e08b80
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/mozilla/PublicKeyAndChallenge.cs
@@ -0,0 +1,67 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Mozilla
+{
+ /**
+ * This is designed to parse
+ * the PublicKeyAndChallenge created by the KEYGEN tag included by
+ * Mozilla based browsers.
+ *
+ * PublicKeyAndChallenge ::= SEQUENCE {
+ * spki SubjectPublicKeyInfo,
+ * challenge IA5STRING
+ * }
+ *
+ *
+ */
+ public class PublicKeyAndChallenge
+ : Asn1Encodable
+ {
+ private Asn1Sequence pkacSeq;
+ private SubjectPublicKeyInfo spki;
+ private DerIA5String challenge;
+
+ public static PublicKeyAndChallenge GetInstance(
+ object obj)
+ {
+ if (obj is PublicKeyAndChallenge)
+ {
+ return (PublicKeyAndChallenge) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new PublicKeyAndChallenge((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException(
+ "unknown object in 'PublicKeyAndChallenge' factory : "
+ + obj.GetType().Name + ".");
+ }
+
+ public PublicKeyAndChallenge(
+ Asn1Sequence seq)
+ {
+ pkacSeq = seq;
+ spki = SubjectPublicKeyInfo.GetInstance(seq[0]);
+ challenge = DerIA5String.GetInstance(seq[1]);
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return pkacSeq;
+ }
+
+ public SubjectPublicKeyInfo SubjectPublicKeyInfo
+ {
+ get { return spki; }
+ }
+
+ public DerIA5String Challenge
+ {
+ get { return challenge; }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/nist/NISTNamedCurves.cs b/iTechSharp/srcbc/asn1/nist/NISTNamedCurves.cs
new file mode 100644
index 0000000..52cde89
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/nist/NISTNamedCurves.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections;
+using System.Globalization;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.Nist
+{
+ /**
+ * Utility class for fetching curves using their NIST names as published in FIPS-PUB 186-2
+ */
+ public sealed class NistNamedCurves
+ {
+ private NistNamedCurves()
+ {
+ }
+
+ private static readonly Hashtable objIds = new Hashtable();
+ private static readonly Hashtable names = new Hashtable();
+
+ private static void DefineCurve(
+ string name,
+ DerObjectIdentifier oid)
+ {
+ objIds.Add(name, oid);
+ names.Add(oid, name);
+ }
+
+ static NistNamedCurves()
+ {
+ DefineCurve("B-571", SecObjectIdentifiers.SecT571r1);
+ DefineCurve("B-409", SecObjectIdentifiers.SecT409r1);
+ DefineCurve("B-283", SecObjectIdentifiers.SecT283r1);
+ DefineCurve("B-233", SecObjectIdentifiers.SecT233r1);
+ DefineCurve("B-163", SecObjectIdentifiers.SecT163r2);
+ DefineCurve("P-521", SecObjectIdentifiers.SecP521r1);
+ DefineCurve("P-256", SecObjectIdentifiers.SecP256r1);
+ DefineCurve("P-224", SecObjectIdentifiers.SecP224r1);
+ DefineCurve("P-384", SecObjectIdentifiers.SecP384r1);
+ }
+
+ public static X9ECParameters GetByName(
+ string name)
+ {
+ DerObjectIdentifier oid = (DerObjectIdentifier) objIds[name.ToUpper(CultureInfo.InvariantCulture)];
+
+ if (oid != null)
+ {
+ return GetByOid(oid);
+ }
+
+ return null;
+ }
+
+ /**
+ * return the X9ECParameters object for the named curve represented by
+ * the passed in object identifier. Null if the curve isn't present.
+ *
+ * @param oid an object identifier representing a named curve, if present.
+ */
+ public static X9ECParameters GetByOid(
+ DerObjectIdentifier oid)
+ {
+ return SecNamedCurves.GetByOid(oid);
+ }
+
+ /**
+ * return the object identifier signified by the passed in name. Null
+ * if there is no object identifier associated with name.
+ *
+ * @return the object identifier associated with name, if present.
+ */
+ public static DerObjectIdentifier GetOid(
+ string name)
+ {
+ return (DerObjectIdentifier) objIds[name.ToUpper(CultureInfo.InvariantCulture)];
+ }
+
+ /**
+ * return the named curve name represented by the given object identifier.
+ */
+ public static string GetName(
+ DerObjectIdentifier oid)
+ {
+ return (string) names[oid];
+ }
+
+ /**
+ * returns an enumeration containing the name strings for curves
+ * contained in this structure.
+ */
+ public static IEnumerable Names
+ {
+ get { return new EnumerableProxy(objIds.Keys); }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/nist/NISTObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/nist/NISTObjectIdentifiers.cs
new file mode 100644
index 0000000..619b6fb
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/nist/NISTObjectIdentifiers.cs
@@ -0,0 +1,55 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Nist
+{
+ public sealed class NistObjectIdentifiers
+ {
+ private NistObjectIdentifiers()
+ {
+ }
+
+ //
+ // NIST
+ // iso/itu(2) joint-assign(16) us(840) organization(1) gov(101) csor(3)
+
+ //
+ // nistalgorithms(4)
+ //
+ public static readonly DerObjectIdentifier NistAlgorithm = new DerObjectIdentifier("2.16.840.1.101.3.4");
+
+ public static readonly DerObjectIdentifier IdSha256 = new DerObjectIdentifier(NistAlgorithm + ".2.1");
+ public static readonly DerObjectIdentifier IdSha384 = new DerObjectIdentifier(NistAlgorithm + ".2.2");
+ public static readonly DerObjectIdentifier IdSha512 = new DerObjectIdentifier(NistAlgorithm + ".2.3");
+ public static readonly DerObjectIdentifier IdSha224 = new DerObjectIdentifier(NistAlgorithm + ".2.4");
+
+ public static readonly DerObjectIdentifier Aes = new DerObjectIdentifier(NistAlgorithm + ".1");
+
+ public static readonly DerObjectIdentifier IdAes128Ecb = new DerObjectIdentifier(Aes + ".1");
+ public static readonly DerObjectIdentifier IdAes128Cbc = new DerObjectIdentifier(Aes + ".2");
+ public static readonly DerObjectIdentifier IdAes128Ofb = new DerObjectIdentifier(Aes + ".3");
+ public static readonly DerObjectIdentifier IdAes128Cfb = new DerObjectIdentifier(Aes + ".4");
+ public static readonly DerObjectIdentifier IdAes128Wrap = new DerObjectIdentifier(Aes + ".5");
+
+ public static readonly DerObjectIdentifier IdAes192Ecb = new DerObjectIdentifier(Aes + ".21");
+ public static readonly DerObjectIdentifier IdAes192Cbc = new DerObjectIdentifier(Aes + ".22");
+ public static readonly DerObjectIdentifier IdAes192Ofb = new DerObjectIdentifier(Aes + ".23");
+ public static readonly DerObjectIdentifier IdAes192Cfb = new DerObjectIdentifier(Aes + ".24");
+ public static readonly DerObjectIdentifier IdAes192Wrap = new DerObjectIdentifier(Aes + ".25");
+
+ public static readonly DerObjectIdentifier IdAes256Ecb = new DerObjectIdentifier(Aes + ".41");
+ public static readonly DerObjectIdentifier IdAes256Cbc = new DerObjectIdentifier(Aes + ".42");
+ public static readonly DerObjectIdentifier IdAes256Ofb = new DerObjectIdentifier(Aes + ".43");
+ public static readonly DerObjectIdentifier IdAes256Cfb = new DerObjectIdentifier(Aes + ".44");
+ public static readonly DerObjectIdentifier IdAes256Wrap = new DerObjectIdentifier(Aes + ".45");
+
+ //
+ // signatures
+ //
+ public static readonly DerObjectIdentifier IdDsaWithSha2 = new DerObjectIdentifier(NistAlgorithm + ".3");
+
+ public static readonly DerObjectIdentifier DsaWithSha224 = new DerObjectIdentifier(IdDsaWithSha2 + ".1");
+ public static readonly DerObjectIdentifier DsaWithSha256 = new DerObjectIdentifier(IdDsaWithSha2 + ".2");
+ public static readonly DerObjectIdentifier DsaWithSha384 = new DerObjectIdentifier(IdDsaWithSha2 + ".3");
+ public static readonly DerObjectIdentifier DsaWithSha512 = new DerObjectIdentifier(IdDsaWithSha2 + ".4");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ntt/NTTObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/ntt/NTTObjectIdentifiers.cs
new file mode 100644
index 0000000..cd25956
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ntt/NTTObjectIdentifiers.cs
@@ -0,0 +1,14 @@
+namespace Org.BouncyCastle.Asn1.Ntt
+{
+ ///
+ * BasicOcspResponse ::= Sequence {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT Sequence OF Certificate OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ tbsResponseData, signatureAlgorithm, signature);
+
+ if (certs != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, certs));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/CertID.cs b/iTechSharp/srcbc/asn1/ocsp/CertID.cs
new file mode 100644
index 0000000..4b25109
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/CertID.cs
@@ -0,0 +1,98 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class CertID
+ : Asn1Encodable
+ {
+ private readonly AlgorithmIdentifier hashAlgorithm;
+ private readonly Asn1OctetString issuerNameHash;
+ private readonly Asn1OctetString issuerKeyHash;
+ private readonly DerInteger serialNumber;
+
+ public static CertID GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static CertID GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is CertID)
+ {
+ return (CertID)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new CertID((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public CertID(
+ AlgorithmIdentifier hashAlgorithm,
+ Asn1OctetString issuerNameHash,
+ Asn1OctetString issuerKeyHash,
+ DerInteger serialNumber)
+ {
+ this.hashAlgorithm = hashAlgorithm;
+ this.issuerNameHash = issuerNameHash;
+ this.issuerKeyHash = issuerKeyHash;
+ this.serialNumber = serialNumber;
+ }
+
+ private CertID(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 4)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]);
+ this.issuerNameHash = Asn1OctetString.GetInstance(seq[1]);
+ this.issuerKeyHash = Asn1OctetString.GetInstance(seq[2]);
+ this.serialNumber = DerInteger.GetInstance(seq[3]);
+ }
+
+ public AlgorithmIdentifier HashAlgorithm
+ {
+ get { return hashAlgorithm; }
+ }
+
+ public Asn1OctetString IssuerNameHash
+ {
+ get { return issuerNameHash; }
+ }
+
+ public Asn1OctetString IssuerKeyHash
+ {
+ get { return issuerKeyHash; }
+ }
+
+ public DerInteger SerialNumber
+ {
+ get { return serialNumber; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * CertID ::= Sequence {
+ * hashAlgorithm AlgorithmIdentifier,
+ * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
+ * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
+ * serialNumber CertificateSerialNumber }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/CertStatus.cs b/iTechSharp/srcbc/asn1/ocsp/CertStatus.cs
new file mode 100644
index 0000000..d922572
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/CertStatus.cs
@@ -0,0 +1,94 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class CertStatus
+ : Asn1Encodable
+ {
+ private readonly int tagNo;
+ private readonly Asn1Encodable value;
+
+ /**
+ * create a CertStatus object with a tag of zero.
+ */
+ public CertStatus()
+ {
+ tagNo = 0;
+ value = DerNull.Instance;
+ }
+
+ public CertStatus(
+ RevokedInfo info)
+ {
+ tagNo = 1;
+ value = info;
+ }
+
+ public CertStatus(
+ int tagNo,
+ Asn1Encodable value)
+ {
+ this.tagNo = tagNo;
+ this.value = value;
+ }
+
+ public CertStatus(
+ Asn1TaggedObject choice)
+ {
+ this.tagNo = choice.TagNo;
+
+ switch (choice.TagNo)
+ {
+ case 1:
+ value = RevokedInfo.GetInstance(choice, false);
+ break;
+ case 0:
+ case 2:
+ value = DerNull.Instance;
+ break;
+ }
+ }
+
+ public static CertStatus GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is CertStatus)
+ {
+ return (CertStatus)obj;
+ }
+
+ if (obj is Asn1TaggedObject)
+ {
+ return new CertStatus((Asn1TaggedObject)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public int TagNo
+ {
+ get { return tagNo; }
+ }
+
+ public Asn1Encodable Status
+ {
+ get { return value; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * CertStatus ::= CHOICE {
+ * good [0] IMPLICIT Null,
+ * revoked [1] IMPLICIT RevokedInfo,
+ * unknown [2] IMPLICIT UnknownInfo }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerTaggedObject(false, tagNo, value);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/CrlID.cs b/iTechSharp/srcbc/asn1/ocsp/CrlID.cs
new file mode 100644
index 0000000..cfb3d6f
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/CrlID.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class CrlID
+ : Asn1Encodable
+ {
+ private readonly DerIA5String crlUrl;
+ private readonly DerInteger crlNum;
+ private readonly DerGeneralizedTime crlTime;
+
+ // TODO Add GetInstance method(s) and amke this private?
+ public CrlID(
+ Asn1Sequence seq)
+ {
+ foreach (Asn1TaggedObject o in seq)
+ {
+ switch (o.TagNo)
+ {
+ case 0:
+ crlUrl = DerIA5String.GetInstance(o, true);
+ break;
+ case 1:
+ crlNum = DerInteger.GetInstance(o, true);
+ break;
+ case 2:
+ crlTime = DerGeneralizedTime.GetInstance(o, true);
+ break;
+ default:
+ throw new ArgumentException("unknown tag number: " + o.TagNo);
+ }
+ }
+ }
+
+ public DerIA5String CrlUrl
+ {
+ get { return crlUrl; }
+ }
+
+ public DerInteger CrlNum
+ {
+ get { return crlNum; }
+ }
+
+ public DerGeneralizedTime CrlTime
+ {
+ get { return crlTime; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * CrlID ::= Sequence {
+ * crlUrl [0] EXPLICIT IA5String OPTIONAL,
+ * crlNum [1] EXPLICIT Integer OPTIONAL,
+ * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (crlUrl != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, crlUrl));
+ }
+
+ if (crlNum != null)
+ {
+ v.Add(new DerTaggedObject(true, 1, crlNum));
+ }
+
+ if (crlTime != null)
+ {
+ v.Add(new DerTaggedObject(true, 2, crlTime));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/OCSPObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/ocsp/OCSPObjectIdentifiers.cs
new file mode 100644
index 0000000..a37c855
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/OCSPObjectIdentifiers.cs
@@ -0,0 +1,23 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public abstract class OcspObjectIdentifiers
+ {
+ internal const string PkixOcspId = "1.3.6.1.5.5.7.48.1";
+
+ public static readonly DerObjectIdentifier PkixOcsp = new DerObjectIdentifier(PkixOcspId);
+ public static readonly DerObjectIdentifier PkixOcspBasic = new DerObjectIdentifier(PkixOcspId + ".1");
+
+ //
+ // extensions
+ //
+ public static readonly DerObjectIdentifier PkixOcspNonce = new DerObjectIdentifier(PkixOcsp + ".2");
+ public static readonly DerObjectIdentifier PkixOcspCrl = new DerObjectIdentifier(PkixOcsp + ".3");
+
+ public static readonly DerObjectIdentifier PkixOcspResponse = new DerObjectIdentifier(PkixOcsp + ".4");
+ public static readonly DerObjectIdentifier PkixOcspNocheck = new DerObjectIdentifier(PkixOcsp + ".5");
+ public static readonly DerObjectIdentifier PkixOcspArchiveCutoff = new DerObjectIdentifier(PkixOcsp + ".6");
+ public static readonly DerObjectIdentifier PkixOcspServiceLocator = new DerObjectIdentifier(PkixOcsp + ".7");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/OCSPRequest.cs b/iTechSharp/srcbc/asn1/ocsp/OCSPRequest.cs
new file mode 100644
index 0000000..1e804d7
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/OCSPRequest.cs
@@ -0,0 +1,89 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class OcspRequest
+ : Asn1Encodable
+ {
+ private readonly TbsRequest tbsRequest;
+ private readonly Signature optionalSignature;
+
+ public static OcspRequest GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static OcspRequest GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is OcspRequest)
+ {
+ return (OcspRequest)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new OcspRequest((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public OcspRequest(
+ TbsRequest tbsRequest,
+ Signature optionalSignature)
+ {
+ if (tbsRequest == null)
+ throw new ArgumentNullException("tbsRequest");
+
+ this.tbsRequest = tbsRequest;
+ this.optionalSignature = optionalSignature;
+ }
+
+ private OcspRequest(
+ Asn1Sequence seq)
+ {
+ tbsRequest = TbsRequest.GetInstance(seq[0]);
+
+ if (seq.Count == 2)
+ {
+ optionalSignature = Signature.GetInstance(
+ (Asn1TaggedObject)seq[1], true);
+ }
+ }
+
+ public TbsRequest TbsRequest
+ {
+ get { return tbsRequest; }
+ }
+
+ public Signature OptionalSignature
+ {
+ get { return optionalSignature; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * OcspRequest ::= Sequence {
+ * tbsRequest TBSRequest,
+ * optionalSignature [0] EXPLICIT Signature OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(tbsRequest);
+
+ if (optionalSignature != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, optionalSignature));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/OCSPResponse.cs b/iTechSharp/srcbc/asn1/ocsp/OCSPResponse.cs
new file mode 100644
index 0000000..e9aad81
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/OCSPResponse.cs
@@ -0,0 +1,90 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class OcspResponse
+ : Asn1Encodable
+ {
+ private readonly OcspResponseStatus responseStatus;
+ private readonly ResponseBytes responseBytes;
+
+ public static OcspResponse GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static OcspResponse GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is OcspResponse)
+ {
+ return (OcspResponse)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new OcspResponse((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public OcspResponse(
+ OcspResponseStatus responseStatus,
+ ResponseBytes responseBytes)
+ {
+ if (responseStatus == null)
+ throw new ArgumentNullException("responseStatus");
+
+ this.responseStatus = responseStatus;
+ this.responseBytes = responseBytes;
+ }
+
+ private OcspResponse(
+ Asn1Sequence seq)
+ {
+ responseStatus = new OcspResponseStatus(
+ DerEnumerated.GetInstance(seq[0]));
+
+ if (seq.Count == 2)
+ {
+ responseBytes = ResponseBytes.GetInstance(
+ (Asn1TaggedObject)seq[1], true);
+ }
+ }
+
+ public OcspResponseStatus ResponseStatus
+ {
+ get { return responseStatus; }
+ }
+
+ public ResponseBytes ResponseBytes
+ {
+ get { return responseBytes; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * OcspResponse ::= Sequence {
+ * responseStatus OcspResponseStatus,
+ * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(responseStatus);
+
+ if (responseBytes != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, responseBytes));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/OCSPResponseStatus.cs b/iTechSharp/srcbc/asn1/ocsp/OCSPResponseStatus.cs
new file mode 100644
index 0000000..653317e
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/OCSPResponseStatus.cs
@@ -0,0 +1,41 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class OcspResponseStatus
+ : DerEnumerated
+ {
+ public const int Successful = 0;
+ public const int MalformedRequest = 1;
+ public const int InternalError = 2;
+ public const int TryLater = 3;
+ public const int SignatureRequired = 5;
+ public const int Unauthorized = 6;
+
+ /**
+ * The OcspResponseStatus enumeration.
+ *
+ * OcspResponseStatus ::= Enumerated {
+ * successful (0), --Response has valid confirmations
+ * malformedRequest (1), --Illegal confirmation request
+ * internalError (2), --Internal error in issuer
+ * tryLater (3), --Try again later
+ * --(4) is not used
+ * sigRequired (5), --Must sign the request
+ * unauthorized (6) --Request unauthorized
+ * }
+ *
+ */
+ public OcspResponseStatus(int value)
+ : base(value)
+ {
+ }
+
+ public OcspResponseStatus(DerEnumerated value)
+ : base(value.Value.IntValue)
+ {
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/Request.cs b/iTechSharp/srcbc/asn1/ocsp/Request.cs
new file mode 100644
index 0000000..116c15e
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/Request.cs
@@ -0,0 +1,90 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class Request
+ : Asn1Encodable
+ {
+ private readonly CertID reqCert;
+ private readonly X509Extensions singleRequestExtensions;
+
+ public static Request GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static Request GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is Request)
+ {
+ return (Request)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Request((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public Request(
+ CertID reqCert,
+ X509Extensions singleRequestExtensions)
+ {
+ if (reqCert == null)
+ throw new ArgumentNullException("reqCert");
+
+ this.reqCert = reqCert;
+ this.singleRequestExtensions = singleRequestExtensions;
+ }
+
+ private Request(
+ Asn1Sequence seq)
+ {
+ reqCert = CertID.GetInstance(seq[0]);
+
+ if (seq.Count == 2)
+ {
+ singleRequestExtensions = X509Extensions.GetInstance(
+ (Asn1TaggedObject)seq[1], true);
+ }
+ }
+
+ public CertID ReqCert
+ {
+ get { return reqCert; }
+ }
+
+ public X509Extensions SingleRequestExtensions
+ {
+ get { return singleRequestExtensions; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Request ::= Sequence {
+ * reqCert CertID,
+ * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(reqCert);
+
+ if (singleRequestExtensions != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, singleRequestExtensions));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/ResponderID.cs b/iTechSharp/srcbc/asn1/ocsp/ResponderID.cs
new file mode 100644
index 0000000..1ee0058
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/ResponderID.cs
@@ -0,0 +1,77 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class ResponderID
+ : Asn1Encodable
+ {
+ private readonly Asn1Encodable id;
+
+ public static ResponderID GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ResponderID)
+ {
+ return (ResponderID)obj;
+ }
+
+ if (obj is DerOctetString)
+ {
+ return new ResponderID((DerOctetString)obj);
+ }
+
+ if (obj is Asn1TaggedObject)
+ {
+ Asn1TaggedObject o = (Asn1TaggedObject)obj;
+
+ if (o.TagNo == 1)
+ {
+ return new ResponderID(X509Name.GetInstance(o, true));
+ }
+
+ return new ResponderID(Asn1OctetString.GetInstance(o, true));
+ }
+
+ return new ResponderID(X509Name.GetInstance(obj));
+ }
+
+ public ResponderID(
+ Asn1OctetString id)
+ {
+ if (id == null)
+ throw new ArgumentNullException("id");
+
+ this.id = id;
+ }
+
+ public ResponderID(
+ X509Name id)
+ {
+ if (id == null)
+ throw new ArgumentNullException("id");
+
+ this.id = id;
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * ResponderID ::= CHOICE {
+ * byName [1] Name,
+ * byKey [2] KeyHash }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ if (id is Asn1OctetString)
+ {
+ return new DerTaggedObject(true, 2, id);
+ }
+
+ return new DerTaggedObject(true, 1, id);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/ResponseBytes.cs b/iTechSharp/srcbc/asn1/ocsp/ResponseBytes.cs
new file mode 100644
index 0000000..2ce59fa
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/ResponseBytes.cs
@@ -0,0 +1,82 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class ResponseBytes
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier responseType;
+ private readonly Asn1OctetString response;
+
+ public static ResponseBytes GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static ResponseBytes GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ResponseBytes)
+ {
+ return (ResponseBytes)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ResponseBytes((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public ResponseBytes(
+ DerObjectIdentifier responseType,
+ Asn1OctetString response)
+ {
+ if (responseType == null)
+ throw new ArgumentNullException("responseType");
+ if (response == null)
+ throw new ArgumentNullException("response");
+
+ this.responseType = responseType;
+ this.response = response;
+ }
+
+ private ResponseBytes(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.responseType = DerObjectIdentifier.GetInstance(seq[0]);
+ this.response = Asn1OctetString.GetInstance(seq[1]);
+ }
+
+ public DerObjectIdentifier ResponseType
+ {
+ get { return responseType; }
+ }
+
+ public Asn1OctetString Response
+ {
+ get { return response; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * ResponseBytes ::= Sequence {
+ * responseType OBJECT IDENTIFIER,
+ * response OCTET STRING }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(responseType, response);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/ResponseData.cs b/iTechSharp/srcbc/asn1/ocsp/ResponseData.cs
new file mode 100644
index 0000000..173829d
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/ResponseData.cs
@@ -0,0 +1,158 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class ResponseData
+ : Asn1Encodable
+ {
+ private static readonly DerInteger V1 = new DerInteger(0);
+
+ private readonly bool versionPresent;
+ private readonly DerInteger version;
+ private readonly ResponderID responderID;
+ private readonly DerGeneralizedTime producedAt;
+ private readonly Asn1Sequence responses;
+ private readonly X509Extensions responseExtensions;
+
+ public static ResponseData GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static ResponseData GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ResponseData)
+ {
+ return (ResponseData)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ResponseData((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public ResponseData(
+ DerInteger version,
+ ResponderID responderID,
+ DerGeneralizedTime producedAt,
+ Asn1Sequence responses,
+ X509Extensions responseExtensions)
+ {
+ this.version = version;
+ this.responderID = responderID;
+ this.producedAt = producedAt;
+ this.responses = responses;
+ this.responseExtensions = responseExtensions;
+ }
+
+ public ResponseData(
+ ResponderID responderID,
+ DerGeneralizedTime producedAt,
+ Asn1Sequence responses,
+ X509Extensions responseExtensions)
+ : this(V1, responderID, producedAt, responses, responseExtensions)
+ {
+ }
+
+ private ResponseData(
+ Asn1Sequence seq)
+ {
+ int index = 0;
+
+ Asn1Encodable enc = seq[0];
+ if (enc is Asn1TaggedObject)
+ {
+ Asn1TaggedObject o = (Asn1TaggedObject)enc;
+
+ if (o.TagNo == 0)
+ {
+ this.versionPresent = true;
+ this.version = DerInteger.GetInstance(o, true);
+ index++;
+ }
+ else
+ {
+ this.version = V1;
+ }
+ }
+ else
+ {
+ this.version = V1;
+ }
+
+ this.responderID = ResponderID.GetInstance(seq[index++]);
+ this.producedAt = (DerGeneralizedTime)seq[index++];
+ this.responses = (Asn1Sequence)seq[index++];
+
+ if (seq.Count > index)
+ {
+ this.responseExtensions = X509Extensions.GetInstance(
+ (Asn1TaggedObject)seq[index], true);
+ }
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public ResponderID ResponderID
+ {
+ get { return responderID; }
+ }
+
+ public DerGeneralizedTime ProducedAt
+ {
+ get { return producedAt; }
+ }
+
+ public Asn1Sequence Responses
+ {
+ get { return responses; }
+ }
+
+ public X509Extensions ResponseExtensions
+ {
+ get { return responseExtensions; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * ResponseData ::= Sequence {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses Sequence OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (versionPresent || !version.Equals(V1))
+ {
+ v.Add(new DerTaggedObject(true, 0, version));
+ }
+
+ v.Add(responderID, producedAt, responses);
+
+ if (responseExtensions != null)
+ {
+ v.Add(new DerTaggedObject(true, 1, responseExtensions));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/RevokedInfo.cs b/iTechSharp/srcbc/asn1/ocsp/RevokedInfo.cs
new file mode 100644
index 0000000..7d9d590
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/RevokedInfo.cs
@@ -0,0 +1,96 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class RevokedInfo
+ : Asn1Encodable
+ {
+ private readonly DerGeneralizedTime revocationTime;
+ private readonly CrlReason revocationReason;
+
+ public static RevokedInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static RevokedInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is RevokedInfo)
+ {
+ return (RevokedInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new RevokedInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public RevokedInfo(
+ DerGeneralizedTime revocationTime)
+ : this(revocationTime, null)
+ {
+ }
+
+ public RevokedInfo(
+ DerGeneralizedTime revocationTime,
+ CrlReason revocationReason)
+ {
+ if (revocationTime == null)
+ throw new ArgumentNullException("revocationTime");
+
+ this.revocationTime = revocationTime;
+ this.revocationReason = revocationReason;
+ }
+
+ private RevokedInfo(
+ Asn1Sequence seq)
+ {
+ this.revocationTime = (DerGeneralizedTime) seq[0];
+
+ if (seq.Count > 1)
+ {
+ this.revocationReason = new CrlReason(
+ DerEnumerated.GetInstance((Asn1TaggedObject) seq[1], true));
+ }
+ }
+
+ public DerGeneralizedTime RevocationTime
+ {
+ get { return revocationTime; }
+ }
+
+ public CrlReason RevocationReason
+ {
+ get { return revocationReason; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * RevokedInfo ::= Sequence {
+ * revocationTime GeneralizedTime,
+ * revocationReason [0] EXPLICIT CRLReason OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(revocationTime);
+
+ if (revocationReason != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, revocationReason));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/ServiceLocator.cs b/iTechSharp/srcbc/asn1/ocsp/ServiceLocator.cs
new file mode 100644
index 0000000..56bc49d
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/ServiceLocator.cs
@@ -0,0 +1,95 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class ServiceLocator
+ : Asn1Encodable
+ {
+ private readonly X509Name issuer;
+ private readonly Asn1Object locator;
+
+ public static ServiceLocator GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static ServiceLocator GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ServiceLocator)
+ {
+ return (ServiceLocator) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ServiceLocator((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public ServiceLocator(
+ X509Name issuer)
+ : this(issuer, null)
+ {
+ }
+
+ public ServiceLocator(
+ X509Name issuer,
+ Asn1Object locator)
+ {
+ if (issuer == null)
+ throw new ArgumentNullException("issuer");
+
+ this.issuer = issuer;
+ this.locator = locator;
+ }
+
+ private ServiceLocator(
+ Asn1Sequence seq)
+ {
+ this.issuer = X509Name.GetInstance(seq[0]);
+
+ if (seq.Count > 1)
+ {
+ this.locator = seq[1].ToAsn1Object();
+ }
+ }
+
+ public X509Name Issuer
+ {
+ get { return issuer; }
+ }
+
+ public Asn1Object Locator
+ {
+ get { return locator; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * ServiceLocator ::= Sequence {
+ * issuer Name,
+ * locator AuthorityInfoAccessSyntax OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(issuer);
+
+ if (locator != null)
+ {
+ v.Add(locator);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/Signature.cs b/iTechSharp/srcbc/asn1/ocsp/Signature.cs
new file mode 100644
index 0000000..a07e7a7
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/Signature.cs
@@ -0,0 +1,110 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class Signature
+ : Asn1Encodable
+ {
+ internal AlgorithmIdentifier signatureAlgorithm;
+ internal DerBitString signatureValue;
+ internal Asn1Sequence certs;
+
+ public static Signature GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static Signature GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is Signature)
+ {
+ return (Signature)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Signature((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public Signature(
+ AlgorithmIdentifier signatureAlgorithm,
+ DerBitString signatureValue)
+ : this(signatureAlgorithm, signatureValue, null)
+ {
+ }
+
+ public Signature(
+ AlgorithmIdentifier signatureAlgorithm,
+ DerBitString signatureValue,
+ Asn1Sequence certs)
+ {
+ if (signatureAlgorithm == null)
+ throw new ArgumentException("signatureAlgorithm");
+ if (signatureValue == null)
+ throw new ArgumentException("signatureValue");
+
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signatureValue = signatureValue;
+ this.certs = certs;
+ }
+
+ private Signature(
+ Asn1Sequence seq)
+ {
+ signatureAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]);
+ signatureValue = (DerBitString)seq[1];
+
+ if (seq.Count == 3)
+ {
+ certs = Asn1Sequence.GetInstance(
+ (Asn1TaggedObject)seq[2], true);
+ }
+ }
+
+ public AlgorithmIdentifier SignatureAlgorithm
+ {
+ get { return signatureAlgorithm; }
+ }
+
+ public DerBitString SignatureValue
+ {
+ get { return signatureValue; }
+ }
+
+ public Asn1Sequence Certs
+ {
+ get { return certs; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Signature ::= Sequence {
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT Sequence OF Certificate OPTIONAL}
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ signatureAlgorithm, signatureValue);
+
+ if (certs != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, certs));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/SingleResponse.cs b/iTechSharp/srcbc/asn1/ocsp/SingleResponse.cs
new file mode 100644
index 0000000..93d4c21
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/SingleResponse.cs
@@ -0,0 +1,137 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+using System;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class SingleResponse
+ : Asn1Encodable
+ {
+ private readonly CertID certID;
+ private readonly CertStatus certStatus;
+ private readonly DerGeneralizedTime thisUpdate;
+ private readonly DerGeneralizedTime nextUpdate;
+ private readonly X509Extensions singleExtensions;
+
+ public SingleResponse(
+ CertID certID,
+ CertStatus certStatus,
+ DerGeneralizedTime thisUpdate,
+ DerGeneralizedTime nextUpdate,
+ X509Extensions singleExtensions)
+ {
+ this.certID = certID;
+ this.certStatus = certStatus;
+ this.thisUpdate = thisUpdate;
+ this.nextUpdate = nextUpdate;
+ this.singleExtensions = singleExtensions;
+ }
+
+ public SingleResponse(
+ Asn1Sequence seq)
+ {
+ this.certID = CertID.GetInstance(seq[0]);
+ this.certStatus = CertStatus.GetInstance(seq[1]);
+ this.thisUpdate = (DerGeneralizedTime)seq[2];
+
+ if (seq.Count > 4)
+ {
+ this.nextUpdate = DerGeneralizedTime.GetInstance(
+ (Asn1TaggedObject) seq[3], true);
+ this.singleExtensions = X509Extensions.GetInstance(
+ (Asn1TaggedObject) seq[4], true);
+ }
+ else if (seq.Count > 3)
+ {
+ Asn1TaggedObject o = (Asn1TaggedObject) seq[3];
+
+ if (o.TagNo == 0)
+ {
+ this.nextUpdate = DerGeneralizedTime.GetInstance(o, true);
+ }
+ else
+ {
+ this.singleExtensions = X509Extensions.GetInstance(o, true);
+ }
+ }
+ }
+
+ public static SingleResponse GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static SingleResponse GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is SingleResponse)
+ {
+ return (SingleResponse)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SingleResponse((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public CertID CertId
+ {
+ get { return certID; }
+ }
+
+ public CertStatus CertStatus
+ {
+ get { return certStatus; }
+ }
+
+ public DerGeneralizedTime ThisUpdate
+ {
+ get { return thisUpdate; }
+ }
+
+ public DerGeneralizedTime NextUpdate
+ {
+ get { return nextUpdate; }
+ }
+
+ public X509Extensions SingleExtensions
+ {
+ get { return singleExtensions; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * SingleResponse ::= Sequence {
+ * certID CertID,
+ * certStatus CertStatus,
+ * thisUpdate GeneralizedTime,
+ * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
+ * singleExtensions [1] EXPLICIT Extensions OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ certID, certStatus, thisUpdate);
+
+ if (nextUpdate != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, nextUpdate));
+ }
+
+ if (singleExtensions != null)
+ {
+ v.Add(new DerTaggedObject(true, 1, singleExtensions));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/ocsp/TBSRequest.cs b/iTechSharp/srcbc/asn1/ocsp/TBSRequest.cs
new file mode 100644
index 0000000..d9780eb
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/ocsp/TBSRequest.cs
@@ -0,0 +1,147 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+using System;
+
+namespace Org.BouncyCastle.Asn1.Ocsp
+{
+ public class TbsRequest
+ : Asn1Encodable
+ {
+ private static readonly DerInteger V1 = new DerInteger(0);
+
+ private readonly DerInteger version;
+ private readonly GeneralName requestorName;
+ private readonly Asn1Sequence requestList;
+ private readonly X509Extensions requestExtensions;
+
+ public static TbsRequest GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static TbsRequest GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is TbsRequest)
+ {
+ return (TbsRequest)obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new TbsRequest((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public TbsRequest(
+ GeneralName requestorName,
+ Asn1Sequence requestList,
+ X509Extensions requestExtensions)
+ {
+ this.version = V1;
+ this.requestorName = requestorName;
+ this.requestList = requestList;
+ this.requestExtensions = requestExtensions;
+ }
+
+ private TbsRequest(
+ Asn1Sequence seq)
+ {
+ int index = 0;
+
+ Asn1Encodable enc = seq[0];
+ if (enc is Asn1TaggedObject)
+ {
+ Asn1TaggedObject o = (Asn1TaggedObject) enc;
+
+ if (o.TagNo == 0)
+ {
+ version = DerInteger.GetInstance(o, true);
+ index++;
+ }
+ else
+ {
+ version = V1;
+ }
+ }
+ else
+ {
+ version = V1;
+ }
+
+ if (seq[index] is Asn1TaggedObject)
+ {
+ requestorName = GeneralName.GetInstance((Asn1TaggedObject) seq[index++], true);
+ }
+
+ requestList = (Asn1Sequence) seq[index++];
+
+ if (seq.Count == (index + 1))
+ {
+ requestExtensions = X509Extensions.GetInstance((Asn1TaggedObject) seq[index], true);
+ }
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public GeneralName RequestorName
+ {
+ get { return requestorName; }
+ }
+
+ public Asn1Sequence RequestList
+ {
+ get { return requestList; }
+ }
+
+ public X509Extensions RequestExtensions
+ {
+ get { return requestExtensions; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * TBSRequest ::= Sequence {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * requestorName [1] EXPLICIT GeneralName OPTIONAL,
+ * requestList Sequence OF Request,
+ * requestExtensions [2] EXPLICIT Extensions OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ //
+ // if default don't include.
+ //
+ if (!version.Equals(V1))
+ {
+ v.Add(new DerTaggedObject(true, 0, version));
+ }
+
+ if (requestorName != null)
+ {
+ v.Add(new DerTaggedObject(true, 1, requestorName));
+ }
+
+ v.Add(requestList);
+
+ if (requestExtensions != null)
+ {
+ v.Add(new DerTaggedObject(true, 2, requestExtensions));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/oiw/ElGamalParameter.cs b/iTechSharp/srcbc/asn1/oiw/ElGamalParameter.cs
new file mode 100644
index 0000000..3e020f0
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/oiw/ElGamalParameter.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Oiw
+{
+ public class ElGamalParameter
+ : Asn1Encodable
+ {
+ internal DerInteger p, g;
+
+ public ElGamalParameter(
+ BigInteger p,
+ BigInteger g)
+ {
+ this.p = new DerInteger(p);
+ this.g = new DerInteger(g);
+ }
+
+ public ElGamalParameter(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ p = DerInteger.GetInstance(seq[0]);
+ g = DerInteger.GetInstance(seq[1]);
+ }
+
+ public BigInteger P
+ {
+ get { return p.PositiveValue; }
+ }
+
+ public BigInteger G
+ {
+ get { return g.PositiveValue; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(p, g);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/oiw/OIWObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/oiw/OIWObjectIdentifiers.cs
new file mode 100644
index 0000000..3d8d4cf
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/oiw/OIWObjectIdentifiers.cs
@@ -0,0 +1,24 @@
+namespace Org.BouncyCastle.Asn1.Oiw
+{
+ public abstract class OiwObjectIdentifiers
+ {
+ public static readonly DerObjectIdentifier MD4WithRsa = new DerObjectIdentifier("1.3.14.3.2.2");
+ public static readonly DerObjectIdentifier MD5WithRsa = new DerObjectIdentifier("1.3.14.3.2.3");
+ public static readonly DerObjectIdentifier MD4WithRsaEncryption = new DerObjectIdentifier("1.3.14.3.2.4");
+
+ public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7");
+
+ // id-SHA1 OBJECT IDENTIFIER ::=
+ // {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } //
+ public static readonly DerObjectIdentifier IdSha1 = new DerObjectIdentifier("1.3.14.3.2.26");
+
+ public static readonly DerObjectIdentifier DsaWithSha1 = new DerObjectIdentifier("1.3.14.3.2.27");
+
+ public static readonly DerObjectIdentifier Sha1WithRsa = new DerObjectIdentifier("1.3.14.3.2.29");
+
+ // ElGamal Algorithm OBJECT IDENTIFIER ::=
+ // {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 }
+ //
+ public static readonly DerObjectIdentifier ElGamalAlgorithm = new DerObjectIdentifier("1.3.14.7.2.1.1");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/Attribute.cs b/iTechSharp/srcbc/asn1/pkcs/Attribute.cs
new file mode 100644
index 0000000..ceec115
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/Attribute.cs
@@ -0,0 +1,79 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class AttributePkcs
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier attrType;
+ private readonly Asn1Set attrValues;
+
+ /**
+ * return an Attribute object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static AttributePkcs GetInstance(
+ object obj)
+ {
+ AttributePkcs attr = obj as AttributePkcs;
+ if (obj == null || attr != null)
+ {
+ return attr;
+ }
+
+ Asn1Sequence seq = obj as Asn1Sequence;
+ if (seq != null)
+ {
+ return new AttributePkcs(seq);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ private AttributePkcs(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ attrType = DerObjectIdentifier.GetInstance(seq[0]);
+ attrValues = Asn1Set.GetInstance(seq[1]);
+ }
+
+ public AttributePkcs(
+ DerObjectIdentifier attrType,
+ Asn1Set attrValues)
+ {
+ this.attrType = attrType;
+ this.attrValues = attrValues;
+ }
+
+ public DerObjectIdentifier AttrType
+ {
+ get { return attrType; }
+ }
+
+ public Asn1Set AttrValues
+ {
+ get { return attrValues; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Attr ::= Sequence {
+ * attrType OBJECT IDENTIFIER,
+ * attrValues Set OF AttributeValue
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(attrType, attrValues);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/AuthenticatedSafe.cs b/iTechSharp/srcbc/asn1/pkcs/AuthenticatedSafe.cs
new file mode 100644
index 0000000..f3dabb8
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/AuthenticatedSafe.cs
@@ -0,0 +1,37 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class AuthenticatedSafe
+ : Asn1Encodable
+ {
+ private readonly ContentInfo[] info;
+
+ public AuthenticatedSafe(
+ Asn1Sequence seq)
+ {
+ info = new ContentInfo[seq.Count];
+
+ for (int i = 0; i != info.Length; i++)
+ {
+ info[i] = ContentInfo.GetInstance(seq[i]);
+ }
+ }
+
+ public AuthenticatedSafe(
+ ContentInfo[] info)
+ {
+ this.info = (ContentInfo[]) info.Clone();
+ }
+
+ public ContentInfo[] GetContentInfo()
+ {
+ return (ContentInfo[]) info.Clone();
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new BerSequence(info);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/CertBag.cs b/iTechSharp/srcbc/asn1/pkcs/CertBag.cs
new file mode 100644
index 0000000..41afa1b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/CertBag.cs
@@ -0,0 +1,46 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class CertBag
+ : Asn1Encodable
+ {
+ private readonly Asn1Sequence seq;
+ private readonly DerObjectIdentifier certID;
+ private readonly Asn1Object certValue;
+
+ public CertBag(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.seq = seq;
+ this.certID = DerObjectIdentifier.GetInstance(seq[0]);
+ this.certValue = DerTaggedObject.GetInstance(seq[1]).GetObject();
+ }
+
+ public CertBag(
+ DerObjectIdentifier certID,
+ Asn1Object certValue)
+ {
+ this.certID = certID;
+ this.certValue = certValue;
+ }
+
+ public DerObjectIdentifier CertID
+ {
+ get { return certID; }
+ }
+
+ public Asn1Object CertValue
+ {
+ get { return certValue; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(certID, new DerTaggedObject(0, certValue));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/CertificationRequest.cs b/iTechSharp/srcbc/asn1/pkcs/CertificationRequest.cs
new file mode 100644
index 0000000..bb0e0cc
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/CertificationRequest.cs
@@ -0,0 +1,81 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ /**
+ * Pkcs10 Certfication request object.
+ *
+ * CertificationRequest ::= Sequence {
+ * certificationRequestInfo CertificationRequestInfo,
+ * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
+ * signature BIT STRING
+ * }
+ *
+ */
+ public class CertificationRequest
+ : Asn1Encodable
+ {
+ protected CertificationRequestInfo reqInfo;
+ protected AlgorithmIdentifier sigAlgId;
+ protected DerBitString sigBits;
+
+ public static CertificationRequest GetInstance(
+ object obj)
+ {
+ if (obj is CertificationRequest)
+ return (CertificationRequest) obj;
+
+ if (obj is Asn1Sequence)
+ return new CertificationRequest((Asn1Sequence) obj);
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ protected CertificationRequest()
+ {
+ }
+
+ public CertificationRequest(
+ CertificationRequestInfo requestInfo,
+ AlgorithmIdentifier algorithm,
+ DerBitString signature)
+ {
+ this.reqInfo = requestInfo;
+ this.sigAlgId = algorithm;
+ this.sigBits = signature;
+ }
+
+ public CertificationRequest(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 3)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ reqInfo = CertificationRequestInfo.GetInstance(seq[0]);
+ sigAlgId = AlgorithmIdentifier.GetInstance(seq[1]);
+ sigBits = DerBitString.GetInstance(seq[2]);
+ }
+
+ public CertificationRequestInfo GetCertificationRequestInfo()
+ {
+ return reqInfo;
+ }
+
+ public AlgorithmIdentifier SignatureAlgorithm
+ {
+ get { return sigAlgId; }
+ }
+
+ public DerBitString Signature
+ {
+ get { return sigBits; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(reqInfo, sigAlgId, sigBits);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/CertificationRequestInfo.cs b/iTechSharp/srcbc/asn1/pkcs/CertificationRequestInfo.cs
new file mode 100644
index 0000000..690d068
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/CertificationRequestInfo.cs
@@ -0,0 +1,123 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ /**
+ * Pkcs10 CertificationRequestInfo object.
+ *
+ * CertificationRequestInfo ::= Sequence {
+ * version Integer { v1(0) } (v1,...),
+ * subject Name,
+ * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+ * attributes [0] Attributes{{ CRIAttributes }}
+ * }
+ *
+ * Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }}
+ *
+ * Attr { ATTRIBUTE:IOSet } ::= Sequence {
+ * type ATTRIBUTE.&id({IOSet}),
+ * values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
+ * }
+ *
+ */
+ public class CertificationRequestInfo
+ : Asn1Encodable
+ {
+ internal DerInteger version = new DerInteger(0);
+ internal X509Name subject;
+ internal SubjectPublicKeyInfo subjectPKInfo;
+ internal Asn1Set attributes;
+
+ public static CertificationRequestInfo GetInstance(
+ object obj)
+ {
+ if (obj is CertificationRequestInfo)
+ {
+ return (CertificationRequestInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new CertificationRequestInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public CertificationRequestInfo(
+ X509Name subject,
+ SubjectPublicKeyInfo pkInfo,
+ Asn1Set attributes)
+ {
+ this.subject = subject;
+ this.subjectPKInfo = pkInfo;
+ this.attributes = attributes;
+
+ if (subject == null || version == null || subjectPKInfo == null)
+ {
+ throw new ArgumentException(
+ "Not all mandatory fields set in CertificationRequestInfo generator.");
+ }
+ }
+
+ private CertificationRequestInfo(
+ Asn1Sequence seq)
+ {
+ version = (DerInteger) seq[0];
+
+ subject = X509Name.GetInstance(seq[1]);
+ subjectPKInfo = SubjectPublicKeyInfo.GetInstance(seq[2]);
+
+ //
+ // some CertificationRequestInfo objects seem to treat this field
+ // as optional.
+ //
+ if (seq.Count > 3)
+ {
+ DerTaggedObject tagobj = (DerTaggedObject) seq[3];
+ attributes = Asn1Set.GetInstance(tagobj, false);
+ }
+
+ if (subject == null || version == null || subjectPKInfo == null)
+ {
+ throw new ArgumentException(
+ "Not all mandatory fields set in CertificationRequestInfo generator.");
+ }
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public X509Name Subject
+ {
+ get { return subject; }
+ }
+
+ public SubjectPublicKeyInfo SubjectPublicKeyInfo
+ {
+ get { return subjectPKInfo; }
+ }
+
+ public Asn1Set Attributes
+ {
+ get { return attributes; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, subject, subjectPKInfo);
+
+ if (attributes != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, attributes));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/ContentInfo.cs b/iTechSharp/srcbc/asn1/pkcs/ContentInfo.cs
new file mode 100644
index 0000000..78213c1
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/ContentInfo.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class ContentInfo
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier contentType;
+ private readonly Asn1Encodable content;
+
+ public static ContentInfo GetInstance(
+ object obj)
+ {
+ if (obj is ContentInfo)
+ {
+ return (ContentInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ContentInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ private ContentInfo(
+ Asn1Sequence seq)
+ {
+ contentType = (DerObjectIdentifier) seq[0];
+
+ if (seq.Count > 1)
+ {
+ content = ((Asn1TaggedObject) seq[1]).GetObject();
+ }
+ }
+
+ public ContentInfo(
+ DerObjectIdentifier contentType,
+ Asn1Encodable content)
+ {
+ this.contentType = contentType;
+ this.content = content;
+ }
+
+ public DerObjectIdentifier ContentType
+ {
+ get { return contentType; }
+ }
+
+ public Asn1Encodable Content
+ {
+ get { return content; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * ContentInfo ::= Sequence {
+ * contentType ContentType,
+ * content
+ * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(contentType);
+
+ if (content != null)
+ {
+ v.Add(new BerTaggedObject(0, content));
+ }
+
+ return new BerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/DHParameter.cs b/iTechSharp/srcbc/asn1/pkcs/DHParameter.cs
new file mode 100644
index 0000000..25a091a
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/DHParameter.cs
@@ -0,0 +1,72 @@
+using Org.BouncyCastle.Asn1;
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class DHParameter
+ : Asn1Encodable
+ {
+ internal DerInteger p, g, l;
+
+ public DHParameter(
+ BigInteger p,
+ BigInteger g,
+ int l)
+ {
+ this.p = new DerInteger(p);
+ this.g = new DerInteger(g);
+
+ if (l != 0)
+ {
+ this.l = new DerInteger(l);
+ }
+ }
+
+ public DHParameter(
+ Asn1Sequence seq)
+ {
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ p = (DerInteger)e.Current;
+
+ e.MoveNext();
+ g = (DerInteger)e.Current;
+
+ if (e.MoveNext())
+ {
+ l = (DerInteger) e.Current;
+ }
+ }
+
+ public BigInteger P
+ {
+ get { return p.PositiveValue; }
+ }
+
+ public BigInteger G
+ {
+ get { return g.PositiveValue; }
+ }
+
+ public BigInteger L
+ {
+ get { return l == null ? null : l.PositiveValue; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(p, g);
+
+ if (this.l != null)
+ {
+ v.Add(l);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/EncryptedData.cs b/iTechSharp/srcbc/asn1/pkcs/EncryptedData.cs
new file mode 100644
index 0000000..2af7f33
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/EncryptedData.cs
@@ -0,0 +1,104 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ /**
+ * The EncryptedData object.
+ *
+ * EncryptedData ::= Sequence {
+ * version Version,
+ * encryptedContentInfo EncryptedContentInfo
+ * }
+ *
+ *
+ * EncryptedContentInfo ::= Sequence {
+ * contentType ContentType,
+ * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+ * }
+ *
+ * EncryptedContent ::= OCTET STRING
+ *
+ */
+ public class EncryptedData
+ : Asn1Encodable
+ {
+ private readonly Asn1Sequence data;
+// private readonly DerObjectIdentifier bagId;
+// private readonly Asn1Object bagValue;
+
+ public static EncryptedData GetInstance(
+ object obj)
+ {
+ if (obj is EncryptedData)
+ {
+ return (EncryptedData) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new EncryptedData((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ private EncryptedData(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ int version = ((DerInteger) seq[0]).Value.IntValue;
+ if (version != 0)
+ {
+ throw new ArgumentException("sequence not version 0");
+ }
+
+ this.data = (Asn1Sequence) seq[1];
+ }
+
+ public EncryptedData(
+ DerObjectIdentifier contentType,
+ AlgorithmIdentifier encryptionAlgorithm,
+ Asn1Encodable content)
+ {
+ data = new BerSequence(
+ contentType,
+ encryptionAlgorithm.ToAsn1Object(),
+ new BerTaggedObject(false, 0, content));
+ }
+
+ public DerObjectIdentifier ContentType
+ {
+ get { return (DerObjectIdentifier) data[0]; }
+ }
+
+ public AlgorithmIdentifier EncryptionAlgorithm
+ {
+ get { return AlgorithmIdentifier.GetInstance(data[1]); }
+ }
+
+ public Asn1OctetString Content
+ {
+ get
+ {
+ if (data.Count == 3)
+ {
+ DerTaggedObject o = (DerTaggedObject) data[2];
+
+ return Asn1OctetString.GetInstance(o.GetObject());
+ }
+
+ return null;
+ }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new BerSequence(new DerInteger(0), data);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/EncryptedPrivateKeyInfo.cs b/iTechSharp/srcbc/asn1/pkcs/EncryptedPrivateKeyInfo.cs
new file mode 100644
index 0000000..b97b8f5
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/EncryptedPrivateKeyInfo.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class EncryptedPrivateKeyInfo
+ : Asn1Encodable
+ {
+ private readonly AlgorithmIdentifier algId;
+ private readonly Asn1OctetString data;
+
+ private EncryptedPrivateKeyInfo(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ algId = AlgorithmIdentifier.GetInstance(seq[0]);
+ data = Asn1OctetString.GetInstance(seq[1]);
+ }
+
+ public EncryptedPrivateKeyInfo(
+ AlgorithmIdentifier algId,
+ byte[] encoding)
+ {
+ this.algId = algId;
+ this.data = new DerOctetString(encoding);
+ }
+
+ public static EncryptedPrivateKeyInfo GetInstance(
+ object obj)
+ {
+ if (obj is EncryptedPrivateKeyInfo)
+ {
+ return (EncryptedPrivateKeyInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new EncryptedPrivateKeyInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public AlgorithmIdentifier EncryptionAlgorithm
+ {
+ get { return algId; }
+ }
+
+ public byte[] GetEncryptedData()
+ {
+ return data.GetOctets();
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * EncryptedPrivateKeyInfo ::= Sequence {
+ * encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
+ * encryptedData EncryptedData
+ * }
+ *
+ * EncryptedData ::= OCTET STRING
+ *
+ * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * ... -- For local profiles
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(algId, data);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/EncryptionScheme.cs b/iTechSharp/srcbc/asn1/pkcs/EncryptionScheme.cs
new file mode 100644
index 0000000..5337dc7
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/EncryptionScheme.cs
@@ -0,0 +1,31 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class EncryptionScheme
+ : AlgorithmIdentifier
+ {
+ private readonly Asn1Object objectID, obj;
+
+ internal EncryptionScheme(
+ Asn1Sequence seq)
+ : base(seq)
+ {
+ objectID = (Asn1Object) seq[0];
+ obj = (Asn1Object) seq[1];
+ }
+
+ public Asn1Object Asn1Object
+ {
+ get { return obj; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(objectID, obj);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/IssuerAndSerialNumber.cs b/iTechSharp/srcbc/asn1/pkcs/IssuerAndSerialNumber.cs
new file mode 100644
index 0000000..ff608f1
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/IssuerAndSerialNumber.cs
@@ -0,0 +1,71 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class IssuerAndSerialNumber
+ : Asn1Encodable
+ {
+ private readonly X509Name name;
+ private readonly DerInteger certSerialNumber;
+
+ public static IssuerAndSerialNumber GetInstance(
+ object obj)
+ {
+ if (obj is IssuerAndSerialNumber)
+ {
+ return (IssuerAndSerialNumber) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new IssuerAndSerialNumber((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ private IssuerAndSerialNumber(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.name = X509Name.GetInstance(seq[0]);
+ this.certSerialNumber = DerInteger.GetInstance(seq[1]);
+ }
+
+ public IssuerAndSerialNumber(
+ X509Name name,
+ BigInteger certSerialNumber)
+ {
+ this.name = name;
+ this.certSerialNumber = new DerInteger(certSerialNumber);
+ }
+
+ public IssuerAndSerialNumber(
+ X509Name name,
+ DerInteger certSerialNumber)
+ {
+ this.name = name;
+ this.certSerialNumber = certSerialNumber;
+ }
+
+ public X509Name Name
+ {
+ get { return name; }
+ }
+
+ public DerInteger CertificateSerialNumber
+ {
+ get { return certSerialNumber; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(name, certSerialNumber);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/KeyDerivationFunc.cs b/iTechSharp/srcbc/asn1/pkcs/KeyDerivationFunc.cs
new file mode 100644
index 0000000..1bc0a61
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/KeyDerivationFunc.cs
@@ -0,0 +1,21 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class KeyDerivationFunc
+ : AlgorithmIdentifier
+ {
+ internal KeyDerivationFunc(Asn1Sequence seq)
+ : base(seq)
+ {
+ }
+
+ internal KeyDerivationFunc(
+ DerObjectIdentifier id,
+ Asn1Encodable parameters)
+ : base(id, parameters)
+ {
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/MacData.cs b/iTechSharp/srcbc/asn1/pkcs/MacData.cs
new file mode 100644
index 0000000..c318eaf
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/MacData.cs
@@ -0,0 +1,81 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class MacData
+ : Asn1Encodable
+ {
+ internal DigestInfo digInfo;
+ internal byte[] salt;
+ internal BigInteger iterationCount;
+
+ public static MacData GetInstance(
+ object obj)
+ {
+ if (obj is MacData)
+ {
+ return (MacData) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new MacData((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ private MacData(
+ Asn1Sequence seq)
+ {
+ this.digInfo = DigestInfo.GetInstance(seq[0]);
+ this.salt = ((Asn1OctetString) seq[1]).GetOctets();
+
+ if (seq.Count == 3)
+ {
+ this.iterationCount = ((DerInteger) seq[2]).Value;
+ }
+ else
+ {
+ this.iterationCount = BigInteger.One;
+ }
+ }
+
+ public MacData(
+ DigestInfo digInfo,
+ byte[] salt,
+ int iterationCount)
+ {
+ this.digInfo = digInfo;
+ this.salt = (byte[]) salt.Clone();
+ this.iterationCount = BigInteger.ValueOf(iterationCount);
+ }
+
+ public DigestInfo Mac
+ {
+ get { return digInfo; }
+ }
+
+ public byte[] GetSalt()
+ {
+ return (byte[]) salt.Clone();
+ }
+
+ public BigInteger IterationCount
+ {
+ get { return iterationCount; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(
+ digInfo,
+ new DerOctetString(salt),
+ new DerInteger(iterationCount));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/PBEParameter.cs b/iTechSharp/srcbc/asn1/pkcs/PBEParameter.cs
new file mode 100644
index 0000000..48659ad
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/PBEParameter.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class PbeParameter
+ : Asn1Encodable
+ {
+ private readonly Asn1OctetString octStr;
+ private readonly DerInteger iterationCount;
+
+ public static PbeParameter GetInstance(
+ object obj)
+ {
+ if (obj is PbeParameter || obj == null)
+ {
+ return (PbeParameter) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new PbeParameter((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ private PbeParameter(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ octStr = Asn1OctetString.GetInstance(seq[0]);
+ iterationCount = DerInteger.GetInstance(seq[1]);
+ }
+
+ public PbeParameter(
+ byte[] salt,
+ int iterationCount)
+ {
+ this.octStr = new DerOctetString(salt);
+ this.iterationCount = new DerInteger(iterationCount);
+ }
+
+ public byte[] GetSalt()
+ {
+ return octStr.GetOctets();
+ }
+
+ public BigInteger IterationCount
+ {
+ get { return iterationCount.Value; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(octStr, iterationCount);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/PBES2Parameters.cs b/iTechSharp/srcbc/asn1/pkcs/PBES2Parameters.cs
new file mode 100644
index 0000000..86f1ec3
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/PBES2Parameters.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class PbeS2Parameters
+ : Asn1Encodable
+ {
+ private readonly KeyDerivationFunc func;
+ private readonly EncryptionScheme scheme;
+
+ public PbeS2Parameters(
+ Asn1Sequence obj)
+ {
+ IEnumerator e = obj.GetEnumerator();
+
+ e.MoveNext();
+ Asn1Sequence funcSeq = (Asn1Sequence) e.Current;
+
+ if (funcSeq[0].Equals(PkcsObjectIdentifiers.IdPbkdf2))
+ {
+ func = new KeyDerivationFunc(PkcsObjectIdentifiers.IdPbkdf2, funcSeq[1]);
+ }
+ else
+ {
+ func = new KeyDerivationFunc(funcSeq);
+ }
+
+ e.MoveNext();
+ scheme = new EncryptionScheme((Asn1Sequence) e.Current);
+ }
+
+ public KeyDerivationFunc KeyDerivationFunc
+ {
+ get { return func; }
+ }
+
+ public EncryptionScheme EncryptionScheme
+ {
+ get { return scheme; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(func, scheme);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/PBKDF2Params.cs b/iTechSharp/srcbc/asn1/pkcs/PBKDF2Params.cs
new file mode 100644
index 0000000..b98e6f4
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/PBKDF2Params.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class Pbkdf2Params
+ : Asn1Encodable
+ {
+ internal Asn1OctetString octStr;
+ internal DerInteger iterationCount;
+ internal DerInteger keyLength;
+
+ public static Pbkdf2Params GetInstance(
+ object obj)
+ {
+ if (obj is Pbkdf2Params || obj == null)
+ {
+ return (Pbkdf2Params) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Pbkdf2Params((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public Pbkdf2Params(
+ Asn1Sequence seq)
+ {
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ octStr = (Asn1OctetString) e.Current;
+
+ e.MoveNext();
+ iterationCount = (DerInteger) e.Current;
+
+ if (e.MoveNext())
+ {
+ keyLength = (DerInteger) e.Current;
+ }
+ }
+
+ public Pbkdf2Params(
+ byte[] salt,
+ int iterationCount)
+ {
+ this.octStr = new DerOctetString(salt);
+ this.iterationCount = new DerInteger(iterationCount);
+ }
+
+ public byte[] GetSalt()
+ {
+ return octStr.GetOctets();
+ }
+
+ public BigInteger IterationCount
+ {
+ get { return iterationCount.Value; }
+ }
+
+ public BigInteger KeyLength
+ {
+ get { return keyLength == null ? null : keyLength.Value; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ octStr, iterationCount);
+
+ if (keyLength != null)
+ {
+ v.Add(keyLength);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/PKCS12PBEParams.cs b/iTechSharp/srcbc/asn1/pkcs/PKCS12PBEParams.cs
new file mode 100644
index 0000000..7521f93
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/PKCS12PBEParams.cs
@@ -0,0 +1,63 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class Pkcs12PbeParams
+ : Asn1Encodable
+ {
+ private readonly DerInteger iterations;
+ private readonly Asn1OctetString iv;
+
+ public Pkcs12PbeParams(
+ byte[] salt,
+ int iterations)
+ {
+ this.iv = new DerOctetString(salt);
+ this.iterations = new DerInteger(iterations);
+ }
+
+ private Pkcs12PbeParams(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ iv = Asn1OctetString.GetInstance(seq[0]);
+ iterations = DerInteger.GetInstance(seq[1]);
+ }
+
+ public static Pkcs12PbeParams GetInstance(
+ object obj)
+ {
+ if (obj is Pkcs12PbeParams)
+ {
+ return (Pkcs12PbeParams) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new Pkcs12PbeParams((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public BigInteger Iterations
+ {
+ get { return iterations.Value; }
+ }
+
+ public byte[] GetIV()
+ {
+ return iv.GetOctets();
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(iv, iterations);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/PKCSObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/pkcs/PKCSObjectIdentifiers.cs
new file mode 100644
index 0000000..7141d1d
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/PKCSObjectIdentifiers.cs
@@ -0,0 +1,251 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public abstract class PkcsObjectIdentifiers
+ {
+ //
+ // pkcs-1 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+ //
+ public const string Pkcs1 = "1.2.840.113549.1.1";
+
+ public static readonly DerObjectIdentifier RsaEncryption = new DerObjectIdentifier(Pkcs1 + ".1");
+ public static readonly DerObjectIdentifier MD2WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".2");
+ public static readonly DerObjectIdentifier MD4WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".3");
+ public static readonly DerObjectIdentifier MD5WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".4");
+ public static readonly DerObjectIdentifier Sha1WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".5");
+ public static readonly DerObjectIdentifier SrsaOaepEncryptionSet = new DerObjectIdentifier(Pkcs1 + ".6");
+ public static readonly DerObjectIdentifier IdRsaesOaep = new DerObjectIdentifier(Pkcs1 + ".7");
+ public static readonly DerObjectIdentifier IdMgf1 = new DerObjectIdentifier(Pkcs1 + ".8");
+ public static readonly DerObjectIdentifier IdPSpecified = new DerObjectIdentifier(Pkcs1 + ".9");
+ public static readonly DerObjectIdentifier IdRsassaPss = new DerObjectIdentifier(Pkcs1 + ".10");
+ public static readonly DerObjectIdentifier Sha256WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".11");
+ public static readonly DerObjectIdentifier Sha384WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".12");
+ public static readonly DerObjectIdentifier Sha512WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".13");
+ public static readonly DerObjectIdentifier Sha224WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".14");
+
+ //
+ // pkcs-3 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 }
+ //
+ public const string Pkcs3 = "1.2.840.113549.1.3";
+
+ public static readonly DerObjectIdentifier DhKeyAgreement = new DerObjectIdentifier(Pkcs3 + ".1");
+
+ //
+ // pkcs-5 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 }
+ //
+ public const string Pkcs5 = "1.2.840.113549.1.5";
+
+ public static readonly DerObjectIdentifier PbeWithMD2AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".1");
+ public static readonly DerObjectIdentifier PbeWithMD2AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".4");
+ public static readonly DerObjectIdentifier PbeWithMD5AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".3");
+ public static readonly DerObjectIdentifier PbeWithMD5AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".6");
+ public static readonly DerObjectIdentifier PbeWithSha1AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".10");
+ public static readonly DerObjectIdentifier PbeWithSha1AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".11");
+
+ public static readonly DerObjectIdentifier IdPbeS2 = new DerObjectIdentifier(Pkcs5 + ".13");
+ public static readonly DerObjectIdentifier IdPbkdf2 = new DerObjectIdentifier(Pkcs5 + ".12");
+
+ //
+ // encryptionAlgorithm OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) 3 }
+ //
+ public const string EncryptionAlgorithm = "1.2.840.113549.3";
+
+ public static readonly DerObjectIdentifier DesEde3Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".7");
+ public static readonly DerObjectIdentifier RC2Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".2");
+
+ //
+ // object identifiers for digests
+ //
+ public const string DigestAlgorithm = "1.2.840.113549.2";
+
+ //
+ // md2 OBJECT IDENTIFIER ::=
+ // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 2}
+ //
+ public static readonly DerObjectIdentifier MD2 = new DerObjectIdentifier(DigestAlgorithm + ".2");
+
+ //
+ // md4 OBJECT IDENTIFIER ::=
+ // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 4}
+ //
+ public static readonly DerObjectIdentifier MD4 = new DerObjectIdentifier(DigestAlgorithm + ".4");
+
+ //
+ // md5 OBJECT IDENTIFIER ::=
+ // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 5}
+ //
+ public static readonly DerObjectIdentifier MD5 = new DerObjectIdentifier(DigestAlgorithm + ".5");
+
+ public static readonly DerObjectIdentifier IdHmacWithSha1 = new DerObjectIdentifier(DigestAlgorithm + ".7");
+ public static readonly DerObjectIdentifier IdHmacWithSha224 = new DerObjectIdentifier(DigestAlgorithm + ".8");
+ public static readonly DerObjectIdentifier IdHmacWithSha256 = new DerObjectIdentifier(DigestAlgorithm + ".9");
+ public static readonly DerObjectIdentifier IdHmacWithSha384 = new DerObjectIdentifier(DigestAlgorithm + ".10");
+ public static readonly DerObjectIdentifier IdHmacWithSha512 = new DerObjectIdentifier(DigestAlgorithm + ".11");
+
+ //
+ // pkcs-7 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
+ //
+ public const string Pkcs7 = "1.2.840.113549.1.7";
+
+ public static readonly DerObjectIdentifier Data = new DerObjectIdentifier(Pkcs7 + ".1");
+ public static readonly DerObjectIdentifier SignedData = new DerObjectIdentifier(Pkcs7 + ".2");
+ public static readonly DerObjectIdentifier EnvelopedData = new DerObjectIdentifier(Pkcs7 + ".3");
+ public static readonly DerObjectIdentifier SignedAndEnvelopedData = new DerObjectIdentifier(Pkcs7 + ".4");
+ public static readonly DerObjectIdentifier DigestedData = new DerObjectIdentifier(Pkcs7 + ".5");
+ public static readonly DerObjectIdentifier EncryptedData = new DerObjectIdentifier(Pkcs7 + ".6");
+
+ //
+ // pkcs-9 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+ //
+ public const string Pkcs9 = "1.2.840.113549.1.9";
+
+ public static readonly DerObjectIdentifier Pkcs9AtEmailAddress = new DerObjectIdentifier(Pkcs9 + ".1");
+ public static readonly DerObjectIdentifier Pkcs9AtUnstructuredName = new DerObjectIdentifier(Pkcs9 + ".2");
+ public static readonly DerObjectIdentifier Pkcs9AtContentType = new DerObjectIdentifier(Pkcs9 + ".3");
+ public static readonly DerObjectIdentifier Pkcs9AtMessageDigest = new DerObjectIdentifier(Pkcs9 + ".4");
+ public static readonly DerObjectIdentifier Pkcs9AtSigningTime = new DerObjectIdentifier(Pkcs9 + ".5");
+ public static readonly DerObjectIdentifier Pkcs9AtCounterSignature = new DerObjectIdentifier(Pkcs9 + ".6");
+ public static readonly DerObjectIdentifier Pkcs9AtChallengePassword = new DerObjectIdentifier(Pkcs9 + ".7");
+ public static readonly DerObjectIdentifier Pkcs9AtUnstructuredAddress = new DerObjectIdentifier(Pkcs9 + ".8");
+ public static readonly DerObjectIdentifier Pkcs9AtExtendedCertificateAttributes = new DerObjectIdentifier(Pkcs9 + ".9");
+ public static readonly DerObjectIdentifier Pkcs9AtSigningDescription = new DerObjectIdentifier(Pkcs9 + ".13");
+ public static readonly DerObjectIdentifier Pkcs9AtExtensionRequest = new DerObjectIdentifier(Pkcs9 + ".14");
+ public static readonly DerObjectIdentifier Pkcs9AtSmimeCapabilities = new DerObjectIdentifier(Pkcs9 + ".15");
+ public static readonly DerObjectIdentifier Pkcs9AtFriendlyName = new DerObjectIdentifier(Pkcs9 + ".20");
+ public static readonly DerObjectIdentifier Pkcs9AtLocalKeyID = new DerObjectIdentifier(Pkcs9 + ".21");
+
+ [Obsolete("Use X509Certificate instead")]
+ public static readonly DerObjectIdentifier X509CertType = new DerObjectIdentifier(Pkcs9 + ".22.1");
+
+ public const string CertTypes = Pkcs9 + ".22";
+ public static readonly DerObjectIdentifier X509Certificate = new DerObjectIdentifier(CertTypes + ".1");
+ public static readonly DerObjectIdentifier SdsiCertificate = new DerObjectIdentifier(CertTypes + ".2");
+
+ public const string CrlTypes = Pkcs9 + ".23";
+ public static readonly DerObjectIdentifier X509Crl = new DerObjectIdentifier(CrlTypes + ".1");
+
+ public static readonly DerObjectIdentifier IdAlgPwriKek = new DerObjectIdentifier(Pkcs9 + ".16.3.9");
+
+ //
+ // SMIME capability sub oids.
+ //
+ public static readonly DerObjectIdentifier PreferSignedData = new DerObjectIdentifier(Pkcs9 + ".15.1");
+ public static readonly DerObjectIdentifier CannotDecryptAny = new DerObjectIdentifier(Pkcs9 + ".15.2");
+ public static readonly DerObjectIdentifier SmimeCapabilitiesVersions = new DerObjectIdentifier(Pkcs9 + ".15.3");
+
+ //
+ // other SMIME attributes
+ //
+ public static readonly DerObjectIdentifier IdAAReceiptRequest = new DerObjectIdentifier(Pkcs9 + ".16.2.1");
+
+ //
+ // id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)}
+ //
+ public const string IdCT = "1.2.840.113549.1.9.16.1";
+
+ public static readonly DerObjectIdentifier IdCTTstInfo = new DerObjectIdentifier(IdCT + ".4");
+ public static readonly DerObjectIdentifier IdCTCompressedData = new DerObjectIdentifier(IdCT + ".9");
+
+ //
+ // id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)}
+ //
+ public const string IdCti = "1.2.840.113549.1.9.16.6";
+
+ public static readonly DerObjectIdentifier IdCtiEtsProofOfOrigin = new DerObjectIdentifier(IdCti + ".1");
+ public static readonly DerObjectIdentifier IdCtiEtsProofOfReceipt = new DerObjectIdentifier(IdCti + ".2");
+ public static readonly DerObjectIdentifier IdCtiEtsProofOfDelivery = new DerObjectIdentifier(IdCti + ".3");
+ public static readonly DerObjectIdentifier IdCtiEtsProofOfSender = new DerObjectIdentifier(IdCti + ".4");
+ public static readonly DerObjectIdentifier IdCtiEtsProofOfApproval = new DerObjectIdentifier(IdCti + ".5");
+ public static readonly DerObjectIdentifier IdCtiEtsProofOfCreation = new DerObjectIdentifier(IdCti + ".6");
+
+ //
+ // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)}
+ //
+ public const string IdAA = "1.2.840.113549.1.9.16.2";
+
+ public static readonly DerObjectIdentifier IdAAContentHint = new DerObjectIdentifier(IdAA + ".4"); // See RFC 2634
+
+ /*
+ * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11}
+ *
+ */
+ public static readonly DerObjectIdentifier IdAAEncrypKeyPref = new DerObjectIdentifier(IdAA + ".11");
+ public static readonly DerObjectIdentifier IdAASigningCertificate = new DerObjectIdentifier(IdAA + ".12");
+ public static readonly DerObjectIdentifier IdAASigningCertificateV2 = new DerObjectIdentifier(IdAA + ".47");
+
+ public static readonly DerObjectIdentifier IdAAContentIdentifier = new DerObjectIdentifier(IdAA + ".7"); // See RFC 2634
+
+ /*
+ * RFC 3126
+ */
+ public static readonly DerObjectIdentifier IdAASignatureTimeStampToken = new DerObjectIdentifier(IdAA + ".14");
+
+ public static readonly DerObjectIdentifier IdAAEtsSigPolicyID = new DerObjectIdentifier(IdAA + ".15");
+ public static readonly DerObjectIdentifier IdAAEtsCommitmentType = new DerObjectIdentifier(IdAA + ".16");
+ public static readonly DerObjectIdentifier IdAAEtsSignerLocation = new DerObjectIdentifier(IdAA + ".17");
+ public static readonly DerObjectIdentifier IdAAEtsSignerAttr = new DerObjectIdentifier(IdAA + ".18");
+ public static readonly DerObjectIdentifier IdAAEtsOtherSigCert = new DerObjectIdentifier(IdAA + ".19");
+ public static readonly DerObjectIdentifier IdAAEtsContentTimestamp = new DerObjectIdentifier(IdAA + ".20");
+ public static readonly DerObjectIdentifier IdAAEtsCertificateRefs = new DerObjectIdentifier(IdAA + ".21");
+ public static readonly DerObjectIdentifier IdAAEtsRevocationRefs = new DerObjectIdentifier(IdAA + ".22");
+ public static readonly DerObjectIdentifier IdAAEtsCertValues = new DerObjectIdentifier(IdAA + ".23");
+ public static readonly DerObjectIdentifier IdAAEtsRevocationValues = new DerObjectIdentifier(IdAA + ".24");
+ public static readonly DerObjectIdentifier IdAAEtsEscTimeStamp = new DerObjectIdentifier(IdAA + ".25");
+ public static readonly DerObjectIdentifier IdAAEtsCertCrlTimestamp = new DerObjectIdentifier(IdAA + ".26");
+ public static readonly DerObjectIdentifier IdAAEtsArchiveTimestamp = new DerObjectIdentifier(IdAA + ".27");
+
+ [Obsolete("Use 'IdAAEtsSigPolicyID' instead")]
+ public static readonly DerObjectIdentifier IdAASigPolicyID = IdAAEtsSigPolicyID;
+ [Obsolete("Use 'IdAAEtsCommitmentType' instead")]
+ public static readonly DerObjectIdentifier IdAACommitmentType = IdAAEtsCommitmentType;
+ [Obsolete("Use 'IdAAEtsSignerLocation' instead")]
+ public static readonly DerObjectIdentifier IdAASignerLocation = IdAAEtsSignerLocation;
+ [Obsolete("Use 'IdAAEtsOtherSigCert' instead")]
+ public static readonly DerObjectIdentifier IdAAOtherSigCert = IdAAEtsOtherSigCert;
+
+ //
+ // id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)}
+ //
+ public const string IdSpq = "1.2.840.113549.1.9.16.5";
+
+ public static readonly DerObjectIdentifier IdSpqEtsUri = new DerObjectIdentifier(IdSpq + ".1");
+ public static readonly DerObjectIdentifier IdSpqEtsUNotice = new DerObjectIdentifier(IdSpq + ".2");
+
+ //
+ // pkcs-12 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 }
+ //
+ public const string Pkcs12 = "1.2.840.113549.1.12";
+ public const string BagTypes = Pkcs12 + ".10.1";
+
+ public static readonly DerObjectIdentifier KeyBag = new DerObjectIdentifier(BagTypes + ".1");
+ public static readonly DerObjectIdentifier Pkcs8ShroudedKeyBag = new DerObjectIdentifier(BagTypes + ".2");
+ public static readonly DerObjectIdentifier CertBag = new DerObjectIdentifier(BagTypes + ".3");
+ public static readonly DerObjectIdentifier CrlBag = new DerObjectIdentifier(BagTypes + ".4");
+ public static readonly DerObjectIdentifier SecretBag = new DerObjectIdentifier(BagTypes + ".5");
+ public static readonly DerObjectIdentifier SafeContentsBag = new DerObjectIdentifier(BagTypes + ".6");
+
+ public const string Pkcs12PbeIds = Pkcs12 + ".1";
+
+ public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".1");
+ public static readonly DerObjectIdentifier PbeWithShaAnd40BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".2");
+ public static readonly DerObjectIdentifier PbeWithShaAnd3KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".3");
+ public static readonly DerObjectIdentifier PbeWithShaAnd2KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".4");
+ public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".5");
+ public static readonly DerObjectIdentifier PbewithShaAnd40BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".6");
+
+ public static readonly DerObjectIdentifier IdAlgCms3DesWrap = new DerObjectIdentifier("1.2.840.113549.1.9.16.3.6");
+ public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = new DerObjectIdentifier("1.2.840.113549.1.9.16.3.7");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/Pfx.cs b/iTechSharp/srcbc/asn1/pkcs/Pfx.cs
new file mode 100644
index 0000000..9676f64
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/Pfx.cs
@@ -0,0 +1,65 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ /**
+ * the infamous Pfx from Pkcs12
+ */
+ public class Pfx
+ : Asn1Encodable
+ {
+ private ContentInfo contentInfo;
+ private MacData macData;
+
+ public Pfx(
+ Asn1Sequence seq)
+ {
+ BigInteger version = ((DerInteger) seq[0]).Value;
+ if (version.IntValue != 3)
+ {
+ throw new ArgumentException("wrong version for PFX PDU");
+ }
+
+ contentInfo = ContentInfo.GetInstance(seq[1]);
+
+ if (seq.Count == 3)
+ {
+ macData = MacData.GetInstance(seq[2]);
+ }
+ }
+
+ public Pfx(
+ ContentInfo contentInfo,
+ MacData macData)
+ {
+ this.contentInfo = contentInfo;
+ this.macData = macData;
+ }
+
+ public ContentInfo AuthSafe
+ {
+ get { return contentInfo; }
+ }
+
+ public MacData MacData
+ {
+ get { return macData; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ new DerInteger(3), contentInfo);
+
+ if (macData != null)
+ {
+ v.Add(macData);
+ }
+
+ return new BerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/PrivateKeyInfo.cs b/iTechSharp/srcbc/asn1/pkcs/PrivateKeyInfo.cs
new file mode 100644
index 0000000..d5ab73f
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/PrivateKeyInfo.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class PrivateKeyInfo
+ : Asn1Encodable
+ {
+ private readonly Asn1Object privKey;
+ private readonly AlgorithmIdentifier algID;
+ private readonly Asn1Set attributes;
+
+ public static PrivateKeyInfo GetInstance(
+ object obj)
+ {
+ if (obj is PrivateKeyInfo || obj == null)
+ {
+ return (PrivateKeyInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new PrivateKeyInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public PrivateKeyInfo(
+ AlgorithmIdentifier algID,
+ Asn1Object privateKey)
+ : this(algID, privateKey, null)
+ {
+ }
+
+ public PrivateKeyInfo(
+ AlgorithmIdentifier algID,
+ Asn1Object privateKey,
+ Asn1Set attributes)
+ {
+ this.privKey = privateKey;
+ this.algID = algID;
+ this.attributes = attributes;
+ }
+
+ private PrivateKeyInfo(
+ Asn1Sequence seq)
+ {
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ BigInteger version = ((DerInteger) e.Current).Value;
+ if (version.IntValue != 0)
+ {
+ throw new ArgumentException("wrong version for private key info");
+ }
+
+ e.MoveNext();
+ algID = AlgorithmIdentifier.GetInstance(e.Current);
+
+ try
+ {
+ e.MoveNext();
+ Asn1OctetString data = (Asn1OctetString) e.Current;
+
+ privKey = Asn1Object.FromByteArray(data.GetOctets());
+ }
+ catch (IOException)
+ {
+ throw new ArgumentException("Error recoverying private key from sequence");
+ }
+
+ if (e.MoveNext())
+ {
+ attributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false);
+ }
+ }
+
+ public AlgorithmIdentifier AlgorithmID
+ {
+ get { return algID; }
+ }
+
+ public Asn1Object PrivateKey
+ {
+ get { return privKey; }
+ }
+
+ public Asn1Set Attributes
+ {
+ get { return attributes; }
+ }
+
+ /**
+ * write out an RSA private key with it's asscociated information
+ * as described in Pkcs8.
+ *
+ * PrivateKeyInfo ::= Sequence {
+ * version Version,
+ * privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
+ * privateKey PrivateKey,
+ * attributes [0] IMPLICIT Attributes OPTIONAL
+ * }
+ * Version ::= Integer {v1(0)} (v1,...)
+ *
+ * PrivateKey ::= OCTET STRING
+ *
+ * Attributes ::= Set OF Attr
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ new DerInteger(0),
+ algID,
+ new DerOctetString(privKey));
+
+ if (attributes != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, attributes));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/RC2CBCParameter.cs b/iTechSharp/srcbc/asn1/pkcs/RC2CBCParameter.cs
new file mode 100644
index 0000000..f5355d0
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/RC2CBCParameter.cs
@@ -0,0 +1,81 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class RC2CbcParameter
+ : Asn1Encodable
+ {
+ internal DerInteger version;
+ internal Asn1OctetString iv;
+
+ public static RC2CbcParameter GetInstance(
+ object obj)
+ {
+ if (obj is Asn1Sequence)
+ {
+ return new RC2CbcParameter((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public RC2CbcParameter(
+ byte[] iv)
+ {
+ this.iv = new DerOctetString(iv);
+ }
+
+ public RC2CbcParameter(
+ int parameterVersion,
+ byte[] iv)
+ {
+ this.version = new DerInteger(parameterVersion);
+ this.iv = new DerOctetString(iv);
+ }
+
+ private RC2CbcParameter(
+ Asn1Sequence seq)
+ {
+ if (seq.Count == 1)
+ {
+ iv = (Asn1OctetString)seq[0];
+ }
+ else
+ {
+ version = (DerInteger)seq[0];
+ iv = (Asn1OctetString)seq[1];
+ }
+ }
+
+ public BigInteger RC2ParameterVersion
+ {
+ get
+ {
+ return version == null ? null : version.Value;
+ }
+ }
+
+ public byte[] GetIV()
+ {
+ return Arrays.Clone(iv.GetOctets());
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (version != null)
+ {
+ v.Add(version);
+ }
+
+ v.Add(iv);
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/RSAESOAEPparams.cs b/iTechSharp/srcbc/asn1/pkcs/RSAESOAEPparams.cs
new file mode 100644
index 0000000..5ecb394
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/RSAESOAEPparams.cs
@@ -0,0 +1,145 @@
+using System;
+
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class RsaesOaepParameters
+ : Asn1Encodable
+ {
+ private AlgorithmIdentifier hashAlgorithm;
+ private AlgorithmIdentifier maskGenAlgorithm;
+ private AlgorithmIdentifier pSourceAlgorithm;
+
+ public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+ public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
+ public readonly static AlgorithmIdentifier DefaultPSourceAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]));
+
+ public static RsaesOaepParameters GetInstance(
+ object obj)
+ {
+ if (obj is RsaesOaepParameters)
+ {
+ return (RsaesOaepParameters)obj;
+ }
+ else if (obj is Asn1Sequence)
+ {
+ return new RsaesOaepParameters((Asn1Sequence)obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ /**
+ * The default version
+ */
+ public RsaesOaepParameters()
+ {
+ hashAlgorithm = DefaultHashAlgorithm;
+ maskGenAlgorithm = DefaultMaskGenFunction;
+ pSourceAlgorithm = DefaultPSourceAlgorithm;
+ }
+
+ public RsaesOaepParameters(
+ AlgorithmIdentifier hashAlgorithm,
+ AlgorithmIdentifier maskGenAlgorithm,
+ AlgorithmIdentifier pSourceAlgorithm)
+ {
+ this.hashAlgorithm = hashAlgorithm;
+ this.maskGenAlgorithm = maskGenAlgorithm;
+ this.pSourceAlgorithm = pSourceAlgorithm;
+ }
+
+ public RsaesOaepParameters(
+ Asn1Sequence seq)
+ {
+ hashAlgorithm = DefaultHashAlgorithm;
+ maskGenAlgorithm = DefaultMaskGenFunction;
+ pSourceAlgorithm = DefaultPSourceAlgorithm;
+
+ for (int i = 0; i != seq.Count; i++)
+ {
+ Asn1TaggedObject o = (Asn1TaggedObject)seq[i];
+
+ switch (o.TagNo)
+ {
+ case 0:
+ hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
+ break;
+ case 1:
+ maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
+ break;
+ case 2:
+ pSourceAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
+ break;
+ default:
+ throw new ArgumentException("unknown tag");
+ }
+ }
+ }
+
+ public AlgorithmIdentifier HashAlgorithm
+ {
+ get { return hashAlgorithm; }
+ }
+
+ public AlgorithmIdentifier MaskGenAlgorithm
+ {
+ get { return maskGenAlgorithm; }
+ }
+
+ public AlgorithmIdentifier PSourceAlgorithm
+ {
+ get { return pSourceAlgorithm; }
+ }
+
+ /**
+ *
+ * RSAES-OAEP-params ::= SEQUENCE {
+ * hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
+ * maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
+ * pSourceAlgorithm [2] PKCS1PSourceAlgorithms DEFAULT pSpecifiedEmpty
+ * }
+ *
+ * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL },
+ * ... -- Allows for future expansion --
+ * }
+ * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ * ... -- Allows for future expansion --
+ * }
+ * PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-pSpecified PARAMETERS OCTET STRING },
+ * ... -- Allows for future expansion --
+ * }
+ *
+ * @return the asn1 primitive representing the parameters.
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (!hashAlgorithm.Equals(DefaultHashAlgorithm))
+ {
+ v.Add(new DerTaggedObject(true, 0, hashAlgorithm));
+ }
+
+ if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction))
+ {
+ v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm));
+ }
+
+ if (!pSourceAlgorithm.Equals(DefaultPSourceAlgorithm))
+ {
+ v.Add(new DerTaggedObject(true, 2, pSourceAlgorithm));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/RSAPrivateKeyStructure.cs b/iTechSharp/srcbc/asn1/pkcs/RSAPrivateKeyStructure.cs
new file mode 100644
index 0000000..dbb07c7
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/RSAPrivateKeyStructure.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class RsaPrivateKeyStructure
+ : Asn1Encodable
+ {
+ private readonly BigInteger modulus;
+ private readonly BigInteger publicExponent;
+ private readonly BigInteger privateExponent;
+ private readonly BigInteger prime1;
+ private readonly BigInteger prime2;
+ private readonly BigInteger exponent1;
+ private readonly BigInteger exponent2;
+ private readonly BigInteger coefficient;
+
+ public RsaPrivateKeyStructure(
+ BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger prime1,
+ BigInteger prime2,
+ BigInteger exponent1,
+ BigInteger exponent2,
+ BigInteger coefficient)
+ {
+ this.modulus = modulus;
+ this.publicExponent = publicExponent;
+ this.privateExponent = privateExponent;
+ this.prime1 = prime1;
+ this.prime2 = prime2;
+ this.exponent1 = exponent1;
+ this.exponent2 = exponent2;
+ this.coefficient = coefficient;
+ }
+
+ public RsaPrivateKeyStructure(
+ Asn1Sequence seq)
+ {
+ BigInteger version = ((DerInteger) seq[0]).Value;
+ if (version.IntValue != 0)
+ throw new ArgumentException("wrong version for RSA private key");
+
+ modulus = ((DerInteger) seq[1]).Value;
+ publicExponent = ((DerInteger) seq[2]).Value;
+ privateExponent = ((DerInteger) seq[3]).Value;
+ prime1 = ((DerInteger) seq[4]).Value;
+ prime2 = ((DerInteger) seq[5]).Value;
+ exponent1 = ((DerInteger) seq[6]).Value;
+ exponent2 = ((DerInteger) seq[7]).Value;
+ coefficient = ((DerInteger) seq[8]).Value;
+ }
+
+ public BigInteger Modulus
+ {
+ get { return modulus; }
+ }
+
+ public BigInteger PublicExponent
+ {
+ get { return publicExponent; }
+ }
+
+ public BigInteger PrivateExponent
+ {
+ get { return privateExponent; }
+ }
+
+ public BigInteger Prime1
+ {
+ get { return prime1; }
+ }
+
+ public BigInteger Prime2
+ {
+ get { return prime2; }
+ }
+
+ public BigInteger Exponent1
+ {
+ get { return exponent1; }
+ }
+
+ public BigInteger Exponent2
+ {
+ get { return exponent2; }
+ }
+
+ public BigInteger Coefficient
+ {
+ get { return coefficient; }
+ }
+
+ /**
+ * This outputs the key in Pkcs1v2 format.
+ *
+ * RsaPrivateKey ::= Sequence {
+ * version Version,
+ * modulus Integer, -- n
+ * publicExponent Integer, -- e
+ * privateExponent Integer, -- d
+ * prime1 Integer, -- p
+ * prime2 Integer, -- q
+ * exponent1 Integer, -- d mod (p-1)
+ * exponent2 Integer, -- d mod (q-1)
+ * coefficient Integer -- (inverse of q) mod p
+ * }
+ *
+ * Version ::= Integer
+ *
+ *
+ * RSASSA-PSS-params ::= SEQUENCE {
+ * hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
+ * maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
+ * saltLength [2] INTEGER DEFAULT 20,
+ * trailerField [3] TrailerField DEFAULT trailerFieldBC
+ * }
+ *
+ * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL },
+ * ... -- Allows for future expansion --
+ * }
+ *
+ * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ * ... -- Allows for future expansion --
+ * }
+ *
+ * TrailerField ::= INTEGER { trailerFieldBC(1) }
+ *
+ * @return the asn1 primitive representing the parameters.
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (!hashAlgorithm.Equals(DefaultHashAlgorithm))
+ {
+ v.Add(new DerTaggedObject(true, 0, hashAlgorithm));
+ }
+
+ if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction))
+ {
+ v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm));
+ }
+
+ if (!saltLength.Equals(DefaultSaltLength))
+ {
+ v.Add(new DerTaggedObject(true, 2, saltLength));
+ }
+
+ if (!trailerField.Equals(DefaultTrailerField))
+ {
+ v.Add(new DerTaggedObject(true, 3, trailerField));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/SafeBag.cs b/iTechSharp/srcbc/asn1/pkcs/SafeBag.cs
new file mode 100644
index 0000000..4b9350b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/SafeBag.cs
@@ -0,0 +1,70 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ public class SafeBag
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier bagID;
+ private readonly Asn1Object bagValue;
+ private readonly Asn1Set bagAttributes;
+
+ public SafeBag(
+ DerObjectIdentifier oid,
+ Asn1Object obj)
+ {
+ this.bagID = oid;
+ this.bagValue = obj;
+ this.bagAttributes = null;
+ }
+
+ public SafeBag(
+ DerObjectIdentifier oid,
+ Asn1Object obj,
+ Asn1Set bagAttributes)
+ {
+ this.bagID = oid;
+ this.bagValue = obj;
+ this.bagAttributes = bagAttributes;
+ }
+
+ public SafeBag(
+ Asn1Sequence seq)
+ {
+ this.bagID = (DerObjectIdentifier) seq[0];
+ this.bagValue = ((DerTaggedObject) seq[1]).GetObject();
+ if (seq.Count == 3)
+ {
+ this.bagAttributes = (Asn1Set) seq[2];
+ }
+ }
+
+ public DerObjectIdentifier BagID
+ {
+ get { return bagID; }
+ }
+
+ public Asn1Object BagValue
+ {
+ get { return bagValue; }
+ }
+
+ public Asn1Set BagAttributes
+ {
+ get { return bagAttributes; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ bagID, new DerTaggedObject(0, bagValue));
+
+ if (bagAttributes != null)
+ {
+ v.Add(bagAttributes);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/SignedData.cs b/iTechSharp/srcbc/asn1/pkcs/SignedData.cs
new file mode 100644
index 0000000..10951d3
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/SignedData.cs
@@ -0,0 +1,163 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ /**
+ * a Pkcs#7 signed data object.
+ */
+ public class SignedData
+ : Asn1Encodable
+ {
+ private readonly DerInteger version;
+ private readonly Asn1Set digestAlgorithms;
+ private readonly ContentInfo contentInfo;
+ private readonly Asn1Set certificates;
+ private readonly Asn1Set crls;
+ private readonly Asn1Set signerInfos;
+
+ public static SignedData GetInstance(
+ object obj)
+ {
+ if (obj is SignedData)
+ {
+ return (SignedData) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SignedData((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public SignedData(
+ DerInteger _version,
+ Asn1Set _digestAlgorithms,
+ ContentInfo _contentInfo,
+ Asn1Set _certificates,
+ Asn1Set _crls,
+ Asn1Set _signerInfos)
+ {
+ version = _version;
+ digestAlgorithms = _digestAlgorithms;
+ contentInfo = _contentInfo;
+ certificates = _certificates;
+ crls = _crls;
+ signerInfos = _signerInfos;
+ }
+
+ private SignedData(
+ Asn1Sequence seq)
+ {
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ version = (DerInteger) e.Current;
+
+ e.MoveNext();
+ digestAlgorithms = (Asn1Set) e.Current;
+
+ e.MoveNext();
+ contentInfo = ContentInfo.GetInstance(e.Current);
+
+ while (e.MoveNext())
+ {
+ Asn1Object o = (Asn1Object) e.Current;
+
+ //
+ // an interesting feature of SignedData is that there appear to be varying implementations...
+ // for the moment we ignore anything which doesn't fit.
+ //
+ if (o is DerTaggedObject)
+ {
+ DerTaggedObject tagged = (DerTaggedObject) o;
+
+ switch (tagged.TagNo)
+ {
+ case 0:
+ certificates = Asn1Set.GetInstance(tagged, false);
+ break;
+ case 1:
+ crls = Asn1Set.GetInstance(tagged, false);
+ break;
+ default:
+ throw new ArgumentException("unknown tag value " + tagged.TagNo);
+ }
+ }
+ else
+ {
+ signerInfos = (Asn1Set) o;
+ }
+ }
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public Asn1Set DigestAlgorithms
+ {
+ get { return digestAlgorithms; }
+ }
+
+ public ContentInfo ContentInfo
+ {
+ get { return contentInfo; }
+ }
+
+ public Asn1Set Certificates
+ {
+ get { return certificates; }
+ }
+
+ public Asn1Set Crls
+ {
+ get { return crls; }
+ }
+
+ public Asn1Set SignerInfos
+ {
+ get { return signerInfos; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * SignedData ::= Sequence {
+ * version Version,
+ * digestAlgorithms DigestAlgorithmIdentifiers,
+ * contentInfo ContentInfo,
+ * certificates
+ * [0] IMPLICIT ExtendedCertificatesAndCertificates
+ * OPTIONAL,
+ * crls
+ * [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ * signerInfos SignerInfos }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, digestAlgorithms, contentInfo);
+
+ if (certificates != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, certificates));
+ }
+
+ if (crls != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, crls));
+ }
+
+ v.Add(signerInfos);
+
+ return new BerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/pkcs/SignerInfo.cs b/iTechSharp/srcbc/asn1/pkcs/SignerInfo.cs
new file mode 100644
index 0000000..1e46945
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/pkcs/SignerInfo.cs
@@ -0,0 +1,154 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+ /**
+ * a Pkcs#7 signer info object.
+ */
+ public class SignerInfo
+ : Asn1Encodable
+ {
+ private DerInteger version;
+ private IssuerAndSerialNumber issuerAndSerialNumber;
+ private AlgorithmIdentifier digAlgorithm;
+ private Asn1Set authenticatedAttributes;
+ private AlgorithmIdentifier digEncryptionAlgorithm;
+ private Asn1OctetString encryptedDigest;
+ private Asn1Set unauthenticatedAttributes;
+
+ public static SignerInfo GetInstance(
+ object obj)
+ {
+ if (obj is SignerInfo)
+ {
+ return (SignerInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SignerInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+ }
+
+ public SignerInfo(
+ DerInteger version,
+ IssuerAndSerialNumber issuerAndSerialNumber,
+ AlgorithmIdentifier digAlgorithm,
+ Asn1Set authenticatedAttributes,
+ AlgorithmIdentifier digEncryptionAlgorithm,
+ Asn1OctetString encryptedDigest,
+ Asn1Set unauthenticatedAttributes)
+ {
+ this.version = version;
+ this.issuerAndSerialNumber = issuerAndSerialNumber;
+ this.digAlgorithm = digAlgorithm;
+ this.authenticatedAttributes = authenticatedAttributes;
+ this.digEncryptionAlgorithm = digEncryptionAlgorithm;
+ this.encryptedDigest = encryptedDigest;
+ this.unauthenticatedAttributes = unauthenticatedAttributes;
+ }
+
+ public SignerInfo(
+ Asn1Sequence seq)
+ {
+ IEnumerator e = seq.GetEnumerator();
+
+ e.MoveNext();
+ version = (DerInteger) e.Current;
+
+ e.MoveNext();
+ issuerAndSerialNumber = IssuerAndSerialNumber.GetInstance(e.Current);
+
+ e.MoveNext();
+ digAlgorithm = AlgorithmIdentifier.GetInstance(e.Current);
+
+ e.MoveNext();
+ object obj = e.Current;
+
+ if (obj is Asn1TaggedObject)
+ {
+ authenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject) obj, false);
+
+ e.MoveNext();
+ digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(e.Current);
+ }
+ else
+ {
+ authenticatedAttributes = null;
+ digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(obj);
+ }
+
+ e.MoveNext();
+ encryptedDigest = DerOctetString.GetInstance(e.Current);
+
+ if (e.MoveNext())
+ {
+ unauthenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject)e.Current, false);
+ }
+ else
+ {
+ unauthenticatedAttributes = null;
+ }
+ }
+
+ public DerInteger Version { get { return version; } }
+
+ public IssuerAndSerialNumber IssuerAndSerialNumber { get { return issuerAndSerialNumber; } }
+
+ public Asn1Set AuthenticatedAttributes { get { return authenticatedAttributes; } }
+
+ public AlgorithmIdentifier DigestAlgorithm { get { return digAlgorithm; } }
+
+ public Asn1OctetString EncryptedDigest { get { return encryptedDigest; } }
+
+ public AlgorithmIdentifier DigestEncryptionAlgorithm { get { return digEncryptionAlgorithm; } }
+
+ public Asn1Set UnauthenticatedAttributes { get { return unauthenticatedAttributes; } }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * SignerInfo ::= Sequence {
+ * version Version,
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
+ * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+ * encryptedDigest EncryptedDigest,
+ * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+ * }
+ *
+ * EncryptedDigest ::= OCTET STRING
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, issuerAndSerialNumber, digAlgorithm);
+
+ if (authenticatedAttributes != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, authenticatedAttributes));
+ }
+
+ v.Add(digEncryptionAlgorithm, encryptedDigest);
+
+ if (unauthenticatedAttributes != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, unauthenticatedAttributes));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/sec/ECPrivateKeyStructure.cs b/iTechSharp/srcbc/asn1/sec/ECPrivateKeyStructure.cs
new file mode 100644
index 0000000..b4592cd
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/sec/ECPrivateKeyStructure.cs
@@ -0,0 +1,82 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+using System;
+
+namespace Org.BouncyCastle.Asn1.Sec
+{
+ /**
+ * the elliptic curve private key object from SEC 1
+ */
+ public class ECPrivateKeyStructure
+ : Asn1Encodable
+ {
+ private readonly Asn1Sequence seq;
+
+ public ECPrivateKeyStructure(
+ Asn1Sequence seq)
+ {
+ if (seq == null)
+ throw new ArgumentNullException("seq");
+
+ this.seq = seq;
+ }
+
+ public ECPrivateKeyStructure(
+ BigInteger key)
+ {
+ this.seq = new DerSequence(
+ new DerInteger(1),
+ new DerOctetString(key.ToByteArrayUnsigned()));
+ }
+
+ public BigInteger GetKey()
+ {
+ Asn1OctetString octs = (Asn1OctetString) seq[1];
+
+ return new BigInteger(1, octs.GetOctets());
+ }
+
+ public DerBitString GetPublicKey()
+ {
+ return (DerBitString) GetObjectInTag(1);
+ }
+
+ public Asn1Object GetParameters()
+ {
+ return GetObjectInTag(0);
+ }
+
+ private Asn1Object GetObjectInTag(
+ int tagNo)
+ {
+ foreach (Asn1Encodable ae in seq)
+ {
+ Asn1Object obj = ae.ToAsn1Object();
+
+ if (obj is Asn1TaggedObject)
+ {
+ Asn1TaggedObject tag = (Asn1TaggedObject) obj;
+ if (tag.TagNo == tagNo)
+ {
+ return tag.GetObject();
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * ECPrivateKey ::= SEQUENCE {
+ * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+ * privateKey OCTET STRING,
+ * parameters [0] Parameters OPTIONAL,
+ * publicKey [1] BIT STRING OPTIONAL }
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return seq;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/sec/SECNamedCurves.cs b/iTechSharp/srcbc/asn1/sec/SECNamedCurves.cs
new file mode 100644
index 0000000..3eb5e35
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/sec/SECNamedCurves.cs
@@ -0,0 +1,1191 @@
+using System;
+using System.Collections;
+using System.Globalization;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Utilities.Collections;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Asn1.Sec
+{
+ public sealed class SecNamedCurves
+ {
+ private SecNamedCurves()
+ {
+ }
+
+ private static BigInteger FromHex(
+ string hex)
+ {
+ return new BigInteger(1, Hex.Decode(hex));
+ }
+
+ /*
+ * secp112r1
+ */
+ internal class Secp112r1Holder
+ : X9ECParametersHolder
+ {
+ private Secp112r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp112r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = (2^128 - 3) / 76439
+ BigInteger p = FromHex("DB7C2ABF62E35E668076BEAD208B");
+ BigInteger a = FromHex("DB7C2ABF62E35E668076BEAD2088");
+ BigInteger b = FromHex("659EF8BA043916EEDE8911702B22");
+ byte[] S = Hex.Decode("00F50B028E4D696E676875615175290472783FB1");
+ BigInteger n = FromHex("DB7C2ABF62E35E7628DFAC6561C5");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "09487239995A5EE76B55F9C2F098"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "09487239995A5EE76B55F9C2F098"
+ + "A89CE5AF8724C0A23E0E0FF77500"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp112r2
+ */
+ internal class Secp112r2Holder
+ : X9ECParametersHolder
+ {
+ private Secp112r2Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp112r2Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = (2^128 - 3) / 76439
+ BigInteger p = FromHex("DB7C2ABF62E35E668076BEAD208B");
+ BigInteger a = FromHex("6127C24C05F38A0AAAF65C0EF02C");
+ BigInteger b = FromHex("51DEF1815DB5ED74FCC34C85D709");
+ byte[] S = Hex.Decode("002757A1114D696E6768756151755316C05E0BD4");
+ BigInteger n = FromHex("36DF0AAFD8B8D7597CA10520D04B");
+ BigInteger h = BigInteger.ValueOf(4);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "4BA30AB5E892B4E1649DD0928643"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "4BA30AB5E892B4E1649DD0928643"
+ + "ADCD46F5882E3747DEF36E956E97"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp128r1
+ */
+ internal class Secp128r1Holder
+ : X9ECParametersHolder
+ {
+ private Secp128r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp128r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^128 - 2^97 - 1
+ BigInteger p = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
+ BigInteger a = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC");
+ BigInteger b = FromHex("E87579C11079F43DD824993C2CEE5ED3");
+ byte[] S = Hex.Decode("000E0D4D696E6768756151750CC03A4473D03679");
+ BigInteger n = FromHex("FFFFFFFE0000000075A30D1B9038A115");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "161FF7528B899B2D0C28607CA52C5B86"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "161FF7528B899B2D0C28607CA52C5B86"
+ + "CF5AC8395BAFEB13C02DA292DDED7A83"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp128r2
+ */
+ internal class Secp128r2Holder
+ : X9ECParametersHolder
+ {
+ private Secp128r2Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp128r2Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^128 - 2^97 - 1
+ BigInteger p = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
+ BigInteger a = FromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1");
+ BigInteger b = FromHex("5EEEFCA380D02919DC2C6558BB6D8A5D");
+ byte[] S = Hex.Decode("004D696E67687561517512D8F03431FCE63B88F4");
+ BigInteger n = FromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
+ BigInteger h = BigInteger.ValueOf(4);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "7B6AA5D85E572983E6FB32A7CDEBC140"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "7B6AA5D85E572983E6FB32A7CDEBC140"
+ + "27B6916A894D3AEE7106FE805FC34B44"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp160k1
+ */
+ internal class Secp160k1Holder
+ : X9ECParametersHolder
+ {
+ private Secp160k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp160k1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(7);
+ byte[] S = null;
+ BigInteger n = FromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"
+ + "938CF935318FDCED6BC28286531733C3F03C4FEE"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp160r1
+ */
+ internal class Secp160r1Holder
+ : X9ECParametersHolder
+ {
+ private Secp160r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp160r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^160 - 2^31 - 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF");
+ BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC");
+ BigInteger b = FromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45");
+ byte[] S = Hex.Decode("1053CDE42C14D696E67687561517533BF3F83345");
+ BigInteger n = FromHex("0100000000000000000001F4C8F927AED3CA752257");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "4A96B5688EF573284664698968C38BB913CBFC82"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "4A96B5688EF573284664698968C38BB913CBFC82"
+ + "23A628553168947D59DCC912042351377AC5FB32"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp160r2
+ */
+ internal class Secp160r2Holder
+ : X9ECParametersHolder
+ {
+ private Secp160r2Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp160r2Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
+ BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70");
+ BigInteger b = FromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA");
+ byte[] S = Hex.Decode("B99B99B099B323E02709A4D696E6768756151751");
+ BigInteger n = FromHex("0100000000000000000000351EE786A818F3A1A16B");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "52DCB034293A117E1F4FF11B30F7199D3144CE6D"
+ + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp192k1
+ */
+ internal class Secp192k1Holder
+ : X9ECParametersHolder
+ {
+ private Secp192k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp192k1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37");
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(3);
+ byte[] S = null;
+ BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
+ + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp192r1
+ */
+ internal class Secp192r1Holder
+ : X9ECParametersHolder
+ {
+ private Secp192r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp192r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^192 - 2^64 - 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
+ BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
+ BigInteger b = FromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1");
+ byte[] S = Hex.Decode("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
+ + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp224k1
+ */
+ internal class Secp224k1Holder
+ : X9ECParametersHolder
+ {
+ private Secp224k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp224k1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D");
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(5);
+ byte[] S = null;
+ BigInteger n = FromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
+ + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp224r1
+ */
+ internal class Secp224r1Holder
+ : X9ECParametersHolder
+ {
+ private Secp224r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp224r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^224 - 2^96 + 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
+ BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE");
+ BigInteger b = FromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4");
+ byte[] S = Hex.Decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
+ + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp256k1
+ */
+ internal class Secp256k1Holder
+ : X9ECParametersHolder
+ {
+ private Secp256k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp256k1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(7);
+ byte[] S = null;
+ BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
+ + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp256r1
+ */
+ internal class Secp256r1Holder
+ : X9ECParametersHolder
+ {
+ private Secp256r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp256r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1
+ BigInteger p = FromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
+ BigInteger a = FromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
+ BigInteger b = FromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
+ byte[] S = Hex.Decode("C49D360886E704936A6678E1139D26B7819F7E90");
+ BigInteger n = FromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
+ + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp384r1
+ */
+ internal class Secp384r1Holder
+ : X9ECParametersHolder
+ {
+ private Secp384r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp384r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^384 - 2^128 - 2^96 + 2^32 - 1
+ BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
+ BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC");
+ BigInteger b = FromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF");
+ byte[] S = Hex.Decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * secp521r1
+ */
+ internal class Secp521r1Holder
+ : X9ECParametersHolder
+ {
+ private Secp521r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Secp521r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ // p = 2^521 - 1
+ BigInteger p = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+ BigInteger a = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC");
+ BigInteger b = FromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00");
+ byte[] S = Hex.Decode("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
+ BigInteger h = BigInteger.ValueOf(1);
+
+ ECCurve curve = new FpCurve(p, a, b);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect113r1
+ */
+ internal class Sect113r1Holder
+ : X9ECParametersHolder
+ {
+ private Sect113r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect113r1Holder();
+
+ private const int m = 113;
+ private const int k = 9;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = FromHex("003088250CA6E7C7FE649CE85820F7");
+ BigInteger b = FromHex("00E8BEE4D3E2260744188BE0E9C723");
+ byte[] S = Hex.Decode("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ BigInteger n = FromHex("0100000000000000D9CCEC8A39E56F");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "009D73616F35F4AB1407D73562C10F"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "009D73616F35F4AB1407D73562C10F"
+ + "00A52830277958EE84D1315ED31886"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect113r2
+ */
+ internal class Sect113r2Holder
+ : X9ECParametersHolder
+ {
+ private Sect113r2Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect113r2Holder();
+
+ private const int m = 113;
+ private const int k = 9;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = FromHex("00689918DBEC7E5A0DD6DFC0AA55C7");
+ BigInteger b = FromHex("0095E9A9EC9B297BD4BF36E059184F");
+ byte[] S = Hex.Decode("10C0FB15760860DEF1EEF4D696E676875615175D");
+ BigInteger n = FromHex("010000000000000108789B2496AF93");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "01A57A6A7B26CA5EF52FCDB8164797"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "01A57A6A7B26CA5EF52FCDB8164797"
+ + "00B3ADC94ED1FE674C06E695BABA1D"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect131r1
+ */
+ internal class Sect131r1Holder
+ : X9ECParametersHolder
+ {
+ private Sect131r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect131r1Holder();
+
+ private const int m = 131;
+ private const int k1 = 2;
+ private const int k2 = 3;
+ private const int k3 = 8;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = FromHex("07A11B09A76B562144418FF3FF8C2570B8");
+ BigInteger b = FromHex("0217C05610884B63B9C6C7291678F9D341");
+ byte[] S = Hex.Decode("4D696E676875615175985BD3ADBADA21B43A97E2");
+ BigInteger n = FromHex("0400000000000000023123953A9464B54D");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "0081BAF91FDF9833C40F9C181343638399"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "0081BAF91FDF9833C40F9C181343638399"
+ + "078C6E7EA38C001F73C8134B1B4EF9E150"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect131r2
+ */
+ internal class Sect131r2Holder
+ : X9ECParametersHolder
+ {
+ private Sect131r2Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect131r2Holder();
+
+ private const int m = 131;
+ private const int k1 = 2;
+ private const int k2 = 3;
+ private const int k3 = 8;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = FromHex("03E5A88919D7CAFCBF415F07C2176573B2");
+ BigInteger b = FromHex("04B8266A46C55657AC734CE38F018F2192");
+ byte[] S = Hex.Decode("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ BigInteger n = FromHex("0400000000000000016954A233049BA98F");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "0356DCD8F2F95031AD652D23951BB366A8"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "0356DCD8F2F95031AD652D23951BB366A8"
+ + "0648F06D867940A5366D9E265DE9EB240F"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect163k1
+ */
+ internal class Sect163k1Holder
+ : X9ECParametersHolder
+ {
+ private Sect163k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect163k1Holder();
+
+ private const int m = 163;
+ private const int k1 = 3;
+ private const int k2 = 6;
+ private const int k3 = 7;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.ValueOf(1);
+ BigInteger b = BigInteger.ValueOf(1);
+ byte[] S = null;
+ BigInteger n = FromHex("04000000000000000000020108A2E0CC0D99F8A5EF");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"
+ + "0289070FB05D38FF58321F2E800536D538CCDAA3D9"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect163r1
+ */
+ internal class Sect163r1Holder
+ : X9ECParametersHolder
+ {
+ private Sect163r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect163r1Holder();
+
+ private const int m = 163;
+ private const int k1 = 3;
+ private const int k2 = 6;
+ private const int k3 = 7;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = FromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2");
+ BigInteger b = FromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9");
+ byte[] S = Hex.Decode("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "0369979697AB43897789566789567F787A7876A654"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "0369979697AB43897789566789567F787A7876A654"
+ + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect163r2
+ */
+ internal class Sect163r2Holder
+ : X9ECParametersHolder
+ {
+ private Sect163r2Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect163r2Holder();
+
+ private const int m = 163;
+ private const int k1 = 3;
+ private const int k2 = 6;
+ private const int k3 = 7;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.ValueOf(1);
+ BigInteger b = FromHex("020A601907B8C953CA1481EB10512F78744A3205FD");
+ byte[] S = Hex.Decode("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ BigInteger n = FromHex("040000000000000000000292FE77E70C12A4234C33");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "03F0EBA16286A2D57EA0991168D4994637E8343E36"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "03F0EBA16286A2D57EA0991168D4994637E8343E36"
+ + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect193r1
+ */
+ internal class Sect193r1Holder
+ : X9ECParametersHolder
+ {
+ private Sect193r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect193r1Holder();
+
+ private const int m = 193;
+ private const int k = 15;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = FromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01");
+ BigInteger b = FromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814");
+ byte[] S = Hex.Decode("103FAEC74D696E676875615175777FC5B191EF30");
+ BigInteger n = FromHex("01000000000000000000000000C7F34A778F443ACC920EBA49");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"
+ + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect193r2
+ */
+ internal class Sect193r2Holder
+ : X9ECParametersHolder
+ {
+ private Sect193r2Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect193r2Holder();
+
+ private const int m = 193;
+ private const int k = 15;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = FromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B");
+ BigInteger b = FromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE");
+ byte[] S = Hex.Decode("10B7B4D696E676875615175137C8A16FD0DA2211");
+ BigInteger n = FromHex("010000000000000000000000015AAB561B005413CCD4EE99D5");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"
+ + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect233k1
+ */
+ internal class Sect233k1Holder
+ : X9ECParametersHolder
+ {
+ private Sect233k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect233k1Holder();
+
+ private const int m = 233;
+ private const int k = 74;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(1);
+ byte[] S = null;
+ BigInteger n = FromHex("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF");
+ BigInteger h = BigInteger.ValueOf(4);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"
+ + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect233r1
+ */
+ internal class Sect233r1Holder
+ : X9ECParametersHolder
+ {
+ private Sect233r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect233r1Holder();
+
+ private const int m = 233;
+ private const int k = 74;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.ValueOf(1);
+ BigInteger b = FromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD");
+ byte[] S = Hex.Decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ BigInteger n = FromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"
+ + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect239k1
+ */
+ internal class Sect239k1Holder
+ : X9ECParametersHolder
+ {
+ private Sect239k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect239k1Holder();
+
+ private const int m = 239;
+ private const int k = 158;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(1);
+ byte[] S = null;
+ BigInteger n = FromHex("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5");
+ BigInteger h = BigInteger.ValueOf(4);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"
+ + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect283k1
+ */
+ internal class Sect283k1Holder
+ : X9ECParametersHolder
+ {
+ private Sect283k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect283k1Holder();
+
+ private const int m = 283;
+ private const int k1 = 5;
+ private const int k2 = 7;
+ private const int k3 = 12;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(1);
+ byte[] S = null;
+ BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61");
+ BigInteger h = BigInteger.ValueOf(4);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect283r1
+ */
+ internal class Sect283r1Holder
+ : X9ECParametersHolder
+ {
+ private Sect283r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect283r1Holder();
+
+ private const int m = 283;
+ private const int k1 = 5;
+ private const int k2 = 7;
+ private const int k3 = 12;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.ValueOf(1);
+ BigInteger b = FromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5");
+ byte[] S = Hex.Decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect409k1
+ */
+ internal class Sect409k1Holder
+ : X9ECParametersHolder
+ {
+ private Sect409k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect409k1Holder();
+
+ private const int m = 409;
+ private const int k = 87;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(1);
+ byte[] S = null;
+ BigInteger n = FromHex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF");
+ BigInteger h = BigInteger.ValueOf(4);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect409r1
+ */
+ internal class Sect409r1Holder
+ : X9ECParametersHolder
+ {
+ private Sect409r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect409r1Holder();
+
+ private const int m = 409;
+ private const int k = 87;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.ValueOf(1);
+ BigInteger b = FromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F");
+ byte[] S = Hex.Decode("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ BigInteger n = FromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect571k1
+ */
+ internal class Sect571k1Holder
+ : X9ECParametersHolder
+ {
+ private Sect571k1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect571k1Holder();
+
+ private const int m = 571;
+ private const int k1 = 2;
+ private const int k2 = 5;
+ private const int k3 = 10;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.Zero;
+ BigInteger b = BigInteger.ValueOf(1);
+ byte[] S = null;
+ BigInteger n = FromHex("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001");
+ BigInteger h = BigInteger.ValueOf(4);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("02"
+ //+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+ /*
+ * sect571r1
+ */
+ internal class Sect571r1Holder
+ : X9ECParametersHolder
+ {
+ private Sect571r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new Sect571r1Holder();
+
+ private const int m = 571;
+ private const int k1 = 2;
+ private const int k2 = 5;
+ private const int k3 = 10;
+
+ protected override X9ECParameters CreateParameters()
+ {
+ BigInteger a = BigInteger.ValueOf(1);
+ BigInteger b = FromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A");
+ byte[] S = Hex.Decode("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47");
+ BigInteger h = BigInteger.ValueOf(2);
+
+ ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h);
+ //ECPoint G = curve.DecodePoint(Hex.Decode("03"
+ //+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"));
+ ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"));
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ }
+
+
+ private static readonly Hashtable objIds = new Hashtable();
+ private static readonly Hashtable curves = new Hashtable();
+ private static readonly Hashtable names = new Hashtable();
+
+ private static void DefineCurve(
+ string name,
+ DerObjectIdentifier oid,
+ X9ECParametersHolder holder)
+ {
+ objIds.Add(name, oid);
+ names.Add(oid, name);
+ curves.Add(oid, holder);
+ }
+
+ static SecNamedCurves()
+ {
+ DefineCurve("secp112r1", SecObjectIdentifiers.SecP112r1, Secp112r1Holder.Instance);
+ DefineCurve("secp112r2", SecObjectIdentifiers.SecP112r2, Secp112r2Holder.Instance);
+ DefineCurve("secp128r1", SecObjectIdentifiers.SecP128r1, Secp128r1Holder.Instance);
+ DefineCurve("secp128r2", SecObjectIdentifiers.SecP128r2, Secp128r2Holder.Instance);
+ DefineCurve("secp160k1", SecObjectIdentifiers.SecP160k1, Secp160k1Holder.Instance);
+ DefineCurve("secp160r1", SecObjectIdentifiers.SecP160r1, Secp160r1Holder.Instance);
+ DefineCurve("secp160r2", SecObjectIdentifiers.SecP160r2, Secp160r2Holder.Instance);
+ DefineCurve("secp192k1", SecObjectIdentifiers.SecP192k1, Secp192k1Holder.Instance);
+ DefineCurve("secp192r1", SecObjectIdentifiers.SecP192r1, Secp192r1Holder.Instance);
+ DefineCurve("secp224k1", SecObjectIdentifiers.SecP224k1, Secp224k1Holder.Instance);
+ DefineCurve("secp224r1", SecObjectIdentifiers.SecP224r1, Secp224r1Holder.Instance);
+ DefineCurve("secp256k1", SecObjectIdentifiers.SecP256k1, Secp256k1Holder.Instance);
+ DefineCurve("secp256r1", SecObjectIdentifiers.SecP256r1, Secp256r1Holder.Instance);
+ DefineCurve("secp384r1", SecObjectIdentifiers.SecP384r1, Secp384r1Holder.Instance);
+ DefineCurve("secp521r1", SecObjectIdentifiers.SecP521r1, Secp521r1Holder.Instance);
+
+ DefineCurve("sect113r1", SecObjectIdentifiers.SecT113r1, Sect113r1Holder.Instance);
+ DefineCurve("sect113r2", SecObjectIdentifiers.SecT113r2, Sect113r2Holder.Instance);
+ DefineCurve("sect131r1", SecObjectIdentifiers.SecT131r1, Sect131r1Holder.Instance);
+ DefineCurve("sect131r2", SecObjectIdentifiers.SecT131r2, Sect131r2Holder.Instance);
+ DefineCurve("sect163k1", SecObjectIdentifiers.SecT163k1, Sect163k1Holder.Instance);
+ DefineCurve("sect163r1", SecObjectIdentifiers.SecT163r1, Sect163r1Holder.Instance);
+ DefineCurve("sect163r2", SecObjectIdentifiers.SecT163r2, Sect163r2Holder.Instance);
+ DefineCurve("sect193r1", SecObjectIdentifiers.SecT193r1, Sect193r1Holder.Instance);
+ DefineCurve("sect193r2", SecObjectIdentifiers.SecT193r2, Sect193r2Holder.Instance);
+ DefineCurve("sect233k1", SecObjectIdentifiers.SecT233k1, Sect233k1Holder.Instance);
+ DefineCurve("sect233r1", SecObjectIdentifiers.SecT233r1, Sect233r1Holder.Instance);
+ DefineCurve("sect239k1", SecObjectIdentifiers.SecT239k1, Sect239k1Holder.Instance);
+ DefineCurve("sect283k1", SecObjectIdentifiers.SecT283k1, Sect283k1Holder.Instance);
+ DefineCurve("sect283r1", SecObjectIdentifiers.SecT283r1, Sect283r1Holder.Instance);
+ DefineCurve("sect409k1", SecObjectIdentifiers.SecT409k1, Sect409k1Holder.Instance);
+ DefineCurve("sect409r1", SecObjectIdentifiers.SecT409r1, Sect409r1Holder.Instance);
+ DefineCurve("sect571k1", SecObjectIdentifiers.SecT571k1, Sect571k1Holder.Instance);
+ DefineCurve("sect571r1", SecObjectIdentifiers.SecT571r1, Sect571r1Holder.Instance);
+ }
+
+ public static X9ECParameters GetByName(
+ string name)
+ {
+ DerObjectIdentifier oid = (DerObjectIdentifier)
+ objIds[name.ToLower(CultureInfo.InvariantCulture)];
+
+ return oid == null ? null : GetByOid(oid);
+ }
+
+ /**
+ * return the X9ECParameters object for the named curve represented by
+ * the passed in object identifier. Null if the curve isn't present.
+ *
+ * @param oid an object identifier representing a named curve, if present.
+ */
+ public static X9ECParameters GetByOid(
+ DerObjectIdentifier oid)
+ {
+ X9ECParametersHolder holder = (X9ECParametersHolder) curves[oid];
+
+ return holder == null ? null : holder.Parameters;
+ }
+
+ /**
+ * return the object identifier signified by the passed in name. Null
+ * if there is no object identifier associated with name.
+ *
+ * @return the object identifier associated with name, if present.
+ */
+ public static DerObjectIdentifier GetOid(
+ string name)
+ {
+ return (DerObjectIdentifier) objIds[name.ToLower(CultureInfo.InvariantCulture)];
+ }
+
+ /**
+ * return the named curve name represented by the given object identifier.
+ */
+ public static string GetName(
+ DerObjectIdentifier oid)
+ {
+ return (string) names[oid];
+ }
+
+ /**
+ * returns an enumeration containing the name strings for curves
+ * contained in this structure.
+ */
+ public static IEnumerable Names
+ {
+ get { return new EnumerableProxy(objIds.Keys); }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/sec/SECObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/sec/SECObjectIdentifiers.cs
new file mode 100644
index 0000000..afc10e1
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/sec/SECObjectIdentifiers.cs
@@ -0,0 +1,52 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X9;
+
+namespace Org.BouncyCastle.Asn1.Sec
+{
+ public abstract class SecObjectIdentifiers
+ {
+ /**
+ * EllipticCurve OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) curve(0)
+ * }
+ */
+ public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier("1.3.132.0");
+
+ public static readonly DerObjectIdentifier SecT163k1 = new DerObjectIdentifier(EllipticCurve + ".1");
+ public static readonly DerObjectIdentifier SecT163r1 = new DerObjectIdentifier(EllipticCurve + ".2");
+ public static readonly DerObjectIdentifier SecT239k1 = new DerObjectIdentifier(EllipticCurve + ".3");
+ public static readonly DerObjectIdentifier SecT113r1 = new DerObjectIdentifier(EllipticCurve + ".4");
+ public static readonly DerObjectIdentifier SecT113r2 = new DerObjectIdentifier(EllipticCurve + ".5");
+ public static readonly DerObjectIdentifier SecP112r1 = new DerObjectIdentifier(EllipticCurve + ".6");
+ public static readonly DerObjectIdentifier SecP112r2 = new DerObjectIdentifier(EllipticCurve + ".7");
+ public static readonly DerObjectIdentifier SecP160r1 = new DerObjectIdentifier(EllipticCurve + ".8");
+ public static readonly DerObjectIdentifier SecP160k1 = new DerObjectIdentifier(EllipticCurve + ".9");
+ public static readonly DerObjectIdentifier SecP256k1 = new DerObjectIdentifier(EllipticCurve + ".10");
+ public static readonly DerObjectIdentifier SecT163r2 = new DerObjectIdentifier(EllipticCurve + ".15");
+ public static readonly DerObjectIdentifier SecT283k1 = new DerObjectIdentifier(EllipticCurve + ".16");
+ public static readonly DerObjectIdentifier SecT283r1 = new DerObjectIdentifier(EllipticCurve + ".17");
+ public static readonly DerObjectIdentifier SecT131r1 = new DerObjectIdentifier(EllipticCurve + ".22");
+ public static readonly DerObjectIdentifier SecT131r2 = new DerObjectIdentifier(EllipticCurve + ".23");
+ public static readonly DerObjectIdentifier SecT193r1 = new DerObjectIdentifier(EllipticCurve + ".24");
+ public static readonly DerObjectIdentifier SecT193r2 = new DerObjectIdentifier(EllipticCurve + ".25");
+ public static readonly DerObjectIdentifier SecT233k1 = new DerObjectIdentifier(EllipticCurve + ".26");
+ public static readonly DerObjectIdentifier SecT233r1 = new DerObjectIdentifier(EllipticCurve + ".27");
+ public static readonly DerObjectIdentifier SecP128r1 = new DerObjectIdentifier(EllipticCurve + ".28");
+ public static readonly DerObjectIdentifier SecP128r2 = new DerObjectIdentifier(EllipticCurve + ".29");
+ public static readonly DerObjectIdentifier SecP160r2 = new DerObjectIdentifier(EllipticCurve + ".30");
+ public static readonly DerObjectIdentifier SecP192k1 = new DerObjectIdentifier(EllipticCurve + ".31");
+ public static readonly DerObjectIdentifier SecP224k1 = new DerObjectIdentifier(EllipticCurve + ".32");
+ public static readonly DerObjectIdentifier SecP224r1 = new DerObjectIdentifier(EllipticCurve + ".33");
+ public static readonly DerObjectIdentifier SecP384r1 = new DerObjectIdentifier(EllipticCurve + ".34");
+ public static readonly DerObjectIdentifier SecP521r1 = new DerObjectIdentifier(EllipticCurve + ".35");
+ public static readonly DerObjectIdentifier SecT409k1 = new DerObjectIdentifier(EllipticCurve + ".36");
+ public static readonly DerObjectIdentifier SecT409r1 = new DerObjectIdentifier(EllipticCurve + ".37");
+ public static readonly DerObjectIdentifier SecT571k1 = new DerObjectIdentifier(EllipticCurve + ".38");
+ public static readonly DerObjectIdentifier SecT571r1 = new DerObjectIdentifier(EllipticCurve + ".39");
+
+ public static readonly DerObjectIdentifier SecP192r1 = X9ObjectIdentifiers.Prime192v1;
+ public static readonly DerObjectIdentifier SecP256r1 = X9ObjectIdentifiers.Prime256v1;
+ }
+}
\ No newline at end of file
diff --git a/iTechSharp/srcbc/asn1/smime/SMIMEAttributes.cs b/iTechSharp/srcbc/asn1/smime/SMIMEAttributes.cs
new file mode 100644
index 0000000..e154e5e
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/smime/SMIMEAttributes.cs
@@ -0,0 +1,11 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ public abstract class SmimeAttributes
+ {
+ public static readonly DerObjectIdentifier SmimeCapabilities = PkcsObjectIdentifiers.Pkcs9AtSmimeCapabilities;
+ public static readonly DerObjectIdentifier EncrypKeyPref = PkcsObjectIdentifiers.IdAAEncrypKeyPref;
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/smime/SMIMECapabilities.cs b/iTechSharp/srcbc/asn1/smime/SMIMECapabilities.cs
new file mode 100644
index 0000000..62a3774
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/smime/SMIMECapabilities.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ /**
+ * Handler class for dealing with S/MIME Capabilities
+ */
+ public class SmimeCapabilities
+ : Asn1Encodable
+ {
+ /**
+ * general preferences
+ */
+ public static readonly DerObjectIdentifier PreferSignedData = PkcsObjectIdentifiers.PreferSignedData;
+ public static readonly DerObjectIdentifier CannotDecryptAny = PkcsObjectIdentifiers.CannotDecryptAny;
+ public static readonly DerObjectIdentifier SmimeCapabilitesVersions = PkcsObjectIdentifiers.SmimeCapabilitiesVersions;
+
+ /**
+ * encryption algorithms preferences
+ */
+ public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7");
+ public static readonly DerObjectIdentifier DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc;
+ public static readonly DerObjectIdentifier RC2Cbc = PkcsObjectIdentifiers.RC2Cbc;
+
+ private Asn1Sequence capabilities;
+
+ /**
+ * return an Attr object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static SmimeCapabilities GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is SmimeCapabilities)
+ {
+ return (SmimeCapabilities) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SmimeCapabilities((Asn1Sequence) obj);
+ }
+
+ if (obj is AttributeX509)
+ {
+ return new SmimeCapabilities(
+ (Asn1Sequence)(((AttributeX509) obj).AttrValues[0]));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public SmimeCapabilities(
+ Asn1Sequence seq)
+ {
+ capabilities = seq;
+ }
+
+ /**
+ * returns an ArrayList with 0 or more objects of all the capabilities
+ * matching the passed in capability Oid. If the Oid passed is null the
+ * entire set is returned.
+ */
+ public ArrayList GetCapabilities(
+ DerObjectIdentifier capability)
+ {
+ ArrayList list = new ArrayList();
+
+ if (capability == null)
+ {
+ foreach (object o in capabilities)
+ {
+ SmimeCapability cap = SmimeCapability.GetInstance(o);
+
+ list.Add(cap);
+ }
+ }
+ else
+ {
+ foreach (object o in capabilities)
+ {
+ SmimeCapability cap = SmimeCapability.GetInstance(o);
+
+ if (capability.Equals(cap.CapabilityID))
+ {
+ list.Add(cap);
+ }
+ }
+ }
+
+ return list;
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * SMIMECapabilities ::= Sequence OF SMIMECapability
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return capabilities;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/smime/SMIMECapabilitiesAttribute.cs b/iTechSharp/srcbc/asn1/smime/SMIMECapabilitiesAttribute.cs
new file mode 100644
index 0000000..310c478
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/smime/SMIMECapabilitiesAttribute.cs
@@ -0,0 +1,16 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ public class SmimeCapabilitiesAttribute
+ : AttributeX509
+ {
+ public SmimeCapabilitiesAttribute(
+ SmimeCapabilityVector capabilities)
+ : base(SmimeAttributes.SmimeCapabilities,
+ new DerSet(new DerSequence(capabilities.ToAsn1EncodableVector())))
+ {
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/smime/SMIMECapability.cs b/iTechSharp/srcbc/asn1/smime/SMIMECapability.cs
new file mode 100644
index 0000000..5709cb8
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/smime/SMIMECapability.cs
@@ -0,0 +1,101 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ public class SmimeCapability
+ : Asn1Encodable
+ {
+ /**
+ * general preferences
+ */
+ public static readonly DerObjectIdentifier PreferSignedData = PkcsObjectIdentifiers.PreferSignedData;
+ public static readonly DerObjectIdentifier CannotDecryptAny = PkcsObjectIdentifiers.CannotDecryptAny;
+ public static readonly DerObjectIdentifier SmimeCapabilitiesVersions = PkcsObjectIdentifiers.SmimeCapabilitiesVersions;
+
+ /**
+ * encryption algorithms preferences
+ */
+ public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7");
+ public static readonly DerObjectIdentifier DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc;
+ public static readonly DerObjectIdentifier RC2Cbc = PkcsObjectIdentifiers.RC2Cbc;
+
+ private DerObjectIdentifier capabilityID;
+ private Asn1Object parameters;
+
+ public SmimeCapability(
+ Asn1Sequence seq)
+ {
+ capabilityID = (DerObjectIdentifier) seq[0].ToAsn1Object();
+
+ if (seq.Count > 1)
+ {
+ parameters = seq[1].ToAsn1Object();
+ }
+ }
+
+ public SmimeCapability(
+ DerObjectIdentifier capabilityID,
+ Asn1Encodable parameters)
+ {
+ if (capabilityID == null)
+ throw new ArgumentNullException("capabilityID");
+
+ this.capabilityID = capabilityID;
+
+ if (parameters != null)
+ {
+ this.parameters = parameters.ToAsn1Object();
+ }
+ }
+
+ public static SmimeCapability GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is SmimeCapability)
+ {
+ return (SmimeCapability) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SmimeCapability((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid SmimeCapability");
+ }
+
+ public DerObjectIdentifier CapabilityID
+ {
+ get { return capabilityID; }
+ }
+
+ public Asn1Object Parameters
+ {
+ get { return parameters; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * SMIMECapability ::= Sequence {
+ * capabilityID OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY capabilityID OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(capabilityID);
+
+ if (parameters != null)
+ {
+ v.Add(parameters);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/smime/SMIMECapabilityVector.cs b/iTechSharp/srcbc/asn1/smime/SMIMECapabilityVector.cs
new file mode 100644
index 0000000..842825b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/smime/SMIMECapabilityVector.cs
@@ -0,0 +1,37 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ /**
+ * Handler for creating a vector S/MIME Capabilities
+ */
+ public class SmimeCapabilityVector
+ {
+ private readonly Asn1EncodableVector capabilities = new Asn1EncodableVector();
+
+ public void AddCapability(
+ DerObjectIdentifier capability)
+ {
+ capabilities.Add(new DerSequence(capability));
+ }
+
+ public void AddCapability(
+ DerObjectIdentifier capability,
+ int value)
+ {
+ capabilities.Add(new DerSequence(capability, new DerInteger(value)));
+ }
+
+ public void AddCapability(
+ DerObjectIdentifier capability,
+ Asn1Encodable parameters)
+ {
+ capabilities.Add(new DerSequence(capability, parameters));
+ }
+
+ public Asn1EncodableVector ToAsn1EncodableVector()
+ {
+ return capabilities;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs b/iTechSharp/srcbc/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs
new file mode 100644
index 0000000..19c5fd7
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs
@@ -0,0 +1,44 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ /**
+ * The SmimeEncryptionKeyPreference object.
+ *
+ * SmimeEncryptionKeyPreference ::= CHOICE {
+ * issuerAndSerialNumber [0] IssuerAndSerialNumber,
+ * receipentKeyId [1] RecipientKeyIdentifier,
+ * subjectAltKeyIdentifier [2] SubjectKeyIdentifier
+ * }
+ *
+ */
+ public class SmimeEncryptionKeyPreferenceAttribute
+ : AttributeX509
+ {
+ public SmimeEncryptionKeyPreferenceAttribute(
+ IssuerAndSerialNumber issAndSer)
+ : base(SmimeAttributes.EncrypKeyPref,
+ new DerSet(new DerTaggedObject(false, 0, issAndSer)))
+ {
+ }
+
+ public SmimeEncryptionKeyPreferenceAttribute(
+ RecipientKeyIdentifier rKeyID)
+ : base(SmimeAttributes.EncrypKeyPref,
+ new DerSet(new DerTaggedObject(false, 1, rKeyID)))
+ {
+ }
+
+ /**
+ * @param sKeyId the subjectKeyIdentifier value (normally the X.509 one)
+ */
+ public SmimeEncryptionKeyPreferenceAttribute(
+ Asn1OctetString sKeyID)
+ : base(SmimeAttributes.EncrypKeyPref,
+ new DerSet(new DerTaggedObject(false, 2, sKeyID)))
+ {
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/teletrust/TeleTrusTNamedCurves.cs b/iTechSharp/srcbc/asn1/teletrust/TeleTrusTNamedCurves.cs
new file mode 100644
index 0000000..25032dd
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/teletrust/TeleTrusTNamedCurves.cs
@@ -0,0 +1,427 @@
+using System.Collections;
+using System.Globalization;
+
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Utilities.Collections;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Asn1.TeleTrust
+{
+ /**
+ * elliptic curves defined in "ECC Brainpool Standard Curves and Curve Generation"
+ * http://www.ecc-brainpool.org/download/draft_pkix_additional_ecc_dp.txt
+ */
+ public class TeleTrusTNamedCurves
+ {
+ internal class BrainpoolP160r1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP160r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP160r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q
+ new BigInteger("340E7BE2A280EB74E2BE61BADA745D97E8F7C300", 16), // a
+ new BigInteger("1E589A8595423412134FAA2DBDEC95C8D8675E58", 16)); // b
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321")), // G
+ new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP160t1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP160t1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP160t1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ // new BigInteger("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B", 16), // Z
+ new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q
+ new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620C", 16), // a'
+ new BigInteger("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", 16)); // b'
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD")), // G
+ new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP192r1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP192r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP192r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q
+ new BigInteger("6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", 16), // a
+ new BigInteger("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16)); // b
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F")), // G
+ new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP192t1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP192t1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP192t1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ //new BigInteger("1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB") //Z
+ new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q
+ new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294", 16), // a'
+ new BigInteger("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", 16)); // b'
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9")), // G'
+ new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP224r1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP224r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP224r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q
+ new BigInteger("68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", 16), // a
+ new BigInteger("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16)); // b
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD")), // G
+ new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16), //n
+ new BigInteger("01", 16)); // n
+ }
+ }
+
+ internal class BrainpoolP224t1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP224t1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP224t1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ //new BigInteger("2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F") //Z
+ new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q
+ new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC", 16), // a'
+ new BigInteger("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", 16)); // b'
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C")), // G'
+ new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP256r1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP256r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP256r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q
+ new BigInteger("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", 16), // a
+ new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16)); // b
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997")), // G
+ new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP256t1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP256t1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP256t1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ //new BigInteger("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0") //Z
+ new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q
+ new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374", 16), // a'
+ new BigInteger("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16)); // b'
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE")), // G'
+ new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP320r1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP320r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP320r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q
+ new BigInteger("3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", 16), // a
+ new BigInteger("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16)); // b
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1")), // G
+ new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP320t1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP320t1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP320t1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ //new BigInteger("15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18FEFC3E5AB7496F3C7B1") //Z
+ new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q
+ new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24", 16), // a'
+ new BigInteger("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", 16)); // b'
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3")), // G'
+ new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP384r1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP384r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP384r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q
+ new BigInteger("7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", 16), // a
+ new BigInteger("4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16)); // b
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315")), // G
+ new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP384t1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP384t1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP384t1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ //new BigInteger("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C") //Z
+ new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q
+ new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50", 16), // a'
+ new BigInteger("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16)); // b'
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928")), // G'
+ new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP512r1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP512r1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP512r1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q
+ new BigInteger("7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", 16), // a
+ new BigInteger("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16)); // b
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892")), // G
+ new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+ internal class BrainpoolP512t1Holder
+ : X9ECParametersHolder
+ {
+ private BrainpoolP512t1Holder() {}
+
+ internal static readonly X9ECParametersHolder Instance = new BrainpoolP512t1Holder();
+
+ protected override X9ECParameters CreateParameters()
+ {
+ ECCurve curve = new FpCurve(
+ //new BigInteger("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB") //Z
+ new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q
+ new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0", 16), // a'
+ new BigInteger("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16)); // b'
+
+ return new X9ECParameters(
+ curve,
+ curve.DecodePoint(Hex.Decode("04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332")), // G'
+ new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16), //n
+ new BigInteger("01", 16)); // h
+ }
+ }
+
+
+ private static readonly Hashtable objIds = new Hashtable();
+ private static readonly Hashtable curves = new Hashtable();
+ private static readonly Hashtable names = new Hashtable();
+
+ private static void DefineCurve(
+ string name,
+ DerObjectIdentifier oid,
+ X9ECParametersHolder holder)
+ {
+ objIds.Add(name, oid);
+ names.Add(oid, name);
+ curves.Add(oid, holder);
+ }
+
+ static TeleTrusTNamedCurves()
+ {
+ DefineCurve("brainpoolp160r1", TeleTrusTObjectIdentifiers.BrainpoolP160R1, BrainpoolP160r1Holder.Instance);
+ DefineCurve("brainpoolp160t1", TeleTrusTObjectIdentifiers.BrainpoolP160T1, BrainpoolP160t1Holder.Instance);
+ DefineCurve("brainpoolp192r1", TeleTrusTObjectIdentifiers.BrainpoolP192R1, BrainpoolP192r1Holder.Instance);
+ DefineCurve("brainpoolp192t1", TeleTrusTObjectIdentifiers.BrainpoolP192T1, BrainpoolP192t1Holder.Instance);
+ DefineCurve("brainpoolp224r1", TeleTrusTObjectIdentifiers.BrainpoolP224R1, BrainpoolP224r1Holder.Instance);
+ DefineCurve("brainpoolp224t1", TeleTrusTObjectIdentifiers.BrainpoolP224T1, BrainpoolP224t1Holder.Instance);
+ DefineCurve("brainpoolp256r1", TeleTrusTObjectIdentifiers.BrainpoolP256R1, BrainpoolP256r1Holder.Instance);
+ DefineCurve("brainpoolp256t1", TeleTrusTObjectIdentifiers.BrainpoolP256T1, BrainpoolP256t1Holder.Instance);
+ DefineCurve("brainpoolp320r1", TeleTrusTObjectIdentifiers.BrainpoolP320R1, BrainpoolP320r1Holder.Instance);
+ DefineCurve("brainpoolp320t1", TeleTrusTObjectIdentifiers.BrainpoolP320T1, BrainpoolP320t1Holder.Instance);
+ DefineCurve("brainpoolp384r1", TeleTrusTObjectIdentifiers.BrainpoolP384R1, BrainpoolP384r1Holder.Instance);
+ DefineCurve("brainpoolp384t1", TeleTrusTObjectIdentifiers.BrainpoolP384T1, BrainpoolP384t1Holder.Instance);
+ DefineCurve("brainpoolp512r1", TeleTrusTObjectIdentifiers.BrainpoolP512R1, BrainpoolP512r1Holder.Instance);
+ DefineCurve("brainpoolp512t1", TeleTrusTObjectIdentifiers.BrainpoolP512T1, BrainpoolP512t1Holder.Instance);
+ }
+
+ public static X9ECParameters GetByName(
+ string name)
+ {
+ DerObjectIdentifier oid = (DerObjectIdentifier)
+ objIds[name.ToLower(CultureInfo.InvariantCulture)];
+
+ return oid == null ? null : GetByOid(oid);
+ }
+
+ /**
+ * return the X9ECParameters object for the named curve represented by
+ * the passed in object identifier. Null if the curve isn't present.
+ *
+ * @param oid an object identifier representing a named curve, if present.
+ */
+ public static X9ECParameters GetByOid(
+ DerObjectIdentifier oid)
+ {
+ X9ECParametersHolder holder = (X9ECParametersHolder) curves[oid];
+
+ return holder == null ? null : holder.Parameters;
+ }
+
+ /**
+ * return the object identifier signified by the passed in name. Null
+ * if there is no object identifier associated with name.
+ *
+ * @return the object identifier associated with name, if present.
+ */
+ public static DerObjectIdentifier GetOid(
+ string name)
+ {
+ return (DerObjectIdentifier) objIds[name.ToLower(CultureInfo.InvariantCulture)];
+ }
+
+ /**
+ * return the named curve name represented by the given object identifier.
+ */
+ public static string GetName(
+ DerObjectIdentifier oid)
+ {
+ return (string) names[oid];
+ }
+
+
+ /**
+ * returns an enumeration containing the name strings for curves
+ * contained in this structure.
+ */
+ public static IEnumerable Names
+ {
+ get { return new EnumerableProxy(objIds.Keys); }
+ }
+
+ public static DerObjectIdentifier GetOid(
+ short curvesize,
+ bool twisted)
+ {
+ return GetOid("brainpoolP" + curvesize + (twisted ? "t" : "r") + "1");
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/teletrust/TeleTrusTObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/teletrust/TeleTrusTObjectIdentifiers.cs
new file mode 100644
index 0000000..56e7084
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/teletrust/TeleTrusTObjectIdentifiers.cs
@@ -0,0 +1,45 @@
+namespace Org.BouncyCastle.Asn1.TeleTrust
+{
+ public sealed class TeleTrusTObjectIdentifiers
+ {
+ private TeleTrusTObjectIdentifiers()
+ {
+ }
+
+ public static readonly DerObjectIdentifier TeleTrusTAlgorithm = new DerObjectIdentifier("1.3.36.3");
+
+ public static readonly DerObjectIdentifier RipeMD160 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.1");
+ public static readonly DerObjectIdentifier RipeMD128 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.2");
+ public static readonly DerObjectIdentifier RipeMD256 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.3");
+
+ public static readonly DerObjectIdentifier TeleTrusTRsaSignatureAlgorithm = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.1");
+
+ public static readonly DerObjectIdentifier RsaSignatureWithRipeMD160 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".2");
+ public static readonly DerObjectIdentifier RsaSignatureWithRipeMD128 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".3");
+ public static readonly DerObjectIdentifier RsaSignatureWithRipeMD256 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".4");
+
+ public static readonly DerObjectIdentifier ECSign = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.2");
+
+ public static readonly DerObjectIdentifier ECSignWithSha1 = new DerObjectIdentifier(ECSign + ".1");
+ public static readonly DerObjectIdentifier ECSignWithRipeMD160 = new DerObjectIdentifier(ECSign + ".2");
+
+ public static readonly DerObjectIdentifier EccBrainpool = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.2.8");
+ public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier(EccBrainpool + ".1");
+ public static readonly DerObjectIdentifier VersionOne = new DerObjectIdentifier(EllipticCurve + ".1");
+
+ public static readonly DerObjectIdentifier BrainpoolP160R1 = new DerObjectIdentifier(VersionOne + ".1");
+ public static readonly DerObjectIdentifier BrainpoolP160T1 = new DerObjectIdentifier(VersionOne + ".2");
+ public static readonly DerObjectIdentifier BrainpoolP192R1 = new DerObjectIdentifier(VersionOne + ".3");
+ public static readonly DerObjectIdentifier BrainpoolP192T1 = new DerObjectIdentifier(VersionOne + ".4");
+ public static readonly DerObjectIdentifier BrainpoolP224R1 = new DerObjectIdentifier(VersionOne + ".5");
+ public static readonly DerObjectIdentifier BrainpoolP224T1 = new DerObjectIdentifier(VersionOne + ".6");
+ public static readonly DerObjectIdentifier BrainpoolP256R1 = new DerObjectIdentifier(VersionOne + ".7");
+ public static readonly DerObjectIdentifier BrainpoolP256T1 = new DerObjectIdentifier(VersionOne + ".8");
+ public static readonly DerObjectIdentifier BrainpoolP320R1 = new DerObjectIdentifier(VersionOne + ".9");
+ public static readonly DerObjectIdentifier BrainpoolP320T1 = new DerObjectIdentifier(VersionOne + ".10");
+ public static readonly DerObjectIdentifier BrainpoolP384R1 = new DerObjectIdentifier(VersionOne + ".11");
+ public static readonly DerObjectIdentifier BrainpoolP384T1 = new DerObjectIdentifier(VersionOne + ".12");
+ public static readonly DerObjectIdentifier BrainpoolP512R1 = new DerObjectIdentifier(VersionOne + ".13");
+ public static readonly DerObjectIdentifier BrainpoolP512T1 = new DerObjectIdentifier(VersionOne + ".14");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/tsp/Accuracy.cs b/iTechSharp/srcbc/asn1/tsp/Accuracy.cs
new file mode 100644
index 0000000..a193f52
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/tsp/Accuracy.cs
@@ -0,0 +1,149 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Tsp
+{
+ public class Accuracy
+ : Asn1Encodable
+ {
+ private readonly DerInteger seconds;
+ private readonly DerInteger millis;
+ private readonly DerInteger micros;
+
+ // constants
+ protected const int MinMillis = 1;
+ protected const int MaxMillis = 999;
+ protected const int MinMicros = 1;
+ protected const int MaxMicros = 999;
+
+ public Accuracy(
+ DerInteger seconds,
+ DerInteger millis,
+ DerInteger micros)
+ {
+ //Verifications
+ if (millis != null
+ && (millis.Value.IntValue < MinMillis
+ || millis.Value.IntValue > MaxMillis))
+ {
+ throw new ArgumentException(
+ "Invalid millis field : not in (1..999)");
+ }
+
+ if (micros != null
+ && (micros.Value.IntValue < MinMicros
+ || micros.Value.IntValue > MaxMicros))
+ {
+ throw new ArgumentException(
+ "Invalid micros field : not in (1..999)");
+ }
+
+ this.seconds = seconds;
+ this.millis = millis;
+ this.micros = micros;
+ }
+
+ private Accuracy(
+ Asn1Sequence seq)
+ {
+ for (int i = 0; i < seq.Count; ++i)
+ {
+ // seconds
+ if (seq[i] is DerInteger)
+ {
+ seconds = (DerInteger) seq[i];
+ }
+ else if (seq[i] is DerTaggedObject)
+ {
+ DerTaggedObject extra = (DerTaggedObject) seq[i];
+
+ switch (extra.TagNo)
+ {
+ case 0:
+ millis = DerInteger.GetInstance(extra, false);
+ if (millis.Value.IntValue < MinMillis
+ || millis.Value.IntValue > MaxMillis)
+ {
+ throw new ArgumentException(
+ "Invalid millis field : not in (1..999).");
+ }
+ break;
+ case 1:
+ micros = DerInteger.GetInstance(extra, false);
+ if (micros.Value.IntValue < MinMicros
+ || micros.Value.IntValue > MaxMicros)
+ {
+ throw new ArgumentException(
+ "Invalid micros field : not in (1..999).");
+ }
+ break;
+ default:
+ throw new ArgumentException("Invalig tag number");
+ }
+ }
+ }
+ }
+
+ public static Accuracy GetInstance(
+ object o)
+ {
+ if (o == null || o is Accuracy)
+ {
+ return (Accuracy) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new Accuracy((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException(
+ "Unknown object in 'Accuracy' factory: " + o.GetType().FullName);
+ }
+
+ public DerInteger Seconds
+ {
+ get { return seconds; }
+ }
+
+ public DerInteger Millis
+ {
+ get { return millis; }
+ }
+
+ public DerInteger Micros
+ {
+ get { return micros; }
+ }
+
+ /**
+ *
+ * Accuracy ::= SEQUENCE {
+ * seconds INTEGER OPTIONAL,
+ * millis [0] INTEGER (1..999) OPTIONAL,
+ * micros [1] INTEGER (1..999) OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (seconds != null)
+ {
+ v.Add(seconds);
+ }
+
+ if (millis != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, millis));
+ }
+
+ if (micros != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, micros));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/tsp/MessageImprint.cs b/iTechSharp/srcbc/asn1/tsp/MessageImprint.cs
new file mode 100644
index 0000000..0933bae
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/tsp/MessageImprint.cs
@@ -0,0 +1,74 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Tsp
+{
+ public class MessageImprint
+ : Asn1Encodable
+ {
+ private readonly AlgorithmIdentifier hashAlgorithm;
+ private readonly byte[] hashedMessage;
+
+ /**
+ * @param o
+ * @return a MessageImprint object.
+ */
+ public static MessageImprint GetInstance(
+ object o)
+ {
+ if (o == null || o is MessageImprint)
+ {
+ return (MessageImprint) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new MessageImprint((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException(
+ "Unknown object in 'MessageImprint' factory: " + o.GetType().FullName);
+ }
+
+ private MessageImprint(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]);
+ this.hashedMessage = Asn1OctetString.GetInstance(seq[1]).GetOctets();
+ }
+
+ public MessageImprint(
+ AlgorithmIdentifier hashAlgorithm,
+ byte[] hashedMessage)
+ {
+ this.hashAlgorithm = hashAlgorithm;
+ this.hashedMessage = hashedMessage;
+ }
+
+ public AlgorithmIdentifier HashAlgorithm
+ {
+ get { return hashAlgorithm; }
+ }
+
+ public byte[] GetHashedMessage()
+ {
+ return hashedMessage;
+ }
+
+ /**
+ *
+ * MessageImprint ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * hashedMessage OCTET STRING }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(hashAlgorithm, new DerOctetString(hashedMessage));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/tsp/TSTInfo.cs b/iTechSharp/srcbc/asn1/tsp/TSTInfo.cs
new file mode 100644
index 0000000..c05c670
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/tsp/TSTInfo.cs
@@ -0,0 +1,244 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Tsp
+{
+ public class TstInfo
+ : Asn1Encodable
+ {
+ private readonly DerInteger version;
+ private readonly DerObjectIdentifier tsaPolicyId;
+ private readonly MessageImprint messageImprint;
+ private readonly DerInteger serialNumber;
+ private readonly DerGeneralizedTime genTime;
+ private readonly Accuracy accuracy;
+ private readonly DerBoolean ordering;
+ private readonly DerInteger nonce;
+ private readonly GeneralName tsa;
+ private readonly X509Extensions extensions;
+
+ public static TstInfo GetInstance(
+ object o)
+ {
+ if (o == null || o is TstInfo)
+ {
+ return (TstInfo) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new TstInfo((Asn1Sequence) o);
+ }
+
+ if (o is Asn1OctetString)
+ {
+ try
+ {
+ byte[] octets = ((Asn1OctetString)o).GetOctets();
+ return GetInstance(Asn1Object.FromByteArray(octets));
+ }
+ catch (IOException)
+ {
+ throw new ArgumentException(
+ "Bad object format in 'TstInfo' factory.");
+ }
+ }
+
+ throw new ArgumentException(
+ "Unknown object in 'TstInfo' factory: " + o.GetType().FullName);
+ }
+
+ private TstInfo(
+ Asn1Sequence seq)
+ {
+ IEnumerator e = seq.GetEnumerator();
+
+ // version
+ e.MoveNext();
+ version = DerInteger.GetInstance(e.Current);
+
+ // tsaPolicy
+ e.MoveNext();
+ tsaPolicyId = DerObjectIdentifier.GetInstance(e.Current);
+
+ // messageImprint
+ e.MoveNext();
+ messageImprint = MessageImprint.GetInstance(e.Current);
+
+ // serialNumber
+ e.MoveNext();
+ serialNumber = DerInteger.GetInstance(e.Current);
+
+ // genTime
+ e.MoveNext();
+ genTime = DerGeneralizedTime.GetInstance(e.Current);
+
+ // default for ordering
+ ordering = DerBoolean.False;
+
+ while (e.MoveNext())
+ {
+ Asn1Object o = (Asn1Object) e.Current;
+
+ if (o is Asn1TaggedObject)
+ {
+ DerTaggedObject tagged = (DerTaggedObject) o;
+
+ switch (tagged.TagNo)
+ {
+ case 0:
+ tsa = GeneralName.GetInstance(tagged, true);
+ break;
+ case 1:
+ extensions = X509Extensions.GetInstance(tagged, false);
+ break;
+ default:
+ throw new ArgumentException("Unknown tag value " + tagged.TagNo);
+ }
+ }
+
+ if (o is DerSequence)
+ {
+ accuracy = Accuracy.GetInstance(o);
+ }
+
+ if (o is DerBoolean)
+ {
+ ordering = DerBoolean.GetInstance(o);
+ }
+
+ if (o is DerInteger)
+ {
+ nonce = DerInteger.GetInstance(o);
+ }
+ }
+ }
+
+ public TstInfo(
+ DerObjectIdentifier tsaPolicyId,
+ MessageImprint messageImprint,
+ DerInteger serialNumber,
+ DerGeneralizedTime genTime,
+ Accuracy accuracy,
+ DerBoolean ordering,
+ DerInteger nonce,
+ GeneralName tsa,
+ X509Extensions extensions)
+ {
+ this.version = new DerInteger(1);
+ this.tsaPolicyId = tsaPolicyId;
+ this.messageImprint = messageImprint;
+ this.serialNumber = serialNumber;
+ this.genTime = genTime;
+ this.accuracy = accuracy;
+ this.ordering = ordering;
+ this.nonce = nonce;
+ this.tsa = tsa;
+ this.extensions = extensions;
+ }
+
+ public MessageImprint MessageImprint
+ {
+ get { return messageImprint; }
+ }
+
+ public DerObjectIdentifier Policy
+ {
+ get { return tsaPolicyId; }
+ }
+
+ public DerInteger SerialNumber
+ {
+ get { return serialNumber; }
+ }
+
+ public Accuracy Accuracy
+ {
+ get { return accuracy; }
+ }
+
+ public DerGeneralizedTime GenTime
+ {
+ get { return genTime; }
+ }
+
+ public DerBoolean Ordering
+ {
+ get { return ordering; }
+ }
+
+ public DerInteger Nonce
+ {
+ get { return nonce; }
+ }
+
+ public GeneralName Tsa
+ {
+ get { return tsa; }
+ }
+
+ public X509Extensions Extensions
+ {
+ get { return extensions; }
+ }
+
+ /**
+ *
+ *
+ * TstInfo ::= SEQUENCE {
+ * version INTEGER { v1(1) },
+ * policy TSAPolicyId,
+ * messageImprint MessageImprint,
+ * -- MUST have the same value as the similar field in
+ * -- TimeStampReq
+ * serialNumber INTEGER,
+ * -- Time-Stamping users MUST be ready to accommodate integers
+ * -- up to 160 bits.
+ * genTime GeneralizedTime,
+ * accuracy Accuracy OPTIONAL,
+ * ordering BOOLEAN DEFAULT FALSE,
+ * nonce INTEGER OPTIONAL,
+ * -- MUST be present if the similar field was present
+ * -- in TimeStampReq. In that case it MUST have the same value.
+ * tsa [0] GeneralName OPTIONAL,
+ * extensions [1] IMPLICIT Extensions OPTIONAL }
+ *
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, tsaPolicyId, messageImprint, serialNumber, genTime);
+
+ if (accuracy != null)
+ {
+ v.Add(accuracy);
+ }
+
+ if (ordering != null && ordering.IsTrue)
+ {
+ v.Add(ordering);
+ }
+
+ if (nonce != null)
+ {
+ v.Add(nonce);
+ }
+
+ if (tsa != null)
+ {
+ v.Add(new DerTaggedObject(true, 0, tsa));
+ }
+
+ if (extensions != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, extensions));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/tsp/TimeStampReq.cs b/iTechSharp/srcbc/asn1/tsp/TimeStampReq.cs
new file mode 100644
index 0000000..55e973e
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/tsp/TimeStampReq.cs
@@ -0,0 +1,164 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Tsp
+{
+ public class TimeStampReq
+ : Asn1Encodable
+ {
+ private readonly DerInteger version;
+ private readonly MessageImprint messageImprint;
+ private readonly DerObjectIdentifier tsaPolicy;
+ private readonly DerInteger nonce;
+ private readonly DerBoolean certReq;
+ private readonly X509Extensions extensions;
+
+ public static TimeStampReq GetInstance(
+ object o)
+ {
+ if (o == null || o is TimeStampReq)
+ {
+ return (TimeStampReq) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new TimeStampReq((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException(
+ "Unknown object in 'TimeStampReq' factory: " + o.GetType().FullName);
+ }
+
+ private TimeStampReq(
+ Asn1Sequence seq)
+ {
+ int nbObjects = seq.Count;
+ int seqStart = 0;
+
+ // version
+ version = DerInteger.GetInstance(seq[seqStart++]);
+
+ // messageImprint
+ messageImprint = MessageImprint.GetInstance(seq[seqStart++]);
+
+ for (int opt = seqStart; opt < nbObjects; opt++)
+ {
+ // tsaPolicy
+ if (seq[opt] is DerObjectIdentifier)
+ {
+ tsaPolicy = DerObjectIdentifier.GetInstance(seq[opt]);
+ }
+ // nonce
+ else if (seq[opt] is DerInteger)
+ {
+ nonce = DerInteger.GetInstance(seq[opt]);
+ }
+ // certReq
+ else if (seq[opt] is DerBoolean)
+ {
+ certReq = DerBoolean.GetInstance(seq[opt]);
+ }
+ // extensions
+ else if (seq[opt] is Asn1TaggedObject)
+ {
+ Asn1TaggedObject tagged = (Asn1TaggedObject) seq[opt];
+ if (tagged.TagNo == 0)
+ {
+ extensions = X509Extensions.GetInstance(tagged, false);
+ }
+ }
+ }
+ }
+
+ public TimeStampReq(
+ MessageImprint messageImprint,
+ DerObjectIdentifier tsaPolicy,
+ DerInteger nonce,
+ DerBoolean certReq,
+ X509Extensions extensions)
+ {
+ // default
+ this.version = new DerInteger(1);
+
+ this.messageImprint = messageImprint;
+ this.tsaPolicy = tsaPolicy;
+ this.nonce = nonce;
+ this.certReq = certReq;
+ this.extensions = extensions;
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public MessageImprint MessageImprint
+ {
+ get { return messageImprint; }
+ }
+
+ public DerObjectIdentifier ReqPolicy
+ {
+ get { return tsaPolicy; }
+ }
+
+ public DerInteger Nonce
+ {
+ get { return nonce; }
+ }
+
+ public DerBoolean CertReq
+ {
+ get { return certReq; }
+ }
+
+ public X509Extensions Extensions
+ {
+ get { return extensions; }
+ }
+
+ /**
+ *
+ * TimeStampReq ::= SEQUENCE {
+ * version INTEGER { v1(1) },
+ * messageImprint MessageImprint,
+ * --a hash algorithm OID and the hash value of the data to be
+ * --time-stamped
+ * reqPolicy TSAPolicyId OPTIONAL,
+ * nonce INTEGER OPTIONAL,
+ * certReq BOOLEAN DEFAULT FALSE,
+ * extensions [0] IMPLICIT Extensions OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, messageImprint);
+
+ if (tsaPolicy != null)
+ {
+ v.Add(tsaPolicy);
+ }
+
+ if (nonce != null)
+ {
+ v.Add(nonce);
+ }
+
+ if (certReq != null && certReq.IsTrue)
+ {
+ v.Add(certReq);
+ }
+
+ if (extensions != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, extensions));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/tsp/TimeStampResp.cs b/iTechSharp/srcbc/asn1/tsp/TimeStampResp.cs
new file mode 100644
index 0000000..f26fb30
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/tsp/TimeStampResp.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.Cmp;
+using Org.BouncyCastle.Asn1.Cms;
+
+namespace Org.BouncyCastle.Asn1.Tsp
+{
+ public class TimeStampResp
+ : Asn1Encodable
+ {
+ private readonly PkiStatusInfo pkiStatusInfo;
+ private readonly ContentInfo timeStampToken;
+
+ public static TimeStampResp GetInstance(
+ object o)
+ {
+ if (o == null || o is TimeStampResp)
+ {
+ return (TimeStampResp) o;
+ }
+
+ if (o is Asn1Sequence)
+ {
+ return new TimeStampResp((Asn1Sequence) o);
+ }
+
+ throw new ArgumentException(
+ "Unknown object in 'TimeStampResp' factory: " + o.GetType().FullName);
+ }
+
+ private TimeStampResp(
+ Asn1Sequence seq)
+ {
+ this.pkiStatusInfo = PkiStatusInfo.GetInstance(seq[0]);
+
+ if (seq.Count > 1)
+ {
+ this.timeStampToken = ContentInfo.GetInstance(seq[1]);
+ }
+ }
+
+ public TimeStampResp(
+ PkiStatusInfo pkiStatusInfo,
+ ContentInfo timeStampToken)
+ {
+ this.pkiStatusInfo = pkiStatusInfo;
+ this.timeStampToken = timeStampToken;
+ }
+
+ public PkiStatusInfo Status
+ {
+ get { return pkiStatusInfo; }
+ }
+
+ public ContentInfo TimeStampToken
+ {
+ get { return timeStampToken; }
+ }
+
+ /**
+ *
+ * TimeStampResp ::= SEQUENCE {
+ * status PkiStatusInfo,
+ * timeStampToken TimeStampToken OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(pkiStatusInfo);
+
+ if (timeStampToken != null)
+ {
+ v.Add(timeStampToken);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/util/Asn1Dump.cs b/iTechSharp/srcbc/asn1/util/Asn1Dump.cs
new file mode 100644
index 0000000..3f4b995
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/util/Asn1Dump.cs
@@ -0,0 +1,250 @@
+using System;
+using System.Collections;
+using System.Text;
+
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Asn1.Utilities
+{
+ public sealed class Asn1Dump
+ {
+ private static readonly string NewLine = Platform.NewLine;
+
+ private Asn1Dump()
+ {
+ }
+
+ private const string Tab = " ";
+
+ /**
+ * dump a Der object as a formatted string with indentation
+ *
+ * @param obj the Asn1Object to be dumped out.
+ */
+ private static string AsString(
+ string indent,
+ Asn1Object obj)
+ {
+ if (obj is Asn1Sequence)
+ {
+ StringBuilder buf = new StringBuilder(indent);
+
+ string tab = indent + Tab;
+
+ if (obj is BerSequence)
+ {
+ buf.Append("BER Sequence");
+ }
+ else if (obj is DerSequence)
+ {
+ buf.Append("DER Sequence");
+ }
+ else
+ {
+ buf.Append("Sequence");
+ }
+
+ buf.Append(NewLine);
+
+ foreach (Asn1Encodable o in ((Asn1Sequence)obj))
+ {
+ if (o == null || o is Asn1Null)
+ {
+ buf.Append(tab);
+ buf.Append("NULL");
+ buf.Append(NewLine);
+ }
+ else
+ {
+ buf.Append(AsString(tab, o.ToAsn1Object()));
+ }
+ }
+ return buf.ToString();
+ }
+ else if (obj is DerTaggedObject)
+ {
+ StringBuilder buf = new StringBuilder();
+ string tab = indent + Tab;
+
+ buf.Append(indent);
+ if (obj is BerTaggedObject)
+ {
+ buf.Append("BER Tagged [");
+ }
+ else
+ {
+ buf.Append("Tagged [");
+ }
+
+ DerTaggedObject o = (DerTaggedObject)obj;
+
+ buf.Append(((int)o.TagNo).ToString());
+ buf.Append(']');
+
+ if (!o.IsExplicit())
+ {
+ buf.Append(" IMPLICIT ");
+ }
+
+ buf.Append(NewLine);
+
+ if (o.IsEmpty())
+ {
+ buf.Append(tab);
+ buf.Append("EMPTY");
+ buf.Append(NewLine);
+ }
+ else
+ {
+ buf.Append(AsString(tab, o.GetObject()));
+ }
+
+ return buf.ToString();
+ }
+ else if (obj is BerSet)
+ {
+ StringBuilder buf = new StringBuilder();
+ string tab = indent + Tab;
+
+ buf.Append(indent);
+ buf.Append("BER Set");
+ buf.Append(NewLine);
+
+ foreach (Asn1Encodable o in ((Asn1Set)obj))
+ {
+ if (o == null)
+ {
+ buf.Append(tab);
+ buf.Append("NULL");
+ buf.Append(NewLine);
+ }
+ else
+ {
+ buf.Append(AsString(tab, o.ToAsn1Object()));
+ }
+ }
+
+ return buf.ToString();
+ }
+ else if (obj is DerSet)
+ {
+ StringBuilder buf = new StringBuilder();
+ string tab = indent + Tab;
+
+ buf.Append(indent);
+ buf.Append("DER Set");
+ buf.Append(NewLine);
+
+ foreach (Asn1Encodable o in ((Asn1Set)obj))
+ {
+ if (o == null)
+ {
+ buf.Append(tab);
+ buf.Append("NULL");
+ buf.Append(NewLine);
+ }
+ else
+ {
+ buf.Append(AsString(tab, o.ToAsn1Object()));
+ }
+ }
+
+ return buf.ToString();
+ }
+ else if (obj is DerObjectIdentifier)
+ {
+ return indent + "ObjectIdentifier(" + ((DerObjectIdentifier)obj).Id + ")" + NewLine;
+ }
+ else if (obj is DerBoolean)
+ {
+ return indent + "Boolean(" + ((DerBoolean)obj).IsTrue + ")" + NewLine;
+ }
+ else if (obj is DerInteger)
+ {
+ return indent + "Integer(" + ((DerInteger)obj).Value + ")" + NewLine;
+ }
+ else if (obj is BerOctetString)
+ {
+ return indent + "BER Octet String" + "[" + ((Asn1OctetString)obj).GetOctets().Length + "] " + NewLine;
+ }
+ else if (obj is DerOctetString)
+ {
+ return indent + "DER Octet String" + "[" + ((Asn1OctetString)obj).GetOctets().Length + "] " + NewLine;
+ }
+ else if (obj is DerBitString)
+ {
+ return indent + "DER Bit String" + "[" + ((DerBitString)obj).GetBytes().Length + ", " + ((DerBitString)obj).PadBits + "] " + NewLine;
+ }
+ else if (obj is DerIA5String)
+ {
+ return indent + "IA5String(" + ((DerIA5String)obj).GetString() + ") " + NewLine;
+ }
+ else if (obj is DerUtf8String)
+ {
+ return indent + "UTF8String(" + ((DerUtf8String)obj).GetString() + ") " + NewLine;
+ }
+ else if (obj is DerPrintableString)
+ {
+ return indent + "PrintableString(" + ((DerPrintableString)obj).GetString() + ") " + NewLine;
+ }
+ else if (obj is DerVisibleString)
+ {
+ return indent + "VisibleString(" + ((DerVisibleString)obj).GetString() + ") " + NewLine;
+ }
+ else if (obj is DerBmpString)
+ {
+ return indent + "BMPString(" + ((DerBmpString)obj).GetString() + ") " + NewLine;
+ }
+ else if (obj is DerT61String)
+ {
+ return indent + "T61String(" + ((DerT61String)obj).GetString() + ") " + NewLine;
+ }
+ else if (obj is DerUtcTime)
+ {
+ return indent + "UTCTime(" + ((DerUtcTime)obj).TimeString + ") " + NewLine;
+ }
+ else if (obj is DerGeneralizedTime)
+ {
+ return indent + "GeneralizedTime(" + ((DerGeneralizedTime)obj).GetTime() + ") " + NewLine;
+ }
+ else if (obj is DerUnknownTag)
+ {
+ byte[] hex = Hex.Encode(((DerUnknownTag)obj).GetData());
+ return indent + "Unknown " + ((int)((DerUnknownTag)obj).Tag).ToString("X") + " "
+ + Encoding.ASCII.GetString(hex, 0, hex.Length) + NewLine;
+ }
+ else
+ {
+ return indent + obj.ToString() + NewLine;
+ }
+ }
+
+ [Obsolete("Use version accepting Asn1Encodable")]
+ public static string DumpAsString(
+ object obj)
+ {
+ if (obj is Asn1Object)
+ {
+ return AsString("", (Asn1Object)obj);
+ }
+ else if (obj is Asn1Encodable)
+ {
+ return AsString("", ((Asn1Encodable)obj).ToAsn1Object());
+ }
+
+ return "unknown object type " + obj.ToString();
+ }
+
+ /**
+ * dump out a DER object as a formatted string
+ *
+ * @param obj the Asn1Encodable to be dumped out.
+ */
+ public static string DumpAsString(
+ Asn1Encodable obj)
+ {
+ return AsString("", obj.ToAsn1Object());
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/util/Dump.cs b/iTechSharp/srcbc/asn1/util/Dump.cs
new file mode 100644
index 0000000..27c87f1
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/util/Dump.cs
@@ -0,0 +1,28 @@
+using Org.BouncyCastle.Asn1;
+
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1.Utilities
+{
+ public sealed class Dump
+ {
+ private Dump()
+ {
+ }
+
+ public static void Main(string[] args)
+ {
+ FileStream fIn = File.OpenRead(args[0]);
+ Asn1InputStream bIn = new Asn1InputStream(fIn);
+
+ Asn1Object obj;
+ while ((obj = bIn.ReadObject()) != null)
+ {
+ Console.WriteLine(Asn1Dump.DumpAsString(obj));
+ }
+
+ bIn.Close();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/util/FilterStream.cs b/iTechSharp/srcbc/asn1/util/FilterStream.cs
new file mode 100644
index 0000000..27dc0af
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/util/FilterStream.cs
@@ -0,0 +1,67 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1.Utilities
+{
+ public class FilterStream : Stream
+ {
+ public FilterStream(Stream s)
+ {
+ this.s = s;
+ }
+ public override bool CanRead
+ {
+ get { return s.CanRead; }
+ }
+ public override bool CanSeek
+ {
+ get { return s.CanSeek; }
+ }
+ public override bool CanWrite
+ {
+ get { return s.CanWrite; }
+ }
+ public override long Length
+ {
+ get { return s.Length; }
+ }
+ public override long Position
+ {
+ get { return s.Position; }
+ set { s.Position = value; }
+ }
+ public override void Close()
+ {
+ s.Close();
+ }
+ public override void Flush()
+ {
+ s.Flush();
+ }
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ return s.Seek(offset, origin);
+ }
+ public override void SetLength(long value)
+ {
+ s.SetLength(value);
+ }
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ return s.Read(buffer, offset, count);
+ }
+ public override int ReadByte()
+ {
+ return s.ReadByte();
+ }
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ s.Write(buffer, offset, count);
+ }
+ public override void WriteByte(byte value)
+ {
+ s.WriteByte(value);
+ }
+ private readonly Stream s;
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x500/DirectoryString.cs b/iTechSharp/srcbc/asn1/x500/DirectoryString.cs
new file mode 100644
index 0000000..8fb97db
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x500/DirectoryString.cs
@@ -0,0 +1,76 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X500
+{
+ public class DirectoryString
+ : Asn1Encodable, IAsn1String
+ //, Asn1Choice
+ {
+ private readonly DerStringBase str;
+
+ public static DirectoryString GetInstance(
+ object obj)
+ {
+ if (obj is DirectoryString)
+ {
+ return (DirectoryString) obj;
+ }
+
+ if (obj is DerStringBase)
+ {
+ if (obj is DerT61String
+ || obj is DerPrintableString
+ || obj is DerUniversalString
+ || obj is DerUtf8String
+ || obj is DerBmpString)
+ {
+ return new DirectoryString((DerStringBase) obj);
+ }
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public static DirectoryString GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ if (!isExplicit)
+ throw new ArgumentException("choice item must be explicitly tagged");
+
+ return GetInstance(obj.GetObject());
+ }
+
+ private DirectoryString(
+ DerStringBase str)
+ {
+ this.str = str;
+ }
+
+ public DirectoryString(
+ string str)
+ {
+ this.str = new DerUtf8String(str);
+ }
+
+ public string GetString()
+ {
+ return str.GetString();
+ }
+
+ /**
+ *
+ * DirectoryString ::= CHOICE {
+ * teletexString TeletexString (SIZE (1..MAX)),
+ * printableString PrintableString (SIZE (1..MAX)),
+ * universalString UniversalString (SIZE (1..MAX)),
+ * utf8String UTF8String (SIZE (1..MAX)),
+ * bmpString BMPString (SIZE (1..MAX)) }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return str.ToAsn1Object();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AccessDescription.cs b/iTechSharp/srcbc/asn1/x509/AccessDescription.cs
new file mode 100644
index 0000000..a45f43b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AccessDescription.cs
@@ -0,0 +1,88 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The AccessDescription object.
+ *
+ * AccessDescription ::= SEQUENCE {
+ * accessMethod OBJECT IDENTIFIER,
+ * accessLocation GeneralName }
+ *
+ */
+ public class AccessDescription
+ : Asn1Encodable
+ {
+ public readonly static DerObjectIdentifier IdADCAIssuers = new DerObjectIdentifier("1.3.6.1.5.5.7.48.2");
+
+ public readonly static DerObjectIdentifier IdADOcsp = new DerObjectIdentifier("1.3.6.1.5.5.7.48.1");
+
+ internal DerObjectIdentifier accessMethod;
+ internal GeneralName accessLocation;
+
+ public static AccessDescription GetInstance(
+ object obj)
+ {
+ if (obj is AccessDescription)
+ {
+ return (AccessDescription) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new AccessDescription((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private AccessDescription(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("wrong number of elements in inner sequence");
+
+ accessMethod = DerObjectIdentifier.GetInstance(seq[0]);
+ accessLocation = GeneralName.GetInstance(seq[1]);
+ }
+
+ /**
+ * create an AccessDescription with the oid and location provided.
+ */
+ public AccessDescription(
+ DerObjectIdentifier oid,
+ GeneralName location)
+ {
+ accessMethod = oid;
+ accessLocation = location;
+ }
+
+ /**
+ *
+ * @return the access method.
+ */
+ public DerObjectIdentifier AccessMethod
+ {
+ get { return accessMethod; }
+ }
+
+ /**
+ *
+ * @return the access location
+ */
+ public GeneralName AccessLocation
+ {
+ get { return accessLocation; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(accessMethod, accessLocation);
+ }
+
+ public override string ToString()
+ {
+ return ("AccessDescription: Oid(" + this.accessMethod.Id + ")");
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AlgorithmIdentifier.cs b/iTechSharp/srcbc/asn1/x509/AlgorithmIdentifier.cs
new file mode 100644
index 0000000..6f24a73
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AlgorithmIdentifier.cs
@@ -0,0 +1,110 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class AlgorithmIdentifier
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier objectID;
+ private readonly Asn1Encodable parameters;
+
+ public static AlgorithmIdentifier GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static AlgorithmIdentifier GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is AlgorithmIdentifier)
+ {
+ return (AlgorithmIdentifier) obj;
+ }
+
+ if (obj is DerObjectIdentifier)
+ {
+ return new AlgorithmIdentifier((DerObjectIdentifier) obj);
+ }
+
+ if (obj is string)
+ {
+ return new AlgorithmIdentifier((string) obj);
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new AlgorithmIdentifier((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public AlgorithmIdentifier(
+ DerObjectIdentifier objectID)
+ {
+ this.objectID = objectID;
+ }
+
+ public AlgorithmIdentifier(
+ string objectID)
+ {
+ this.objectID = new DerObjectIdentifier(objectID);
+ }
+
+ public AlgorithmIdentifier(
+ DerObjectIdentifier objectID,
+ Asn1Encodable parameters)
+ {
+ this.objectID = objectID;
+ this.parameters = parameters;
+ }
+
+ internal AlgorithmIdentifier(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ objectID = DerObjectIdentifier.GetInstance(seq[0]);
+
+ if (seq.Count == 2)
+ {
+ parameters = seq[1];
+ }
+ }
+
+ public virtual DerObjectIdentifier ObjectID
+ {
+ get { return objectID; }
+ }
+
+ public Asn1Encodable Parameters
+ {
+ get { return parameters; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * AlgorithmIdentifier ::= Sequence {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(objectID);
+
+ if (parameters != null)
+ {
+ v.Add(parameters);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AttCertIssuer.cs b/iTechSharp/srcbc/asn1/x509/AttCertIssuer.cs
new file mode 100644
index 0000000..b5d4f47
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AttCertIssuer.cs
@@ -0,0 +1,86 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class AttCertIssuer
+ : Asn1Encodable
+ {
+ internal readonly Asn1Encodable obj;
+ internal readonly Asn1Object choiceObj;
+
+ public static AttCertIssuer GetInstance(
+ object obj)
+ {
+ if (obj is AttCertIssuer)
+ {
+ return (AttCertIssuer)obj;
+ }
+ else if (obj is V2Form)
+ {
+ return new AttCertIssuer(V2Form.GetInstance(obj));
+ }
+ else if (obj is GeneralNames)
+ {
+ return new AttCertIssuer((GeneralNames)obj);
+ }
+ else if (obj is Asn1TaggedObject)
+ {
+ return new AttCertIssuer(V2Form.GetInstance((Asn1TaggedObject)obj, false));
+ }
+ else if (obj is Asn1Sequence)
+ {
+ return new AttCertIssuer(GeneralNames.GetInstance(obj));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public static AttCertIssuer GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ return GetInstance(obj.GetObject()); // must be explictly tagged
+ }
+
+ ///
+ * AttCertIssuer ::= CHOICE {
+ * v1Form GeneralNames, -- MUST NOT be used in this
+ * -- profile
+ * v2Form [0] V2Form -- v2 only
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return choiceObj;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AttCertValidityPeriod.cs b/iTechSharp/srcbc/asn1/x509/AttCertValidityPeriod.cs
new file mode 100644
index 0000000..7f86cd0
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AttCertValidityPeriod.cs
@@ -0,0 +1,78 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class AttCertValidityPeriod
+ : Asn1Encodable
+ {
+ private readonly DerGeneralizedTime notBeforeTime;
+ private readonly DerGeneralizedTime notAfterTime;
+
+ public static AttCertValidityPeriod GetInstance(
+ object obj)
+ {
+ if (obj is AttCertValidityPeriod || obj == null)
+ {
+ return (AttCertValidityPeriod) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new AttCertValidityPeriod((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public static AttCertValidityPeriod GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ private AttCertValidityPeriod(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ notBeforeTime = DerGeneralizedTime.GetInstance(seq[0]);
+ notAfterTime = DerGeneralizedTime.GetInstance(seq[1]);
+ }
+
+ public AttCertValidityPeriod(
+ DerGeneralizedTime notBeforeTime,
+ DerGeneralizedTime notAfterTime)
+ {
+ this.notBeforeTime = notBeforeTime;
+ this.notAfterTime = notAfterTime;
+ }
+
+ public DerGeneralizedTime NotBeforeTime
+ {
+ get { return notBeforeTime; }
+ }
+
+ public DerGeneralizedTime NotAfterTime
+ {
+ get { return notAfterTime; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * AttCertValidityPeriod ::= Sequence {
+ * notBeforeTime GeneralizedTime,
+ * notAfterTime GeneralizedTime
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(notBeforeTime, notAfterTime);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/Attribute.cs b/iTechSharp/srcbc/asn1/x509/Attribute.cs
new file mode 100644
index 0000000..7279134
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/Attribute.cs
@@ -0,0 +1,77 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class AttributeX509
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier attrType;
+ private readonly Asn1Set attrValues;
+
+ /**
+ * return an Attr object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static AttributeX509 GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is AttributeX509)
+ {
+ return (AttributeX509) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new AttributeX509((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private AttributeX509(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ attrType = DerObjectIdentifier.GetInstance(seq[0]);
+ attrValues = Asn1Set.GetInstance(seq[1]);
+ }
+
+ public AttributeX509(
+ DerObjectIdentifier attrType,
+ Asn1Set attrValues)
+ {
+ this.attrType = attrType;
+ this.attrValues = attrValues;
+ }
+
+ public DerObjectIdentifier AttrType
+ {
+ get { return attrType; }
+ }
+
+ public Asn1Set AttrValues
+ {
+ get { return attrValues; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Attr ::= Sequence {
+ * attrType OBJECT IDENTIFIER,
+ * attrValues Set OF AttributeValue
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(attrType, attrValues);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AttributeCertificate.cs b/iTechSharp/srcbc/asn1/x509/AttributeCertificate.cs
new file mode 100644
index 0000000..4ad3246
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AttributeCertificate.cs
@@ -0,0 +1,85 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class AttributeCertificate
+ : Asn1Encodable
+ {
+ private readonly AttributeCertificateInfo acinfo;
+ private readonly AlgorithmIdentifier signatureAlgorithm;
+ private readonly DerBitString signatureValue;
+
+ /**
+ * @param obj
+ * @return
+ */
+ public static AttributeCertificate GetInstance(
+ object obj)
+ {
+ if (obj is AttributeCertificate)
+ {
+ return (AttributeCertificate) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new AttributeCertificate((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public AttributeCertificate(
+ AttributeCertificateInfo acinfo,
+ AlgorithmIdentifier signatureAlgorithm,
+ DerBitString signatureValue)
+ {
+ this.acinfo = acinfo;
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signatureValue = signatureValue;
+ }
+
+ private AttributeCertificate(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 3)
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+ this.acinfo = AttributeCertificateInfo.GetInstance(seq[0]);
+ this.signatureAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]);
+ this.signatureValue = DerBitString.GetInstance(seq[2]);
+ }
+
+ public AttributeCertificateInfo ACInfo
+ {
+ get { return acinfo; }
+ }
+
+ public AlgorithmIdentifier SignatureAlgorithm
+ {
+ get { return signatureAlgorithm; }
+ }
+
+ public DerBitString SignatureValue
+ {
+ get { return signatureValue; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * AttributeCertificate ::= Sequence {
+ * acinfo AttributeCertificateInfo,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signatureValue BIT STRING
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(acinfo, signatureAlgorithm, signatureValue);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AttributeCertificateInfo.cs b/iTechSharp/srcbc/asn1/x509/AttributeCertificateInfo.cs
new file mode 100644
index 0000000..dcef3d4
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AttributeCertificateInfo.cs
@@ -0,0 +1,156 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class AttributeCertificateInfo
+ : Asn1Encodable
+ {
+ internal readonly DerInteger version;
+ internal readonly Holder holder;
+ internal readonly AttCertIssuer issuer;
+ internal readonly AlgorithmIdentifier signature;
+ internal readonly DerInteger serialNumber;
+ internal readonly AttCertValidityPeriod attrCertValidityPeriod;
+ internal readonly Asn1Sequence attributes;
+ internal readonly DerBitString issuerUniqueID;
+ internal readonly X509Extensions extensions;
+
+ public static AttributeCertificateInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+ }
+
+ public static AttributeCertificateInfo GetInstance(
+ object obj)
+ {
+ if (obj is AttributeCertificateInfo)
+ {
+ return (AttributeCertificateInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new AttributeCertificateInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private AttributeCertificateInfo(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 7 || seq.Count > 9)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ this.version = DerInteger.GetInstance(seq[0]);
+ this.holder = Holder.GetInstance(seq[1]);
+ this.issuer = AttCertIssuer.GetInstance(seq[2]);
+ this.signature = AlgorithmIdentifier.GetInstance(seq[3]);
+ this.serialNumber = DerInteger.GetInstance(seq[4]);
+ this.attrCertValidityPeriod = AttCertValidityPeriod.GetInstance(seq[5]);
+ this.attributes = Asn1Sequence.GetInstance(seq[6]);
+
+ for (int i = 7; i < seq.Count; i++)
+ {
+ Asn1Encodable obj = (Asn1Encodable) seq[i];
+
+ if (obj is DerBitString)
+ {
+ this.issuerUniqueID = DerBitString.GetInstance(seq[i]);
+ }
+ else if (obj is Asn1Sequence || obj is X509Extensions)
+ {
+ this.extensions = X509Extensions.GetInstance(seq[i]);
+ }
+ }
+ }
+
+ public DerInteger Version
+ {
+ get { return version; }
+ }
+
+ public Holder Holder
+ {
+ get { return holder; }
+ }
+
+ public AttCertIssuer Issuer
+ {
+ get { return issuer; }
+ }
+
+ public AlgorithmIdentifier Signature
+ {
+ get { return signature; }
+ }
+
+ public DerInteger SerialNumber
+ {
+ get { return serialNumber; }
+ }
+
+ public AttCertValidityPeriod AttrCertValidityPeriod
+ {
+ get { return attrCertValidityPeriod; }
+ }
+
+ public Asn1Sequence Attributes
+ {
+ get { return attributes; }
+ }
+
+ public DerBitString IssuerUniqueID
+ {
+ get { return issuerUniqueID; }
+ }
+
+ public X509Extensions Extensions
+ {
+ get { return extensions; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * AttributeCertificateInfo ::= Sequence {
+ * version AttCertVersion -- version is v2,
+ * holder Holder,
+ * issuer AttCertIssuer,
+ * signature AlgorithmIdentifier,
+ * serialNumber CertificateSerialNumber,
+ * attrCertValidityPeriod AttCertValidityPeriod,
+ * attributes Sequence OF Attr,
+ * issuerUniqueID UniqueIdentifier OPTIONAL,
+ * extensions Extensions OPTIONAL
+ * }
+ *
+ * AttCertVersion ::= Integer { v2(1) }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, holder, issuer, signature, serialNumber,
+ attrCertValidityPeriod, attributes);
+
+ if (issuerUniqueID != null)
+ {
+ v.Add(issuerUniqueID);
+ }
+
+ if (extensions != null)
+ {
+ v.Add(extensions);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AttributeTable.cs b/iTechSharp/srcbc/asn1/x509/AttributeTable.cs
new file mode 100644
index 0000000..1913ab5
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AttributeTable.cs
@@ -0,0 +1,54 @@
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class AttributeTable
+ {
+ private readonly Hashtable attributes;
+
+ public AttributeTable(
+ Hashtable attrs)
+ {
+ this.attributes = new Hashtable(attrs);
+ }
+
+ public AttributeTable(
+ Asn1EncodableVector v)
+ {
+ this.attributes = new Hashtable(v.Count);
+
+ for (int i = 0; i != v.Count; i++)
+ {
+ AttributeX509 a = AttributeX509.GetInstance(v[i]);
+
+ attributes.Add(a.AttrType, a);
+ }
+ }
+
+ public AttributeTable(
+ Asn1Set s)
+ {
+ this.attributes = new Hashtable(s.Count);
+
+ for (int i = 0; i != s.Count; i++)
+ {
+ AttributeX509 a = AttributeX509.GetInstance(s[i]);
+
+ attributes.Add(a.AttrType, a);
+ }
+ }
+
+ public AttributeX509 Get(
+ DerObjectIdentifier oid)
+ {
+ return (AttributeX509) attributes[oid];
+ }
+
+ public Hashtable ToHashtable()
+ {
+ return new Hashtable(attributes);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AuthorityInformationAccess.cs b/iTechSharp/srcbc/asn1/x509/AuthorityInformationAccess.cs
new file mode 100644
index 0000000..524ce67
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AuthorityInformationAccess.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The AuthorityInformationAccess object.
+ *
+ * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
+ *
+ * AuthorityInfoAccessSyntax ::=
+ * Sequence SIZE (1..MAX) OF AccessDescription
+ * AccessDescription ::= Sequence {
+ * accessMethod OBJECT IDENTIFIER,
+ * accessLocation GeneralName }
+ *
+ * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
+ * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
+ * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
+ *
+ */
+ public class AuthorityInformationAccess
+ : Asn1Encodable
+ {
+ internal readonly DerObjectIdentifier accessMethod;
+ internal readonly GeneralName accessLocation;
+
+ public static AuthorityInformationAccess GetInstance(
+ object obj)
+ {
+ if (obj is AuthorityInformationAccess)
+ {
+ return (AuthorityInformationAccess) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new AuthorityInformationAccess((Asn1Sequence) obj);
+ }
+
+ if (obj is X509Extension)
+ {
+ return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private AuthorityInformationAccess(
+ Asn1Sequence seq)
+ {
+ foreach (DerSequence vec in seq)
+ {
+ if (vec.Count != 2)
+ {
+ throw new ArgumentException("wrong number of elements in inner sequence");
+ }
+
+ accessMethod = (DerObjectIdentifier) vec[0];
+ accessLocation = (GeneralName) vec[1];
+ }
+ }
+
+ /**
+ * create an AuthorityInformationAccess with the oid and location provided.
+ */
+ public AuthorityInformationAccess(
+ DerObjectIdentifier oid,
+ GeneralName location)
+ {
+ accessMethod = oid;
+ accessLocation = location;
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(new DerSequence(accessMethod, accessLocation));
+ }
+
+ public override string ToString()
+ {
+ return ("AuthorityInformationAccess: Oid(" + this.accessMethod.Id + ")");
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/AuthorityKeyIdentifier.cs b/iTechSharp/srcbc/asn1/x509/AuthorityKeyIdentifier.cs
new file mode 100644
index 0000000..12ccacf
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/AuthorityKeyIdentifier.cs
@@ -0,0 +1,211 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The AuthorityKeyIdentifier object.
+ *
+ * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
+ *
+ * AuthorityKeyIdentifier ::= Sequence {
+ * keyIdentifier [0] IMPLICIT KeyIdentifier OPTIONAL,
+ * authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL,
+ * authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL }
+ *
+ * KeyIdentifier ::= OCTET STRING
+ *
+ *
+ */
+ public class AuthorityKeyIdentifier
+ : Asn1Encodable
+ {
+ internal readonly Asn1OctetString keyidentifier;
+ internal readonly GeneralNames certissuer;
+ internal readonly DerInteger certserno;
+
+ public static AuthorityKeyIdentifier GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static AuthorityKeyIdentifier GetInstance(
+ object obj)
+ {
+ if (obj is AuthorityKeyIdentifier)
+ {
+ return (AuthorityKeyIdentifier) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new AuthorityKeyIdentifier((Asn1Sequence) obj);
+ }
+
+ if (obj is X509Extension)
+ {
+ return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ protected internal AuthorityKeyIdentifier(
+ Asn1Sequence seq)
+ {
+ foreach (Asn1TaggedObject o in seq)
+ {
+ switch (o.TagNo)
+ {
+ case 0:
+ this.keyidentifier = Asn1OctetString.GetInstance(o, false);
+ break;
+ case 1:
+ this.certissuer = GeneralNames.GetInstance(o, false);
+ break;
+ case 2:
+ this.certserno = DerInteger.GetInstance(o, false);
+ break;
+ default:
+ throw new ArgumentException("illegal tag");
+ }
+ }
+ }
+
+ /**
+ *
+ * Calulates the keyidentifier using a SHA1 hash over the BIT STRING
+ * from SubjectPublicKeyInfo as defined in RFC2459.
+ *
+ * Example of making a AuthorityKeyIdentifier:
+ *
+ * SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
+ * publicKey.getEncoded()).readObject());
+ * AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
+ *
+ *
+ **/
+ public AuthorityKeyIdentifier(
+ SubjectPublicKeyInfo spki)
+ {
+ IDigest digest = new Sha1Digest();
+ byte[] resBuf = new byte[digest.GetDigestSize()];
+
+ byte[] bytes = spki.PublicKeyData.GetBytes();
+ digest.BlockUpdate(bytes, 0, bytes.Length);
+ digest.DoFinal(resBuf, 0);
+ this.keyidentifier = new DerOctetString(resBuf);
+ }
+
+ /**
+ * create an AuthorityKeyIdentifier with the GeneralNames tag and
+ * the serial number provided as well.
+ */
+ public AuthorityKeyIdentifier(
+ SubjectPublicKeyInfo spki,
+ GeneralNames name,
+ BigInteger serialNumber)
+ {
+ IDigest digest = new Sha1Digest();
+ byte[] resBuf = new byte[digest.GetDigestSize()];
+
+ byte[] bytes = spki.PublicKeyData.GetBytes();
+ digest.BlockUpdate(bytes, 0, bytes.Length);
+ digest.DoFinal(resBuf, 0);
+
+ this.keyidentifier = new DerOctetString(resBuf);
+ this.certissuer = name;
+ this.certserno = new DerInteger(serialNumber);
+ }
+
+ /**
+ * create an AuthorityKeyIdentifier with the GeneralNames tag and
+ * the serial number provided.
+ */
+ public AuthorityKeyIdentifier(
+ GeneralNames name,
+ BigInteger serialNumber)
+ {
+ this.keyidentifier = null;
+ this.certissuer = GeneralNames.GetInstance(name.ToAsn1Object());
+ this.certserno = new DerInteger(serialNumber);
+ }
+
+ /**
+ * create an AuthorityKeyIdentifier with a precomputed key identifier
+ */
+ public AuthorityKeyIdentifier(
+ byte[] keyIdentifier)
+ {
+ this.keyidentifier = new DerOctetString(keyIdentifier);
+ this.certissuer = null;
+ this.certserno = null;
+ }
+
+ /**
+ * create an AuthorityKeyIdentifier with a precomupted key identifier
+ * and the GeneralNames tag and the serial number provided as well.
+ */
+ public AuthorityKeyIdentifier(
+ byte[] keyIdentifier,
+ GeneralNames name,
+ BigInteger serialNumber)
+ {
+ this.keyidentifier = new DerOctetString(keyIdentifier);
+ this.certissuer = GeneralNames.GetInstance(name.ToAsn1Object());
+ this.certserno = new DerInteger(serialNumber);
+ }
+
+ public byte[] GetKeyIdentifier()
+ {
+ return keyidentifier == null ? null : keyidentifier.GetOctets();
+ }
+
+ public GeneralNames AuthorityCertIssuer
+ {
+ get { return certissuer; }
+ }
+
+ public BigInteger AuthorityCertSerialNumber
+ {
+ get { return certserno == null ? null : certserno.Value; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (keyidentifier != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, keyidentifier));
+ }
+
+ if (certissuer != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, certissuer));
+ }
+
+ if (certserno != null)
+ {
+ v.Add(new DerTaggedObject(false, 2, certserno));
+ }
+
+ return new DerSequence(v);
+ }
+
+ public override string ToString()
+ {
+ return ("AuthorityKeyIdentifier: KeyID(" + this.keyidentifier.GetOctets() + ")");
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/BasicConstraints.cs b/iTechSharp/srcbc/asn1/x509/BasicConstraints.cs
new file mode 100644
index 0000000..522cb61
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/BasicConstraints.cs
@@ -0,0 +1,133 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class BasicConstraints
+ : Asn1Encodable
+ {
+ private readonly DerBoolean cA;
+ private readonly DerInteger pathLenConstraint;
+
+ public static BasicConstraints GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static BasicConstraints GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is BasicConstraints)
+ {
+ return (BasicConstraints) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new BasicConstraints((Asn1Sequence) obj);
+ }
+
+ if (obj is X509Extension)
+ {
+ return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private BasicConstraints(
+ Asn1Sequence seq)
+ {
+ if (seq.Count > 0)
+ {
+ if (seq[0] is DerBoolean)
+ {
+ this.cA = DerBoolean.GetInstance(seq[0]);
+ }
+ else
+ {
+ this.pathLenConstraint = DerInteger.GetInstance(seq[0]);
+ }
+
+ if (seq.Count > 1)
+ {
+ if (this.cA == null)
+ throw new ArgumentException("wrong sequence in constructor", "seq");
+
+ this.pathLenConstraint = DerInteger.GetInstance(seq[1]);
+ }
+ }
+ }
+
+ public BasicConstraints(
+ bool cA)
+ {
+ if (cA)
+ {
+ this.cA = DerBoolean.True;
+ }
+ }
+
+ /**
+ * create a cA=true object for the given path length constraint.
+ *
+ * @param pathLenConstraint
+ */
+ public BasicConstraints(
+ int pathLenConstraint)
+ {
+ this.cA = DerBoolean.True;
+ this.pathLenConstraint = new DerInteger(pathLenConstraint);
+ }
+
+ public bool IsCA()
+ {
+ return cA != null && cA.IsTrue;
+ }
+
+ public BigInteger PathLenConstraint
+ {
+ get { return pathLenConstraint == null ? null : pathLenConstraint.Value; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * BasicConstraints := Sequence {
+ * cA Boolean DEFAULT FALSE,
+ * pathLenConstraint Integer (0..MAX) OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (cA != null)
+ {
+ v.Add(cA);
+ }
+
+ if (pathLenConstraint != null) // yes some people actually do this when cA is false...
+ {
+ v.Add(pathLenConstraint);
+ }
+
+ return new DerSequence(v);
+ }
+
+ public override string ToString()
+ {
+ if (pathLenConstraint == null)
+ {
+ return "BasicConstraints: isCa(" + this.IsCA() + ")";
+ }
+
+ return "BasicConstraints: isCa(" + this.IsCA() + "), pathLenConstraint = " + pathLenConstraint.Value;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/CRLDistPoint.cs b/iTechSharp/srcbc/asn1/x509/CRLDistPoint.cs
new file mode 100644
index 0000000..2b5c197
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/CRLDistPoint.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Text;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class CrlDistPoint
+ : Asn1Encodable
+ {
+ internal readonly Asn1Sequence seq;
+
+ public static CrlDistPoint GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static CrlDistPoint GetInstance(
+ object obj)
+ {
+ if (obj is CrlDistPoint || obj == null)
+ {
+ return (CrlDistPoint) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new CrlDistPoint((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private CrlDistPoint(
+ Asn1Sequence seq)
+ {
+ this.seq = seq;
+ }
+
+ public CrlDistPoint(
+ DistributionPoint[] points)
+ {
+ seq = new DerSequence(points);
+ }
+
+ /**
+ * Return the distribution points making up the sequence.
+ *
+ * @return DistributionPoint[]
+ */
+ public DistributionPoint[] GetDistributionPoints()
+ {
+ DistributionPoint[] dp = new DistributionPoint[seq.Count];
+
+ for (int i = 0; i != seq.Count; ++i)
+ {
+ dp[i] = DistributionPoint.GetInstance(seq[i]);
+ }
+
+ return dp;
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * CrlDistPoint ::= Sequence SIZE {1..MAX} OF DistributionPoint
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return seq;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder buf = new StringBuilder();
+ string sep = Platform.NewLine;
+
+ buf.Append("CRLDistPoint:");
+ buf.Append(sep);
+ DistributionPoint[] dp = GetDistributionPoints();
+ for (int i = 0; i != dp.Length; i++)
+ {
+ buf.Append(" ");
+ buf.Append(dp[i]);
+ buf.Append(sep);
+ }
+ return buf.ToString();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/CRLNumber.cs b/iTechSharp/srcbc/asn1/x509/CRLNumber.cs
new file mode 100644
index 0000000..d744416
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/CRLNumber.cs
@@ -0,0 +1,30 @@
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The CRLNumber object.
+ *
+ * CRLNumber::= Integer(0..MAX)
+ *
+ */
+ public class CrlNumber
+ : DerInteger
+ {
+ public CrlNumber(
+ BigInteger number)
+ : base(number)
+ {
+ }
+
+ public BigInteger Number
+ {
+ get { return PositiveValue; }
+ }
+
+ public override string ToString()
+ {
+ return "CRLNumber: " + Number;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/CRLReason.cs b/iTechSharp/srcbc/asn1/x509/CRLReason.cs
new file mode 100644
index 0000000..e8eb53a
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/CRLReason.cs
@@ -0,0 +1,61 @@
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The CRLReason enumeration.
+ *
+ * CRLReason ::= Enumerated {
+ * unspecified (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6),
+ * removeFromCRL (8),
+ * privilegeWithdrawn (9),
+ * aACompromise (10)
+ * }
+ *
+ */
+ public class CrlReason
+ : DerEnumerated
+ {
+ public const int Unspecified = 0;
+ public const int KeyCompromise = 1;
+ public const int CACompromise = 2;
+ public const int AffiliationChanged = 3;
+ public const int Superseded = 4;
+ public const int CessationOfOperation = 5;
+ public const int CertificateHold = 6;
+ // 7 -> Unknown
+ public const int RemoveFromCrl = 8;
+ public const int PrivilegeWithdrawn = 9;
+ public const int AACompromise = 10;
+
+ private static readonly string[] ReasonString = new string[]
+ {
+ "Unspecified", "KeyCompromise", "CACompromise", "AffiliationChanged",
+ "Superseded", "CessationOfOperation", "CertificateHold", "Unknown",
+ "RemoveFromCrl", "PrivilegeWithdrawn", "AACompromise"
+ };
+
+ public CrlReason(
+ int reason)
+ : base(reason)
+ {
+ }
+
+ public CrlReason(
+ DerEnumerated reason)
+ : base(reason.Value.IntValue)
+ {
+ }
+
+ public override string ToString()
+ {
+ int reason = Value.IntValue;
+ string str = (reason < 0 || reason > 10) ? "Invalid" : ReasonString[reason];
+ return "CrlReason: " + str;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/CertPolicyId.cs b/iTechSharp/srcbc/asn1/x509/CertPolicyId.cs
new file mode 100644
index 0000000..11cebcd
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/CertPolicyId.cs
@@ -0,0 +1,20 @@
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * CertPolicyId, used in the CertificatePolicies and PolicyMappings
+ * X509V3 Extensions.
+ *
+ *
+ * CertPolicyId ::= OBJECT IDENTIFIER
+ *
+ */
+ public class CertPolicyID
+ : DerObjectIdentifier
+ {
+ public CertPolicyID(
+ string id)
+ : base(id)
+ {
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/CertificateList.cs b/iTechSharp/srcbc/asn1/x509/CertificateList.cs
new file mode 100644
index 0000000..85351a0
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/CertificateList.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * PKIX RFC-2459
+ *
+ * The X.509 v2 CRL syntax is as follows. For signature calculation,
+ * the data that is to be signed is ASN.1 Der encoded.
+ *
+ *
+ * CertificateList ::= Sequence {
+ * tbsCertList TbsCertList,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signatureValue BIT STRING }
+ *
+ */
+ public class CertificateList
+ : Asn1Encodable
+ {
+ private readonly TbsCertificateList tbsCertList;
+ private readonly AlgorithmIdentifier sigAlgID;
+ private readonly DerBitString sig;
+
+ public static CertificateList GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static CertificateList GetInstance(
+ object obj)
+ {
+ if (obj is CertificateList)
+ {
+ return (CertificateList) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new CertificateList((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ private CertificateList(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 3)
+ throw new ArgumentException("sequence wrong size for CertificateList", "seq");
+
+ tbsCertList = TbsCertificateList.GetInstance(seq[0]);
+ sigAlgID = AlgorithmIdentifier.GetInstance(seq[1]);
+ sig = DerBitString.GetInstance(seq[2]);
+ }
+
+ public TbsCertificateList TbsCertList
+ {
+ get { return tbsCertList; }
+ }
+
+ public CrlEntry[] GetRevokedCertificates()
+ {
+ return tbsCertList.GetRevokedCertificates();
+ }
+
+ public IEnumerable GetRevokedCertificateEnumeration()
+ {
+ return tbsCertList.GetRevokedCertificateEnumeration();
+ }
+
+ public AlgorithmIdentifier SignatureAlgorithm
+ {
+ get { return sigAlgID; }
+ }
+
+ public DerBitString Signature
+ {
+ get { return sig; }
+ }
+
+ public int Version
+ {
+ get { return tbsCertList.Version; }
+ }
+
+ public X509Name Issuer
+ {
+ get { return tbsCertList.Issuer; }
+ }
+
+ public Time ThisUpdate
+ {
+ get { return tbsCertList.ThisUpdate; }
+ }
+
+ public Time NextUpdate
+ {
+ get { return tbsCertList.NextUpdate; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(tbsCertList, sigAlgID, sig);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/CertificatePair.cs b/iTechSharp/srcbc/asn1/x509/CertificatePair.cs
new file mode 100644
index 0000000..8baa647
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/CertificatePair.cs
@@ -0,0 +1,160 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * This class helps to support crossCerfificatePairs in a LDAP directory
+ * according RFC 2587
+ *
+ *
+ * crossCertificatePairATTRIBUTE::={
+ * WITH SYNTAX CertificatePair
+ * EQUALITY MATCHING RULE certificatePairExactMatch
+ * ID joint-iso-ccitt(2) ds(5) attributeType(4) crossCertificatePair(40)}
+ *
+ *
+ * The forward elements of the crossCertificatePair attribute of a
+ * CA's directory entry shall be used to store all, except self-issued
+ * certificates issued to this CA. Optionally, the reverse elements of the
+ * crossCertificatePair attribute, of a CA's directory entry may contain a
+ * subset of certificates issued by this CA to other CAs. When both the forward
+ * and the reverse elements are present in a single attribute value, issuer name
+ * in one certificate shall match the subject name in the other and vice versa,
+ * and the subject public key in one certificate shall be capable of verifying
+ * the digital signature on the other certificate and vice versa.
+ *
+ * When a reverse element is present, the forward element value and the reverse
+ * element value need not be stored in the same attribute value; in other words,
+ * they can be stored in either a single attribute value or two attribute
+ * values.
+ *
+ *
+ * CertificatePair ::= SEQUENCE {
+ * forward [0] Certificate OPTIONAL,
+ * reverse [1] Certificate OPTIONAL,
+ * -- at least one of the pair shall be present -- }
+ *
+ */
+ public class CertificatePair
+ : Asn1Encodable
+ {
+ private X509CertificateStructure forward, reverse;
+
+ public static CertificatePair GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is CertificatePair)
+ {
+ return (CertificatePair) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new CertificatePair((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor from Asn1Sequence.
+ *
+ * The sequence is of type CertificatePair:
+ *
+ *
+ * CertificatePair ::= SEQUENCE {
+ * forward [0] Certificate OPTIONAL,
+ * reverse [1] Certificate OPTIONAL,
+ * -- at least one of the pair shall be present -- }
+ *
+ *
+ * @param seq The ASN.1 sequence.
+ */
+ private CertificatePair(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 1 && seq.Count != 2)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+ }
+
+ foreach (object obj in seq)
+ {
+ Asn1TaggedObject o = Asn1TaggedObject.GetInstance(obj);
+ if (o.TagNo == 0)
+ {
+ forward = X509CertificateStructure.GetInstance(o, true);
+ }
+ else if (o.TagNo == 1)
+ {
+ reverse = X509CertificateStructure.GetInstance(o, true);
+ }
+ else
+ {
+ throw new ArgumentException("Bad tag number: " + o.TagNo);
+ }
+ }
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * @param forward Certificates issued to this CA.
+ * @param reverse Certificates issued by this CA to other CAs.
+ */
+ public CertificatePair(
+ X509CertificateStructure forward,
+ X509CertificateStructure reverse)
+ {
+ this.forward = forward;
+ this.reverse = reverse;
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * CertificatePair ::= SEQUENCE {
+ * forward [0] Certificate OPTIONAL,
+ * reverse [1] Certificate OPTIONAL,
+ * -- at least one of the pair shall be present -- }
+ *
+ *
+ * @return a DERObject
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector vec = new Asn1EncodableVector();
+
+ if (forward != null)
+ {
+ vec.Add(new DerTaggedObject(0, forward));
+ }
+
+ if (reverse != null)
+ {
+ vec.Add(new DerTaggedObject(1, reverse));
+ }
+
+ return new DerSequence(vec);
+ }
+
+ /**
+ * @return Returns the forward.
+ */
+ public X509CertificateStructure Forward
+ {
+ get { return forward; }
+ }
+
+ /**
+ * @return Returns the reverse.
+ */
+ public X509CertificateStructure Reverse
+ {
+ get { return reverse; }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/DSAParameter.cs b/iTechSharp/srcbc/asn1/x509/DSAParameter.cs
new file mode 100644
index 0000000..b2b325f
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/DSAParameter.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class DsaParameter
+ : Asn1Encodable
+ {
+ internal readonly DerInteger p, q, g;
+
+ public static DsaParameter GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static DsaParameter GetInstance(
+ object obj)
+ {
+ if(obj == null || obj is DsaParameter)
+ {
+ return (DsaParameter) obj;
+ }
+
+ if(obj is Asn1Sequence)
+ {
+ return new DsaParameter((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid DsaParameter: " + obj.GetType().Name);
+ }
+
+ public DsaParameter(
+ BigInteger p,
+ BigInteger q,
+ BigInteger g)
+ {
+ this.p = new DerInteger(p);
+ this.q = new DerInteger(q);
+ this.g = new DerInteger(g);
+ }
+
+ private DsaParameter(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 3)
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+ this.p = DerInteger.GetInstance(seq[0]);
+ this.q = DerInteger.GetInstance(seq[1]);
+ this.g = DerInteger.GetInstance(seq[2]);
+ }
+
+ public BigInteger P
+ {
+ get { return p.PositiveValue; }
+ }
+
+ public BigInteger Q
+ {
+ get { return q.PositiveValue; }
+ }
+
+ public BigInteger G
+ {
+ get { return g.PositiveValue; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(p, q, g);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/DigestInfo.cs b/iTechSharp/srcbc/asn1/x509/DigestInfo.cs
new file mode 100644
index 0000000..1dec227
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/DigestInfo.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The DigestInfo object.
+ *
+ * DigestInfo::=Sequence{
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING }
+ *
+ */
+ public class DigestInfo
+ : Asn1Encodable
+ {
+ private readonly byte[] digest;
+ private readonly AlgorithmIdentifier algID;
+
+ public static DigestInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static DigestInfo GetInstance(
+ object obj)
+ {
+ if (obj is DigestInfo)
+ {
+ return (DigestInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new DigestInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public DigestInfo(
+ AlgorithmIdentifier algID,
+ byte[] digest)
+ {
+ this.digest = digest;
+ this.algID = algID;
+ }
+
+ private DigestInfo(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+ algID = AlgorithmIdentifier.GetInstance(seq[0]);
+ digest = Asn1OctetString.GetInstance(seq[1]).GetOctets();
+ }
+
+ public AlgorithmIdentifier AlgorithmID
+ {
+ get { return algID; }
+ }
+
+ public byte[] GetDigest()
+ {
+ return digest;
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(algID, new DerOctetString(digest));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/DisplayText.cs b/iTechSharp/srcbc/asn1/x509/DisplayText.cs
new file mode 100644
index 0000000..287e597
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/DisplayText.cs
@@ -0,0 +1,172 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * DisplayText
class, used in
+ * CertificatePolicies
X509 V3 extensions (in policy qualifiers).
+ *
+ *
+ * DisplayText ::= CHOICE {
+ * ia5String IA5String (SIZE (1..200)),
+ * visibleString VisibleString (SIZE (1..200)),
+ * bmpString BMPString (SIZE (1..200)),
+ * utf8String UTF8String (SIZE (1..200)) }
+ *
DisplayTextMaximumSize
here.
+ *
+ */
+ public const int DisplayTextMaximumSize = 200;
+
+ internal readonly int contentType;
+ internal readonly IAsn1String contents;
+
+ /**
+ * Creates a new DisplayText
instance.
+ *
+ * @param type the desired encoding type for the text.
+ * @param text the text to store. Strings longer than 200
+ * characters are truncated.
+ */
+ public DisplayText(
+ int type,
+ string text)
+ {
+ if (text.Length > DisplayTextMaximumSize)
+ {
+ // RFC3280 limits these strings to 200 chars
+ // truncate the string
+ text = text.Substring(0, DisplayTextMaximumSize);
+ }
+
+ contentType = type;
+ switch (type)
+ {
+ case ContentTypeIA5String:
+ contents = (IAsn1String)new DerIA5String (text);
+ break;
+ case ContentTypeUtf8String:
+ contents = (IAsn1String)new DerUtf8String(text);
+ break;
+ case ContentTypeVisibleString:
+ contents = (IAsn1String)new DerVisibleString(text);
+ break;
+ case ContentTypeBmpString:
+ contents = (IAsn1String)new DerBmpString(text);
+ break;
+ default:
+ contents = (IAsn1String)new DerUtf8String(text);
+ break;
+ }
+ }
+
+// /**
+// * return true if the passed in string can be represented without
+// * loss as a PrintableString, false otherwise.
+// */
+// private bool CanBePrintable(
+// string str)
+// {
+// for (int i = str.Length - 1; i >= 0; i--)
+// {
+// if (str[i] > 0x007f)
+// {
+// return false;
+// }
+// }
+//
+// return true;
+// }
+
+ /**
+ * Creates a new DisplayText
instance.
+ *
+ * @param text the text to encapsulate. Strings longer than 200
+ * characters are truncated.
+ */
+ public DisplayText(
+ string text)
+ {
+ // by default use UTF8String
+ if (text.Length > DisplayTextMaximumSize)
+ {
+ text = text.Substring(0, DisplayTextMaximumSize);
+ }
+
+ contentType = ContentTypeUtf8String;
+ contents = new DerUtf8String(text);
+ }
+
+ /**
+ * Creates a new DisplayText
instance.
+ * DisplayText
class
+ * from it's Asn1Encodable form.Asn1Encodable
instance.
+ */
+ public DisplayText(
+ IAsn1String contents)
+ {
+ this.contents = contents;
+ }
+
+ public static DisplayText GetInstance(
+ object obj)
+ {
+ if (obj is IAsn1String)
+ {
+ return new DisplayText((IAsn1String) obj);
+ }
+
+ if (obj is DisplayText)
+ {
+ return (DisplayText) obj;
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return (Asn1Object) contents;
+ }
+
+ /**
+ * Returns the stored string
object.
+ *
+ * @return the stored text as a string
.
+ */
+ public string GetString()
+ {
+ return contents.GetString();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/DistributionPoint.cs b/iTechSharp/srcbc/asn1/x509/DistributionPoint.cs
new file mode 100644
index 0000000..ad1d398
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/DistributionPoint.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Text;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The DistributionPoint object.
+ *
+ * DistributionPoint ::= Sequence {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * reasons [1] ReasonFlags OPTIONAL,
+ * cRLIssuer [2] GeneralNames OPTIONAL
+ * }
+ *
+ */
+ public class DistributionPoint
+ : Asn1Encodable
+ {
+ internal readonly DistributionPointName distributionPoint;
+ internal readonly ReasonFlags reasons;
+ internal readonly GeneralNames cRLIssuer;
+
+ public static DistributionPoint GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static DistributionPoint GetInstance(
+ object obj)
+ {
+ if(obj == null || obj is DistributionPoint)
+ {
+ return (DistributionPoint) obj;
+ }
+
+ if(obj is Asn1Sequence)
+ {
+ return new DistributionPoint((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid DistributionPoint: " + obj.GetType().Name);
+ }
+
+ private DistributionPoint(
+ Asn1Sequence seq)
+ {
+ for (int i = 0; i != seq.Count; i++)
+ {
+ Asn1TaggedObject t = Asn1TaggedObject.GetInstance(seq[i]);
+
+ switch (t.TagNo)
+ {
+ case 0:
+ distributionPoint = DistributionPointName.GetInstance(t, true);
+ break;
+ case 1:
+ reasons = new ReasonFlags(DerBitString.GetInstance(t, false));
+ break;
+ case 2:
+ cRLIssuer = GeneralNames.GetInstance(t, false);
+ break;
+ }
+ }
+ }
+
+ public DistributionPoint(
+ DistributionPointName distributionPointName,
+ ReasonFlags reasons,
+ GeneralNames crlIssuer)
+ {
+ this.distributionPoint = distributionPointName;
+ this.reasons = reasons;
+ this.cRLIssuer = crlIssuer;
+ }
+
+ public DistributionPointName DistributionPointName
+ {
+ get { return distributionPoint; }
+ }
+
+ public ReasonFlags Reasons
+ {
+ get { return reasons; }
+ }
+
+ public GeneralNames CrlIssuer
+ {
+ get { return cRLIssuer; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (distributionPoint != null)
+ {
+ //
+ // as this is a CHOICE it must be explicitly tagged
+ //
+ v.Add(new DerTaggedObject(0, distributionPoint));
+ }
+
+ if (reasons != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, reasons));
+ }
+
+ if (cRLIssuer != null)
+ {
+ v.Add(new DerTaggedObject(false, 2, cRLIssuer));
+ }
+
+ return new DerSequence(v);
+ }
+
+ public override string ToString()
+ {
+ string sep = Platform.NewLine;
+ StringBuilder buf = new StringBuilder();
+ buf.Append("DistributionPoint: [");
+ buf.Append(sep);
+ if (distributionPoint != null)
+ {
+ appendObject(buf, sep, "distributionPoint", distributionPoint.ToString());
+ }
+ if (reasons != null)
+ {
+ appendObject(buf, sep, "reasons", reasons.ToString());
+ }
+ if (cRLIssuer != null)
+ {
+ appendObject(buf, sep, "cRLIssuer", cRLIssuer.ToString());
+ }
+ buf.Append("]");
+ buf.Append(sep);
+ return buf.ToString();
+ }
+
+ private void appendObject(
+ StringBuilder buf,
+ string sep,
+ string name,
+ string val)
+ {
+ string indent = " ";
+
+ buf.Append(indent);
+ buf.Append(name);
+ buf.Append(":");
+ buf.Append(sep);
+ buf.Append(indent);
+ buf.Append(indent);
+ buf.Append(val);
+ buf.Append(sep);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/DistributionPointName.cs b/iTechSharp/srcbc/asn1/x509/DistributionPointName.cs
new file mode 100644
index 0000000..8439a5d
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/DistributionPointName.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Text;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The DistributionPointName object.
+ *
+ * DistributionPointName ::= CHOICE {
+ * fullName [0] GeneralNames,
+ * nameRelativeToCRLIssuer [1] RelativeDistinguishedName
+ * }
+ *
+ */
+ public class DistributionPointName
+ : Asn1Encodable
+ {
+ internal readonly Asn1Encodable name;
+ internal readonly int type;
+
+ public const int FullName = 0;
+ public const int NameRelativeToCrlIssuer = 1;
+
+ public static DistributionPointName GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1TaggedObject.GetInstance(obj, explicitly));
+ }
+
+ public static DistributionPointName GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is DistributionPointName)
+ {
+ return (DistributionPointName) obj;
+ }
+
+ if (obj is Asn1TaggedObject)
+ {
+ return new DistributionPointName((Asn1TaggedObject) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public DistributionPointName(
+ int type,
+ Asn1Encodable name)
+ {
+ this.type = type;
+ this.name = name;
+ }
+
+ public DistributionPointName(
+ GeneralNames name)
+ : this(FullName, name)
+ {
+ }
+
+ public int PointType
+ {
+ get { return type; }
+ }
+
+ public Asn1Encodable Name
+ {
+ get { return name; }
+ }
+
+ public DistributionPointName(
+ Asn1TaggedObject obj)
+ {
+ this.type = obj.TagNo;
+
+ if (type == FullName)
+ {
+ this.name = GeneralNames.GetInstance(obj, false);
+ }
+ else
+ {
+ this.name = Asn1Set.GetInstance(obj, false);
+ }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerTaggedObject(false, type, name);
+ }
+
+ public override string ToString()
+ {
+ string sep = Platform.NewLine;
+ StringBuilder buf = new StringBuilder();
+ buf.Append("DistributionPointName: [");
+ buf.Append(sep);
+ if (type == FullName)
+ {
+ appendObject(buf, sep, "fullName", name.ToString());
+ }
+ else
+ {
+ appendObject(buf, sep, "nameRelativeToCRLIssuer", name.ToString());
+ }
+ buf.Append("]");
+ buf.Append(sep);
+ return buf.ToString();
+ }
+
+ private void appendObject(
+ StringBuilder buf,
+ string sep,
+ string name,
+ string val)
+ {
+ string indent = " ";
+
+ buf.Append(indent);
+ buf.Append(name);
+ buf.Append(":");
+ buf.Append(sep);
+ buf.Append(indent);
+ buf.Append(indent);
+ buf.Append(val);
+ buf.Append(sep);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/ExtendedKeyUsage.cs b/iTechSharp/srcbc/asn1/x509/ExtendedKeyUsage.cs
new file mode 100644
index 0000000..2aee599
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/ExtendedKeyUsage.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The extendedKeyUsage object.
+ *
+ * extendedKeyUsage ::= Sequence SIZE (1..MAX) OF KeyPurposeId
+ *
+ */
+ public class ExtendedKeyUsage
+ : Asn1Encodable
+ {
+ internal readonly Hashtable usageTable = new Hashtable();
+ internal readonly Asn1Sequence seq;
+
+ public static ExtendedKeyUsage GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static ExtendedKeyUsage GetInstance(
+ object obj)
+ {
+ if (obj is ExtendedKeyUsage)
+ {
+ return (ExtendedKeyUsage) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ExtendedKeyUsage((Asn1Sequence) obj);
+ }
+
+ if (obj is X509Extension)
+ {
+ return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj));
+ }
+
+ throw new ArgumentException("Invalid ExtendedKeyUsage: " + obj.GetType().Name);
+ }
+
+ private ExtendedKeyUsage(
+ Asn1Sequence seq)
+ {
+ this.seq = seq;
+
+ foreach (object o in seq)
+ {
+ if (!(o is DerObjectIdentifier))
+ throw new ArgumentException("Only DerObjectIdentifier instances allowed in ExtendedKeyUsage.");
+
+ this.usageTable.Add(o, o);
+ }
+ }
+
+ public ExtendedKeyUsage(
+ ArrayList usages)
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ foreach (Asn1Object o in usages)
+ {
+ v.Add(o);
+
+ this.usageTable.Add(o, o);
+ }
+
+ this.seq = new DerSequence(v);
+ }
+
+ public bool HasKeyPurposeId(
+ KeyPurposeID keyPurposeId)
+ {
+ return usageTable[keyPurposeId] != null;
+ }
+
+ /**
+ * Returns all extended key usages.
+ * The returned ArrayList contains DerObjectIdentifier instances.
+ * @return An ArrayList with all key purposes.
+ */
+ public ArrayList GetUsages()
+ {
+ return new ArrayList(usageTable.Values);
+ }
+
+ [Obsolete("Use 'Count' property instead")]
+ public int Size
+ {
+ get { return usageTable.Count; }
+ }
+
+ public int Count
+ {
+ get { return usageTable.Count; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return seq;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/GeneralName.cs b/iTechSharp/srcbc/asn1/x509/GeneralName.cs
new file mode 100644
index 0000000..2a19237
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/GeneralName.cs
@@ -0,0 +1,240 @@
+using System;
+using System.Text;
+
+using Org.BouncyCastle.Utilities.Net;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The GeneralName object.
+ *
+ * GeneralName ::= CHOICE {
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER}
+ *
+ * OtherName ::= Sequence {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * EDIPartyName ::= Sequence {
+ * nameAssigner [0] DirectoryString OPTIONAL,
+ * partyName [1] DirectoryString }
+ *
+ */
+ public class GeneralName
+ : Asn1Encodable
+ {
+ public const int OtherName = 0;
+ public const int Rfc822Name = 1;
+ public const int DnsName = 2;
+ public const int X400Address = 3;
+ public const int DirectoryName = 4;
+ public const int EdiPartyName = 5;
+ public const int UniformResourceIdentifier = 6;
+ public const int IPAddress = 7;
+ public const int RegisteredID = 8;
+
+ internal readonly Asn1Encodable obj;
+ internal readonly int tag;
+
+ public GeneralName(
+ X509Name directoryName)
+ {
+ this.obj = directoryName;
+ this.tag = 4;
+ }
+
+ /**
+ * When the subjectAltName extension contains an Internet mail address,
+ * the address MUST be included as an rfc822Name. The format of an
+ * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].
+ *
+ * When the subjectAltName extension contains a domain name service
+ * label, the domain name MUST be stored in the dNSName (an IA5String).
+ * The name MUST be in the "preferred name syntax," as specified by RFC
+ * 1034 [RFC 1034].
+ *
+ * When the subjectAltName extension contains a URI, the name MUST be
+ * stored in the uniformResourceIdentifier (an IA5String). The name MUST
+ * be a non-relative URL, and MUST follow the URL syntax and encoding
+ * rules specified in [RFC 1738]. The name must include both a scheme
+ * (e.g., "http" or "ftp") and a scheme-specific-part. The scheme-
+ * specific-part must include a fully qualified domain name or IP
+ * address as the host.
+ *
+ * When the subjectAltName extension contains a iPAddress, the address
+ * MUST be stored in the octet string in "network byte order," as
+ * specified in RFC 791 [RFC 791]. The least significant bit (LSB) of
+ * each octet is the LSB of the corresponding byte in the network
+ * address. For IP Version 4, as specified in RFC 791, the octet string
+ * MUST contain exactly four octets. For IP Version 6, as specified in
+ * RFC 1883, the octet string MUST contain exactly sixteen octets [RFC
+ * 1883].
+ */
+ public GeneralName(
+ Asn1Object name,
+ int tag)
+ {
+ this.obj = name;
+ this.tag = tag;
+ }
+
+ public GeneralName(
+ int tag,
+ Asn1Encodable name)
+ {
+ this.obj = name;
+ this.tag = tag;
+ }
+
+ /**
+ * Create a GeneralName for the given tag from the passed in String.
+ *
+ *
+ * For x400Address, otherName and ediPartyName there is no common string
+ * format defined.
+ *
+ * GeneralNames ::= Sequence SIZE {1..MAX} OF GeneralName
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return seq;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder buf = new StringBuilder();
+ string sep = Platform.NewLine;
+ GeneralName[] names = GetNames();
+
+ buf.Append("GeneralNames:");
+ buf.Append(sep);
+
+ for (int i = 0; i != names.Length; i++)
+ {
+ buf.Append(" ");
+ buf.Append(names[i]);
+ buf.Append(sep);
+ }
+ return buf.ToString();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/GeneralSubtree.cs b/iTechSharp/srcbc/asn1/x509/GeneralSubtree.cs
new file mode 100644
index 0000000..febf5e5
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/GeneralSubtree.cs
@@ -0,0 +1,177 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * Class for containing a restriction object subtrees in NameConstraints. See
+ * RFC 3280.
+ *
+ *
+ *
+ * GeneralSubtree ::= SEQUENCE
+ * {
+ * baseName GeneralName,
+ * minimum [0] BaseDistance DEFAULT 0,
+ * maximum [1] BaseDistance OPTIONAL
+ * }
+ *
+ *
+ * @see org.bouncycastle.asn1.x509.NameConstraints
+ *
+ */
+ public class GeneralSubtree
+ : Asn1Encodable
+ {
+ private readonly GeneralName baseName;
+ private readonly DerInteger minimum;
+ private readonly DerInteger maximum;
+
+ private GeneralSubtree(
+ Asn1Sequence seq)
+ {
+ baseName = GeneralName.GetInstance(seq[0]);
+
+ switch (seq.Count)
+ {
+ case 1:
+ break;
+ case 2:
+ {
+ Asn1TaggedObject o = Asn1TaggedObject.GetInstance(seq[1]);
+ switch (o.TagNo)
+ {
+ case 0:
+ minimum = DerInteger.GetInstance(o, false);
+ break;
+ case 1:
+ maximum = DerInteger.GetInstance(o, false);
+ break;
+ default:
+ throw new ArgumentException("Bad tag number: " + o.TagNo);
+ }
+ break;
+ }
+ case 3:
+ {
+ minimum = DerInteger.GetInstance(Asn1TaggedObject.GetInstance(seq[1]));
+ maximum = DerInteger.GetInstance(Asn1TaggedObject.GetInstance(seq[2]));
+ break;
+ }
+ default:
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * According RFC 3280, the minimum and maximum fields are not used with any
+ * name forms, thus minimum MUST be zero, and maximum MUST be absent.
+ * null
, zero is assumed, if
+ * maximum is null
, maximum is absent.
+ * GeneralSubtree ::= SEQUENCE
+ * {
+ * baseName GeneralName,
+ * minimum [0] BaseDistance DEFAULT 0,
+ * maximum [1] BaseDistance OPTIONAL
+ * }
+ *
+ *
+ * @return a DERObject
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(baseName);
+
+ if (minimum != null && minimum.Value.SignValue != 0)
+ {
+ v.Add(new DerTaggedObject(false, 0, minimum));
+ }
+
+ if (maximum != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, maximum));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/Holder.cs b/iTechSharp/srcbc/asn1/x509/Holder.cs
new file mode 100644
index 0000000..d04f1cb
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/Holder.cs
@@ -0,0 +1,257 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The Holder object.
+ *
+ * Holder ::= SEQUENCE {
+ * baseCertificateID [0] IssuerSerial OPTIONAL,
+ * -- the issuer and serial number of
+ * -- the holder's Public Key Certificate
+ * entityName [1] GeneralNames OPTIONAL,
+ * -- the name of the claimant or role
+ * objectDigestInfo [2] ObjectDigestInfo OPTIONAL
+ * -- used to directly authenticate the holder,
+ * -- for example, an executable
+ * }
+ *
+ *
+ * subject CHOICE {
+ * baseCertificateID [0] IssuerSerial,
+ * -- associated with a Public Key Certificate
+ * subjectName [1] GeneralNames },
+ * -- associated with a name
+ *
+ *
+ * Holder ::= Sequence {
+ * baseCertificateID [0] IssuerSerial OPTIONAL,
+ * -- the issuer and serial number of
+ * -- the holder's Public Key Certificate
+ * entityName [1] GeneralNames OPTIONAL,
+ * -- the name of the claimant or role
+ * objectDigestInfo [2] ObjectDigestInfo OPTIONAL
+ * -- used to directly authenticate the holder,
+ * -- for example, an executable
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ if (version == 1)
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (baseCertificateID != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, baseCertificateID));
+ }
+
+ if (entityName != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, entityName));
+ }
+
+ if (objectDigestInfo != null)
+ {
+ v.Add(new DerTaggedObject(false, 2, objectDigestInfo));
+ }
+
+ return new DerSequence(v);
+ }
+
+ if (entityName != null)
+ {
+ return new DerTaggedObject(false, 1, entityName);
+ }
+
+ return new DerTaggedObject(false, 0, baseCertificateID);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/IetfAttrSyntax.cs b/iTechSharp/srcbc/asn1/x509/IetfAttrSyntax.cs
new file mode 100644
index 0000000..e719865
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/IetfAttrSyntax.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * Implementation of IetfAttrSyntax
as specified by RFC3281.
+ */
+ public class IetfAttrSyntax
+ : Asn1Encodable
+ {
+ public const int ValueOctets = 1;
+ public const int ValueOid = 2;
+ public const int ValueUtf8 = 3;
+
+ internal readonly GeneralNames policyAuthority;
+ internal readonly Asn1EncodableVector values = new Asn1EncodableVector();
+
+ internal int valueChoice = -1;
+
+ /**
+ *
+ */
+ public IetfAttrSyntax(
+ Asn1Sequence seq)
+ {
+ int i = 0;
+
+ if (seq[0] is Asn1TaggedObject)
+ {
+ policyAuthority = GeneralNames.GetInstance(((Asn1TaggedObject)seq[0]), false);
+ i++;
+ }
+ else if (seq.Count == 2)
+ { // VOMS fix
+ policyAuthority = GeneralNames.GetInstance(seq[0]);
+ i++;
+ }
+
+ if (!(seq[i] is Asn1Sequence))
+ {
+ throw new ArgumentException("Non-IetfAttrSyntax encoding");
+ }
+
+ seq = (Asn1Sequence) seq[i];
+
+ foreach (Asn1Object obj in seq)
+ {
+ int type;
+
+ if (obj is DerObjectIdentifier)
+ {
+ type = ValueOid;
+ }
+ else if (obj is DerUtf8String)
+ {
+ type = ValueUtf8;
+ }
+ else if (obj is DerOctetString)
+ {
+ type = ValueOctets;
+ }
+ else
+ {
+ throw new ArgumentException("Bad value type encoding IetfAttrSyntax");
+ }
+
+ if (valueChoice < 0)
+ {
+ valueChoice = type;
+ }
+
+ if (type != valueChoice)
+ {
+ throw new ArgumentException("Mix of value types in IetfAttrSyntax");
+ }
+
+ values.Add(obj);
+ }
+ }
+
+ public GeneralNames PolicyAuthority
+ {
+ get { return policyAuthority; }
+ }
+
+ public int ValueType
+ {
+ get { return valueChoice; }
+ }
+
+ public object[] GetValues()
+ {
+ if (this.ValueType == ValueOctets)
+ {
+ Asn1OctetString[] tmp = new Asn1OctetString[values.Count];
+
+ for (int i = 0; i != tmp.Length; i++)
+ {
+ tmp[i] = (Asn1OctetString) values[i];
+ }
+
+ return tmp;
+ }
+
+ if (this.ValueType == ValueOid)
+ {
+ DerObjectIdentifier[] tmp = new DerObjectIdentifier[values.Count];
+
+ for (int i = 0; i != tmp.Length; i++)
+ {
+ tmp[i] = (DerObjectIdentifier) values[i];
+ }
+
+ return tmp;
+ }
+
+ {
+ DerUtf8String[] tmp = new DerUtf8String[values.Count];
+
+ for (int i = 0; i != tmp.Length; i++)
+ {
+ tmp[i] = (DerUtf8String) values[i];
+ }
+
+ return tmp;
+ }
+ }
+
+ /**
+ *
+ *
+ *
+ * IetfAttrSyntax ::= Sequence {
+ * policyAuthority [0] GeneralNames OPTIONAL,
+ * values Sequence OF CHOICE {
+ * octets OCTET STRING,
+ * oid OBJECT IDENTIFIER,
+ * string UTF8String
+ * }
+ * }
+ *
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (policyAuthority != null)
+ {
+ v.Add(new DerTaggedObject(0, policyAuthority));
+ }
+
+ v.Add(new DerSequence(values));
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/IssuerSerial.cs b/iTechSharp/srcbc/asn1/x509/IssuerSerial.cs
new file mode 100644
index 0000000..6a24e73
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/IssuerSerial.cs
@@ -0,0 +1,98 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class IssuerSerial
+ : Asn1Encodable
+ {
+ internal readonly GeneralNames issuer;
+ internal readonly DerInteger serial;
+ internal readonly DerBitString issuerUid;
+
+ public static IssuerSerial GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is IssuerSerial)
+ {
+ return (IssuerSerial) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new IssuerSerial((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public static IssuerSerial GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ private IssuerSerial(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2 && seq.Count != 3)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ issuer = GeneralNames.GetInstance(seq[0]);
+ serial = DerInteger.GetInstance(seq[1]);
+
+ if (seq.Count == 3)
+ {
+ issuerUid = DerBitString.GetInstance(seq[2]);
+ }
+ }
+
+ public IssuerSerial(
+ GeneralNames issuer,
+ DerInteger serial)
+ {
+ this.issuer = issuer;
+ this.serial = serial;
+ }
+
+ public GeneralNames Issuer
+ {
+ get { return issuer; }
+ }
+
+ public DerInteger Serial
+ {
+ get { return serial; }
+ }
+
+ public DerBitString IssuerUid
+ {
+ get { return issuerUid; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * IssuerSerial ::= Sequence {
+ * issuer GeneralNames,
+ * serial CertificateSerialNumber,
+ * issuerUid UniqueIdentifier OPTIONAL
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ issuer, serial);
+
+ if (issuerUid != null)
+ {
+ v.Add(issuerUid);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/IssuingDistributionPoint.cs b/iTechSharp/srcbc/asn1/x509/IssuingDistributionPoint.cs
new file mode 100644
index 0000000..3af0d56
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/IssuingDistributionPoint.cs
@@ -0,0 +1,247 @@
+using System;
+using System.Text;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ *
+ * IssuingDistributionPoint ::= SEQUENCE {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ * onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ * onlySomeReasons [3] ReasonFlags OPTIONAL,
+ * indirectCRL [4] BOOLEAN DEFAULT FALSE,
+ * onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
+ *
+ */
+ public class IssuingDistributionPoint
+ : Asn1Encodable
+ {
+ private readonly DistributionPointName _distributionPoint;
+ private readonly bool _onlyContainsUserCerts;
+ private readonly bool _onlyContainsCACerts;
+ private readonly ReasonFlags _onlySomeReasons;
+ private readonly bool _indirectCRL;
+ private readonly bool _onlyContainsAttributeCerts;
+
+ private readonly Asn1Sequence seq;
+
+ public static IssuingDistributionPoint GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static IssuingDistributionPoint GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is IssuingDistributionPoint)
+ {
+ return (IssuingDistributionPoint) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new IssuingDistributionPoint((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor from given details.
+ *
+ * @param distributionPoint
+ * May contain an URI as pointer to most current CRL.
+ * @param onlyContainsUserCerts Covers revocation information for end certificates.
+ * @param onlyContainsCACerts Covers revocation information for CA certificates.
+ *
+ * @param onlySomeReasons
+ * Which revocation reasons does this point cover.
+ * @param indirectCRL
+ * If true
then the CRL contains revocation
+ * information about certificates ssued by other CAs.
+ * @param onlyContainsAttributeCerts Covers revocation information for attribute certificates.
+ */
+ public IssuingDistributionPoint(
+ DistributionPointName distributionPoint,
+ bool onlyContainsUserCerts,
+ bool onlyContainsCACerts,
+ ReasonFlags onlySomeReasons,
+ bool indirectCRL,
+ bool onlyContainsAttributeCerts)
+ {
+ this._distributionPoint = distributionPoint;
+ this._indirectCRL = indirectCRL;
+ this._onlyContainsAttributeCerts = onlyContainsAttributeCerts;
+ this._onlyContainsCACerts = onlyContainsCACerts;
+ this._onlyContainsUserCerts = onlyContainsUserCerts;
+ this._onlySomeReasons = onlySomeReasons;
+
+ Asn1EncodableVector vec = new Asn1EncodableVector();
+ if (distributionPoint != null)
+ { // CHOICE item so explicitly tagged
+ vec.Add(new DerTaggedObject(true, 0, distributionPoint));
+ }
+ if (onlyContainsUserCerts)
+ {
+ vec.Add(new DerTaggedObject(false, 1, DerBoolean.True));
+ }
+ if (onlyContainsCACerts)
+ {
+ vec.Add(new DerTaggedObject(false, 2, DerBoolean.True));
+ }
+ if (onlySomeReasons != null)
+ {
+ vec.Add(new DerTaggedObject(false, 3, onlySomeReasons));
+ }
+ if (indirectCRL)
+ {
+ vec.Add(new DerTaggedObject(false, 4, DerBoolean.True));
+ }
+ if (onlyContainsAttributeCerts)
+ {
+ vec.Add(new DerTaggedObject(false, 5, DerBoolean.True));
+ }
+
+ seq = new DerSequence(vec);
+ }
+
+ /**
+ * Constructor from Asn1Sequence
+ */
+ private IssuingDistributionPoint(
+ Asn1Sequence seq)
+ {
+ this.seq = seq;
+
+ for (int i = 0; i != seq.Count; i++)
+ {
+ Asn1TaggedObject o = Asn1TaggedObject.GetInstance(seq[i]);
+
+ switch (o.TagNo)
+ {
+ case 0:
+ // CHOICE so explicit
+ _distributionPoint = DistributionPointName.GetInstance(o, true);
+ break;
+ case 1:
+ _onlyContainsUserCerts = DerBoolean.GetInstance(o, false).IsTrue;
+ break;
+ case 2:
+ _onlyContainsCACerts = DerBoolean.GetInstance(o, false).IsTrue;
+ break;
+ case 3:
+ _onlySomeReasons = new ReasonFlags(ReasonFlags.GetInstance(o, false));
+ break;
+ case 4:
+ _indirectCRL = DerBoolean.GetInstance(o, false).IsTrue;
+ break;
+ case 5:
+ _onlyContainsAttributeCerts = DerBoolean.GetInstance(o, false).IsTrue;
+ break;
+ default:
+ throw new ArgumentException("unknown tag in IssuingDistributionPoint");
+ }
+ }
+ }
+
+ public bool OnlyContainsUserCerts
+ {
+ get { return _onlyContainsUserCerts; }
+ }
+
+ public bool OnlyContainsCACerts
+ {
+ get { return _onlyContainsCACerts; }
+ }
+
+ public bool IsIndirectCrl
+ {
+ get { return _indirectCRL; }
+ }
+
+ public bool OnlyContainsAttributeCerts
+ {
+ get { return _onlyContainsAttributeCerts; }
+ }
+
+ /**
+ * @return Returns the distributionPoint.
+ */
+ public DistributionPointName DistributionPoint
+ {
+ get { return _distributionPoint; }
+ }
+
+ /**
+ * @return Returns the onlySomeReasons.
+ */
+ public ReasonFlags OnlySomeReasons
+ {
+ get { return _onlySomeReasons; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return seq;
+ }
+
+ public override string ToString()
+ {
+ string sep = Platform.NewLine;
+ StringBuilder buf = new StringBuilder();
+
+ buf.Append("IssuingDistributionPoint: [");
+ buf.Append(sep);
+ if (_distributionPoint != null)
+ {
+ appendObject(buf, sep, "distributionPoint", _distributionPoint.ToString());
+ }
+ if (_onlyContainsUserCerts)
+ {
+ appendObject(buf, sep, "onlyContainsUserCerts", _onlyContainsUserCerts.ToString());
+ }
+ if (_onlyContainsCACerts)
+ {
+ appendObject(buf, sep, "onlyContainsCACerts", _onlyContainsCACerts.ToString());
+ }
+ if (_onlySomeReasons != null)
+ {
+ appendObject(buf, sep, "onlySomeReasons", _onlySomeReasons.ToString());
+ }
+ if (_onlyContainsAttributeCerts)
+ {
+ appendObject(buf, sep, "onlyContainsAttributeCerts", _onlyContainsAttributeCerts.ToString());
+ }
+ if (_indirectCRL)
+ {
+ appendObject(buf, sep, "indirectCRL", _indirectCRL.ToString());
+ }
+ buf.Append("]");
+ buf.Append(sep);
+ return buf.ToString();
+ }
+
+ private void appendObject(
+ StringBuilder buf,
+ string sep,
+ string name,
+ string val)
+ {
+ string indent = " ";
+
+ buf.Append(indent);
+ buf.Append(name);
+ buf.Append(":");
+ buf.Append(sep);
+ buf.Append(indent);
+ buf.Append(indent);
+ buf.Append(val);
+ buf.Append(sep);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/KeyPurposeId.cs b/iTechSharp/srcbc/asn1/x509/KeyPurposeId.cs
new file mode 100644
index 0000000..4b48a9b
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/KeyPurposeId.cs
@@ -0,0 +1,36 @@
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The KeyPurposeID object.
+ *
+ * KeyPurposeID ::= OBJECT IDENTIFIER
+ *
+ */
+ public sealed class KeyPurposeID
+ : DerObjectIdentifier
+ {
+ private const string IdKP = "1.3.6.1.5.5.7.3";
+
+ private KeyPurposeID(
+ string id)
+ : base(id)
+ {
+ }
+
+ public static readonly KeyPurposeID AnyExtendedKeyUsage = new KeyPurposeID(X509Extensions.ExtendedKeyUsage.Id + ".0");
+ public static readonly KeyPurposeID IdKPServerAuth = new KeyPurposeID(IdKP + ".1");
+ public static readonly KeyPurposeID IdKPClientAuth = new KeyPurposeID(IdKP + ".2");
+ public static readonly KeyPurposeID IdKPCodeSigning = new KeyPurposeID(IdKP + ".3");
+ public static readonly KeyPurposeID IdKPEmailProtection = new KeyPurposeID(IdKP + ".4");
+ public static readonly KeyPurposeID IdKPIpsecEndSystem = new KeyPurposeID(IdKP + ".5");
+ public static readonly KeyPurposeID IdKPIpsecTunnel = new KeyPurposeID(IdKP + ".6");
+ public static readonly KeyPurposeID IdKPIpsecUser = new KeyPurposeID(IdKP + ".7");
+ public static readonly KeyPurposeID IdKPTimeStamping = new KeyPurposeID(IdKP + ".8");
+ public static readonly KeyPurposeID IdKPOcspSigning = new KeyPurposeID(IdKP + ".9");
+
+ //
+ // microsoft key purpose ids
+ //
+ public static readonly KeyPurposeID IdKPSmartCardLogon = new KeyPurposeID("1.3.6.1.4.1.311.20.2.2");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/KeyUsage.cs b/iTechSharp/srcbc/asn1/x509/KeyUsage.cs
new file mode 100644
index 0000000..fef04e8
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/KeyUsage.cs
@@ -0,0 +1,79 @@
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The KeyUsage object.
+ *
+ * id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+ *
+ * KeyUsage ::= BIT STRING {
+ * digitalSignature (0),
+ * nonRepudiation (1),
+ * keyEncipherment (2),
+ * dataEncipherment (3),
+ * keyAgreement (4),
+ * keyCertSign (5),
+ * cRLSign (6),
+ * encipherOnly (7),
+ * decipherOnly (8) }
+ *
+ */
+ public class KeyUsage
+ : DerBitString
+ {
+ public const int DigitalSignature = (1 << 7);
+ public const int NonRepudiation = (1 << 6);
+ public const int KeyEncipherment = (1 << 5);
+ public const int DataEncipherment = (1 << 4);
+ public const int KeyAgreement = (1 << 3);
+ public const int KeyCertSign = (1 << 2);
+ public const int CrlSign = (1 << 1);
+ public const int EncipherOnly = (1 << 0);
+ public const int DecipherOnly = (1 << 15);
+
+ public static new KeyUsage GetInstance(
+ object obj)
+ {
+ if (obj is KeyUsage)
+ {
+ return (KeyUsage)obj;
+ }
+
+ if (obj is X509Extension)
+ {
+ return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj));
+ }
+
+ return new KeyUsage(DerBitString.GetInstance(obj));
+ }
+
+ /**
+ * Basic constructor.
+ *
+ * @param usage - the bitwise OR of the Key Usage flags giving the
+ * allowed uses for the key.
+ * e.g. (KeyUsage.keyEncipherment | KeyUsage.dataEncipherment)
+ */
+ public KeyUsage(
+ int usage)
+ : base(GetBytes(usage), GetPadBits(usage))
+ {
+ }
+
+ private KeyUsage(
+ DerBitString usage)
+ : base(usage.GetBytes(), usage.PadBits)
+ {
+ }
+
+ public override string ToString()
+ {
+ byte[] data = GetBytes();
+ if (data.Length == 1)
+ {
+ return "KeyUsage: 0x" + (data[0] & 0xff).ToString("X");
+ }
+
+ return "KeyUsage: 0x" + ((data[1] & 0xff) << 8 | (data[0] & 0xff)).ToString("X");
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/NameConstraints.cs b/iTechSharp/srcbc/asn1/x509/NameConstraints.cs
new file mode 100644
index 0000000..d6e9c10
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/NameConstraints.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class NameConstraints
+ : Asn1Encodable
+ {
+ private Asn1Sequence permitted, excluded;
+
+ public NameConstraints(
+ Asn1Sequence seq)
+ {
+ foreach (Asn1TaggedObject o in seq)
+ {
+ switch (o.TagNo)
+ {
+ case 0:
+ permitted = Asn1Sequence.GetInstance(o, false);
+ break;
+ case 1:
+ excluded = Asn1Sequence.GetInstance(o, false);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * NoticeReference
class, used in
+ * CertificatePolicies
X509 V3 extensions
+ * (in policy qualifiers).
+ *
+ *
+ * NoticeReference ::= Sequence {
+ * organization DisplayText,
+ * noticeNumbers Sequence OF Integer }
+ *
+ *
+ *
+ * @see PolicyQualifierInfo
+ * @see PolicyInformation
+ */
+ public class NoticeReference
+ : Asn1Encodable
+ {
+ internal readonly DisplayText organization;
+ internal readonly Asn1Sequence noticeNumbers;
+
+ /**
+ * Creates a new NoticeReference
instance.
+ *
+ * @param orgName a string
value
+ * @param numbers a ArrayList
value
+ */
+ public NoticeReference(
+ string orgName,
+ ArrayList numbers)
+ {
+ organization = new DisplayText(orgName);
+
+ object o = numbers[0];
+
+ Asn1EncodableVector av = new Asn1EncodableVector();
+ if (o is int)
+ {
+ foreach (int nm in numbers)
+ {
+ av.Add(new DerInteger(nm));
+ }
+ }
+
+ noticeNumbers = new DerSequence(av);
+ }
+
+ /**
+ * Creates a new NoticeReference
instance.
+ *
+ * @param orgName a string
value
+ * @param numbers an Asn1Sequence
value
+ */
+ public NoticeReference(
+ string orgName,
+ Asn1Sequence numbers)
+ {
+ organization = new DisplayText(orgName);
+ noticeNumbers = numbers;
+ }
+
+ /**
+ * Creates a new NoticeReference
instance.
+ *
+ * @param displayTextType an int
value
+ * @param orgName a string
value
+ * @param numbers an Asn1Sequence
value
+ */
+ public NoticeReference(
+ int displayTextType,
+ string orgName,
+ Asn1Sequence numbers)
+ {
+ organization = new DisplayText(displayTextType, orgName);
+ noticeNumbers = numbers;
+ }
+
+ /**
+ * Creates a new NoticeReference
instance.
+ * NoticeReference
+ * instance from its encodable/encoded form.Asn1Sequence
value obtained from either
+ * calling @{link ToAsn1Object()} for a NoticeReference
+ * instance or from parsing it from a Der-encoded stream.
+ */
+ private NoticeReference(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+ organization = DisplayText.GetInstance(seq[0]);
+ noticeNumbers = Asn1Sequence.GetInstance(seq[1]);
+ }
+
+ public static NoticeReference GetInstance(
+ object obj)
+ {
+ if (obj is NoticeReference)
+ {
+ return (NoticeReference) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new NoticeReference((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj");
+ }
+
+ /**
+ * Describe ToAsn1Object
method here.
+ *
+ * @return a Asn1Object
value
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(organization, noticeNumbers);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/ObjectDigestInfo.cs b/iTechSharp/srcbc/asn1/x509/ObjectDigestInfo.cs
new file mode 100644
index 0000000..6d5b9c6
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/ObjectDigestInfo.cs
@@ -0,0 +1,177 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * ObjectDigestInfo ASN.1 structure used in v2 attribute certificates.
+ *
+ *
+ *
+ * ObjectDigestInfo ::= SEQUENCE {
+ * digestedObjectType ENUMERATED {
+ * publicKey (0),
+ * publicKeyCert (1),
+ * otherObjectTypes (2) },
+ * -- otherObjectTypes MUST NOT
+ * -- be used in this profile
+ * otherObjectTypeID OBJECT IDENTIFIER OPTIONAL,
+ * digestAlgorithm AlgorithmIdentifier,
+ * objectDigest BIT STRING
+ * }
+ *
+ *
+ *
+ */
+ public class ObjectDigestInfo
+ : Asn1Encodable
+ {
+ /**
+ * The public key is hashed.
+ */
+ public const int PublicKey = 0;
+
+ /**
+ * The public key certificate is hashed.
+ */
+ public const int PublicKeyCert = 1;
+
+ /**
+ * An other object is hashed.
+ */
+ public const int OtherObjectDigest = 2;
+
+ internal readonly DerEnumerated digestedObjectType;
+ internal readonly DerObjectIdentifier otherObjectTypeID;
+ internal readonly AlgorithmIdentifier digestAlgorithm;
+ internal readonly DerBitString objectDigest;
+
+ public static ObjectDigestInfo GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is ObjectDigestInfo)
+ {
+ return (ObjectDigestInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new ObjectDigestInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public static ObjectDigestInfo GetInstance(
+ Asn1TaggedObject obj,
+ bool isExplicit)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+ }
+
+ /**
+ * Constructor from given details.
+ * digestedObjectType
is not {@link #publicKeyCert} or
+ * {@link #publicKey} otherObjectTypeID
must be given,
+ * otherwise it is ignored.otherObjectDigest
.
+ * @param digestAlgorithm The algorithm identifier for the hash.
+ * @param objectDigest The hash value.
+ */
+ public ObjectDigestInfo(
+ int digestedObjectType,
+ string otherObjectTypeID,
+ AlgorithmIdentifier digestAlgorithm,
+ byte[] objectDigest)
+ {
+ this.digestedObjectType = new DerEnumerated(digestedObjectType);
+
+ if (digestedObjectType == OtherObjectDigest)
+ {
+ this.otherObjectTypeID = new DerObjectIdentifier(otherObjectTypeID);
+ }
+
+ this.digestAlgorithm = digestAlgorithm;
+
+ this.objectDigest = new DerBitString(objectDigest);
+ }
+
+ private ObjectDigestInfo(
+ Asn1Sequence seq)
+ {
+ if (seq.Count > 4 || seq.Count < 3)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ digestedObjectType = DerEnumerated.GetInstance(seq[0]);
+
+ int offset = 0;
+
+ if (seq.Count == 4)
+ {
+ otherObjectTypeID = DerObjectIdentifier.GetInstance(seq[1]);
+ offset++;
+ }
+
+ digestAlgorithm = AlgorithmIdentifier.GetInstance(seq[1 + offset]);
+ objectDigest = DerBitString.GetInstance(seq[2 + offset]);
+ }
+
+ public DerEnumerated DigestedObjectType
+ {
+ get { return digestedObjectType; }
+ }
+
+ public DerObjectIdentifier OtherObjectTypeID
+ {
+ get { return otherObjectTypeID; }
+ }
+
+ public AlgorithmIdentifier DigestAlgorithm
+ {
+ get { return digestAlgorithm; }
+ }
+
+ public DerBitString ObjectDigest
+ {
+ get { return objectDigest; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ *
+ *
+ * ObjectDigestInfo ::= SEQUENCE {
+ * digestedObjectType ENUMERATED {
+ * publicKey (0),
+ * publicKeyCert (1),
+ * otherObjectTypes (2) },
+ * -- otherObjectTypes MUST NOT
+ * -- be used in this profile
+ * otherObjectTypeID OBJECT IDENTIFIER OPTIONAL,
+ * digestAlgorithm AlgorithmIdentifier,
+ * objectDigest BIT STRING
+ * }
+ *
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(digestedObjectType);
+
+ if (otherObjectTypeID != null)
+ {
+ v.Add(otherObjectTypeID);
+ }
+
+ v.Add(digestAlgorithm, objectDigest);
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/PolicyInformation.cs b/iTechSharp/srcbc/asn1/x509/PolicyInformation.cs
new file mode 100644
index 0000000..29d2450
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/PolicyInformation.cs
@@ -0,0 +1,80 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class PolicyInformation
+ : Asn1Encodable
+ {
+ private readonly DerObjectIdentifier policyIdentifier;
+ private readonly Asn1Sequence policyQualifiers;
+
+ private PolicyInformation(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ policyIdentifier = DerObjectIdentifier.GetInstance(seq[0]);
+
+ if (seq.Count > 1)
+ {
+ policyQualifiers = Asn1Sequence.GetInstance(seq[1]);
+ }
+ }
+
+ public PolicyInformation(
+ DerObjectIdentifier policyIdentifier)
+ {
+ this.policyIdentifier = policyIdentifier;
+ }
+
+ public PolicyInformation(
+ DerObjectIdentifier policyIdentifier,
+ Asn1Sequence policyQualifiers)
+ {
+ this.policyIdentifier = policyIdentifier;
+ this.policyQualifiers = policyQualifiers;
+ }
+
+ public static PolicyInformation GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is PolicyInformation)
+ {
+ return (PolicyInformation) obj;
+ }
+
+ return new PolicyInformation(Asn1Sequence.GetInstance(obj));
+ }
+
+ public DerObjectIdentifier PolicyIdentifier
+ {
+ get { return policyIdentifier; }
+ }
+
+ public Asn1Sequence PolicyQualifiers
+ {
+ get { return policyQualifiers; }
+ }
+
+ /*
+ * PolicyInformation ::= Sequence {
+ * policyIdentifier CertPolicyId,
+ * policyQualifiers Sequence SIZE (1..MAX) OF
+ * PolicyQualifierInfo OPTIONAL }
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(policyIdentifier);
+
+ if (policyQualifiers != null)
+ {
+ v.Add(policyQualifiers);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/PolicyMappings.cs b/iTechSharp/srcbc/asn1/x509/PolicyMappings.cs
new file mode 100644
index 0000000..9e1a31a
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/PolicyMappings.cs
@@ -0,0 +1,62 @@
+using System.Collections;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * PolicyMappings V3 extension, described in RFC3280.
+ *
+ * PolicyMappings ::= Sequence SIZE (1..MAX) OF Sequence {
+ * issuerDomainPolicy CertPolicyId,
+ * subjectDomainPolicy CertPolicyId }
+ *
+ *
+ * @see RFC 3280, section 4.2.1.6
+ */
+ public class PolicyMappings
+ : Asn1Encodable
+ {
+ private readonly Asn1Sequence seq;
+
+ /**
+ * Creates a new PolicyMappings
instance.
+ *
+ * @param seq an Asn1Sequence
constructed as specified
+ * in RFC 3280
+ */
+ public PolicyMappings(
+ Asn1Sequence seq)
+ {
+ this.seq = seq;
+ }
+
+ /**
+ * Creates a new PolicyMappings
instance.
+ *
+ * @param mappings a HashMap
value that maps
+ * string
oids
+ * to other string
oids.
+ */
+ public PolicyMappings(
+ Hashtable mappings)
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ foreach (string idp in mappings.Keys)
+ {
+ string sdp = (string) mappings[idp];
+
+ v.Add(
+ new DerSequence(
+ new DerObjectIdentifier(idp),
+ new DerObjectIdentifier(sdp)));
+ }
+
+ seq = new DerSequence(v);
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return seq;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/PolicyQualifierId.cs b/iTechSharp/srcbc/asn1/x509/PolicyQualifierId.cs
new file mode 100644
index 0000000..c858f08
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/PolicyQualifierId.cs
@@ -0,0 +1,28 @@
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * PolicyQualifierId, used in the CertificatePolicies
+ * X509V3 extension.
+ *
+ *
+ * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+ * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+ * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+ * PolicyQualifierId ::=
+ * OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+ *
+ */
+ public sealed class PolicyQualifierID : DerObjectIdentifier
+ {
+ private const string IdQt = "1.3.6.1.5.5.7.2";
+
+ private PolicyQualifierID(
+ string id)
+ : base(id)
+ {
+ }
+
+ public static readonly PolicyQualifierID IdQtCps = new PolicyQualifierID(IdQt + ".1");
+ public static readonly PolicyQualifierID IdQtUnotice = new PolicyQualifierID(IdQt + ".2");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/PolicyQualifierInfo.cs b/iTechSharp/srcbc/asn1/x509/PolicyQualifierInfo.cs
new file mode 100644
index 0000000..187f8d3
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/PolicyQualifierInfo.cs
@@ -0,0 +1,91 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * Policy qualifiers, used in the X509V3 CertificatePolicies
+ * extension.
+ *
+ *
+ * PolicyQualifierInfo ::= Sequence {
+ * policyQualifierId PolicyQualifierId,
+ * qualifier ANY DEFINED BY policyQualifierId }
+ *
+ */
+ public class PolicyQualifierInfo
+ : Asn1Encodable
+ {
+ internal readonly DerObjectIdentifier policyQualifierId;
+ internal readonly Asn1Encodable qualifier;
+
+ /**
+ * Creates a new PolicyQualifierInfo
instance.
+ *
+ * @param policyQualifierId a PolicyQualifierId
value
+ * @param qualifier the qualifier, defined by the above field.
+ */
+ public PolicyQualifierInfo(
+ DerObjectIdentifier policyQualifierId,
+ Asn1Encodable qualifier)
+ {
+ this.policyQualifierId = policyQualifierId;
+ this.qualifier = qualifier;
+ }
+
+ /**
+ * Creates a new PolicyQualifierInfo
containing a
+ * cPSuri qualifier.
+ *
+ * @param cps the CPS (certification practice statement) uri as a
+ * string
.
+ */
+ public PolicyQualifierInfo(
+ string cps)
+ {
+ policyQualifierId = PolicyQualifierID.IdQtCps;
+ qualifier = new DerIA5String(cps);
+ }
+
+ /**
+ * Creates a new PolicyQualifierInfo
instance.
+ *
+ * @param as PolicyQualifierInfo
X509 structure
+ * encoded as an Asn1Sequence.
+ */
+ private PolicyQualifierInfo(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+ policyQualifierId = DerObjectIdentifier.GetInstance(seq[0]);
+ qualifier = seq[1];
+ }
+
+ public static PolicyQualifierInfo GetInstance(
+ object obj)
+ {
+ if (obj is PolicyQualifierInfo)
+ {
+ return (PolicyQualifierInfo) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new PolicyQualifierInfo((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj");
+ }
+
+ /**
+ * Returns a Der-encodable representation of this instance.
+ *
+ * @return a Asn1Object
value
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(policyQualifierId, qualifier);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/PrivateKeyUsagePeriod.cs b/iTechSharp/srcbc/asn1/x509/PrivateKeyUsagePeriod.cs
new file mode 100644
index 0000000..ad2961e
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/PrivateKeyUsagePeriod.cs
@@ -0,0 +1,82 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ ///
+ /// PrivateKeyUsagePeriod ::= SEQUENCE
+ /// {
+ /// notBefore [0] GeneralizedTime OPTIONAL,
+ /// notAfter [1] GeneralizedTime OPTIONAL }
+ ///
+ ///
+ * RSAPublicKey ::= Sequence {
+ * modulus Integer, -- n
+ * publicExponent Integer, -- e
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(
+ new DerInteger(Modulus),
+ new DerInteger(PublicExponent));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/ReasonFlags.cs b/iTechSharp/srcbc/asn1/x509/ReasonFlags.cs
new file mode 100644
index 0000000..f204c36
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/ReasonFlags.cs
@@ -0,0 +1,46 @@
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The ReasonFlags object.
+ *
+ * ReasonFlags ::= BIT STRING {
+ * unused(0),
+ * keyCompromise(1),
+ * cACompromise(2),
+ * affiliationChanged(3),
+ * superseded(4),
+ * cessationOfOperation(5),
+ * certficateHold(6)
+ * }
+ *
+ */
+ public class ReasonFlags
+ : DerBitString
+ {
+ public const int Unused = (1 << 7);
+ public const int KeyCompromise = (1 << 6);
+ public const int CACompromise = (1 << 5);
+ public const int AffiliationChanged = (1 << 4);
+ public const int Superseded = (1 << 3);
+ public const int CessationOfOperation = (1 << 2);
+ public const int CertificateHold = (1 << 1);
+ public const int PrivilegeWithdrawn = (1 << 0);
+ public const int AACompromise = (1 << 15);
+
+ /**
+ * @param reasons - the bitwise OR of the Key Reason flags giving the
+ * allowed uses for the key.
+ */
+ public ReasonFlags(
+ int reasons)
+ : base(GetBytes(reasons), GetPadBits(reasons))
+ {
+ }
+
+ public ReasonFlags(
+ DerBitString reasons)
+ : base(reasons.GetBytes(), reasons.PadBits)
+ {
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/RoleSyntax.cs b/iTechSharp/srcbc/asn1/x509/RoleSyntax.cs
new file mode 100644
index 0000000..7058363
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/RoleSyntax.cs
@@ -0,0 +1,234 @@
+using System;
+using System.Text;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * Implementation of the RoleSyntax object as specified by the RFC3281.
+ *
+ *
+ * RoleSyntax ::= SEQUENCE {
+ * roleAuthority [0] GeneralNames OPTIONAL,
+ * roleName [1] GeneralName
+ * }
+ *
+ */
+ public class RoleSyntax
+ : Asn1Encodable
+ {
+ private readonly GeneralNames roleAuthority;
+ private readonly GeneralName roleName;
+
+ /**
+ * RoleSyntax factory method.
+ * @param obj the object used to construct an instance of
+ * RoleSyntax
. It must be an instance of RoleSyntax
+ *
or Asn1Sequence
.
+ * @return the instance of RoleSyntax
built from the
+ * supplied object.
+ * @throws java.lang.ArgumentException if the object passed
+ * to the factory is not an instance of RoleSyntax
or
+ * Asn1Sequence
.
+ */
+ public static RoleSyntax GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is RoleSyntax)
+ {
+ return (RoleSyntax) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new RoleSyntax((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in 'RoleSyntax' factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor.
+ * @param roleAuthority the role authority of this RoleSyntax.
+ * @param roleName the role name of this RoleSyntax.
+ */
+ public RoleSyntax(
+ GeneralNames roleAuthority,
+ GeneralName roleName)
+ {
+ if (roleName == null
+ || roleName.TagNo != GeneralName.UniformResourceIdentifier
+ || ((IAsn1String) roleName.Name).GetString().Equals(""))
+ {
+ throw new ArgumentException("the role name MUST be non empty and MUST " +
+ "use the URI option of GeneralName");
+ }
+
+ this.roleAuthority = roleAuthority;
+ this.roleName = roleName;
+ }
+
+ /**
+ * Constructor. Invoking this constructor is the same as invoking
+ * new RoleSyntax(null, roleName)
.
+ * @param roleName the role name of this RoleSyntax.
+ */
+ public RoleSyntax(
+ GeneralName roleName)
+ : this(null, roleName)
+ {
+ }
+
+ /**
+ * Utility constructor. Takes a string
argument representing
+ * the role name, builds a GeneralName
to hold the role name
+ * and calls the constructor that takes a GeneralName
.
+ * @param roleName
+ */
+ public RoleSyntax(
+ string roleName)
+ : this(new GeneralName(GeneralName.UniformResourceIdentifier,
+ (roleName == null)? "": roleName))
+ {
+ }
+
+ /**
+ * Constructor that builds an instance of RoleSyntax
by
+ * extracting the encoded elements from the Asn1Sequence
+ * object supplied.
+ * @param seq an instance of Asn1Sequence
that holds
+ * the encoded elements used to build this RoleSyntax
.
+ */
+ private RoleSyntax(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 1 || seq.Count > 2)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ for (int i = 0; i != seq.Count; i++)
+ {
+ Asn1TaggedObject taggedObject = Asn1TaggedObject.GetInstance(seq[i]);
+ switch (taggedObject.TagNo)
+ {
+ case 0:
+ roleAuthority = GeneralNames.GetInstance(taggedObject, false);
+ break;
+ case 1:
+ roleName = GeneralName.GetInstance(taggedObject, false);
+ break;
+ default:
+ throw new ArgumentException("Unknown tag in RoleSyntax");
+ }
+ }
+ }
+
+ /**
+ * Gets the role authority of this RoleSyntax.
+ * @return an instance of GeneralNames
holding the
+ * role authority of this RoleSyntax.
+ */
+ public GeneralNames RoleAuthority
+ {
+ get { return this.roleAuthority; }
+ }
+
+ /**
+ * Gets the role name of this RoleSyntax.
+ * @return an instance of GeneralName
holding the
+ * role name of this RoleSyntax.
+ */
+ public GeneralName RoleName
+ {
+ get { return this.roleName; }
+ }
+
+ /**
+ * Gets the role name as a java.lang.string
object.
+ * @return the role name of this RoleSyntax represented as a
+ * string
object.
+ */
+ public string GetRoleNameAsString()
+ {
+ return ((IAsn1String) this.roleName.Name).GetString();
+ }
+
+ /**
+ * Gets the role authority as a string[]
object.
+ * @return the role authority of this RoleSyntax represented as a
+ * string[]
array.
+ */
+ public string[] GetRoleAuthorityAsString()
+ {
+ if (roleAuthority == null)
+ {
+ return new string[0];
+ }
+
+ GeneralName[] names = roleAuthority.GetNames();
+ string[] namesString = new string[names.Length];
+ for(int i = 0; i < names.Length; i++)
+ {
+ Asn1Encodable asn1Value = names[i].Name;
+ if (asn1Value is IAsn1String)
+ {
+ namesString[i] = ((IAsn1String) asn1Value).GetString();
+ }
+ else
+ {
+ namesString[i] = asn1Value.ToString();
+ }
+ }
+
+ return namesString;
+ }
+
+ /**
+ * Implementation of the method ToAsn1Object
as
+ * required by the superclass ASN1Encodable
.
+ *
+ *
+ * RoleSyntax ::= SEQUENCE {
+ * roleAuthority [0] GeneralNames OPTIONAL,
+ * roleName [1] GeneralName
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (this.roleAuthority != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, roleAuthority));
+ }
+
+ v.Add(new DerTaggedObject(false, 1, roleName));
+
+ return new DerSequence(v);
+ }
+
+ public override string ToString()
+ {
+ StringBuilder buff = new StringBuilder("Name: " + this.GetRoleNameAsString() +
+ " - Auth: ");
+
+ if (this.roleAuthority == null || roleAuthority.GetNames().Length == 0)
+ {
+ buff.Append("N/A");
+ }
+ else
+ {
+ string[] names = this.GetRoleAuthorityAsString();
+ buff.Append('[').Append(names[0]);
+ for(int i = 1; i < names.Length; i++)
+ {
+ buff.Append(", ").Append(names[i]);
+ }
+ buff.Append(']');
+ }
+
+ return buff.ToString();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/SubjectDirectoryAttributes.cs b/iTechSharp/srcbc/asn1/x509/SubjectDirectoryAttributes.cs
new file mode 100644
index 0000000..93beaec
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/SubjectDirectoryAttributes.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * This extension may contain further X.500 attributes of the subject. See also
+ * RFC 3039.
+ *
+ *
+ * SubjectDirectoryAttributes ::= Attributes
+ * Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+ * Attribute ::= SEQUENCE
+ * {
+ * type AttributeType
+ * values SET OF AttributeValue
+ * }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ *
+ *
+ * @see org.bouncycastle.asn1.x509.X509Name for AttributeType ObjectIdentifiers.
+ */
+ public class SubjectDirectoryAttributes
+ : Asn1Encodable
+ {
+ private readonly ArrayList attributes = new ArrayList();
+
+ public static SubjectDirectoryAttributes GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is SubjectDirectoryAttributes)
+ {
+ return (SubjectDirectoryAttributes) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SubjectDirectoryAttributes((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ /**
+ * Constructor from Asn1Sequence.
+ *
+ * The sequence is of type SubjectDirectoryAttributes:
+ *
+ *
+ * SubjectDirectoryAttributes ::= Attributes
+ * Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+ * Attribute ::= SEQUENCE
+ * {
+ * type AttributeType
+ * values SET OF AttributeValue
+ * }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ *
+ *
+ * @param seq
+ * The ASN.1 sequence.
+ */
+ private SubjectDirectoryAttributes(
+ Asn1Sequence seq)
+ {
+ foreach (object o in seq)
+ {
+ Asn1Sequence s = Asn1Sequence.GetInstance(o);
+ attributes.Add(AttributeX509.GetInstance(s));
+ }
+ }
+
+ /**
+ * Constructor from an ArrayList of attributes.
+ *
+ * The ArrayList consists of attributes of type {@link Attribute Attribute}
+ *
+ * @param attributes The attributes.
+ *
+ */
+ public SubjectDirectoryAttributes(
+ ArrayList attributes)
+ {
+ this.attributes.AddRange(attributes);
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * Returns:
+ *
+ *
+ * SubjectDirectoryAttributes ::= Attributes
+ * Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+ * Attribute ::= SEQUENCE
+ * {
+ * type AttributeType
+ * values SET OF AttributeValue
+ * }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ *
+ *
+ * @return a DERObject
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ AttributeX509[] v = (AttributeX509[]) attributes.ToArray(typeof(AttributeX509));
+
+ return new DerSequence(v);
+ }
+
+ /**
+ * @return Returns the attributes.
+ */
+ public IEnumerable Attributes
+ {
+ get { return new EnumerableProxy(attributes); }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/SubjectKeyIdentifier.cs b/iTechSharp/srcbc/asn1/x509/SubjectKeyIdentifier.cs
new file mode 100644
index 0000000..02e7de4
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/SubjectKeyIdentifier.cs
@@ -0,0 +1,95 @@
+using System;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The SubjectKeyIdentifier object.
+ *
+ * SubjectKeyIdentifier::= OCTET STRING
+ *
+ */
+ public class SubjectKeyIdentifier
+ : Asn1Encodable
+ {
+ private readonly byte[] keyIdentifier;
+
+ public static SubjectKeyIdentifier GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1OctetString.GetInstance(obj, explicitly));
+ }
+
+ public static SubjectKeyIdentifier GetInstance(
+ object obj)
+ {
+ if (obj is SubjectKeyIdentifier)
+ {
+ return (SubjectKeyIdentifier) obj;
+ }
+
+ if (obj is SubjectPublicKeyInfo)
+ {
+ return new SubjectKeyIdentifier((SubjectPublicKeyInfo) obj);
+ }
+
+ if (obj is Asn1OctetString)
+ {
+ return new SubjectKeyIdentifier((Asn1OctetString) obj);
+ }
+
+ if (obj is X509Extension)
+ {
+ return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj));
+ }
+
+ throw new ArgumentException("Invalid SubjectKeyIdentifier: " + obj.GetType().Name);
+ }
+
+ public SubjectKeyIdentifier(
+ byte[] keyID)
+ {
+ if (keyID == null)
+ throw new ArgumentNullException("keyID");
+
+ this.keyIdentifier = keyID;
+ }
+
+ public SubjectKeyIdentifier(
+ Asn1OctetString keyID)
+ {
+ this.keyIdentifier = keyID.GetOctets();
+ }
+
+ /**
+ *
+ * Calulates the keyIdentifier using a SHA1 hash over the BIT STRING
+ * from SubjectPublicKeyInfo as defined in RFC2459.
+ *
+ **/
+ public SubjectKeyIdentifier(
+ SubjectPublicKeyInfo spki)
+ {
+ IDigest digest = new Sha1Digest();
+ byte[] resBuf = new byte[digest.GetDigestSize()];
+
+ byte[] bytes = spki.PublicKeyData.GetBytes();
+ digest.BlockUpdate(bytes, 0, bytes.Length);
+ digest.DoFinal(resBuf, 0);
+ this.keyIdentifier = resBuf;
+ }
+
+ public byte[] GetKeyIdentifier()
+ {
+ return keyIdentifier;
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerOctetString(keyIdentifier);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/SubjectPublicKeyInfo.cs b/iTechSharp/srcbc/asn1/x509/SubjectPublicKeyInfo.cs
new file mode 100644
index 0000000..07e6868
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/SubjectPublicKeyInfo.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections;
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The object that contains the public key stored in a certficate.
+ *
+ * SubjectPublicKeyInfo ::= Sequence {
+ * algorithm AlgorithmIdentifier,
+ * publicKey BIT STRING }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(algID, keyData);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/TBSCertList.cs b/iTechSharp/srcbc/asn1/x509/TBSCertList.cs
new file mode 100644
index 0000000..b5934a2
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/TBSCertList.cs
@@ -0,0 +1,274 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class CrlEntry
+ : Asn1Encodable
+ {
+ internal Asn1Sequence seq;
+ internal DerInteger userCertificate;
+ internal Time revocationDate;
+ internal X509Extensions crlEntryExtensions;
+
+ public CrlEntry(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 2 || seq.Count > 3)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ this.seq = seq;
+
+ userCertificate = DerInteger.GetInstance(seq[0]);
+ revocationDate = Time.GetInstance(seq[1]);
+ }
+
+ public DerInteger UserCertificate
+ {
+ get { return userCertificate; }
+ }
+
+ public Time RevocationDate
+ {
+ get { return revocationDate; }
+ }
+
+ public X509Extensions Extensions
+ {
+ get
+ {
+ if (crlEntryExtensions == null && seq.Count == 3)
+ {
+ crlEntryExtensions = X509Extensions.GetInstance(seq[2]);
+ }
+
+ return crlEntryExtensions;
+ }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return seq;
+ }
+ }
+
+ /**
+ * PKIX RFC-2459 - TbsCertList object.
+ *
+ * TbsCertList ::= Sequence {
+ * version Version OPTIONAL,
+ * -- if present, shall be v2
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * thisUpdate Time,
+ * nextUpdate Time OPTIONAL,
+ * revokedCertificates Sequence OF Sequence {
+ * userCertificate CertificateSerialNumber,
+ * revocationDate Time,
+ * crlEntryExtensions Extensions OPTIONAL
+ * -- if present, shall be v2
+ * } OPTIONAL,
+ * crlExtensions [0] EXPLICIT Extensions OPTIONAL
+ * -- if present, shall be v2
+ * }
+ *
+ */
+ public class TbsCertificateList
+ : Asn1Encodable
+ {
+ private class RevokedCertificatesEnumeration
+ : IEnumerable
+ {
+ private readonly IEnumerable en;
+
+ internal RevokedCertificatesEnumeration(
+ IEnumerable en)
+ {
+ this.en = en;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return new RevokedCertificatesEnumerator(en.GetEnumerator());
+ }
+
+ private class RevokedCertificatesEnumerator
+ : IEnumerator
+ {
+ private readonly IEnumerator e;
+
+ internal RevokedCertificatesEnumerator(
+ IEnumerator e)
+ {
+ this.e = e;
+ }
+
+ public bool MoveNext()
+ {
+ return e.MoveNext();
+ }
+
+ public void Reset()
+ {
+ e.Reset();
+ }
+
+ public object Current
+ {
+ get { return new CrlEntry(Asn1Sequence.GetInstance(e.Current)); }
+ }
+ }
+ }
+
+ internal Asn1Sequence seq;
+ internal DerInteger version;
+ internal AlgorithmIdentifier signature;
+ internal X509Name issuer;
+ internal Time thisUpdate;
+ internal Time nextUpdate;
+ internal Asn1Sequence revokedCertificates;
+ internal X509Extensions crlExtensions;
+
+ public static TbsCertificateList GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static TbsCertificateList GetInstance(
+ object obj)
+ {
+ TbsCertificateList list = obj as TbsCertificateList;
+
+ if (obj == null || list != null)
+ {
+ return list;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new TbsCertificateList((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ internal TbsCertificateList(
+ Asn1Sequence seq)
+ {
+ if (seq.Count < 3 || seq.Count > 7)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ int seqPos = 0;
+
+ this.seq = seq;
+
+ if (seq[seqPos] is DerInteger)
+ {
+ version = DerInteger.GetInstance(seq[seqPos++]);
+ }
+ else
+ {
+ version = new DerInteger(0);
+ }
+
+ signature = AlgorithmIdentifier.GetInstance(seq[seqPos++]);
+ issuer = X509Name.GetInstance(seq[seqPos++]);
+ thisUpdate = Time.GetInstance(seq[seqPos++]);
+
+ if (seqPos < seq.Count
+ && (seq[seqPos] is DerUtcTime
+ || seq[seqPos] is DerGeneralizedTime
+ || seq[seqPos] is Time))
+ {
+ nextUpdate = Time.GetInstance(seq[seqPos++]);
+ }
+
+ if (seqPos < seq.Count
+ && !(seq[seqPos] is DerTaggedObject))
+ {
+ revokedCertificates = Asn1Sequence.GetInstance(seq[seqPos++]);
+ }
+
+ if (seqPos < seq.Count
+ && seq[seqPos] is DerTaggedObject)
+ {
+ crlExtensions = X509Extensions.GetInstance(seq[seqPos]);
+ }
+ }
+
+ public int Version
+ {
+ get { return version.Value.IntValue + 1; }
+ }
+
+ public DerInteger VersionNumber
+ {
+ get { return version; }
+ }
+
+ public AlgorithmIdentifier Signature
+ {
+ get { return signature; }
+ }
+
+ public X509Name Issuer
+ {
+ get { return issuer; }
+ }
+
+ public Time ThisUpdate
+ {
+ get { return thisUpdate; }
+ }
+
+ public Time NextUpdate
+ {
+ get { return nextUpdate; }
+ }
+
+ public CrlEntry[] GetRevokedCertificates()
+ {
+ if (revokedCertificates == null)
+ {
+ return new CrlEntry[0];
+ }
+
+ CrlEntry[] entries = new CrlEntry[revokedCertificates.Count];
+
+ for (int i = 0; i < entries.Length; i++)
+ {
+ entries[i] = new CrlEntry(Asn1Sequence.GetInstance(revokedCertificates[i]));
+ }
+
+ return entries;
+ }
+
+ public IEnumerable GetRevokedCertificateEnumeration()
+ {
+ if (revokedCertificates == null)
+ {
+ return EmptyEnumerable.Instance;
+ }
+
+ return new RevokedCertificatesEnumeration(revokedCertificates);
+ }
+
+ public X509Extensions Extensions
+ {
+ get { return crlExtensions; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return seq;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/TBSCertificateStructure.cs b/iTechSharp/srcbc/asn1/x509/TBSCertificateStructure.cs
new file mode 100644
index 0000000..03bc6be
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/TBSCertificateStructure.cs
@@ -0,0 +1,189 @@
+using System;
+
+using Org.BouncyCastle.Asn1.Pkcs;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The TbsCertificate object.
+ *
+ * TbsCertificate ::= Sequence {
+ * version [ 0 ] Version DEFAULT v1(0),
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * extensions [ 3 ] Extensions OPTIONAL
+ * }
+ *
+ *
+ * Target ::= CHOICE {
+ * targetName [0] GeneralName,
+ * targetGroup [1] GeneralName,
+ * targetCert [2] TargetCert
+ * }
+ *
+ *
+ * obj
can be a Target or a {@link Asn1TaggedObject}null
.
+ * Target ::= CHOICE {
+ * targetName [0] GeneralName,
+ * targetGroup [1] GeneralName,
+ * targetCert [2] TargetCert
+ * }
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ // GeneralName is a choice already so most be explicitly tagged
+ if (targetName != null)
+ {
+ return new DerTaggedObject(true, 0, targetName);
+ }
+
+ return new DerTaggedObject(true, 1, targetGroup);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/TargetInformation.cs b/iTechSharp/srcbc/asn1/x509/TargetInformation.cs
new file mode 100644
index 0000000..75b18c0
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/TargetInformation.cs
@@ -0,0 +1,123 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * Target information extension for attributes certificates according to RFC
+ * 3281.
+ *
+ *
+ * SEQUENCE OF Targets
+ *
+ *
+ */
+ public class TargetInformation
+ : Asn1Encodable
+ {
+ private readonly Asn1Sequence targets;
+
+ /**
+ * Creates an instance of a TargetInformation from the given object.
+ * obj
can be a TargetInformation or a {@link Asn1Sequence}
+ * SEQUENCE OF Targets
+ *
+ *
+ *
+ * Targets ::= SEQUENCE OF Target
+ *
+ * Target ::= CHOICE {
+ * targetName [0] GeneralName,
+ * targetGroup [1] GeneralName,
+ * targetCert [2] TargetCert
+ * }
+ *
+ * TargetCert ::= SEQUENCE {
+ * targetCertificate IssuerSerial,
+ * targetName GeneralName OPTIONAL,
+ * certDigestInfo ObjectDigestInfo OPTIONAL
+ * }
+ *
+ *
+ * @see org.bouncycastle.asn1.x509.Target
+ * @see org.bouncycastle.asn1.x509.TargetInformation
+ */
+ public class Targets
+ : Asn1Encodable
+ {
+ private readonly Asn1Sequence targets;
+
+ /**
+ * Creates an instance of a Targets from the given object.
+ * obj
can be a Targets or a {@link Asn1Sequence}ArrayList
of {@link Target}s.
+ * @see Target
+ * @throws ArgumentException if the ArrayList contains not only Targets.
+ */
+ public Targets(
+ Target[] targets)
+ {
+ this.targets = new DerSequence(targets);
+ }
+
+ /**
+ * Returns the targets in an ArrayList
.
+ *
+ * Targets ::= SEQUENCE OF Target
+ *
+ *
+ * @return an Asn1Object
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return targets;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/Time.cs b/iTechSharp/srcbc/asn1/x509/Time.cs
new file mode 100644
index 0000000..b03cca7
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/Time.cs
@@ -0,0 +1,126 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class Time
+ : Asn1Encodable
+ {
+ internal Asn1Object time;
+
+ public static Time GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(obj.GetObject());
+ }
+
+ public Time(
+ Asn1Object time)
+ {
+ if (time == null)
+ throw new ArgumentNullException("time");
+
+ if (!(time is DerUtcTime) && !(time is DerGeneralizedTime))
+ {
+ throw new ArgumentException("unknown object passed to Time");
+ }
+
+ this.time = time;
+ }
+
+ /**
+ * creates a time object from a given date - if the date is between 1950
+ * and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime
+ * is used.
+ */
+ public Time(
+ DateTime date)
+ {
+ string d = date.ToString("yyyyMMddHHmmss") + "Z";
+
+ int year = Int32.Parse(d.Substring(0, 4));
+
+ if (year < 1950 || year > 2049)
+ {
+ time = new DerGeneralizedTime(d);
+ }
+ else
+ {
+ time = new DerUtcTime(d.Substring(2));
+ }
+ }
+
+ public static Time GetInstance(
+ object obj)
+ {
+ if (obj is Time)
+ {
+ return (Time) obj;
+ }
+
+ if (obj is DerUtcTime)
+ {
+ return new Time((DerUtcTime) obj);
+ }
+
+ if (obj is DerGeneralizedTime)
+ {
+ return new Time((DerGeneralizedTime) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public string GetTime()
+ {
+ if (time is DerUtcTime)
+ {
+ return ((DerUtcTime) time).AdjustedTimeString;
+ }
+
+ return ((DerGeneralizedTime) time).GetTime();
+ }
+
+ ///
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return time;
+ }
+
+ public override string ToString()
+ {
+ return GetTime();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/UserNotice.cs b/iTechSharp/srcbc/asn1/x509/UserNotice.cs
new file mode 100644
index 0000000..2878a18
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/UserNotice.cs
@@ -0,0 +1,104 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * UserNotice
class, used in
+ * CertificatePolicies
X509 extensions (in policy
+ * qualifiers).
+ *
+ * UserNotice ::= Sequence {
+ * noticeRef NoticeReference OPTIONAL,
+ * explicitText DisplayText OPTIONAL}
+ *
+ *
+ *
+ * @see PolicyQualifierId
+ * @see PolicyInformation
+ */
+ public class UserNotice
+ : Asn1Encodable
+ {
+ internal NoticeReference noticeRef;
+ internal DisplayText explicitText;
+
+ /**
+ * Creates a new UserNotice
instance.
+ *
+ * @param noticeRef a NoticeReference
value
+ * @param explicitText a DisplayText
value
+ */
+ public UserNotice(
+ NoticeReference noticeRef,
+ DisplayText explicitText)
+ {
+ this.noticeRef = noticeRef;
+ this.explicitText = explicitText;
+ }
+
+ /**
+ * Creates a new UserNotice
instance.
+ *
+ * @param noticeRef a NoticeReference
value
+ * @param str the explicitText field as a string.
+ */
+ public UserNotice(
+ NoticeReference noticeRef,
+ string str)
+ {
+ this.noticeRef = noticeRef;
+ this.explicitText = new DisplayText(str);
+ }
+
+ /**
+ * Creates a new UserNotice
instance.
+ * UserNotice
instance
+ * from its encodable/encoded form.
+ *
+ * @param as an ASN1Sequence
value obtained from either
+ * calling @{link toASN1Object()} for a UserNotice
+ * instance or from parsing it from a DER-encoded stream.
+ * TbsCertificate ::= Sequence {
+ * version [ 0 ] Version DEFAULT v1(0),
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * }
+ *
+ *
+ */
+ public class V1TbsCertificateGenerator
+ {
+ internal DerTaggedObject version = new DerTaggedObject(0, new DerInteger(0));
+ internal DerInteger serialNumber;
+ internal AlgorithmIdentifier signature;
+ internal X509Name issuer;
+ internal Time startDate, endDate;
+ internal X509Name subject;
+ internal SubjectPublicKeyInfo subjectPublicKeyInfo;
+
+ public V1TbsCertificateGenerator()
+ {
+ }
+
+ public void SetSerialNumber(
+ DerInteger serialNumber)
+ {
+ this.serialNumber = serialNumber;
+ }
+
+ public void SetSignature(
+ AlgorithmIdentifier signature)
+ {
+ this.signature = signature;
+ }
+
+ public void SetIssuer(
+ X509Name issuer)
+ {
+ this.issuer = issuer;
+ }
+
+ public void SetStartDate(
+ Time startDate)
+ {
+ this.startDate = startDate;
+ }
+
+ public void SetStartDate(
+ DerUtcTime startDate)
+ {
+ this.startDate = new Time(startDate);
+ }
+
+ public void SetEndDate(
+ Time endDate)
+ {
+ this.endDate = endDate;
+ }
+
+ public void SetEndDate(
+ DerUtcTime endDate)
+ {
+ this.endDate = new Time(endDate);
+ }
+
+ public void SetSubject(
+ X509Name subject)
+ {
+ this.subject = subject;
+ }
+
+ public void SetSubjectPublicKeyInfo(
+ SubjectPublicKeyInfo pubKeyInfo)
+ {
+ this.subjectPublicKeyInfo = pubKeyInfo;
+ }
+
+ public TbsCertificateStructure GenerateTbsCertificate()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (subject == null) || (subjectPublicKeyInfo == null))
+ {
+ throw new InvalidOperationException("not all mandatory fields set in V1 TBScertificate generator");
+ }
+
+ return new TbsCertificateStructure(
+ new DerSequence(
+ //version, - not required as default value
+ serialNumber,
+ signature,
+ issuer,
+ new DerSequence(startDate, endDate), // before and after dates
+ subject,
+ subjectPublicKeyInfo));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/V2AttributeCertificateInfoGenerator.cs b/iTechSharp/srcbc/asn1/x509/V2AttributeCertificateInfoGenerator.cs
new file mode 100644
index 0000000..02580b5
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/V2AttributeCertificateInfoGenerator.cs
@@ -0,0 +1,137 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * Generator for Version 2 AttributeCertificateInfo
+ *
+ * AttributeCertificateInfo ::= Sequence {
+ * version AttCertVersion -- version is v2,
+ * holder Holder,
+ * issuer AttCertIssuer,
+ * signature AlgorithmIdentifier,
+ * serialNumber CertificateSerialNumber,
+ * attrCertValidityPeriod AttCertValidityPeriod,
+ * attributes Sequence OF Attr,
+ * issuerUniqueID UniqueIdentifier OPTIONAL,
+ * extensions Extensions OPTIONAL
+ * }
+ *
+ *
+ */
+ public class V2AttributeCertificateInfoGenerator
+ {
+ internal DerInteger version;
+ internal Holder holder;
+ internal AttCertIssuer issuer;
+ internal AlgorithmIdentifier signature;
+ internal DerInteger serialNumber;
+// internal AttCertValidityPeriod attrCertValidityPeriod;
+ internal Asn1EncodableVector attributes;
+ internal DerBitString issuerUniqueID;
+ internal X509Extensions extensions;
+ internal DerGeneralizedTime startDate, endDate;
+
+ public V2AttributeCertificateInfoGenerator()
+ {
+ this.version = new DerInteger(1);
+ attributes = new Asn1EncodableVector();
+ }
+
+ public void SetHolder(
+ Holder holder)
+ {
+ this.holder = holder;
+ }
+
+ public void AddAttribute(
+ string oid,
+ Asn1Encodable value)
+ {
+ attributes.Add(new AttributeX509(new DerObjectIdentifier(oid), new DerSet(value)));
+ }
+
+ /**
+ * @param attribute
+ */
+ public void AddAttribute(AttributeX509 attribute)
+ {
+ attributes.Add(attribute);
+ }
+
+ public void SetSerialNumber(
+ DerInteger serialNumber)
+ {
+ this.serialNumber = serialNumber;
+ }
+
+ public void SetSignature(
+ AlgorithmIdentifier signature)
+ {
+ this.signature = signature;
+ }
+
+ public void SetIssuer(
+ AttCertIssuer issuer)
+ {
+ this.issuer = issuer;
+ }
+
+ public void SetStartDate(
+ DerGeneralizedTime startDate)
+ {
+ this.startDate = startDate;
+ }
+
+ public void SetEndDate(
+ DerGeneralizedTime endDate)
+ {
+ this.endDate = endDate;
+ }
+
+ public void SetIssuerUniqueID(
+ DerBitString issuerUniqueID)
+ {
+ this.issuerUniqueID = issuerUniqueID;
+ }
+
+ public void SetExtensions(
+ X509Extensions extensions)
+ {
+ this.extensions = extensions;
+ }
+
+ public AttributeCertificateInfo GenerateAttributeCertificateInfo()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (holder == null) || (attributes == null))
+ {
+ throw new InvalidOperationException("not all mandatory fields set in V2 AttributeCertificateInfo generator");
+ }
+
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, holder, issuer, signature, serialNumber);
+
+ //
+ // before and after dates => AttCertValidityPeriod
+ //
+ v.Add(new AttCertValidityPeriod(startDate, endDate));
+
+ // Attributes
+ v.Add(new DerSequence(attributes));
+
+ if (issuerUniqueID != null)
+ {
+ v.Add(issuerUniqueID);
+ }
+
+ if (extensions != null)
+ {
+ v.Add(extensions);
+ }
+
+ return AttributeCertificateInfo.GetInstance(new DerSequence(v));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/V2Form.cs b/iTechSharp/srcbc/asn1/x509/V2Form.cs
new file mode 100644
index 0000000..a9c4335
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/V2Form.cs
@@ -0,0 +1,125 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class V2Form
+ : Asn1Encodable
+ {
+ internal GeneralNames issuerName;
+ internal IssuerSerial baseCertificateID;
+ internal ObjectDigestInfo objectDigestInfo;
+
+ public static V2Form GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static V2Form GetInstance(
+ object obj)
+ {
+ if (obj is V2Form)
+ {
+ return (V2Form) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new V2Form((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public V2Form(
+ GeneralNames issuerName)
+ {
+ this.issuerName = issuerName;
+ }
+
+ private V2Form(
+ Asn1Sequence seq)
+ {
+ if (seq.Count > 3)
+ {
+ throw new ArgumentException("Bad sequence size: " + seq.Count);
+ }
+
+ int index = 0;
+
+ if (!(seq[0] is Asn1TaggedObject))
+ {
+ index++;
+ this.issuerName = GeneralNames.GetInstance(seq[0]);
+ }
+
+ for (int i = index; i != seq.Count; i++)
+ {
+ Asn1TaggedObject o = Asn1TaggedObject.GetInstance(seq[i]);
+ if (o.TagNo == 0)
+ {
+ baseCertificateID = IssuerSerial.GetInstance(o, false);
+ }
+ else if (o.TagNo == 1)
+ {
+ objectDigestInfo = ObjectDigestInfo.GetInstance(o, false);
+ }
+ else
+ {
+ throw new ArgumentException("Bad tag number: " + o.TagNo);
+ }
+ }
+ }
+
+ public GeneralNames IssuerName
+ {
+ get { return issuerName; }
+ }
+
+ public IssuerSerial BaseCertificateID
+ {
+ get { return baseCertificateID; }
+ }
+
+ public ObjectDigestInfo ObjectDigestInfo
+ {
+ get { return objectDigestInfo; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ *
+ * V2Form ::= Sequence {
+ * issuerName GeneralNames OPTIONAL,
+ * baseCertificateID [0] IssuerSerial OPTIONAL,
+ * objectDigestInfo [1] ObjectDigestInfo OPTIONAL
+ * -- issuerName MUST be present in this profile
+ * -- baseCertificateID and objectDigestInfo MUST NOT
+ * -- be present in this profile
+ * }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ if (issuerName != null)
+ {
+ v.Add(issuerName);
+ }
+
+ if (baseCertificateID != null)
+ {
+ v.Add(new DerTaggedObject(false, 0, baseCertificateID));
+ }
+
+ if (objectDigestInfo != null)
+ {
+ v.Add(new DerTaggedObject(false, 1, objectDigestInfo));
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/V2TBSCertListGenerator.cs b/iTechSharp/srcbc/asn1/x509/V2TBSCertListGenerator.cs
new file mode 100644
index 0000000..2624b30
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/V2TBSCertListGenerator.cs
@@ -0,0 +1,196 @@
+using System;
+using System.Collections;
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * Generator for Version 2 TbsCertList structures.
+ *
+ * TbsCertList ::= Sequence {
+ * version Version OPTIONAL,
+ * -- if present, shall be v2
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * thisUpdate Time,
+ * nextUpdate Time OPTIONAL,
+ * revokedCertificates Sequence OF Sequence {
+ * userCertificate CertificateSerialNumber,
+ * revocationDate Time,
+ * crlEntryExtensions Extensions OPTIONAL
+ * -- if present, shall be v2
+ * } OPTIONAL,
+ * crlExtensions [0] EXPLICIT Extensions OPTIONAL
+ * -- if present, shall be v2
+ * }
+ *
+ *
+ * Note: This class may be subject to change
+ */
+ public class V2TbsCertListGenerator
+ {
+ private DerInteger version = new DerInteger(1);
+ private AlgorithmIdentifier signature;
+ private X509Name issuer;
+ private Time thisUpdate, nextUpdate;
+ private X509Extensions extensions;
+ private ArrayList crlEntries;
+
+ public V2TbsCertListGenerator()
+ {
+ }
+
+ public void SetSignature(
+ AlgorithmIdentifier signature)
+ {
+ this.signature = signature;
+ }
+
+ public void SetIssuer(
+ X509Name issuer)
+ {
+ this.issuer = issuer;
+ }
+
+ public void SetThisUpdate(
+ DerUtcTime thisUpdate)
+ {
+ this.thisUpdate = new Time(thisUpdate);
+ }
+
+ public void SetNextUpdate(
+ DerUtcTime nextUpdate)
+ {
+ this.nextUpdate = (nextUpdate != null)
+ ? new Time(nextUpdate)
+ : null;
+ }
+
+ public void SetThisUpdate(
+ Time thisUpdate)
+ {
+ this.thisUpdate = thisUpdate;
+ }
+
+ public void SetNextUpdate(
+ Time nextUpdate)
+ {
+ this.nextUpdate = nextUpdate;
+ }
+
+ public void AddCrlEntry(
+ Asn1Sequence crlEntry)
+ {
+ if (crlEntries == null)
+ {
+ crlEntries = new ArrayList();
+ }
+
+ crlEntries.Add(crlEntry);
+ }
+
+ public void AddCrlEntry(DerInteger userCertificate, DerUtcTime revocationDate, int reason)
+ {
+ AddCrlEntry(userCertificate, new Time(revocationDate), reason);
+ }
+
+ public void AddCrlEntry(DerInteger userCertificate, Time revocationDate, int reason)
+ {
+ AddCrlEntry(userCertificate, revocationDate, reason, null);
+ }
+
+ public void AddCrlEntry(DerInteger userCertificate, Time revocationDate, int reason,
+ DerGeneralizedTime invalidityDate)
+ {
+ ArrayList extOids = new ArrayList();
+ ArrayList extValues = new ArrayList();
+
+ if (reason != 0)
+ {
+ CrlReason crlReason = new CrlReason(reason);
+
+ try
+ {
+ extOids.Add(X509Extensions.ReasonCode);
+ extValues.Add(new X509Extension(false, new DerOctetString(crlReason.GetEncoded())));
+ }
+ catch (IOException e)
+ {
+ throw new ArgumentException("error encoding reason: " + e);
+ }
+ }
+
+ if (invalidityDate != null)
+ {
+ try
+ {
+ extOids.Add(X509Extensions.InvalidityDate);
+ extValues.Add(new X509Extension(false, new DerOctetString(invalidityDate.GetEncoded())));
+ }
+ catch (IOException e)
+ {
+ throw new ArgumentException("error encoding invalidityDate: " + e);
+ }
+ }
+
+ if (extOids.Count != 0)
+ {
+ AddCrlEntry(userCertificate, revocationDate, new X509Extensions(extOids, extValues));
+ }
+ else
+ {
+ AddCrlEntry(userCertificate, revocationDate, null);
+ }
+ }
+
+ public void AddCrlEntry(DerInteger userCertificate, Time revocationDate, X509Extensions extensions)
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ userCertificate, revocationDate);
+
+ if (extensions != null)
+ {
+ v.Add(extensions);
+ }
+
+ AddCrlEntry(new DerSequence(v));
+ }
+
+ public void SetExtensions(
+ X509Extensions extensions)
+ {
+ this.extensions = extensions;
+ }
+
+ public TbsCertificateList GenerateTbsCertList()
+ {
+ if ((signature == null) || (issuer == null) || (thisUpdate == null))
+ {
+ throw new InvalidOperationException("Not all mandatory fields set in V2 TbsCertList generator.");
+ }
+
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, signature, issuer, thisUpdate);
+
+ if (nextUpdate != null)
+ {
+ v.Add(nextUpdate);
+ }
+
+ // Add CRLEntries if they exist
+ if (crlEntries != null)
+ {
+ Asn1Sequence[] certs = (Asn1Sequence[]) crlEntries.ToArray(typeof(Asn1Sequence));
+
+ v.Add(new DerSequence(certs));
+ }
+
+ if (extensions != null)
+ {
+ v.Add(new DerTaggedObject(0, extensions));
+ }
+
+ return new TbsCertificateList(new DerSequence(v));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/V3TBSCertificateGenerator.cs b/iTechSharp/srcbc/asn1/x509/V3TBSCertificateGenerator.cs
new file mode 100644
index 0000000..5df7755
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/V3TBSCertificateGenerator.cs
@@ -0,0 +1,144 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * Generator for Version 3 TbsCertificateStructures.
+ *
+ * TbsCertificate ::= Sequence {
+ * version [ 0 ] Version DEFAULT v1(0),
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * extensions [ 3 ] Extensions OPTIONAL
+ * }
+ *
+ *
+ */
+ public class V3TbsCertificateGenerator
+ {
+ internal DerTaggedObject version = new DerTaggedObject(0, new DerInteger(2));
+ internal DerInteger serialNumber;
+ internal AlgorithmIdentifier signature;
+ internal X509Name issuer;
+ internal Time startDate, endDate;
+ internal X509Name subject;
+ internal SubjectPublicKeyInfo subjectPublicKeyInfo;
+ internal X509Extensions extensions;
+
+ private bool altNamePresentAndCritical;
+
+ public V3TbsCertificateGenerator()
+ {
+ }
+
+ public void SetSerialNumber(
+ DerInteger serialNumber)
+ {
+ this.serialNumber = serialNumber;
+ }
+
+ public void SetSignature(
+ AlgorithmIdentifier signature)
+ {
+ this.signature = signature;
+ }
+
+ public void SetIssuer(
+ X509Name issuer)
+ {
+ this.issuer = issuer;
+ }
+
+ public void SetStartDate(
+ DerUtcTime startDate)
+ {
+ this.startDate = new Time(startDate);
+ }
+
+ public void SetStartDate(
+ Time startDate)
+ {
+ this.startDate = startDate;
+ }
+
+ public void SetEndDate(
+ DerUtcTime endDate)
+ {
+ this.endDate = new Time(endDate);
+ }
+
+ public void SetEndDate(
+ Time endDate)
+ {
+ this.endDate = endDate;
+ }
+
+ public void SetSubject(
+ X509Name subject)
+ {
+ this.subject = subject;
+ }
+
+ public void SetSubjectPublicKeyInfo(
+ SubjectPublicKeyInfo pubKeyInfo)
+ {
+ this.subjectPublicKeyInfo = pubKeyInfo;
+ }
+
+ public void SetExtensions(
+ X509Extensions extensions)
+ {
+ this.extensions = extensions;
+
+ if (extensions != null)
+ {
+ X509Extension altName = extensions.GetExtension(X509Extensions.SubjectAlternativeName);
+
+ if (altName != null && altName.IsCritical)
+ {
+ altNamePresentAndCritical = true;
+ }
+ }
+ }
+
+ public TbsCertificateStructure GenerateTbsCertificate()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (subject == null && !altNamePresentAndCritical)
+ || (subjectPublicKeyInfo == null))
+ {
+ throw new InvalidOperationException("not all mandatory fields set in V3 TBScertificate generator");
+ }
+
+ DerSequence validity = new DerSequence(startDate, endDate); // before and after dates
+
+ Asn1EncodableVector v = new Asn1EncodableVector(
+ version, serialNumber, signature, issuer, validity);
+
+ if (subject != null)
+ {
+ v.Add(subject);
+ }
+ else
+ {
+ v.Add(DerSequence.Empty);
+ }
+
+ v.Add(subjectPublicKeyInfo);
+
+ if (extensions != null)
+ {
+ v.Add(new DerTaggedObject(3, extensions));
+ }
+
+ return new TbsCertificateStructure(new DerSequence(v));
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/X509Attributes.cs b/iTechSharp/srcbc/asn1/x509/X509Attributes.cs
new file mode 100644
index 0000000..291329a
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/X509Attributes.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ public class X509Attributes
+ {
+ public static readonly DerObjectIdentifier RoleSyntax = new DerObjectIdentifier("2.5.4.72");
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/X509CertificateStructure.cs b/iTechSharp/srcbc/asn1/x509/X509CertificateStructure.cs
new file mode 100644
index 0000000..6773e4e
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/X509CertificateStructure.cs
@@ -0,0 +1,133 @@
+using System;
+
+using Org.BouncyCastle.Asn1.Pkcs;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * an X509Certificate structure.
+ *
+ * Certificate ::= Sequence {
+ * tbsCertificate TbsCertificate,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING
+ * }
+ *
+ */
+ public class X509CertificateStructure
+ : Asn1Encodable
+ {
+ private readonly TbsCertificateStructure tbsCert;
+ private readonly AlgorithmIdentifier sigAlgID;
+ private readonly DerBitString sig;
+
+ public static X509CertificateStructure GetInstance(
+ Asn1TaggedObject obj,
+ bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
+ public static X509CertificateStructure GetInstance(
+ object obj)
+ {
+ if (obj is X509CertificateStructure)
+ {
+ return (X509CertificateStructure) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new X509CertificateStructure((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public X509CertificateStructure(
+ TbsCertificateStructure tbsCert,
+ AlgorithmIdentifier sigAlgID,
+ DerBitString sig)
+ {
+ if (tbsCert == null)
+ throw new ArgumentNullException("tbsCert");
+ if (sigAlgID == null)
+ throw new ArgumentNullException("sigAlgID");
+ if (sig == null)
+ throw new ArgumentNullException("sig");
+
+ this.tbsCert = tbsCert;
+ this.sigAlgID = sigAlgID;
+ this.sig = sig;
+ }
+
+ private X509CertificateStructure(
+ Asn1Sequence seq)
+ {
+ if (seq.Count != 3)
+ throw new ArgumentException("sequence wrong size for a certificate", "seq");
+
+ //
+ // correct x509 certficate
+ //
+ tbsCert = TbsCertificateStructure.GetInstance(seq[0]);
+ sigAlgID = AlgorithmIdentifier.GetInstance(seq[1]);
+ sig = DerBitString.GetInstance(seq[2]);
+ }
+
+ public TbsCertificateStructure TbsCertificate
+ {
+ get { return tbsCert; }
+ }
+
+ public int Version
+ {
+ get { return tbsCert.Version; }
+ }
+
+ public DerInteger SerialNumber
+ {
+ get { return tbsCert.SerialNumber; }
+ }
+
+ public X509Name Issuer
+ {
+ get { return tbsCert.Issuer; }
+ }
+
+ public Time StartDate
+ {
+ get { return tbsCert.StartDate; }
+ }
+
+ public Time EndDate
+ {
+ get { return tbsCert.EndDate; }
+ }
+
+ public X509Name Subject
+ {
+ get { return tbsCert.Subject; }
+ }
+
+ public SubjectPublicKeyInfo SubjectPublicKeyInfo
+ {
+ get { return tbsCert.SubjectPublicKeyInfo; }
+ }
+
+ public AlgorithmIdentifier SignatureAlgorithm
+ {
+ get { return sigAlgID; }
+ }
+
+ public DerBitString Signature
+ {
+ get { return sig; }
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(tbsCert, sigAlgID, sig);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/X509DefaultEntryConverter.cs b/iTechSharp/srcbc/asn1/x509/X509DefaultEntryConverter.cs
new file mode 100644
index 0000000..0d68a3d
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/X509DefaultEntryConverter.cs
@@ -0,0 +1,62 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * The default converter for X509 DN entries when going from their
+ * string value to ASN.1 strings.
+ */
+ public class X509DefaultEntryConverter
+ : X509NameEntryConverter
+ {
+ /**
+ * Apply default conversion for the given value depending on the oid
+ * and the character range of the value.
+ *
+ * @param oid the object identifier for the DN entry
+ * @param value the value associated with it
+ * @return the ASN.1 equivalent for the string value.
+ */
+ public override Asn1Object GetConvertedValue(
+ DerObjectIdentifier oid,
+ string value)
+ {
+ if (value.Length != 0 && value[0] == '#')
+ {
+ try
+ {
+ return ConvertHexEncoded(value, 1);
+ }
+ catch (IOException)
+ {
+ throw new Exception("can't recode value for oid " + oid.Id);
+ }
+ }
+
+ if (value.Length != 0 && value[0] == '\\')
+ {
+ value = value.Substring(1);
+ }
+
+ if (oid.Equals(X509Name.EmailAddress) || oid.Equals(X509Name.DC))
+ {
+ return new DerIA5String(value);
+ }
+
+ if (oid.Equals(X509Name.DateOfBirth)) // accept time string as well as # (for compatibility)
+ {
+ return new DerGeneralizedTime(value);
+ }
+
+ if (oid.Equals(X509Name.C)
+ || oid.Equals(X509Name.SerialNumber)
+ || oid.Equals(X509Name.DnQualifier))
+ {
+ return new DerPrintableString(value);
+ }
+
+ return new DerUtf8String(value);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/X509Extension.cs b/iTechSharp/srcbc/asn1/x509/X509Extension.cs
new file mode 100644
index 0000000..e3298cf
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/X509Extension.cs
@@ -0,0 +1,74 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * an object for the elements in the X.509 V3 extension block.
+ */
+ public class X509Extension
+ {
+ internal bool critical;
+ internal Asn1OctetString value;
+
+ public X509Extension(
+ DerBoolean critical,
+ Asn1OctetString value)
+ {
+ if (critical == null)
+ {
+ throw new ArgumentNullException("critical");
+ }
+
+ this.critical = critical.IsTrue;
+ this.value = value;
+ }
+
+ public X509Extension(
+ bool critical,
+ Asn1OctetString value)
+ {
+ this.critical = critical;
+ this.value = value;
+ }
+
+ public bool IsCritical { get { return critical; } }
+
+ public Asn1OctetString Value { get { return value; } }
+
+ public override int GetHashCode()
+ {
+ int vh = this.Value.GetHashCode();
+
+ return IsCritical ? vh : ~vh;
+ }
+
+ public override bool Equals(
+ object obj)
+ {
+ X509Extension other = obj as X509Extension;
+ if (other == null)
+ {
+ return false;
+ }
+
+ return Value.Equals(other.Value) && IsCritical == other.IsCritical;
+ }
+
+ ///
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension ::= SEQUENCE {
+ * extnId EXTENSION.&id ({ExtensionSet}),
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING }
+ *
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector vec = new Asn1EncodableVector();
+
+ foreach (DerObjectIdentifier oid in ordering)
+ {
+ X509Extension ext = (X509Extension) extensions[oid];
+ Asn1EncodableVector v = new Asn1EncodableVector(oid);
+
+ if (ext.IsCritical)
+ {
+ v.Add(DerBoolean.True);
+ }
+
+ v.Add(ext.Value);
+
+ vec.Add(new DerSequence(v));
+ }
+
+ return new DerSequence(vec);
+ }
+
+ public bool Equivalent(
+ X509Extensions other)
+ {
+ if (extensions.Count != other.extensions.Count)
+ return false;
+
+ foreach (DerObjectIdentifier oid in extensions.Keys)
+ {
+ if (!extensions[oid].Equals(other.extensions[oid]))
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/X509ExtensionsGenerator.cs b/iTechSharp/srcbc/asn1/x509/X509ExtensionsGenerator.cs
new file mode 100644
index 0000000..abe1cf9
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/X509ExtensionsGenerator.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ ///
+ * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ *
+ * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type OBJECT IDENTIFIER,
+ * value ANY }
+ *
+ */
+ public class X509Name
+ : Asn1Encodable
+ {
+ /**
+ * country code - StringType(SIZE(2))
+ */
+ public static readonly DerObjectIdentifier C = new DerObjectIdentifier("2.5.4.6");
+
+ /**
+ * organization - StringType(SIZE(1..64))
+ */
+ public static readonly DerObjectIdentifier O = new DerObjectIdentifier("2.5.4.10");
+
+ /**
+ * organizational unit name - StringType(SIZE(1..64))
+ */
+ public static readonly DerObjectIdentifier OU = new DerObjectIdentifier("2.5.4.11");
+
+ /**
+ * Title
+ */
+ public static readonly DerObjectIdentifier T = new DerObjectIdentifier("2.5.4.12");
+
+ /**
+ * common name - StringType(SIZE(1..64))
+ */
+ public static readonly DerObjectIdentifier CN = new DerObjectIdentifier("2.5.4.3");
+
+ /**
+ * street - StringType(SIZE(1..64))
+ */
+ public static readonly DerObjectIdentifier Street = new DerObjectIdentifier("2.5.4.9");
+
+ /**
+ * device serial number name - StringType(SIZE(1..64))
+ */
+ public static readonly DerObjectIdentifier SerialNumber = new DerObjectIdentifier("2.5.4.5");
+
+ /**
+ * locality name - StringType(SIZE(1..64))
+ */
+ public static readonly DerObjectIdentifier L = new DerObjectIdentifier("2.5.4.7");
+
+ /**
+ * state, or province name - StringType(SIZE(1..64))
+ */
+ public static readonly DerObjectIdentifier ST = new DerObjectIdentifier("2.5.4.8");
+
+ /**
+ * Naming attributes of type X520name
+ */
+ public static readonly DerObjectIdentifier Surname = new DerObjectIdentifier("2.5.4.4");
+ public static readonly DerObjectIdentifier GivenName = new DerObjectIdentifier("2.5.4.42");
+ public static readonly DerObjectIdentifier Initials = new DerObjectIdentifier("2.5.4.43");
+ public static readonly DerObjectIdentifier Generation = new DerObjectIdentifier("2.5.4.44");
+ public static readonly DerObjectIdentifier UniqueIdentifier = new DerObjectIdentifier("2.5.4.45");
+
+ /**
+ * businessCategory - DirectoryString(SIZE(1..128)
+ */
+ public static readonly DerObjectIdentifier BusinessCategory = new DerObjectIdentifier(
+ "2.5.4.15");
+
+ /**
+ * postalCode - DirectoryString(SIZE(1..40)
+ */
+ public static readonly DerObjectIdentifier PostalCode = new DerObjectIdentifier(
+ "2.5.4.17");
+
+ /**
+ * dnQualifier - DirectoryString(SIZE(1..64)
+ */
+ public static readonly DerObjectIdentifier DnQualifier = new DerObjectIdentifier(
+ "2.5.4.46");
+
+ /**
+ * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64)
+ */
+ public static readonly DerObjectIdentifier Pseudonym = new DerObjectIdentifier(
+ "2.5.4.65");
+
+ /**
+ * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z
+ */
+ public static readonly DerObjectIdentifier DateOfBirth = new DerObjectIdentifier(
+ "1.3.6.1.5.5.7.9.1");
+
+ /**
+ * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128)
+ */
+ public static readonly DerObjectIdentifier PlaceOfBirth = new DerObjectIdentifier(
+ "1.3.6.1.5.5.7.9.2");
+
+ /**
+ * RFC 3039 DateOfBirth - PrintableString (SIZE(1)) -- "M", "F", "m" or "f"
+ */
+ public static readonly DerObjectIdentifier Gender = new DerObjectIdentifier(
+ "1.3.6.1.5.5.7.9.3");
+
+ /**
+ * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166
+ * codes only
+ */
+ public static readonly DerObjectIdentifier CountryOfCitizenship = new DerObjectIdentifier(
+ "1.3.6.1.5.5.7.9.4");
+
+ /**
+ * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166
+ * codes only
+ */
+ public static readonly DerObjectIdentifier CountryOfResidence = new DerObjectIdentifier(
+ "1.3.6.1.5.5.7.9.5");
+
+ /**
+ * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64)
+ */
+ public static readonly DerObjectIdentifier NameAtBirth = new DerObjectIdentifier("1.3.36.8.3.14");
+
+ /**
+ * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF
+ * DirectoryString(SIZE(1..30))
+ */
+ public static readonly DerObjectIdentifier PostalAddress = new DerObjectIdentifier("2.5.4.16");
+
+ /**
+ * id-at-telephoneNumber
+ */
+ public static readonly DerObjectIdentifier TelephoneNumber = new DerObjectIdentifier("2.5.4.20");
+
+ /**
+ * Email address (RSA PKCS#9 extension) - IA5String.
+ *
+ * If reverse is true, create the encoded version of the sequence
+ * starting from the last element in the string.
+ * @param reverse true if we should start scanning from the end (RFC 2553).
+ * @param lookUp table of names and their oids.
+ * @param dirName the X.500 string to be parsed.
+ */
+ public X509Name(
+ bool reverse,
+ Hashtable lookUp,
+ string dirName)
+ : this(reverse, lookUp, dirName, new X509DefaultEntryConverter())
+ {
+ }
+
+ private DerObjectIdentifier DecodeOid(
+ string name,
+ IDictionary lookUp)
+ {
+ if (name.ToUpper(CultureInfo.InvariantCulture).StartsWith("OID."))
+ {
+ return new DerObjectIdentifier(name.Substring(4));
+ }
+ else if (name[0] >= '0' && name[0] <= '9')
+ {
+ return new DerObjectIdentifier(name);
+ }
+
+ DerObjectIdentifier oid = (DerObjectIdentifier)lookUp[name.ToLower(CultureInfo.InvariantCulture)];
+ if (oid == null)
+ {
+ throw new ArgumentException("Unknown object id - " + name + " - passed to distinguished name");
+ }
+
+ return oid;
+ }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes. lookUp
+ * should provide a table of lookups, indexed by lowercase only strings and
+ * yielding a DerObjectIdentifier, other than that OID. and numeric oids
+ * will be processed automatically. The passed in converter is used to convert the
+ * string values to the right of each equals sign to their ASN.1 counterparts.
+ *
+ * @param reverse true if we should start scanning from the end, false otherwise.
+ * @param lookUp table of names and oids.
+ * @param dirName the string dirName
+ * @param converter the converter to convert string values into their ASN.1 equivalents
+ */
+ public X509Name(
+ bool reverse,
+ IDictionary lookUp,
+ string dirName,
+ X509NameEntryConverter converter)
+ {
+ this.converter = converter;
+ X509NameTokenizer nTok = new X509NameTokenizer(dirName);
+
+ while (nTok.HasMoreTokens())
+ {
+ string token = nTok.NextToken();
+ int index = token.IndexOf('=');
+
+ if (index == -1)
+ {
+ throw new ArgumentException("badly formated directory string");
+ }
+
+ string name = token.Substring(0, index);
+ string value = token.Substring(index + 1);
+ DerObjectIdentifier oid = DecodeOid(name, lookUp);
+
+ if (value.IndexOf('+') > 0)
+ {
+ X509NameTokenizer vTok = new X509NameTokenizer(value, '+');
+ string v = vTok.NextToken();
+
+ this.ordering.Add(oid);
+ this.values.Add(v);
+ this.added.Add(false);
+
+ while (vTok.HasMoreTokens())
+ {
+ string sv = vTok.NextToken();
+ int ndx = sv.IndexOf('=');
+
+ string nm = sv.Substring(0, ndx);
+ string vl = sv.Substring(ndx + 1);
+ this.ordering.Add(DecodeOid(nm, lookUp));
+ this.values.Add(vl);
+ this.added.Add(true);
+ }
+ }
+ else
+ {
+ this.ordering.Add(oid);
+ this.values.Add(value);
+ this.added.Add(false);
+ }
+ }
+
+ if (reverse)
+ {
+// this.ordering.Reverse();
+// this.values.Reverse();
+// this.added.Reverse();
+ ArrayList o = new ArrayList();
+ ArrayList v = new ArrayList();
+ ArrayList a = new ArrayList();
+ int count = 1;
+
+ for (int i = 0; i < this.ordering.Count; i++)
+ {
+ if (!((bool) this.added[i]))
+ {
+ count = 0;
+ }
+
+ int index = count++;
+
+ o.Insert(index, this.ordering[i]);
+ v.Insert(index, this.values[i]);
+ a.Insert(index, this.added[i]);
+ }
+
+ this.ordering = o;
+ this.values = v;
+ this.added = a;
+ }
+ }
+
+ /**
+ * return an ArrayList of the oids in the name, in the order they were found.
+ */
+ public ArrayList GetOids()
+ {
+ return (ArrayList) ordering.Clone();
+ }
+
+ /**
+ * return an ArrayList of the values found in the name, in the order they
+ * were found.
+ */
+ public ArrayList GetValues()
+ {
+ return (ArrayList) values.Clone();
+ }
+
+ /**
+ * return an ArrayList of the values found in the name, in the order they
+ * were found, with the DN label corresponding to passed in oid.
+ */
+ public ArrayList GetValues(
+ DerObjectIdentifier oid)
+ {
+ ArrayList v = new ArrayList();
+
+ for (int i = 0; i != values.Count; i++)
+ {
+ if (ordering[i].Equals(oid))
+ {
+ string val = (string)values[i];
+
+ if (val.StartsWith("\\#"))
+ {
+ val = val.Substring(1);
+ }
+
+ v.Add(val);
+ }
+ }
+
+ return v;
+ }
+
+ public override Asn1Object ToAsn1Object()
+ {
+ if (seq == null)
+ {
+ Asn1EncodableVector vec = new Asn1EncodableVector();
+ Asn1EncodableVector sVec = new Asn1EncodableVector();
+ DerObjectIdentifier lstOid = null;
+
+ for (int i = 0; i != ordering.Count; i++)
+ {
+ DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i];
+ string str = (string)values[i];
+
+ if (lstOid == null
+ || ((bool)this.added[i]))
+ {
+ }
+ else
+ {
+ vec.Add(new DerSet(sVec));
+ sVec = new Asn1EncodableVector();
+ }
+
+ sVec.Add(
+ new DerSequence(
+ oid,
+ converter.GetConvertedValue(oid, str)));
+
+ lstOid = oid;
+ }
+
+ vec.Add(new DerSet(sVec));
+
+ seq = new DerSequence(vec);
+ }
+
+ return seq;
+ }
+
+ [Obsolete("Use 'Equivalent(X509Name, int)' instead")]
+ public bool Equals(
+ X509Name other,
+ bool inOrder)
+ {
+ return Equivalent(other, inOrder);
+ }
+
+ /// The X509Name object to test equivalency against.
+ /// If true, the order of elements must be the same,
+ /// as well as the values associated with each element.
+ public bool Equivalent(
+ X509Name other,
+ bool inOrder)
+ {
+ if (!inOrder)
+ return this.Equivalent(other);
+
+ if (other == null)
+ return false;
+
+ if (other == this)
+ return true;
+
+ int orderingSize = ordering.Count;
+
+ if (orderingSize != other.ordering.Count)
+ return false;
+
+ for (int i = 0; i < orderingSize; i++)
+ {
+ DerObjectIdentifier oid = (DerObjectIdentifier) ordering[i];
+ DerObjectIdentifier oOid = (DerObjectIdentifier) other.ordering[i];
+
+ if (!oid.Equals(oOid))
+ return false;
+
+ string val = (string) values[i];
+ string oVal = (string) other.values[i];
+
+ if (!equivalentStrings(val, oVal))
+ return false;
+ }
+
+ return true;
+ }
+
+ [Obsolete("Use 'Equivalent(X509Name)' instead")]
+ public bool Equals(
+ X509Name other)
+ {
+ return Equivalent(other);
+ }
+
+ /**
+ * test for equivalence - note: case is ignored.
+ */
+ public bool Equivalent(
+ X509Name other)
+ {
+ if (other == null)
+ return false;
+
+ if (other == this)
+ return true;
+
+ int orderingSize = ordering.Count;
+
+ if (orderingSize != other.ordering.Count)
+ {
+ return false;
+ }
+
+ bool[] indexes = new bool[orderingSize];
+ int start, end, delta;
+
+ if (ordering[0].Equals(other.ordering[0])) // guess forward
+ {
+ start = 0;
+ end = orderingSize;
+ delta = 1;
+ }
+ else // guess reversed - most common problem
+ {
+ start = orderingSize - 1;
+ end = -1;
+ delta = -1;
+ }
+
+ for (int i = start; i != end; i += delta)
+ {
+ bool found = false;
+ DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i];
+ string value = (string)values[i];
+
+ for (int j = 0; j < orderingSize; j++)
+ {
+ if (indexes[j])
+ {
+ continue;
+ }
+
+ DerObjectIdentifier oOid = (DerObjectIdentifier)other.ordering[j];
+
+ if (oid.Equals(oOid))
+ {
+ string oValue = (string)other.values[j];
+
+ if (equivalentStrings(value, oValue))
+ {
+ indexes[j] = true;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private bool equivalentStrings(
+ string s1,
+ string s2)
+ {
+ string value = s1.ToLower(CultureInfo.InvariantCulture).Trim();
+ string oValue = s2.ToLower(CultureInfo.InvariantCulture).Trim();
+
+ if (!value.Equals(oValue))
+ {
+ value = stripInternalSpaces(value);
+ oValue = stripInternalSpaces(oValue);
+
+ if (!value.Equals(oValue))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private string stripInternalSpaces(
+ string str)
+ {
+ StringBuilder res = new StringBuilder();
+
+ if (str.Length != 0)
+ {
+ char c1 = str[0];
+
+ res.Append(c1);
+
+ for (int k = 1; k < str.Length; k++)
+ {
+ char c2 = str[k];
+ if (!(c1 == ' ' && c2 == ' '))
+ {
+ res.Append(c2);
+ }
+ c1 = c2;
+ }
+ }
+
+ return res.ToString();
+ }
+
+ private void AppendValue(
+ StringBuilder buf,
+ Hashtable oidSymbols,
+ DerObjectIdentifier oid,
+ string val)
+ {
+ string sym = (string) oidSymbols[oid];
+
+ if (sym != null)
+ {
+ buf.Append(sym);
+ }
+ else
+ {
+ buf.Append(oid.Id);
+ }
+
+ buf.Append('=');
+
+ int index = buf.Length;
+
+ buf.Append(val);
+
+ int end = buf.Length;
+
+ if (val.StartsWith("\\#"))
+ {
+ index += 2;
+ }
+
+ while (index != end)
+ {
+ if ((buf[index] == ',')
+ || (buf[index] == '"')
+ || (buf[index] == '\\')
+ || (buf[index] == '+')
+ || (buf[index] == '<')
+ || (buf[index] == '>')
+ || (buf[index] == ';'))
+ {
+ buf.Insert(index++, "\\");
+ end++;
+ }
+
+ index++;
+ }
+ }
+
+ /**
+ * convert the structure to a string - if reverse is true the
+ * oids and values are listed out starting with the last element
+ * in the sequence (ala RFC 2253), otherwise the string will begin
+ * with the first element of the structure. If no string definition
+ * for the oid is found in oidSymbols the string value of the oid is
+ * added. Two standard symbol tables are provided DefaultSymbols, and
+ * RFC2253Symbols as part of this class.
+ *
+ * @param reverse if true start at the end of the sequence and work back.
+ * @param oidSymbols look up table strings for oids.
+ */
+ public string ToString(
+ bool reverse,
+ Hashtable oidSymbols)
+ {
+ StringBuilder buf = new StringBuilder();
+ ArrayList components = new ArrayList();
+ bool first = true;
+
+ StringBuilder ava = null;
+
+ for (int i = 0; i < ordering.Count; i++)
+ {
+ if ((bool) added[i])
+ {
+ ava.Append('+');
+ AppendValue(ava, oidSymbols,
+ (DerObjectIdentifier)ordering[i],
+ (string)values[i]);
+ }
+ else
+ {
+ ava = new StringBuilder();
+ AppendValue(ava, oidSymbols,
+ (DerObjectIdentifier)ordering[i],
+ (string)values[i]);
+ components.Add(ava);
+ }
+ }
+
+ if (reverse)
+ {
+ for (int i = components.Count - 1; i >= 0; i--)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ buf.Append(',');
+ }
+
+ buf.Append(components[i].ToString());
+ }
+ }
+ else
+ {
+ for (int i = 0; i < components.Count; i++)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ buf.Append(',');
+ }
+
+ buf.Append(components[i].ToString());
+ }
+ }
+
+ return buf.ToString();
+ }
+
+ public override string ToString()
+ {
+ return ToString(DefaultReverse, DefaultSymbols);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/asn1/x509/X509NameEntryConverter.cs b/iTechSharp/srcbc/asn1/x509/X509NameEntryConverter.cs
new file mode 100644
index 0000000..5872656
--- /dev/null
+++ b/iTechSharp/srcbc/asn1/x509/X509NameEntryConverter.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * It turns out that the number of standard ways the fields in a DN should be
+ * encoded into their ASN.1 counterparts is rapidly approaching the
+ * number of machines on the internet. By default the X509Name class
+ * will produce UTF8Strings in line with the current recommendations (RFC 3280).
+ *
+ * public class X509DirEntryConverter
+ * : X509NameEntryConverter
+ * {
+ * public Asn1Object GetConvertedValue(
+ * DerObjectIdentifier oid,
+ * string value)
+ * {
+ * if (str.Length() != 0 && str.charAt(0) == '#')
+ * {
+ * return ConvertHexEncoded(str, 1);
+ * }
+ * if (oid.Equals(EmailAddress))
+ * {
+ * return new DerIA5String(str);
+ * }
+ * else if (CanBePrintable(str))
+ * {
+ * return new DerPrintableString(str);
+ * }
+ * else if (CanBeUTF8(str))
+ * {
+ * return new DerUtf8String(str);
+ * }
+ * else
+ * {
+ * return new DerBmpString(str);
+ * }
+ * }
+ * }
+ *
+ *
+ * BiometricData ::= SEQUENCE { + * typeOfBiometricData TypeOfBiometricData, + * hashAlgorithm AlgorithmIdentifier, + * biometricDataHash OCTET STRING, + * sourceDataUri IA5String OPTIONAL } + *+ */ + public class BiometricData + : Asn1Encodable + { + private readonly TypeOfBiometricData typeOfBiometricData; + private readonly AlgorithmIdentifier hashAlgorithm; + private readonly Asn1OctetString biometricDataHash; + private readonly DerIA5String sourceDataUri; + + public static BiometricData GetInstance( + object obj) + { + if (obj == null || obj is BiometricData) + { + return (BiometricData)obj; + } + + if (obj is Asn1Sequence) + { + return new BiometricData(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj"); + } + + private BiometricData( + Asn1Sequence seq) + { + typeOfBiometricData = TypeOfBiometricData.GetInstance(seq[0]); + hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]); + biometricDataHash = Asn1OctetString.GetInstance(seq[2]); + + if (seq.Count > 3) + { + sourceDataUri = DerIA5String.GetInstance(seq[3]); + } + } + + public BiometricData( + TypeOfBiometricData typeOfBiometricData, + AlgorithmIdentifier hashAlgorithm, + Asn1OctetString biometricDataHash, + DerIA5String sourceDataUri) + { + this.typeOfBiometricData = typeOfBiometricData; + this.hashAlgorithm = hashAlgorithm; + this.biometricDataHash = biometricDataHash; + this.sourceDataUri = sourceDataUri; + } + + public BiometricData( + TypeOfBiometricData typeOfBiometricData, + AlgorithmIdentifier hashAlgorithm, + Asn1OctetString biometricDataHash) + { + this.typeOfBiometricData = typeOfBiometricData; + this.hashAlgorithm = hashAlgorithm; + this.biometricDataHash = biometricDataHash; + this.sourceDataUri = null; + } + + public TypeOfBiometricData TypeOfBiometricData + { + get { return typeOfBiometricData; } + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public Asn1OctetString BiometricDataHash + { + get { return biometricDataHash; } + } + + public DerIA5String SourceDataUri + { + get { return sourceDataUri; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector seq = new Asn1EncodableVector( + typeOfBiometricData, hashAlgorithm, biometricDataHash); + + if (sourceDataUri != null) + { + seq.Add(sourceDataUri); + } + + return new DerSequence(seq); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs new file mode 100644 index 0000000..86a4eee --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs @@ -0,0 +1,19 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + public abstract class EtsiQCObjectIdentifiers + { + // + // base id + // + public static readonly DerObjectIdentifier IdEtsiQcs = new DerObjectIdentifier("0.4.0.1862.1"); + + public static readonly DerObjectIdentifier IdEtsiQcsQcCompliance = new DerObjectIdentifier(IdEtsiQcs+".1"); + public static readonly DerObjectIdentifier IdEtsiQcsLimitValue = new DerObjectIdentifier(IdEtsiQcs+".2"); + public static readonly DerObjectIdentifier IdEtsiQcsRetentionPeriod = new DerObjectIdentifier(IdEtsiQcs+".3"); + public static readonly DerObjectIdentifier IdEtsiQcsQcSscd = new DerObjectIdentifier(IdEtsiQcs+".4"); + } +} diff --git a/iTechSharp/srcbc/asn1/x509/qualified/Iso4217CurrencyCode.cs b/iTechSharp/srcbc/asn1/x509/qualified/Iso4217CurrencyCode.cs new file mode 100644 index 0000000..cfb6449 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/qualified/Iso4217CurrencyCode.cs @@ -0,0 +1,84 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The Iso4217CurrencyCode object. + *
+ * Iso4217CurrencyCode ::= CHOICE { + * alphabetic PrintableString (SIZE 3), --Recommended + * numeric INTEGER (1..999) } + * -- Alphabetic or numeric currency code as defined in ISO 4217 + * -- It is recommended that the Alphabetic form is used + *+ */ + public class Iso4217CurrencyCode + : Asn1Encodable + { + internal const int AlphabeticMaxSize = 3; + internal const int NumericMinSize = 1; + internal const int NumericMaxSize = 999; + + internal Asn1Encodable obj; +// internal int numeric; + + public static Iso4217CurrencyCode GetInstance( + object obj) + { + if (obj == null || obj is Iso4217CurrencyCode) + { + return (Iso4217CurrencyCode) obj; + } + + if (obj is DerInteger) + { + DerInteger numericobj = DerInteger.GetInstance(obj); + int numeric = numericobj.Value.IntValue; + return new Iso4217CurrencyCode(numeric); + } + + if (obj is DerPrintableString) + { + DerPrintableString alphabetic = DerPrintableString.GetInstance(obj); + return new Iso4217CurrencyCode(alphabetic.GetString()); + } + + throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj"); + } + + public Iso4217CurrencyCode( + int numeric) + { + if (numeric > NumericMaxSize || numeric < NumericMinSize) + { + throw new ArgumentException("wrong size in numeric code : not in (" +NumericMinSize +".."+ NumericMaxSize +")"); + } + + obj = new DerInteger(numeric); + } + + public Iso4217CurrencyCode( + string alphabetic) + { + if (alphabetic.Length > AlphabeticMaxSize) + { + throw new ArgumentException("wrong size in alphabetic code : max size is " + AlphabeticMaxSize); + } + + obj = new DerPrintableString(alphabetic); + } + + public bool IsAlphabetic { get { return obj is DerPrintableString; } } + + public string Alphabetic { get { return ((DerPrintableString) obj).GetString(); } } + + public int Numeric { get { return ((DerInteger)obj).Value.IntValue; } } + + public override Asn1Object ToAsn1Object() + { + return obj.ToAsn1Object(); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x509/qualified/MonetaryValue.cs b/iTechSharp/srcbc/asn1/x509/qualified/MonetaryValue.cs new file mode 100644 index 0000000..45e1136 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/qualified/MonetaryValue.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The MonetaryValue object. + *
+ * MonetaryValue ::= SEQUENCE { + * currency Iso4217CurrencyCode, + * amount INTEGER, + * exponent INTEGER } + * -- value = amount * 10^exponent + *+ */ + public class MonetaryValue + : Asn1Encodable + { + internal Iso4217CurrencyCode currency; + internal DerInteger amount; + internal DerInteger exponent; + + public static MonetaryValue GetInstance( + object obj) + { + if (obj == null || obj is MonetaryValue) + { + return (MonetaryValue) obj; + } + + if (obj is Asn1Sequence) + { + return new MonetaryValue(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj"); + } + + private MonetaryValue( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + currency = Iso4217CurrencyCode.GetInstance(seq[0]); + amount = DerInteger.GetInstance(seq[1]); + exponent = DerInteger.GetInstance(seq[2]); + } + + public MonetaryValue( + Iso4217CurrencyCode currency, + int amount, + int exponent) + { + this.currency = currency; + this.amount = new DerInteger(amount); + this.exponent = new DerInteger(exponent); + } + + public Iso4217CurrencyCode Currency + { + get { return currency; } + } + + public BigInteger Amount + { + get { return amount.Value; } + } + + public BigInteger Exponent + { + get { return exponent.Value; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(currency, amount, exponent); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x509/qualified/QCStatement.cs b/iTechSharp/srcbc/asn1/x509/qualified/QCStatement.cs new file mode 100644 index 0000000..317f034 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/qualified/QCStatement.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The QCStatement object. + *
+ * QCStatement ::= SEQUENCE { + * statementId OBJECT IDENTIFIER, + * statementInfo ANY DEFINED BY statementId OPTIONAL} + *+ */ + public class QCStatement + : Asn1Encodable + { + private readonly DerObjectIdentifier qcStatementId; + private readonly Asn1Encodable qcStatementInfo; + + public static QCStatement GetInstance( + object obj) + { + if (obj == null || obj is QCStatement) + { + return (QCStatement) obj; + } + + if (obj is Asn1Sequence) + { + return new QCStatement(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj"); + } + + private QCStatement( + Asn1Sequence seq) + { + qcStatementId = DerObjectIdentifier.GetInstance(seq[0]); + + if (seq.Count > 1) + { + qcStatementInfo = seq[1]; + } + } + + public QCStatement( + DerObjectIdentifier qcStatementId) + { + this.qcStatementId = qcStatementId; + } + + public QCStatement( + DerObjectIdentifier qcStatementId, + Asn1Encodable qcStatementInfo) + { + this.qcStatementId = qcStatementId; + this.qcStatementInfo = qcStatementInfo; + } + + public DerObjectIdentifier StatementId + { + get { return qcStatementId; } + } + + public Asn1Encodable StatementInfo + { + get { return qcStatementInfo; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector seq = new Asn1EncodableVector(qcStatementId); + + if (qcStatementInfo != null) + { + seq.Add(qcStatementInfo); + } + + return new DerSequence(seq); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs new file mode 100644 index 0000000..8ebd69e --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs @@ -0,0 +1,21 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + public sealed class Rfc3739QCObjectIdentifiers + { + private Rfc3739QCObjectIdentifiers() + { + } + + // + // base id + // + public static readonly DerObjectIdentifier IdQcs = new DerObjectIdentifier("1.3.6.1.5.5.7.11"); + + public static readonly DerObjectIdentifier IdQcsPkixQCSyntaxV1 = new DerObjectIdentifier(IdQcs+".1"); + public static readonly DerObjectIdentifier IdQcsPkixQCSyntaxV2 = new DerObjectIdentifier(IdQcs+".2"); + } +} diff --git a/iTechSharp/srcbc/asn1/x509/qualified/SemanticsInformation.cs b/iTechSharp/srcbc/asn1/x509/qualified/SemanticsInformation.cs new file mode 100644 index 0000000..72e7cd0 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/qualified/SemanticsInformation.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The SemanticsInformation object. + *
+ * SemanticsInformation ::= SEQUENCE { + * semanticsIdentifier OBJECT IDENTIFIER OPTIONAL, + * nameRegistrationAuthorities NameRegistrationAuthorities + * OPTIONAL } + * (WITH COMPONENTS {..., semanticsIdentifier PRESENT}| + * WITH COMPONENTS {..., nameRegistrationAuthorities PRESENT}) + * + * NameRegistrationAuthorities ::= SEQUENCE SIZE (1..MAX) OF + * GeneralName + *+ */ + public class SemanticsInformation + : Asn1Encodable + { + private readonly DerObjectIdentifier semanticsIdentifier; + private readonly GeneralName[] nameRegistrationAuthorities; + + public static SemanticsInformation GetInstance( + object obj) + { + if (obj == null || obj is SemanticsInformation) + { + return (SemanticsInformation) obj; + } + + if (obj is Asn1Sequence) + { + return new SemanticsInformation(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj"); + } + + public SemanticsInformation( + Asn1Sequence seq) + { + if (seq.Count < 1) + { + throw new ArgumentException("no objects in SemanticsInformation"); + } + + IEnumerator e = seq.GetEnumerator(); + e.MoveNext(); + object obj = e.Current; + if (obj is DerObjectIdentifier) + { + semanticsIdentifier = DerObjectIdentifier.GetInstance(obj); + if (e.MoveNext()) + { + obj = e.Current; + } + else + { + obj = null; + } + } + + if (obj != null) + { + Asn1Sequence generalNameSeq = Asn1Sequence.GetInstance(obj ); + nameRegistrationAuthorities = new GeneralName[generalNameSeq.Count]; + for (int i= 0; i < generalNameSeq.Count; i++) + { + nameRegistrationAuthorities[i] = GeneralName.GetInstance(generalNameSeq[i]); + } + } + } + + public SemanticsInformation( + DerObjectIdentifier semanticsIdentifier, + GeneralName[] generalNames) + { + this.semanticsIdentifier = semanticsIdentifier; + this.nameRegistrationAuthorities = generalNames; + } + + public SemanticsInformation( + DerObjectIdentifier semanticsIdentifier) + { + this.semanticsIdentifier = semanticsIdentifier; + } + + public SemanticsInformation( + GeneralName[] generalNames) + { + this.nameRegistrationAuthorities = generalNames; + } + + public DerObjectIdentifier SemanticsIdentifier { get { return semanticsIdentifier; } } + + public GeneralName[] GetNameRegistrationAuthorities() + { + return nameRegistrationAuthorities; + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector seq = new Asn1EncodableVector(); + + if (this.semanticsIdentifier != null) + { + seq.Add(semanticsIdentifier); + } + + if (this.nameRegistrationAuthorities != null) + { + seq.Add(new DerSequence(nameRegistrationAuthorities)); + } + + return new DerSequence(seq); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x509/qualified/TypeOfBiometricData.cs b/iTechSharp/srcbc/asn1/x509/qualified/TypeOfBiometricData.cs new file mode 100644 index 0000000..51b3118 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/qualified/TypeOfBiometricData.cs @@ -0,0 +1,91 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The TypeOfBiometricData object. + *
+ * TypeOfBiometricData ::= CHOICE { + * predefinedBiometricType PredefinedBiometricType, + * biometricDataOid OBJECT IDENTIFIER } + * + * PredefinedBiometricType ::= INTEGER { + * picture(0),handwritten-signature(1)} + * (picture|handwritten-signature) + *+ */ + public class TypeOfBiometricData + : Asn1Encodable + { + public const int Picture = 0; + public const int HandwrittenSignature = 1; + + internal Asn1Encodable obj; + + public static TypeOfBiometricData GetInstance( + object obj) + { + if (obj == null || obj is TypeOfBiometricData) + { + return (TypeOfBiometricData) obj; + } + + if (obj is DerInteger) + { + DerInteger predefinedBiometricTypeObj = DerInteger.GetInstance(obj); + int predefinedBiometricType = predefinedBiometricTypeObj.Value.IntValue; + + return new TypeOfBiometricData(predefinedBiometricType); + } + + if (obj is DerObjectIdentifier) + { + DerObjectIdentifier BiometricDataOid = DerObjectIdentifier.GetInstance(obj); + return new TypeOfBiometricData(BiometricDataOid); + } + + throw new ArgumentException("unknown object in GetInstance: " + obj.GetType().FullName, "obj"); + } + + public TypeOfBiometricData( + int predefinedBiometricType) + { + if (predefinedBiometricType == Picture || predefinedBiometricType == HandwrittenSignature) + { + obj = new DerInteger(predefinedBiometricType); + } + else + { + throw new ArgumentException("unknow PredefinedBiometricType : " + predefinedBiometricType); + } + } + + public TypeOfBiometricData( + DerObjectIdentifier biometricDataOid) + { + obj = biometricDataOid; + } + + public bool IsPredefined + { + get { return obj is DerInteger; } + } + + public int PredefinedBiometricType + { + get { return ((DerInteger) obj).Value.IntValue; } + } + + public DerObjectIdentifier BiometricDataOid + { + get { return (DerObjectIdentifier) obj; } + } + + public override Asn1Object ToAsn1Object() + { + return obj.ToAsn1Object(); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x509/sigi/NameOrPseudonym.cs b/iTechSharp/srcbc/asn1/x509/sigi/NameOrPseudonym.cs new file mode 100644 index 0000000..8e86823 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/sigi/NameOrPseudonym.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X500; + +namespace Org.BouncyCastle.Asn1.X509.SigI +{ + /** + * Structure for a name or pseudonym. + * + *
+ * NameOrPseudonym ::= CHOICE { + * surAndGivenName SEQUENCE { + * surName DirectoryString, + * givenName SEQUENCE OF DirectoryString + * }, + * pseudonym DirectoryString + * } + *+ * + * @see org.bouncycastle.asn1.x509.sigi.PersonalData + * + */ + public class NameOrPseudonym + : Asn1Encodable + //, Asn1Choice + { + private readonly DirectoryString pseudonym; + private readonly DirectoryString surname; + private readonly Asn1Sequence givenName; + + public static NameOrPseudonym GetInstance( + object obj) + { + if (obj == null || obj is NameOrPseudonym) + { + return (NameOrPseudonym)obj; + } + + if (obj is IAsn1String) + { + return new NameOrPseudonym(DirectoryString.GetInstance(obj)); + } + + if (obj is Asn1Sequence) + { + return new NameOrPseudonym((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj"); + } + + /** + * Constructor from DERString. + * + * The sequence is of type NameOrPseudonym: + * + *
+ * NameOrPseudonym ::= CHOICE { + * surAndGivenName SEQUENCE { + * surName DirectoryString, + * givenName SEQUENCE OF DirectoryString + * }, + * pseudonym DirectoryString + * } + *+ * @param pseudonym pseudonym value to use. + */ + public NameOrPseudonym( + DirectoryString pseudonym) + { + this.pseudonym = pseudonym; + } + + /** + * Constructor from Asn1Sequence. + * + * The sequence is of type NameOrPseudonym: + * + *
+ * NameOrPseudonym ::= CHOICE { + * surAndGivenName SEQUENCE { + * surName DirectoryString, + * givenName SEQUENCE OF DirectoryString + * }, + * pseudonym DirectoryString + * } + *+ * + * @param seq The ASN.1 sequence. + */ + private NameOrPseudonym( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + if (!(seq[0] is IAsn1String)) + throw new ArgumentException("Bad object encountered: " + seq[0].GetType().Name); + + surname = DirectoryString.GetInstance(seq[0]); + givenName = Asn1Sequence.GetInstance(seq[1]); + } + + /** + * Constructor from a given details. + * + * @param pseudonym The pseudonym. + */ + public NameOrPseudonym( + string pseudonym) + : this(new DirectoryString(pseudonym)) + { + } + + /** + * Constructor from a given details. + * + * @param surname The surname. + * @param givenName A sequence of directory strings making up the givenName + */ + public NameOrPseudonym( + DirectoryString surname, + Asn1Sequence givenName) + { + this.surname = surname; + this.givenName = givenName; + } + + public DirectoryString Pseudonym + { + get { return pseudonym; } + } + + public DirectoryString Surname + { + get { return surname; } + } + + public DirectoryString[] GetGivenName() + { + DirectoryString[] items = new DirectoryString[givenName.Count]; + int count = 0; + foreach (object o in givenName) + { + items[count++] = DirectoryString.GetInstance(o); + } + return items; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * + * Returns: + * + *
+ * NameOrPseudonym ::= CHOICE { + * surAndGivenName SEQUENCE { + * surName DirectoryString, + * givenName SEQUENCE OF DirectoryString + * }, + * pseudonym DirectoryString + * } + *+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + if (pseudonym != null) + { + return pseudonym.ToAsn1Object(); + } + + return new DerSequence(surname, givenName); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x509/sigi/PersonalData.cs b/iTechSharp/srcbc/asn1/x509/sigi/PersonalData.cs new file mode 100644 index 0000000..6acdc73 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/sigi/PersonalData.cs @@ -0,0 +1,210 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.X509.SigI +{ + /** + * Contains personal data for the otherName field in the subjectAltNames + * extension. + * + *
+ * PersonalData ::= SEQUENCE { + * nameOrPseudonym NameOrPseudonym, + * nameDistinguisher [0] INTEGER OPTIONAL, + * dateOfBirth [1] GeneralizedTime OPTIONAL, + * placeOfBirth [2] DirectoryString OPTIONAL, + * gender [3] PrintableString OPTIONAL, + * postalAddress [4] DirectoryString OPTIONAL + * } + *+ * + * @see org.bouncycastle.asn1.x509.sigi.NameOrPseudonym + * @see org.bouncycastle.asn1.x509.sigi.SigIObjectIdentifiers + */ + public class PersonalData + : Asn1Encodable + { + private readonly NameOrPseudonym nameOrPseudonym; + private readonly BigInteger nameDistinguisher; + private readonly DerGeneralizedTime dateOfBirth; + private readonly DirectoryString placeOfBirth; + private readonly string gender; + private readonly DirectoryString postalAddress; + + public static PersonalData GetInstance( + object obj) + { + if (obj == null || obj is PersonalData) + { + return (PersonalData) obj; + } + + if (obj is Asn1Sequence) + { + return new PersonalData((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj"); + } + + /** + * Constructor from Asn1Sequence. + * + * The sequence is of type NameOrPseudonym: + * + *
+ * PersonalData ::= SEQUENCE { + * nameOrPseudonym NameOrPseudonym, + * nameDistinguisher [0] INTEGER OPTIONAL, + * dateOfBirth [1] GeneralizedTime OPTIONAL, + * placeOfBirth [2] DirectoryString OPTIONAL, + * gender [3] PrintableString OPTIONAL, + * postalAddress [4] DirectoryString OPTIONAL + * } + *+ * + * @param seq The ASN.1 sequence. + */ + private PersonalData( + Asn1Sequence seq) + { + if (seq.Count < 1) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + IEnumerator e = seq.GetEnumerator(); + e.MoveNext(); + + nameOrPseudonym = NameOrPseudonym.GetInstance(e.Current); + + while (e.MoveNext()) + { + Asn1TaggedObject o = Asn1TaggedObject.GetInstance(e.Current); + int tag = o.TagNo; + switch (tag) + { + case 0: + nameDistinguisher = DerInteger.GetInstance(o, false).Value; + break; + case 1: + dateOfBirth = DerGeneralizedTime.GetInstance(o, false); + break; + case 2: + placeOfBirth = DirectoryString.GetInstance(o, true); + break; + case 3: + gender = DerPrintableString.GetInstance(o, false).GetString(); + break; + case 4: + postalAddress = DirectoryString.GetInstance(o, true); + break; + default: + throw new ArgumentException("Bad tag number: " + o.TagNo); + } + } + } + + /** + * Constructor from a given details. + * + * @param nameOrPseudonym Name or pseudonym. + * @param nameDistinguisher Name distinguisher. + * @param dateOfBirth Date of birth. + * @param placeOfBirth Place of birth. + * @param gender Gender. + * @param postalAddress Postal Address. + */ + public PersonalData( + NameOrPseudonym nameOrPseudonym, + BigInteger nameDistinguisher, + DerGeneralizedTime dateOfBirth, + DirectoryString placeOfBirth, + string gender, + DirectoryString postalAddress) + { + this.nameOrPseudonym = nameOrPseudonym; + this.dateOfBirth = dateOfBirth; + this.gender = gender; + this.nameDistinguisher = nameDistinguisher; + this.postalAddress = postalAddress; + this.placeOfBirth = placeOfBirth; + } + + public NameOrPseudonym NameOrPseudonym + { + get { return nameOrPseudonym; } + } + + public BigInteger NameDistinguisher + { + get { return nameDistinguisher; } + } + + public DerGeneralizedTime DateOfBirth + { + get { return dateOfBirth; } + } + + public DirectoryString PlaceOfBirth + { + get { return placeOfBirth; } + } + + public string Gender + { + get { return gender; } + } + + public DirectoryString PostalAddress + { + get { return postalAddress; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * + * Returns: + * + *
+ * PersonalData ::= SEQUENCE { + * nameOrPseudonym NameOrPseudonym, + * nameDistinguisher [0] INTEGER OPTIONAL, + * dateOfBirth [1] GeneralizedTime OPTIONAL, + * placeOfBirth [2] DirectoryString OPTIONAL, + * gender [3] PrintableString OPTIONAL, + * postalAddress [4] DirectoryString OPTIONAL + * } + *+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector vec = new Asn1EncodableVector(); + vec.Add(nameOrPseudonym); + if (nameDistinguisher != null) + { + vec.Add(new DerTaggedObject(false, 0, new DerInteger(nameDistinguisher))); + } + if (dateOfBirth != null) + { + vec.Add(new DerTaggedObject(false, 1, dateOfBirth)); + } + if (placeOfBirth != null) + { + vec.Add(new DerTaggedObject(true, 2, placeOfBirth)); + } + if (gender != null) + { + vec.Add(new DerTaggedObject(false, 3, new DerPrintableString(gender, true))); + } + if (postalAddress != null) + { + vec.Add(new DerTaggedObject(true, 4, postalAddress)); + } + return new DerSequence(vec); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x509/sigi/SigIObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/x509/sigi/SigIObjectIdentifiers.cs new file mode 100644 index 0000000..682311a --- /dev/null +++ b/iTechSharp/srcbc/asn1/x509/sigi/SigIObjectIdentifiers.cs @@ -0,0 +1,49 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509.SigI +{ + /** + * Object Identifiers of SigI specifciation (German Signature Law + * Interoperability specification). + */ + public sealed class SigIObjectIdentifiers + { + private SigIObjectIdentifiers() + { + } + + public readonly static DerObjectIdentifier IdSigI = new DerObjectIdentifier("1.3.36.8"); + + /** + * Key purpose IDs for German SigI (Signature Interoperability + * Specification) + */ + public readonly static DerObjectIdentifier IdSigIKP = new DerObjectIdentifier(IdSigI + ".2"); + + /** + * Certificate policy IDs for German SigI (Signature Interoperability + * Specification) + */ + public readonly static DerObjectIdentifier IdSigICP = new DerObjectIdentifier(IdSigI + ".1"); + + /** + * Other Name IDs for German SigI (Signature Interoperability Specification) + */ + public readonly static DerObjectIdentifier IdSigION = new DerObjectIdentifier(IdSigI + ".4"); + + /** + * To be used for for the generation of directory service certificates. + */ + public static readonly DerObjectIdentifier IdSigIKPDirectoryService = new DerObjectIdentifier(IdSigIKP + ".1"); + + /** + * ID for PersonalData + */ + public static readonly DerObjectIdentifier IdSigIONPersonalData = new DerObjectIdentifier(IdSigION + ".1"); + + /** + * Certificate is conform to german signature law. + */ + public static readonly DerObjectIdentifier IdSigICPSigConform = new DerObjectIdentifier(IdSigICP + ".1"); + } +} diff --git a/iTechSharp/srcbc/asn1/x9/KeySpecificInfo.cs b/iTechSharp/srcbc/asn1/x9/KeySpecificInfo.cs new file mode 100644 index 0000000..4629864 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/KeySpecificInfo.cs @@ -0,0 +1,58 @@ +using System.Collections; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Diffie-Hellman key exchange KeySpecificInfo structure. See + * RFC 2631, or X9.42, for further details. + */ + public class KeySpecificInfo + : Asn1Encodable + { + private DerObjectIdentifier algorithm; + private Asn1OctetString counter; + + public KeySpecificInfo( + DerObjectIdentifier algorithm, + Asn1OctetString counter) + { + this.algorithm = algorithm; + this.counter = counter; + } + + public KeySpecificInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + algorithm = (DerObjectIdentifier)e.Current; + e.MoveNext(); + counter = (Asn1OctetString)e.Current; + } + + public DerObjectIdentifier Algorithm + { + get { return algorithm; } + } + + public Asn1OctetString Counter + { + get { return counter; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+ * KeySpecificInfo ::= Sequence { + * algorithm OBJECT IDENTIFIER, + * counter OCTET STRING SIZE (4..4) + * } + *+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algorithm, counter); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/OtherInfo.cs b/iTechSharp/srcbc/asn1/x9/OtherInfo.cs new file mode 100644 index 0000000..21863bd --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/OtherInfo.cs @@ -0,0 +1,88 @@ +using System.Collections; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ANS.1 def for Diffie-Hellman key exchange OtherInfo structure. See + * RFC 2631, or X9.42, for further details. + */ + public class OtherInfo + : Asn1Encodable + { + private KeySpecificInfo keyInfo; + private Asn1OctetString partyAInfo; + private Asn1OctetString suppPubInfo; + + public OtherInfo( + KeySpecificInfo keyInfo, + Asn1OctetString partyAInfo, + Asn1OctetString suppPubInfo) + { + this.keyInfo = keyInfo; + this.partyAInfo = partyAInfo; + this.suppPubInfo = suppPubInfo; + } + + public OtherInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + keyInfo = new KeySpecificInfo((Asn1Sequence) e.Current); + + while (e.MoveNext()) + { + DerTaggedObject o = (DerTaggedObject) e.Current; + + if (o.TagNo == 0) + { + partyAInfo = (Asn1OctetString) o.GetObject(); + } + else if ((int) o.TagNo == 2) + { + suppPubInfo = (Asn1OctetString) o.GetObject(); + } + } + } + + public KeySpecificInfo KeyInfo + { + get { return keyInfo; } + } + + public Asn1OctetString PartyAInfo + { + get { return partyAInfo; } + } + + public Asn1OctetString SuppPubInfo + { + get { return suppPubInfo; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+ * OtherInfo ::= Sequence { + * keyInfo KeySpecificInfo, + * partyAInfo [0] OCTET STRING OPTIONAL, + * suppPubInfo [2] OCTET STRING + * } + *+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(keyInfo); + + if (partyAInfo != null) + { + v.Add(new DerTaggedObject(0, partyAInfo)); + } + + v.Add(new DerTaggedObject(2, suppPubInfo)); + + return new DerSequence(v); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X962NamedCurves.cs b/iTechSharp/srcbc/asn1/x9/X962NamedCurves.cs new file mode 100644 index 0000000..f12aafb --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X962NamedCurves.cs @@ -0,0 +1,732 @@ +using System; +using System.Collections; +using System.Globalization; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * table of the current named curves defined in X.962 EC-DSA. + */ + public sealed class X962NamedCurves + { + private X962NamedCurves() + { + } + + internal class Prime192v1Holder + : X9ECParametersHolder + { + private Prime192v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v1Holder(); + + protected override X9ECParameters CreateParameters() + { + ECCurve cFp192v1 = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), + new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); + + return new X9ECParameters( + cFp192v1, + cFp192v1.DecodePoint( + Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), + new BigInteger("ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16), + BigInteger.One, + Hex.Decode("3045AE6FC8422f64ED579528D38120EAE12196D5")); + } + } + + internal class Prime192v2Holder + : X9ECParametersHolder + { + private Prime192v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v2Holder(); + + protected override X9ECParameters CreateParameters() + { + ECCurve cFp192v2 = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), + new BigInteger("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953", 16)); + + return new X9ECParameters( + cFp192v2, + cFp192v2.DecodePoint( + Hex.Decode("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a")), + new BigInteger("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31", 16), + BigInteger.One, + Hex.Decode("31a92ee2029fd10d901b113e990710f0d21ac6b6")); + } + } + + internal class Prime192v3Holder + : X9ECParametersHolder + { + private Prime192v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v3Holder(); + + protected override X9ECParameters CreateParameters() + { + ECCurve cFp192v3 = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), + new BigInteger("22123dc2395a05caa7423daeccc94760a7d462256bd56916", 16)); + + return new X9ECParameters( + cFp192v3, + cFp192v3.DecodePoint( + Hex.Decode("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896")), + new BigInteger("ffffffffffffffffffffffff7a62d031c83f4294f640ec13", 16), + BigInteger.One, + Hex.Decode("c469684435deb378c4b65ca9591e2a5763059a2e")); + } + } + + internal class Prime239v1Holder + : X9ECParametersHolder + { + private Prime239v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v1Holder(); + + protected override X9ECParameters CreateParameters() + { + ECCurve cFp239v1 = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); + + return new X9ECParameters( + cFp239v1, + cFp239v1.DecodePoint( + Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), + new BigInteger("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b", 16), + BigInteger.One, + Hex.Decode("e43bb460f0b80cc0c0b075798e948060f8321b7d")); + } + } + + internal class Prime239v2Holder + : X9ECParametersHolder + { + private Prime239v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v2Holder(); + + protected override X9ECParameters CreateParameters() + { + ECCurve cFp239v2 = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), + new BigInteger("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c", 16)); + + return new X9ECParameters( + cFp239v2, + cFp239v2.DecodePoint( + Hex.Decode("0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7")), + new BigInteger("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063", 16), + BigInteger.One, + Hex.Decode("e8b4011604095303ca3b8099982be09fcb9ae616")); + } + } + + internal class Prime239v3Holder + : X9ECParametersHolder + { + private Prime239v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v3Holder(); + + protected override X9ECParameters CreateParameters() + { + ECCurve cFp239v3 = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), + new BigInteger("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e", 16)); + + return new X9ECParameters( + cFp239v3, + cFp239v3.DecodePoint( + Hex.Decode("036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a")), + new BigInteger("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551", 16), + BigInteger.One, + Hex.Decode("7d7374168ffe3471b60a857686a19475d3bfa2ff")); + } + } + + internal class Prime256v1Holder + : X9ECParametersHolder + { + private Prime256v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime256v1Holder(); + + protected override X9ECParameters CreateParameters() + { + ECCurve cFp256v1 = new FpCurve( + new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"), + new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), + new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16)); + + return new X9ECParameters( + cFp256v1, + cFp256v1.DecodePoint( + Hex.Decode("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")), + new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), + BigInteger.One, + Hex.Decode("c49d360886e704936a6678e1139d26b7819f7e90")); + } + } + + /* + * F2m Curves + */ + internal class C2pnb163v1Holder + : X9ECParametersHolder + { + private C2pnb163v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0400000000000000000001E60FC8821CC74DAEAFC1", 16); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve c2m163v1 = new F2mCurve( + 163, + 1, 2, 8, + new BigInteger("072546B5435234A422E0789675F432C89435DE5242", 16), + new BigInteger("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", 16), + n, h); + + return new X9ECParameters( + c2m163v1, + c2m163v1.DecodePoint( + Hex.Decode("0307AF69989546103D79329FCC3D74880F33BBE803CB")), + n, h, + Hex.Decode("D2COFB15760860DEF1EEF4D696E6768756151754")); + } + } + + internal class C2pnb163v2Holder + : X9ECParametersHolder + { + private C2pnb163v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 16); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve c2m163v2 = new F2mCurve( + 163, + 1, 2, 8, + new BigInteger("0108B39E77C4B108BED981ED0E890E117C511CF072", 16), + new BigInteger("0667ACEB38AF4E488C407433FFAE4F1C811638DF20", 16), + n, h); + + return new X9ECParameters( + c2m163v2, + c2m163v2.DecodePoint( + Hex.Decode("030024266E4EB5106D0A964D92C4860E2671DB9B6CC5")), + n, h, + null); + } + } + + internal class C2pnb163v3Holder + : X9ECParametersHolder + { + private C2pnb163v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 16); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve c2m163v3 = new F2mCurve( + 163, + 1, 2, 8, + new BigInteger("07A526C63D3E25A256A007699F5447E32AE456B50E", 16), + new BigInteger("03F7061798EB99E238FD6F1BF95B48FEEB4854252B", 16), + n, h); + + return new X9ECParameters( + c2m163v3, + c2m163v3.DecodePoint(Hex.Decode("0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB")), + n, h, + null); + } + } + + internal class C2pnb176w1Holder + : X9ECParametersHolder + { + private C2pnb176w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb176w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("010092537397ECA4F6145799D62B0A19CE06FE26AD", 16); + BigInteger h = BigInteger.ValueOf(0xFF6E); + + ECCurve c2m176w1 = new F2mCurve( + 176, + 1, 2, 43, + new BigInteger("00E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", 16), + new BigInteger("005DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", 16), + n, h); + + return new X9ECParameters( + c2m176w1, + c2m176w1.DecodePoint( + Hex.Decode("038D16C2866798B600F9F08BB4A8E860F3298CE04A5798")), + n, h, + null); + } + } + + internal class C2tnb191v1Holder + : X9ECParametersHolder + { + private C2tnb191v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("40000000000000000000000004A20E90C39067C893BBB9A5", 16); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve c2m191v1 = new F2mCurve( + 191, + 9, + new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16), + new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16), + n, h); + + return new X9ECParameters( + c2m191v1, + c2m191v1.DecodePoint( + Hex.Decode("0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D")), + n, h, + Hex.Decode("4E13CA542744D696E67687561517552F279A8C84")); + } + } + + internal class C2tnb191v2Holder + : X9ECParametersHolder + { + private C2tnb191v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("20000000000000000000000050508CB89F652824E06B8173", 16); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve c2m191v2 = new F2mCurve( + 191, + 9, + new BigInteger("401028774D7777C7B7666D1366EA432071274F89FF01E718", 16), + new BigInteger("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", 16), + n, h); + + return new X9ECParameters( + c2m191v2, + c2m191v2.DecodePoint( + Hex.Decode("023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10")), + n, h, + null); + } + } + + internal class C2tnb191v3Holder + : X9ECParametersHolder + { + private C2tnb191v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("155555555555555555555555610C0B196812BFB6288A3EA3", 16); + BigInteger h = BigInteger.ValueOf(6); + + ECCurve c2m191v3 = new F2mCurve( + 191, + 9, + new BigInteger("6C01074756099122221056911C77D77E77A777E7E7E77FCB", 16), + new BigInteger("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", 16), + n, h); + + return new X9ECParameters( + c2m191v3, + c2m191v3.DecodePoint( + Hex.Decode("03375D4CE24FDE434489DE8746E71786015009E66E38A926DD")), + n, h, + null); + } + } + + internal class C2pnb208w1Holder + : X9ECParametersHolder + { + private C2pnb208w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb208w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 16); + BigInteger h = BigInteger.ValueOf(0xFE48); + + ECCurve c2m208w1 = new F2mCurve( + 208, + 1, 2, 83, + new BigInteger("0", 16), + new BigInteger("00C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", 16), + n, h); + + return new X9ECParameters( + c2m208w1, + c2m208w1.DecodePoint( + Hex.Decode("0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A")), + n, h, + null); + } + } + + internal class C2tnb239v1Holder + : X9ECParametersHolder + { + private C2tnb239v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 16); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve c2m239v1 = new F2mCurve( + 239, + 36, + new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), + new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16), + n, h); + + return new X9ECParameters( + c2m239v1, + c2m239v1.DecodePoint( + Hex.Decode("0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D")), + n, h, + null); + } + } + + internal class C2tnb239v2Holder + : X9ECParametersHolder + { + private C2tnb239v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 16); + BigInteger h = BigInteger.ValueOf(6); + + ECCurve c2m239v2 = new F2mCurve( + 239, + 36, + new BigInteger("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", 16), + new BigInteger("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", 16), + n, h); + + return new X9ECParameters( + c2m239v2, + c2m239v2.DecodePoint( + Hex.Decode("0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205")), + n, h, + null); + } + } + + internal class C2tnb239v3Holder + : X9ECParametersHolder + { + private C2tnb239v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 16); + BigInteger h = BigInteger.ValueOf(10); + + ECCurve c2m239v3 = new F2mCurve( + 239, + 36, + new BigInteger("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", 16), + new BigInteger("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", 16), + n, h); + + return new X9ECParameters( + c2m239v3, + c2m239v3.DecodePoint( + Hex.Decode("0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92")), + n, h, + null); + } + } + + internal class C2pnb272w1Holder + : X9ECParametersHolder + { + private C2pnb272w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb272w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", 16); + BigInteger h = BigInteger.ValueOf(0xFF06); + + ECCurve c2m272w1 = new F2mCurve( + 272, + 1, 3, 56, + new BigInteger("0091A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", 16), + new BigInteger("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", 16), + n, h); + + return new X9ECParameters( + c2m272w1, + c2m272w1.DecodePoint( + Hex.Decode("026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D")), + n, h, + null); + } + } + + internal class C2pnb304w1Holder + : X9ECParametersHolder + { + private C2pnb304w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb304w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 16); + BigInteger h = BigInteger.ValueOf(0xFE2E); + + ECCurve c2m304w1 = new F2mCurve( + 304, + 1, 2, 11, + new BigInteger("00FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", 16), + new BigInteger("00BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", 16), + n, h); + + return new X9ECParameters( + c2m304w1, + c2m304w1.DecodePoint( + Hex.Decode("02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614")), + n, h, + null); + } + } + + internal class C2tnb359v1Holder + : X9ECParametersHolder + { + private C2tnb359v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb359v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 16); + BigInteger h = BigInteger.ValueOf(0x4C); + + ECCurve c2m359v1 = new F2mCurve( + 359, + 68, + new BigInteger("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", 16), + new BigInteger("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", 16), + n, h); + + return new X9ECParameters( + c2m359v1, + c2m359v1.DecodePoint( + Hex.Decode("033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097")), + n, h, + null); + } + } + + internal class C2pnb368w1Holder + : X9ECParametersHolder + { + private C2pnb368w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb368w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 16); + BigInteger h = BigInteger.ValueOf(0xFF70); + + ECCurve c2m368w1 = new F2mCurve( + 368, + 1, 2, 85, + new BigInteger("00E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", 16), + new BigInteger("00FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", 16), + n, h); + + return new X9ECParameters( + c2m368w1, + c2m368w1.DecodePoint( + Hex.Decode("021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F")), + n, h, + null); + } + } + + internal class C2tnb431r1Holder + : X9ECParametersHolder + { + private C2tnb431r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb431r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 16); + BigInteger h = BigInteger.ValueOf(0x2760); + + ECCurve c2m431r1 = new F2mCurve( + 431, + 120, + new BigInteger("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", 16), + new BigInteger("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", 16), + n, h); + + return new X9ECParameters( + c2m431r1, + c2m431r1.DecodePoint( + Hex.Decode("02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7")), + n, h, + null); + } + } + + private static readonly Hashtable objIds = new Hashtable(); + private static readonly Hashtable curves = new Hashtable(); + private static readonly Hashtable names = new Hashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(name, oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static X962NamedCurves() + { + DefineCurve("prime192v1", X9ObjectIdentifiers.Prime192v1, Prime192v1Holder.Instance); + DefineCurve("prime192v2", X9ObjectIdentifiers.Prime192v2, Prime192v2Holder.Instance); + DefineCurve("prime192v3", X9ObjectIdentifiers.Prime192v3, Prime192v3Holder.Instance); + DefineCurve("prime239v1", X9ObjectIdentifiers.Prime239v1, Prime239v1Holder.Instance); + DefineCurve("prime239v2", X9ObjectIdentifiers.Prime239v2, Prime239v2Holder.Instance); + DefineCurve("prime239v3", X9ObjectIdentifiers.Prime239v3, Prime239v3Holder.Instance); + DefineCurve("prime256v1", X9ObjectIdentifiers.Prime256v1, Prime256v1Holder.Instance); + DefineCurve("c2pnb163v1", X9ObjectIdentifiers.C2Pnb163v1, C2pnb163v1Holder.Instance); + DefineCurve("c2pnb163v2", X9ObjectIdentifiers.C2Pnb163v2, C2pnb163v2Holder.Instance); + DefineCurve("c2pnb163v3", X9ObjectIdentifiers.C2Pnb163v3, C2pnb163v3Holder.Instance); + DefineCurve("c2pnb176w1", X9ObjectIdentifiers.C2Pnb176w1, C2pnb176w1Holder.Instance); + DefineCurve("c2tnb191v1", X9ObjectIdentifiers.C2Tnb191v1, C2tnb191v1Holder.Instance); + DefineCurve("c2tnb191v2", X9ObjectIdentifiers.C2Tnb191v2, C2tnb191v2Holder.Instance); + DefineCurve("c2tnb191v3", X9ObjectIdentifiers.C2Tnb191v3, C2tnb191v3Holder.Instance); + DefineCurve("c2pnb208w1", X9ObjectIdentifiers.C2Pnb208w1, C2pnb208w1Holder.Instance); + DefineCurve("c2tnb239v1", X9ObjectIdentifiers.C2Tnb239v1, C2tnb239v1Holder.Instance); + DefineCurve("c2tnb239v2", X9ObjectIdentifiers.C2Tnb239v2, C2tnb239v2Holder.Instance); + DefineCurve("c2tnb239v3", X9ObjectIdentifiers.C2Tnb239v3, C2tnb239v3Holder.Instance); + DefineCurve("c2pnb272w1", X9ObjectIdentifiers.C2Pnb272w1, C2pnb272w1Holder.Instance); + DefineCurve("c2pnb304w1", X9ObjectIdentifiers.C2Pnb304w1, C2pnb304w1Holder.Instance); + DefineCurve("c2tnb359v1", X9ObjectIdentifiers.C2Tnb359v1, C2tnb359v1Holder.Instance); + DefineCurve("c2pnb368w1", X9ObjectIdentifiers.C2Pnb368w1, C2pnb368w1Holder.Instance); + DefineCurve("c2tnb431r1", X9ObjectIdentifiers.C2Tnb431r1, C2tnb431r1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = (DerObjectIdentifier) objIds[name.ToLower(CultureInfo.InvariantCulture)]; + + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder) curves[oid]; + + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier) objIds[name.ToLower(CultureInfo.InvariantCulture)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string) names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(objIds.Keys); } + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X962Parameters.cs b/iTechSharp/srcbc/asn1/x9/X962Parameters.cs new file mode 100644 index 0000000..0b0faee --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X962Parameters.cs @@ -0,0 +1,53 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class X962Parameters + : Asn1Encodable + { + private readonly Asn1Object _params; + + public X962Parameters( + X9ECParameters ecParameters) + { + this._params = ecParameters.ToAsn1Object(); + } + + public X962Parameters( + DerObjectIdentifier namedCurve) + { + this._params = namedCurve; + } + + public X962Parameters( + Asn1Object obj) + { + this._params = obj; + } + + public bool IsNamedCurve + { + get { return (_params is DerObjectIdentifier); } + } + + public Asn1Object Parameters + { + get { return _params; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+ * Parameters ::= CHOICE { + * ecParameters ECParameters, + * namedCurve CURVES.&id({CurveNames}), + * implicitlyCA Null + * } + *+ */ + public override Asn1Object ToAsn1Object() + { + return _params; + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X9Curve.cs b/iTechSharp/srcbc/asn1/x9/X9Curve.cs new file mode 100644 index 0000000..b92e7b3 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X9Curve.cs @@ -0,0 +1,147 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve Curve structure. See + * X9.62, for further details. + */ + public class X9Curve + : Asn1Encodable + { + private readonly ECCurve curve; + private readonly byte[] seed; + private readonly DerObjectIdentifier fieldIdentifier; + + public X9Curve( + ECCurve curve) + : this(curve, null) + { + this.curve = curve; + } + + public X9Curve( + ECCurve curve, + byte[] seed) + { + if (curve == null) + throw new ArgumentNullException("curve"); + + this.curve = curve; + this.seed = Arrays.Clone(seed); + + if (curve is FpCurve) + { + this.fieldIdentifier = X9ObjectIdentifiers.PrimeField; + } + else if (curve is F2mCurve) + { + this.fieldIdentifier = X9ObjectIdentifiers.CharacteristicTwoField; + } + else + { + throw new ArgumentException("This type of ECCurve is not implemented"); + } + } + + public X9Curve( + X9FieldID fieldID, + Asn1Sequence seq) + { + if (fieldID == null) + throw new ArgumentNullException("fieldID"); + if (seq == null) + throw new ArgumentNullException("seq"); + + this.fieldIdentifier = fieldID.Identifier; + + if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField)) + { + BigInteger q = ((DerInteger) fieldID.Parameters).Value; + X9FieldElement x9A = new X9FieldElement(q, (Asn1OctetString) seq[0]); + X9FieldElement x9B = new X9FieldElement(q, (Asn1OctetString) seq[1]); + curve = new FpCurve(q, x9A.Value.ToBigInteger(), x9B.Value.ToBigInteger()); + } + else + { + if (fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField)) + { + // Characteristic two field + DerSequence parameters = (DerSequence)fieldID.Parameters; + int m = ((DerInteger)parameters[0]).Value.IntValue; + DerObjectIdentifier representation + = (DerObjectIdentifier)parameters[1]; + + int k1 = 0; + int k2 = 0; + int k3 = 0; + if (representation.Equals(X9ObjectIdentifiers.TPBasis)) + { + // Trinomial basis representation + k1 = ((DerInteger)parameters[2]).Value.IntValue; + } + else + { + // Pentanomial basis representation + DerSequence pentanomial = (DerSequence) parameters[2]; + k1 = ((DerInteger) pentanomial[0]).Value.IntValue; + k2 = ((DerInteger) pentanomial[1]).Value.IntValue; + k3 = ((DerInteger) pentanomial[2]).Value.IntValue; + } + X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (Asn1OctetString)seq[0]); + X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (Asn1OctetString)seq[1]); + // TODO Is it possible to get the order (n) and cofactor(h) too? + curve = new F2mCurve(m, k1, k2, k3, x9A.Value.ToBigInteger(), x9B.Value.ToBigInteger()); + } + } + + if (seq.Count == 3) + { + seed = ((DerBitString) seq[2]).GetBytes(); + } + } + + public ECCurve Curve + { + get { return curve; } + } + + public byte[] GetSeed() + { + return Arrays.Clone(seed); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+ * Curve ::= Sequence { + * a FieldElement, + * b FieldElement, + * seed BIT STRING OPTIONAL + * } + *+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField) + || fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField)) + { + v.Add(new X9FieldElement(curve.A).ToAsn1Object()); + v.Add(new X9FieldElement(curve.B).ToAsn1Object()); + } + + if (seed != null) + { + v.Add(new DerBitString(seed)); + } + + return new DerSequence(v); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X9ECParameters.cs b/iTechSharp/srcbc/asn1/x9/X9ECParameters.cs new file mode 100644 index 0000000..b4b1afb --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X9ECParameters.cs @@ -0,0 +1,165 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve ECParameters structure. See + * X9.62, for further details. + */ + public class X9ECParameters + : Asn1Encodable + { + private X9FieldID fieldID; + private ECCurve curve; + private ECPoint g; + private BigInteger n; + private BigInteger h; + private byte[] seed; + + public X9ECParameters( + Asn1Sequence seq) + { + if (!(seq[0] is DerInteger) + || !((DerInteger) seq[0]).Value.Equals(BigInteger.One)) + { + throw new ArgumentException("bad version in X9ECParameters"); + } + + X9Curve x9c = null; + if (seq[2] is X9Curve) + { + x9c = (X9Curve) seq[2]; + } + else + { + x9c = new X9Curve( + new X9FieldID( + (Asn1Sequence) seq[1]), + (Asn1Sequence) seq[2]); + } + + this.curve = x9c.Curve; + + if (seq[3] is X9ECPoint) + { + this.g = ((X9ECPoint) seq[3]).Point; + } + else + { + this.g = new X9ECPoint(curve, (Asn1OctetString) seq[3]).Point; + } + + this.n = ((DerInteger) seq[4]).Value; + this.seed = x9c.GetSeed(); + + if (seq.Count == 6) + { + this.h = ((DerInteger) seq[5]).Value; + } + else + { + this.h = BigInteger.One; + } + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n) + : this(curve, g, n, BigInteger.One, null) + { + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + this.seed = seed; + + if (curve is FpCurve) + { + this.fieldID = new X9FieldID(((FpCurve) curve).Q); + } + else if (curve is F2mCurve) + { + F2mCurve curveF2m = (F2mCurve) curve; + this.fieldID = new X9FieldID(curveF2m.M, curveF2m.K1, + curveF2m.K2, curveF2m.K3); + } + } + + public ECCurve Curve + { + get { return curve; } + } + + public ECPoint G + { + get { return g; } + } + + public BigInteger N + { + get { return n; } + } + + public BigInteger H + { + get { return h; } + } + + public byte[] GetSeed() + { + return seed; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+ * ECParameters ::= Sequence { + * version Integer { ecpVer1(1) } (ecpVer1), + * fieldID FieldID {{FieldTypes}}, + * curve X9Curve, + * base X9ECPoint, + * order Integer, + * cofactor Integer OPTIONAL + * } + *+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(1), + fieldID, + new X9Curve(curve, seed), + new X9ECPoint(g), + new DerInteger(n)); + + if (!h.Equals(BigInteger.One)) + { + v.Add(new DerInteger(h)); + } + + return new DerSequence(v); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X9ECParametersHolder.cs b/iTechSharp/srcbc/asn1/x9/X9ECParametersHolder.cs new file mode 100644 index 0000000..b345570 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X9ECParametersHolder.cs @@ -0,0 +1,22 @@ +namespace Org.BouncyCastle.Asn1.X9 +{ + public abstract class X9ECParametersHolder + { + private X9ECParameters parameters; + + public X9ECParameters Parameters + { + get + { + if (parameters == null) + { + parameters = CreateParameters(); + } + + return parameters; + } + } + + protected abstract X9ECParameters CreateParameters(); + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X9ECPoint.cs b/iTechSharp/srcbc/asn1/x9/X9ECPoint.cs new file mode 100644 index 0000000..ba2b2bc --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X9ECPoint.cs @@ -0,0 +1,44 @@ +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * class for describing an ECPoint as a Der object. + */ + public class X9ECPoint + : Asn1Encodable + { + private readonly ECPoint p; + + public X9ECPoint( + ECPoint p) + { + this.p = p; + } + + public X9ECPoint( + ECCurve c, + Asn1OctetString s) + { + this.p = c.DecodePoint(s.GetOctets()); + } + + public ECPoint Point + { + get { return p; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+ * ECPoint ::= OCTET STRING + *+ *
+ * Octet string produced using ECPoint.GetEncoded().
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerOctetString(p.GetEncoded()); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X9FieldElement.cs b/iTechSharp/srcbc/asn1/x9/X9FieldElement.cs new file mode 100644 index 0000000..12e263e --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X9FieldElement.cs @@ -0,0 +1,69 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * class for processing an FieldElement as a Der object. + */ + public class X9FieldElement + : Asn1Encodable + { + private ECFieldElement f; + + public X9FieldElement( + ECFieldElement f) + { + this.f = f; + } + + public X9FieldElement( + BigInteger p, + Asn1OctetString s) + : this(new FpFieldElement(p, new BigInteger(1, s.GetOctets()))) + { + } + + public X9FieldElement( + int m, + int k1, + int k2, + int k3, + Asn1OctetString s) + : this(new F2mFieldElement(m, k1, k2, k3, new BigInteger(1, s.GetOctets()))) + { + } + + public ECFieldElement Value + { + get { return f; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *+ * FieldElement ::= OCTET STRING + *+ *
+ *
F2
.
+ * @param primeP The prime p
defining the prime field.
+ */
+ public X9FieldID(
+ BigInteger primeP)
+ {
+ this.id = X9ObjectIdentifiers.PrimeField;
+ this.parameters = new DerInteger(primeP);
+ }
+
+ /**
+ * Constructor for elliptic curves over binary fields
+ * F2m
.
+ * @param m The exponent m
of
+ * F2m
.
+ * @param k1 The integer k1
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param k2 The integer k2
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param k3 The integer k3
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
..
+ */
+ public X9FieldID(
+ int m,
+ int k1,
+ int k2,
+ int k3)
+ {
+ this.id = X9ObjectIdentifiers.CharacteristicTwoField;
+
+ Asn1EncodableVector fieldIdParams = new Asn1EncodableVector(new DerInteger(m));
+
+ if (k2 == 0)
+ {
+ fieldIdParams.Add(
+ X9ObjectIdentifiers.TPBasis,
+ new DerInteger(k1));
+ }
+ else
+ {
+ fieldIdParams.Add(
+ X9ObjectIdentifiers.PPBasis,
+ new DerSequence(
+ new DerInteger(k1),
+ new DerInteger(k2),
+ new DerInteger(k3)));
+ }
+
+ this.parameters = new DerSequence(fieldIdParams);
+ }
+
+ internal X9FieldID(
+ Asn1Sequence seq)
+ {
+ this.id = (DerObjectIdentifier) seq[0];
+ this.parameters = (Asn1Object) seq[1];
+ }
+
+ public DerObjectIdentifier Identifier
+ {
+ get { return id; }
+ }
+
+ public Asn1Object Parameters
+ {
+ get { return parameters; }
+ }
+
+ /**
+ * Produce a Der encoding of the following structure.
+ * + * FieldID ::= Sequence { + * fieldType FIELD-ID.&id({IOSet}), + * parameters FIELD-ID.&Type({IOSet}{@fieldType}) + * } + *+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(id, parameters); + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X9IntegerConverter.cs b/iTechSharp/srcbc/asn1/x9/X9IntegerConverter.cs new file mode 100644 index 0000000..6a19ded --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X9IntegerConverter.cs @@ -0,0 +1,46 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public sealed class X9IntegerConverter + { + private X9IntegerConverter() + { + } + + public static int GetByteLength( + ECFieldElement fe) + { + return (fe.FieldSize + 7) / 8; + } + + public static int GetByteLength( + ECCurve c) + { + return (c.FieldSize + 7) / 8; + } + + public static byte[] IntegerToBytes( + BigInteger s, + int qLength) + { + // TODO Add methods to allow writing BigInteger to existing byte array? + byte[] bytes = s.ToByteArrayUnsigned(); + + if (bytes.Length > qLength) + throw new ArgumentException("s does not fit in specified number of bytes", "s"); + + if (qLength > bytes.Length) + { + byte[] tmp = new byte[qLength]; + Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length); + return tmp; + } + + return bytes; + } + } +} diff --git a/iTechSharp/srcbc/asn1/x9/X9ObjectIdentifiers.cs b/iTechSharp/srcbc/asn1/x9/X9ObjectIdentifiers.cs new file mode 100644 index 0000000..26520c9 --- /dev/null +++ b/iTechSharp/srcbc/asn1/x9/X9ObjectIdentifiers.cs @@ -0,0 +1,132 @@ +namespace Org.BouncyCastle.Asn1.X9 +{ + public abstract class X9ObjectIdentifiers + { + // + // X9.62 + // + // ansi-X9-62 OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x962(10045) } + // + internal const string AnsiX962 = "1.2.840.10045"; + internal const string IdFieldType = AnsiX962 + ".1"; + + public static readonly DerObjectIdentifier PrimeField + = new DerObjectIdentifier(IdFieldType + ".1"); + + public static readonly DerObjectIdentifier CharacteristicTwoField + = new DerObjectIdentifier(IdFieldType + ".2"); + + public static readonly DerObjectIdentifier GNBasis + = new DerObjectIdentifier(IdFieldType + ".2.3.1"); + + public static readonly DerObjectIdentifier TPBasis + = new DerObjectIdentifier(IdFieldType + ".2.3.2"); + + public static readonly DerObjectIdentifier PPBasis + = new DerObjectIdentifier(IdFieldType + ".2.3.3"); + + public const string IdECSigType = AnsiX962 + ".4"; + + public static readonly DerObjectIdentifier ECDsaWithSha1 + = new DerObjectIdentifier(IdECSigType + ".1"); + + public const string IdPublicKeyType = AnsiX962 + ".2"; + + public static readonly DerObjectIdentifier IdECPublicKey + = new DerObjectIdentifier(IdPublicKeyType + ".1"); + + public static readonly DerObjectIdentifier ECDsaWithSha2 = new DerObjectIdentifier(IdECSigType + ".3"); + public static readonly DerObjectIdentifier ECDsaWithSha224 = new DerObjectIdentifier(ECDsaWithSha2 + ".1"); + public static readonly DerObjectIdentifier ECDsaWithSha256 = new DerObjectIdentifier(ECDsaWithSha2 + ".2"); + public static readonly DerObjectIdentifier ECDsaWithSha384 = new DerObjectIdentifier(ECDsaWithSha2 + ".3"); + public static readonly DerObjectIdentifier ECDsaWithSha512 = new DerObjectIdentifier(ECDsaWithSha2 + ".4"); + + + // + // named curves + // + public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier(AnsiX962 + ".3"); + + // + // Two Curves + // + public static readonly DerObjectIdentifier CTwoCurve = new DerObjectIdentifier(EllipticCurve + ".0"); + + public static readonly DerObjectIdentifier C2Pnb163v1 = new DerObjectIdentifier(CTwoCurve + ".1"); + public static readonly DerObjectIdentifier C2Pnb163v2 = new DerObjectIdentifier(CTwoCurve + ".2"); + public static readonly DerObjectIdentifier C2Pnb163v3 = new DerObjectIdentifier(CTwoCurve + ".3"); + public static readonly DerObjectIdentifier C2Pnb176w1 = new DerObjectIdentifier(CTwoCurve + ".4"); + public static readonly DerObjectIdentifier C2Tnb191v1 = new DerObjectIdentifier(CTwoCurve + ".5"); + public static readonly DerObjectIdentifier C2Tnb191v2 = new DerObjectIdentifier(CTwoCurve + ".6"); + public static readonly DerObjectIdentifier C2Tnb191v3 = new DerObjectIdentifier(CTwoCurve + ".7"); + public static readonly DerObjectIdentifier C2Onb191v4 = new DerObjectIdentifier(CTwoCurve + ".8"); + public static readonly DerObjectIdentifier C2Onb191v5 = new DerObjectIdentifier(CTwoCurve + ".9"); + public static readonly DerObjectIdentifier C2Pnb208w1 = new DerObjectIdentifier(CTwoCurve + ".10"); + public static readonly DerObjectIdentifier C2Tnb239v1 = new DerObjectIdentifier(CTwoCurve + ".11"); + public static readonly DerObjectIdentifier C2Tnb239v2 = new DerObjectIdentifier(CTwoCurve + ".12"); + public static readonly DerObjectIdentifier C2Tnb239v3 = new DerObjectIdentifier(CTwoCurve + ".13"); + public static readonly DerObjectIdentifier C2Onb239v4 = new DerObjectIdentifier(CTwoCurve + ".14"); + public static readonly DerObjectIdentifier C2Onb239v5 = new DerObjectIdentifier(CTwoCurve + ".15"); + public static readonly DerObjectIdentifier C2Pnb272w1 = new DerObjectIdentifier(CTwoCurve + ".16"); + public static readonly DerObjectIdentifier C2Pnb304w1 = new DerObjectIdentifier(CTwoCurve + ".17"); + public static readonly DerObjectIdentifier C2Tnb359v1 = new DerObjectIdentifier(CTwoCurve + ".18"); + public static readonly DerObjectIdentifier C2Pnb368w1 = new DerObjectIdentifier(CTwoCurve + ".19"); + public static readonly DerObjectIdentifier C2Tnb431r1 = new DerObjectIdentifier(CTwoCurve + ".20"); + + // + // Prime + // + public static readonly DerObjectIdentifier PrimeCurve = new DerObjectIdentifier(EllipticCurve + ".1"); + + public static readonly DerObjectIdentifier Prime192v1 = new DerObjectIdentifier(PrimeCurve + ".1"); + public static readonly DerObjectIdentifier Prime192v2 = new DerObjectIdentifier(PrimeCurve + ".2"); + public static readonly DerObjectIdentifier Prime192v3 = new DerObjectIdentifier(PrimeCurve + ".3"); + public static readonly DerObjectIdentifier Prime239v1 = new DerObjectIdentifier(PrimeCurve + ".4"); + public static readonly DerObjectIdentifier Prime239v2 = new DerObjectIdentifier(PrimeCurve + ".5"); + public static readonly DerObjectIdentifier Prime239v3 = new DerObjectIdentifier(PrimeCurve + ".6"); + public static readonly DerObjectIdentifier Prime256v1 = new DerObjectIdentifier(PrimeCurve + ".7"); + + // + // Diffie-Hellman + // + // dhpublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x942(10046) number-type(2) 1 } + // + public static readonly DerObjectIdentifier DHPublicNumber = new DerObjectIdentifier("1.2.840.10046.2.1"); + + // + // DSA + // + // dsapublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x957(10040) number-type(4) 1 } + public static readonly DerObjectIdentifier IdDsa = new DerObjectIdentifier("1.2.840.10040.4.1"); + + /** + * id-dsa-with-sha1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) + * us(840) x9-57 (10040) x9cm(4) 3 } + */ + public static readonly DerObjectIdentifier IdDsaWithSha1 = new DerObjectIdentifier("1.2.840.10040.4.3"); + + /** + * X9.63 + */ + public static readonly DerObjectIdentifier X9x63Scheme = new DerObjectIdentifier("1.3.133.16.840.63.0"); + public static readonly DerObjectIdentifier DHSinglePassStdDHSha1KdfScheme = new DerObjectIdentifier(X9x63Scheme + ".2"); + public static readonly DerObjectIdentifier DHSinglePassCofactorDHSha1KdfScheme = new DerObjectIdentifier(X9x63Scheme + ".3"); + public static readonly DerObjectIdentifier MqvSinglePassSha1KdfScheme = new DerObjectIdentifier(X9x63Scheme + ".16"); + + /** + * X9.42 + */ + public static readonly DerObjectIdentifier X9x42Schemes = new DerObjectIdentifier("1.2.840.10046.3"); + public static readonly DerObjectIdentifier DHStatic = new DerObjectIdentifier(X9x42Schemes + ".1"); + public static readonly DerObjectIdentifier DHEphem = new DerObjectIdentifier(X9x42Schemes + ".2"); + public static readonly DerObjectIdentifier DHOneFlow = new DerObjectIdentifier(X9x42Schemes + ".3"); + public static readonly DerObjectIdentifier DHHybrid1 = new DerObjectIdentifier(X9x42Schemes + ".4"); + public static readonly DerObjectIdentifier DHHybrid2 = new DerObjectIdentifier(X9x42Schemes + ".5"); + public static readonly DerObjectIdentifier DHHybridOneFlow = new DerObjectIdentifier(X9x42Schemes + ".6"); + public static readonly DerObjectIdentifier Mqv2 = new DerObjectIdentifier(X9x42Schemes + ".7"); + public static readonly DerObjectIdentifier Mqv1 = new DerObjectIdentifier(X9x42Schemes + ".8"); + } +} diff --git a/iTechSharp/srcbc/bcpg/ArmoredInputStream.cs b/iTechSharp/srcbc/bcpg/ArmoredInputStream.cs new file mode 100644 index 0000000..fc89b9f --- /dev/null +++ b/iTechSharp/srcbc/bcpg/ArmoredInputStream.cs @@ -0,0 +1,492 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * reader for Base64 armored objects - read the headers and then start returning + * bytes when the data is reached. An IOException is thrown if the CRC check + * fails. + */ + public class ArmoredInputStream + : BaseInputStream + { + /* + * set up the decoding table. + */ + private readonly static byte[] decodingTable; + static ArmoredInputStream() + { + decodingTable = new byte[128]; + for (int i = 'A'; i <= 'Z'; i++) + { + decodingTable[i] = (byte)(i - 'A'); + } + for (int i = 'a'; i <= 'z'; i++) + { + decodingTable[i] = (byte)(i - 'a' + 26); + } + for (int i = '0'; i <= '9'; i++) + { + decodingTable[i] = (byte)(i - '0' + 52); + } + decodingTable['+'] = 62; + decodingTable['/'] = 63; + } + + /** + * decode the base 64 encoded input data. + * + * @return the offset the data starts in out. + */ + private int Decode( + int in0, + int in1, + int in2, + int in3, + int[] result) + { + if (in3 < 0) + { + throw new EndOfStreamException("unexpected end of file in armored stream."); + } + + int b1, b2, b3, b4; + if (in2 == '=') + { + b1 = decodingTable[in0] &0xff; + b2 = decodingTable[in1] & 0xff; + result[2] = ((b1 << 2) | (b2 >> 4)) & 0xff; + return 2; + } + else if (in3 == '=') + { + b1 = decodingTable[in0]; + b2 = decodingTable[in1]; + b3 = decodingTable[in2]; + result[1] = ((b1 << 2) | (b2 >> 4)) & 0xff; + result[2] = ((b2 << 4) | (b3 >> 2)) & 0xff; + return 1; + } + else + { + b1 = decodingTable[in0]; + b2 = decodingTable[in1]; + b3 = decodingTable[in2]; + b4 = decodingTable[in3]; + result[0] = ((b1 << 2) | (b2 >> 4)) & 0xff; + result[1] = ((b2 << 4) | (b3 >> 2)) & 0xff; + result[2] = ((b3 << 6) | b4) & 0xff; + return 0; + } + } + + Stream input; + bool start = true; + int[] outBuf = new int[3]; + int bufPtr = 3; + Crc24 crc = new Crc24(); + bool crcFound = false; + bool hasHeaders = true; + string header = null; + bool newLineFound = false; + bool clearText = false; + bool restart = false; + ArrayList headerList= new ArrayList(); + int lastC = 0; + + /** + * Create a stream for reading a PGP armoured message, parsing up to a header + * and then reading the data that follows. + * + * @param input + */ + public ArmoredInputStream( + Stream input) + : this(input, true) + { + } + + /** + * Create an armoured input stream which will assume the data starts + * straight away, or parse for headers first depending on the value of + * hasHeaders. + * + * @param input + * @param hasHeaders true if headers are to be looked for, false otherwise. + */ + public ArmoredInputStream( + Stream input, + bool hasHeaders) + { + this.input = input; + this.hasHeaders = hasHeaders; + + if (hasHeaders) + { + ParseHeaders(); + } + + start = false; + } + + private bool ParseHeaders() + { + header = null; + + int c; + int last = 0; + bool headerFound = false; + + headerList = new ArrayList(); + + // + // if restart we already have a header + // + if (restart) + { + headerFound = true; + } + else + { + while ((c = input.ReadByte()) >= 0) + { + if (c == '-' && (last == 0 || last == '\n' || last == '\r')) + { + headerFound = true; + break; + } + + last = c; + } + } + + if (headerFound) + { + StringBuilder Buffer = new StringBuilder("-"); + bool eolReached = false; + bool crLf = false; + + if (restart) // we've had to look ahead two '-' + { + Buffer.Append('-'); + } + + while ((c = input.ReadByte()) >= 0) + { + if (last == '\r' && c == '\n') + { + crLf = true; + } + if (eolReached && (last != '\r' && c == '\n')) + { + break; + } + if (eolReached && c == '\r') + { + break; + } + if (c == '\r' || (last != '\r' && c == '\n')) + { + string line = Buffer.ToString(); + if (line.Trim().Length < 1) + break; + headerList.Add(line); + Buffer.Length = 0; + } + + if (c != '\n' && c != '\r') + { + Buffer.Append((char)c); + eolReached = false; + } + else + { + if (c == '\r' || (last != '\r' && c == '\n')) + { + eolReached = true; + } + } + + last = c; + } + + if (crLf) + { + input.ReadByte(); // skip last \n + } + } + + if (headerList.Count > 0) + { + header = (string) headerList[0]; + } + + clearText = "-----BEGIN PGP SIGNED MESSAGE-----".Equals(header); + newLineFound = true; + + return headerFound; + } + + /** + * @return true if we are inside the clear text section of a PGP + * signed message. + */ + public bool IsClearText() + { + return clearText; + } + + /** + * Return the armor header line (if there is one) + * @return the armor header line, null if none present. + */ + public string GetArmorHeaderLine() + { + return header; + } + + /** + * Return the armor headers (the lines after the armor header line), + * @return an array of armor headers, null if there aren't any. + */ + public string[] GetArmorHeaders() + { + if (headerList.Count <= 1) + { + return null; + } + + string[] hdrs = new string[headerList.Count - 1]; + for (int i = 0; i != hdrs.Length; i++) + { + hdrs[i] = (string) headerList[i + 1]; + } + + return hdrs; + } + + private int ReadIgnoreSpace() + { + int c; + do + { + c = input.ReadByte(); + } + while (c == ' ' || c == '\t'); + + return c; + } + + private int ReadIgnoreWhitespace() + { + int c; + do + { + c = input.ReadByte(); + } + while (c == ' ' || c == '\t' || c == '\r' || c == '\n'); + + return c; + } + + private int ReadByteClearText() + { + int c = input.ReadByte(); + + if (c == '\r' || (c == '\n' && lastC != '\r')) + { + newLineFound = true; + } + else if (newLineFound && c == '-') + { + c = input.ReadByte(); + if (c == '-') // a header, not dash escaped + { + clearText = false; + start = true; + restart = true; + } + else // a space - must be a dash escape + { + c = input.ReadByte(); + } + newLineFound = false; + } + else + { + if (c != '\n' && lastC != '\r') + { + newLineFound = false; + } + } + + lastC = c; + + return c; + } + + private int ReadClearText(byte[] buffer, int offset, int count) + { + int pos = offset; + try + { + int end = offset + count; + while (pos < end) + { + int c = ReadByteClearText(); + if (c == -1) + { + break; + } + buffer[pos++] = (byte) c; + } + } + catch (IOException ioe) + { + if (pos == offset) throw ioe; + } + + return pos - offset; + } + + private int DoReadByte() + { + if (bufPtr > 2 || crcFound) + { + int c = ReadIgnoreSpace(); + if (c == '\n' || c == '\r') + { + c = ReadIgnoreWhitespace(); + if (c == '=') // crc reached + { + bufPtr = Decode(ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), outBuf); + + if (bufPtr != 0) + { + throw new IOException("no crc found in armored message."); + } + + crcFound = true; + + int i = ((outBuf[0] & 0xff) << 16) + | ((outBuf[1] & 0xff) << 8) + | (outBuf[2] & 0xff); + + if (i != crc.Value) + { + throw new IOException("crc check failed in armored message."); + } + + return ReadByte(); + } + + if (c == '-') // end of record reached + { + while ((c = input.ReadByte()) >= 0) + { + if (c == '\n' || c == '\r') + { + break; + } + } + + if (!crcFound) + { + throw new IOException("crc check not found."); + } + + crcFound = false; + start = true; + bufPtr = 3; + + return -1; + } + } + + if (c < 0) + { + return -1; + } + + bufPtr = Decode(c, ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), outBuf); + } + + return outBuf[bufPtr++]; + } + + public override int ReadByte() + { + if (start) + { + if (hasHeaders) + { + ParseHeaders(); + } + + crc.Reset(); + start = false; + } + + if (clearText) + { + return ReadByteClearText(); + } + + int c = DoReadByte(); + + crc.Update(c); + + return c; + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (start && count > 0) + { + if (hasHeaders) + { + ParseHeaders(); + } + start = false; + } + + if (clearText) + { + return ReadClearText(buffer, offset, count); + } + + int pos = offset; + try + { + int end = offset + count; + while (pos < end) + { + int c = DoReadByte(); + crc.Update(c); + if (c == -1) + { + break; + } + buffer[pos++] = (byte) c; + } + } + catch (IOException ioe) + { + if (pos == offset) throw ioe; + } + + return pos - offset; + } + + public override void Close() + { + input.Close(); + base.Close(); + } + } +} diff --git a/iTechSharp/srcbc/bcpg/ArmoredOutputStream.cs b/iTechSharp/srcbc/bcpg/ArmoredOutputStream.cs new file mode 100644 index 0000000..6d622ed --- /dev/null +++ b/iTechSharp/srcbc/bcpg/ArmoredOutputStream.cs @@ -0,0 +1,328 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic output stream. + */ + public class ArmoredOutputStream + : BaseOutputStream + { + private static readonly byte[] encodingTable = + { + (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', + (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', + (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', + (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', + (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', + (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', + (byte)'v', + (byte)'w', (byte)'x', (byte)'y', (byte)'z', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', + (byte)'7', (byte)'8', (byte)'9', + (byte)'+', (byte)'/' + }; + + /** + * encode the input data producing a base 64 encoded byte array. + */ + private static void Encode( + Stream outStream, + int[] data, + int len) + { + Debug.Assert(len > 0); + Debug.Assert(len < 4); + + byte[] bs = new byte[4]; + int d1 = data[0]; + bs[0] = encodingTable[(d1 >> 2) & 0x3f]; + + switch (len) + { + case 1: + { + bs[1] = encodingTable[(d1 << 4) & 0x3f]; + bs[2] = (byte)'='; + bs[3] = (byte)'='; + break; + } + case 2: + { + int d2 = data[1]; + bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f]; + bs[2] = encodingTable[(d2 << 2) & 0x3f]; + bs[3] = (byte)'='; + break; + } + case 3: + { + int d2 = data[1]; + int d3 = data[2]; + bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f]; + bs[2] = encodingTable[((d2 << 2) | (d3 >> 6)) & 0x3f]; + bs[3] = encodingTable[d3 & 0x3f]; + break; + } + } + + outStream.Write(bs, 0, bs.Length); + } + + private readonly Stream outStream; + private int[] buf = new int[3]; + private int bufPtr = 0; + private Crc24 crc = new Crc24(); + private int chunkCount = 0; + private int lastb; + + private bool start = true; + private bool clearText = false; + private bool newLine = false; + + private string nl = Platform.NewLine; + + private string type; + private string headerStart = "-----BEGIN PGP "; + private string headerTail = "-----"; + private string footerStart = "-----END PGP "; + private string footerTail = "-----"; + + private string version = "BCPG v1.32"; + + private readonly IDictionary headers; + + public ArmoredOutputStream(Stream outStream) + { + this.outStream = outStream; + this.headers = new Hashtable(); + this.headers["Version"] = version; + } + + public ArmoredOutputStream(Stream outStream, IDictionary headers) + { + this.outStream = outStream; + this.headers = new Hashtable(headers); + this.headers["Version"] = version; + } + + /** + * Set an additional header entry. + * + * @param name the name of the header entry. + * @param v the value of the header entry. + */ + public void SetHeader( + string name, + string v) + { + headers[name] = v; + } + + /** + * Reset the headers to only contain a Version string. + */ + public void ResetHeaders() + { + headers.Clear(); + headers["Version"] = version; + } + + /** + * Start a clear text signed message. + * @param hashAlgorithm + */ + public void BeginClearText( + HashAlgorithmTag hashAlgorithm) + { + string hash; + + switch (hashAlgorithm) + { + case HashAlgorithmTag.Sha1: + hash = "SHA1"; + break; + case HashAlgorithmTag.Sha256: + hash = "SHA256"; + break; + case HashAlgorithmTag.Sha384: + hash = "SHA384"; + break; + case HashAlgorithmTag.Sha512: + hash = "SHA512"; + break; + case HashAlgorithmTag.MD2: + hash = "MD2"; + break; + case HashAlgorithmTag.MD5: + hash = "MD5"; + break; + case HashAlgorithmTag.RipeMD160: + hash = "RIPEMD160"; + break; + default: + throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm); + } + + DoWrite("-----BEGIN PGP SIGNED MESSAGE-----" + nl); + DoWrite("Hash: " + hash + nl + nl); + + clearText = true; + newLine = true; + lastb = 0; + } + + public void EndClearText() + { + clearText = false; + } + + public override void WriteByte( + byte b) + { + if (clearText) + { + outStream.WriteByte(b); + + if (newLine) + { + if (!(b == '\n' && lastb == '\r')) + { + newLine = false; + } + if (b == '-') + { + outStream.WriteByte((byte)' '); + outStream.WriteByte((byte)'-'); // dash escape + } + } + if (b == '\r' || (b == '\n' && lastb != '\r')) + { + newLine = true; + } + lastb = b; + return; + } + + if (start) + { + bool newPacket = (b & 0x40) != 0; + + int tag; + if (newPacket) + { + tag = b & 0x3f; + } + else + { + tag = (b & 0x3f) >> 2; + } + + switch ((PacketTag)tag) + { + case PacketTag.PublicKey: + type = "PUBLIC KEY BLOCK"; + break; + case PacketTag.SecretKey: + type = "PRIVATE KEY BLOCK"; + break; + case PacketTag.Signature: + type = "SIGNATURE"; + break; + default: + type = "MESSAGE"; + break; + } + + DoWrite(headerStart + type + headerTail + nl); + WriteHeaderEntry("Version", (string) headers["Version"]); + + foreach (DictionaryEntry de in headers) + { + string k = (string) de.Key; + if (k != "Version") + { + string v = (string) de.Value; + WriteHeaderEntry(k, v); + } + } + + DoWrite(nl); + + start = false; + } + + if (bufPtr == 3) + { + Encode(outStream, buf, bufPtr); + bufPtr = 0; + if ((++chunkCount & 0xf) == 0) + { + DoWrite(nl); + } + } + + crc.Update(b); + buf[bufPtr++] = b & 0xff; + } + + /** + * Note: close does nor close the underlying stream. So it is possible to write + * multiple objects using armoring to a single stream. + */ + public override void Close() + { + if (type != null) + { + if (bufPtr > 0) + { + Encode(outStream, buf, bufPtr); + } + + DoWrite(nl + '='); + + int crcV = crc.Value; + + buf[0] = ((crcV >> 16) & 0xff); + buf[1] = ((crcV >> 8) & 0xff); + buf[2] = (crcV & 0xff); + + Encode(outStream, buf, 3); + + DoWrite(nl); + DoWrite(footerStart); + DoWrite(type); + DoWrite(footerTail); + DoWrite(nl); + + outStream.Flush(); + + type = null; + start = true; + base.Close(); + } + } + + private void WriteHeaderEntry( + string name, + string v) + { + DoWrite(name + ": " + v + nl); + } + + private void DoWrite( + string s) + { + byte[] bs = Encoding.ASCII.GetBytes(s); + outStream.Write(bs, 0, bs.Length); + } + } +} diff --git a/iTechSharp/srcbc/bcpg/BcpgInputStream.cs b/iTechSharp/srcbc/bcpg/BcpgInputStream.cs new file mode 100644 index 0000000..3c69fbd --- /dev/null +++ b/iTechSharp/srcbc/bcpg/BcpgInputStream.cs @@ -0,0 +1,355 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + ///
+ * A simple example of usage.
+ *+ *
+ * CMSCompressedDataGenerator fact = new CMSCompressedDataGenerator(); + * CMSCompressedData data = fact.Generate(content, algorithm); + *+ * + */ + public class CmsCompressedDataGenerator + { + public const string ZLib = "1.2.840.113549.1.9.16.3.8"; + + public CmsCompressedDataGenerator() + { + } + + /** + * Generate an object that contains an CMS Compressed Data + */ + public CmsCompressedData Generate( + CmsProcessable content, + string compressionOid) + { + AlgorithmIdentifier comAlgId; + Asn1OctetString comOcts; + + try + { + MemoryStream bOut = new MemoryStream(); + ZDeflaterOutputStream zOut = new ZDeflaterOutputStream(bOut); + + content.Write(zOut); + + zOut.Close(); + + comAlgId = new AlgorithmIdentifier( + new DerObjectIdentifier(compressionOid), + null); + + comOcts = new BerOctetString(bOut.ToArray()); + } + catch (IOException e) + { + throw new CmsException("exception encoding data.", e); + } + + ContentInfo comContent = new ContentInfo(CmsObjectIdentifiers.Data, comOcts); + ContentInfo contentInfo = new ContentInfo( + CmsObjectIdentifiers.CompressedData, + new CompressedData(comAlgId, comContent)); + + return new CmsCompressedData(contentInfo); + } + } +} diff --git a/iTechSharp/srcbc/cms/CMSCompressedDataParser.cs b/iTechSharp/srcbc/cms/CMSCompressedDataParser.cs new file mode 100644 index 0000000..f45ece5 --- /dev/null +++ b/iTechSharp/srcbc/cms/CMSCompressedDataParser.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Cms +{ + /** + * Class for reading a CMS Compressed Data stream. + *
+ * CMSCompressedDataParser cp = new CMSCompressedDataParser(inputStream); + * + * process(cp.GetContent().GetContentStream()); + *+ * Note: this class does not introduce buffering - if you are processing large files you should create + * the parser with: + *
+ * CMSCompressedDataParser ep = new CMSCompressedDataParser(new BufferedInputStream(inputStream, bufSize)); + *+ * where bufSize is a suitably large buffer size. + */ + public class CmsCompressedDataParser + : CmsContentInfoParser + { + public CmsCompressedDataParser( + byte[] compressedData) + : this(new MemoryStream(compressedData, false)) + { + } + + public CmsCompressedDataParser( + Stream compressedData) + : base(compressedData) + { + } + + public CmsTypedStream GetContent() + { + try + { + CompressedDataParser comData = new CompressedDataParser((Asn1SequenceParser)this.contentInfo.GetContent(Asn1Tags.Sequence)); + ContentInfoParser content = comData.GetEncapContentInfo(); + + Asn1OctetStringParser bytes = (Asn1OctetStringParser)content.GetContent(Asn1Tags.OctetString); + + return new CmsTypedStream(content.ContentType.ToString(), new ZInflaterInputStream(bytes.GetOctetStream())); + } + catch (IOException e) + { + throw new CmsException("IOException reading compressed content.", e); + } + } + } +} diff --git a/iTechSharp/srcbc/cms/CMSCompressedDataStreamGenerator.cs b/iTechSharp/srcbc/cms/CMSCompressedDataStreamGenerator.cs new file mode 100644 index 0000000..b72ca31 --- /dev/null +++ b/iTechSharp/srcbc/cms/CMSCompressedDataStreamGenerator.cs @@ -0,0 +1,124 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a compressed CMS message stream. + *
+ * A simple example of usage. + *
+ *+ * CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator(); + * + * Stream cOut = gen.Open(outputStream, CMSCompressedDataStreamGenerator.ZLIB); + * + * cOut.Write(data); + * + * cOut.Close(); + *+ */ + public class CmsCompressedDataStreamGenerator + { + public const string ZLib = "1.2.840.113549.1.9.16.3.8"; + + /** + * base constructor + */ + public CmsCompressedDataStreamGenerator() + { + } + + public Stream Open( + Stream outStream, + string compressionOID) + { + return Open(outStream, CmsObjectIdentifiers.Data.Id, compressionOID); + } + + public Stream Open( + Stream outStream, + string contentOID, + string compressionOID) + { + BerSequenceGenerator sGen = new BerSequenceGenerator(outStream); + + sGen.AddObject(CmsObjectIdentifiers.CompressedData); + + // + // Compressed Data + // + BerSequenceGenerator cGen = new BerSequenceGenerator( + sGen.GetRawOutputStream(), 0, true); + + // CMSVersion + cGen.AddObject(new DerInteger(0)); + + // CompressionAlgorithmIdentifier + cGen.AddObject(new AlgorithmIdentifier(new DerObjectIdentifier(ZLib))); + + // + // Encapsulated ContentInfo + // + BerSequenceGenerator eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream()); + + eiGen.AddObject(new DerObjectIdentifier(contentOID)); + + BerOctetStringGenerator octGen = new BerOctetStringGenerator( + eiGen.GetRawOutputStream(), 0, true); + + return new CmsCompressedOutputStream( + new ZDeflaterOutputStream(octGen.GetOctetOutputStream()), sGen, cGen, eiGen); + } + + private class CmsCompressedOutputStream + : BaseOutputStream + { + private ZDeflaterOutputStream _out; + private BerSequenceGenerator _sGen; + private BerSequenceGenerator _cGen; + private BerSequenceGenerator _eiGen; + + internal CmsCompressedOutputStream( + ZDeflaterOutputStream outStream, + BerSequenceGenerator sGen, + BerSequenceGenerator cGen, + BerSequenceGenerator eiGen) + { + _out = outStream; + _sGen = sGen; + _cGen = cGen; + _eiGen = eiGen; + } + + public override void WriteByte( + byte b) + { + _out.WriteByte(b); + } + + public override void Write( + byte[] bytes, + int off, + int len) + { + _out.Write(bytes, off, len); + } + + public override void Close() + { + _out.Close(); + _eiGen.Close(); + _cGen.Close(); + _sGen.Close(); + base.Close(); + } + } + } +} diff --git a/iTechSharp/srcbc/cms/CMSContentInfoParser.cs b/iTechSharp/srcbc/cms/CMSContentInfoParser.cs new file mode 100644 index 0000000..04ac4cb --- /dev/null +++ b/iTechSharp/srcbc/cms/CMSContentInfoParser.cs @@ -0,0 +1,47 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; + +namespace Org.BouncyCastle.Cms +{ + public class CmsContentInfoParser + { + protected ContentInfoParser contentInfo; + protected Stream data; + + protected CmsContentInfoParser( + Stream data) + { + if (data == null) + throw new ArgumentNullException("data"); + + this.data = data; + + try + { + Asn1StreamParser inStream = new Asn1StreamParser(data, CmsUtilities.MaximumMemory); + + this.contentInfo = new ContentInfoParser((Asn1SequenceParser)inStream.ReadObject()); + } + catch (IOException e) + { + throw new CmsException("IOException reading content.", e); + } + catch (InvalidCastException e) + { + throw new CmsException("Unexpected object reading content.", e); + } + } + + /** + * Close the underlying data stream. + * @throws IOException if the close fails. + */ + public void Close() + { + this.data.Close(); + } + } +} diff --git a/iTechSharp/srcbc/cms/CMSEnvelopedData.cs b/iTechSharp/srcbc/cms/CMSEnvelopedData.cs new file mode 100644 index 0000000..206af0e --- /dev/null +++ b/iTechSharp/srcbc/cms/CMSEnvelopedData.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Cms +{ + /** + * containing class for an CMS Enveloped Data object + */ + public class CmsEnvelopedData + { + internal RecipientInformationStore recipientInfoStore; + internal ContentInfo contentInfo; + + private AlgorithmIdentifier encAlg; + private Asn1Set unprotectedAttributes; + + public CmsEnvelopedData( + byte[] envelopedData) + : this(CmsUtilities.ReadContentInfo(envelopedData)) + { + } + + public CmsEnvelopedData( + Stream envelopedData) + : this(CmsUtilities.ReadContentInfo(envelopedData)) + { + } + + public CmsEnvelopedData( + ContentInfo contentInfo) + { + this.contentInfo = contentInfo; + + EnvelopedData envData = EnvelopedData.GetInstance(contentInfo.Content); + + // + // read the encrypted content info + // + EncryptedContentInfo encInfo = envData.EncryptedContentInfo; + + this.encAlg = encInfo.ContentEncryptionAlgorithm; + + // + // load the RecipientInfoStore + // + Asn1Set s = envData.RecipientInfos; + IList infos = new ArrayList(); + byte[] contentOctets = encInfo.EncryptedContent.GetOctets(); + + foreach (Asn1Encodable ae in s) + { + RecipientInfo info = RecipientInfo.GetInstance(ae); + MemoryStream contentStream = new MemoryStream(contentOctets, false); + + object type = info.Info; + + if (type is KeyTransRecipientInfo) + { + infos.Add(new KeyTransRecipientInformation( + (KeyTransRecipientInfo) type, encAlg, contentStream)); + } + else if (type is KekRecipientInfo) + { + infos.Add(new KekRecipientInformation( + (KekRecipientInfo) type, encAlg, contentStream)); + } + else if (type is KeyAgreeRecipientInfo) + { + infos.Add(new KeyAgreeRecipientInformation( + (KeyAgreeRecipientInfo) type, encAlg, contentStream)); + } + else if (type is PasswordRecipientInfo) + { + infos.Add(new PasswordRecipientInformation( + (PasswordRecipientInfo) type, encAlg, contentStream)); + } + } + + this.recipientInfoStore = new RecipientInformationStore(infos); + this.unprotectedAttributes = envData.UnprotectedAttrs; + } + + public AlgorithmIdentifier EncryptionAlgorithmID + { + get { return encAlg; } + } + + /** + * return the object identifier for the content encryption algorithm. + */ + public string EncryptionAlgOid + { + get { return encAlg.ObjectID.Id; } + } + + /** + * return a store of the intended recipients for this message + */ + public RecipientInformationStore GetRecipientInfos() + { + return recipientInfoStore; + } + + /** + * return the ContentInfo + */ + public ContentInfo ContentInfo + { + get { return contentInfo; } + } + + /** + * return a table of the unprotected attributes indexed by + * the OID of the attribute. + */ + public Asn1.Cms.AttributeTable GetUnprotectedAttributes() + { + if (unprotectedAttributes == null) + return null; + + return new Asn1.Cms.AttributeTable(unprotectedAttributes); + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return contentInfo.GetEncoded(); + } + } +} diff --git a/iTechSharp/srcbc/cms/CMSEnvelopedDataGenerator.cs b/iTechSharp/srcbc/cms/CMSEnvelopedDataGenerator.cs new file mode 100644 index 0000000..c103ac0 --- /dev/null +++ b/iTechSharp/srcbc/cms/CMSEnvelopedDataGenerator.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + ///
+ /// CmsEnvelopedDataGenerator fact = new CmsEnvelopedDataGenerator(); + /// + /// fact.AddKeyTransRecipient(cert); + /// + /// CmsEnvelopedData data = fact.Generate(content, algorithm); + ///+ ///
+ * Note: that because we are in a streaming mode only one recipient can be tried and it is important + * that the methods on the parser are called in the appropriate order. + *
+ *+ * Example of use - assuming the first recipient matches the private key we have. + *
+ * CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(inputStream); + * + * RecipientInformationStore recipients = ep.GetRecipientInfos(); + * + * Collection c = recipients.getRecipients(); + * Iterator it = c.iterator(); + * + * if (it.hasNext()) + * { + * RecipientInformation recipient = (RecipientInformation)it.next(); + * + * CMSTypedStream recData = recipient.getContentStream(privateKey); + * + * processDataStream(recData.getContentStream()); + * } + *+ * Note: this class does not introduce buffering - if you are processing large files you should create + * the parser with: + *
+ * CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(new BufferedInputStream(inputStream, bufSize)); + *+ * where bufSize is a suitably large buffer size. + * + */ + public class CmsEnvelopedDataParser + : CmsContentInfoParser + { + internal RecipientInformationStore recipientInfoStore; + internal EnvelopedDataParser envelopedData; + + private AlgorithmIdentifier _encAlg; + private Asn1.Cms.AttributeTable _unprotectedAttributes; + private bool _attrNotRead; + + public CmsEnvelopedDataParser( + byte[] envelopedData) + : this(new MemoryStream(envelopedData, false)) + { + } + + public CmsEnvelopedDataParser( + Stream envelopedData) + : base(envelopedData) + { + this._attrNotRead = true; + this.envelopedData = new EnvelopedDataParser( + (Asn1SequenceParser)this.contentInfo.GetContent(Asn1Tags.Sequence)); + + // + // load the RecipientInfoStore + // + Asn1SetParser s = this.envelopedData.GetRecipientInfos(); + IList baseInfos = new ArrayList(); + + IAsn1Convertible entry; + while ((entry = s.ReadObject()) != null) + { + baseInfos.Add(RecipientInfo.GetInstance(entry.ToAsn1Object())); + } + + // + // read the encrypted content info + // + EncryptedContentInfoParser encInfo = this.envelopedData.GetEncryptedContentInfo(); + + this._encAlg = encInfo.ContentEncryptionAlgorithm; + + // + // prime the recipients + // + IList infos = new ArrayList(); + Stream dataStream = ((Asn1OctetStringParser)encInfo.GetEncryptedContent(Asn1Tags.OctetString)).GetOctetStream(); + + foreach (Asn1.Cms.RecipientInfo info in baseInfos) + { + Asn1Encodable recipInfo = info.Info; + if (recipInfo is Asn1.Cms.KeyTransRecipientInfo) + { + infos.Add(new KeyTransRecipientInformation( + (KeyTransRecipientInfo) recipInfo, _encAlg, dataStream)); + } + else if (recipInfo is Asn1.Cms.KekRecipientInfo) + { + infos.Add(new KekRecipientInformation( + (KekRecipientInfo) recipInfo, _encAlg, dataStream)); + } + else if (recipInfo is KeyAgreeRecipientInfo) + { + infos.Add(new KeyAgreeRecipientInformation( + (KeyAgreeRecipientInfo) recipInfo, _encAlg, dataStream)); + } + else if (recipInfo is PasswordRecipientInfo) + { + infos.Add(new PasswordRecipientInformation( + (PasswordRecipientInfo) recipInfo, _encAlg, dataStream)); + } + } + + this.recipientInfoStore = new RecipientInformationStore(infos); + } + + public AlgorithmIdentifier EncryptionAlgorithmID + { + get { return _encAlg; } + } + + /** + * return the object identifier for the content encryption algorithm. + */ + public string EncryptionAlgOid + { + get { return _encAlg.ObjectID.Id; } + } + + /** + * return the ASN.1 encoded encryption algorithm parameters, or null if + * there aren't any. + */ + public Asn1Object EncryptionAlgParams + { + get + { + Asn1Encodable ae = _encAlg.Parameters; + + return ae == null ? null : ae.ToAsn1Object(); + } + } + + /** + * return a store of the intended recipients for this message + */ + public RecipientInformationStore GetRecipientInfos() + { + return this.recipientInfoStore; + } + + /** + * return a table of the unprotected attributes indexed by + * the OID of the attribute. + * @throws IOException + */ + public Asn1.Cms.AttributeTable GetUnprotectedAttributes() + { + if (_unprotectedAttributes == null && _attrNotRead) + { + Asn1SetParser asn1Set = this.envelopedData.GetUnprotectedAttrs(); + + _attrNotRead = false; + + if (asn1Set != null) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + IAsn1Convertible o; + + while ((o = asn1Set.ReadObject()) != null) + { + Asn1SequenceParser seq = (Asn1SequenceParser)o; + + v.Add(seq.ToAsn1Object()); + } + + _unprotectedAttributes = new Asn1.Cms.AttributeTable(new DerSet(v)); + } + } + + return _unprotectedAttributes; + } + } +} diff --git a/iTechSharp/srcbc/cms/CMSEnvelopedDataStreamGenerator.cs b/iTechSharp/srcbc/cms/CMSEnvelopedDataStreamGenerator.cs new file mode 100644 index 0000000..22696fd --- /dev/null +++ b/iTechSharp/srcbc/cms/CMSEnvelopedDataStreamGenerator.cs @@ -0,0 +1,273 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a CMS enveloped-data message stream. + *
+ * A simple example of usage. + *
+ * CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator(); + * + * edGen.AddKeyTransRecipient(cert); + * + * MemoryStream bOut = new MemoryStream(); + * + * Stream out = edGen.Open( + * bOut, CMSEnvelopedDataGenerator.AES128_CBC);* + * out.Write(data); + * + * out.Close(); + *+ * + */ + public class CmsEnvelopedDataStreamGenerator + : CmsEnvelopedGenerator + { + private object _originatorInfo = null; + private object _unprotectedAttributes = null; + private int _bufferSize; + private bool _berEncodeRecipientSet; + + public CmsEnvelopedDataStreamGenerator() + { + } + + ///
+ * CMSEnvelopedDataGenerator fact = new CMSEnvelopedDataGenerator(); + * + * fact.addKeyTransRecipient(cert); + * + * CMSEnvelopedData data = fact.generate(content, algorithm, "BC"); + *+ */ + public class CmsEnvelopedGenerator + { + internal static readonly short[] rc2Table = + { + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab + }; + + internal static readonly short[] rc2Ekb = + { + 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, + 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, + 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, + 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, + 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, + 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, + 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, + 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, + 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, + 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, + 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, + 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, + 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, + 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, + 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, + 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd + }; + + + // TODO Create named constants for all of these + public static readonly string DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc.Id; + public static readonly string RC2Cbc = PkcsObjectIdentifiers.RC2Cbc.Id; + public const string IdeaCbc = "1.3.6.1.4.1.188.7.1.1.2"; + public const string Cast5Cbc = "1.2.840.113533.7.66.10"; + public static readonly string Aes128Cbc = NistObjectIdentifiers.IdAes128Cbc.Id; + public static readonly string Aes192Cbc = NistObjectIdentifiers.IdAes192Cbc.Id; + public static readonly string Aes256Cbc = NistObjectIdentifiers.IdAes256Cbc.Id; + public static readonly string Camellia128Cbc = NttObjectIdentifiers.IdCamellia128Cbc.Id; + public static readonly string Camellia192Cbc = NttObjectIdentifiers.IdCamellia192Cbc.Id; + public static readonly string Camellia256Cbc = NttObjectIdentifiers.IdCamellia256Cbc.Id; + public static readonly string SeedCbc = KisaObjectIdentifiers.IdSeedCbc.Id; + + public static readonly string DesEde3Wrap = PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id; + public static readonly string Aes128Wrap = NistObjectIdentifiers.IdAes128Wrap.Id; + public static readonly string Aes192Wrap = NistObjectIdentifiers.IdAes192Wrap.Id; + public static readonly string Aes256Wrap = NistObjectIdentifiers.IdAes256Wrap.Id; + public static readonly string Camellia128Wrap = NttObjectIdentifiers.IdCamellia128Wrap.Id; + public static readonly string Camellia192Wrap = NttObjectIdentifiers.IdCamellia192Wrap.Id; + public static readonly string Camellia256Wrap = NttObjectIdentifiers.IdCamellia256Wrap.Id; + public static readonly string SeedWrap = KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap.Id; + + public static readonly string ECDHSha1Kdf = X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id; + + internal static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance; + + internal readonly IList recipientInfs = new ArrayList(); + internal readonly SecureRandom rand; + + protected class RecipientInf + { + private readonly X509Certificate cert; + private AlgorithmIdentifier keyEncAlg; + private readonly AsymmetricKeyParameter pubKey; + private readonly Asn1OctetString subKeyId; + + private readonly string secKeyAlgorithm; + private readonly KeyParameter secKey; + private readonly KekIdentifier secKeyId; + + private readonly OriginatorIdentifierOrKey originator; + private const Asn1OctetString ukm = null; + + private readonly AlgorithmIdentifier derivationAlg; + + internal RecipientInf( + X509Certificate cert) + { + this.cert = cert; + this.pubKey = cert.GetPublicKey(); + + try + { + TbsCertificateStructure tbs = TbsCertificateStructure.GetInstance( + Asn1Object.FromByteArray(cert.GetTbsCertificate())); + + keyEncAlg = tbs.SubjectPublicKeyInfo.AlgorithmID; + } +// catch (IOException e) + catch (Exception) + { + throw new ArgumentException("can't extract key algorithm from this cert"); + } +// catch (CertificateEncodingException) +// { +// throw new ArgumentException("can't extract tbs structure from this cert"); +// } + } + + internal RecipientInf( + AsymmetricKeyParameter pubKey, + Asn1OctetString subKeyId) + { + this.pubKey = pubKey; + this.subKeyId = subKeyId; + + try + { + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey); + + keyEncAlg = info.AlgorithmID; + } + catch (IOException) + { + throw new ArgumentException("can't extract key algorithm from this key"); + } + } + + internal RecipientInf( + string secKeyAlgorithm, // TODO Can get this from secKey? + KeyParameter secKey, + KekIdentifier secKeyId) + { + this.secKeyAlgorithm = secKeyAlgorithm; + this.secKey = secKey; + this.secKeyId = secKeyId; + + if (secKeyAlgorithm.StartsWith("DES")) + { + keyEncAlg = new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdAlgCms3DesWrap, + DerNull.Instance); + } + else if (secKeyAlgorithm.StartsWith("RC2")) + { + keyEncAlg = new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdAlgCmsRC2Wrap, + new DerInteger(58)); + } + else if (secKeyAlgorithm.StartsWith("AES")) + { + int length = secKey.GetKey().Length * 8; + DerObjectIdentifier wrapOid; + + if (length == 128) + { + wrapOid = NistObjectIdentifiers.IdAes128Wrap; + } + else if (length == 192) + { + wrapOid = NistObjectIdentifiers.IdAes192Wrap; + } + else if (length == 256) + { + wrapOid = NistObjectIdentifiers.IdAes256Wrap; + } + else + { + throw new ArgumentException("illegal keysize in AES"); + } + + keyEncAlg = new AlgorithmIdentifier(wrapOid); // parameters absent + } + else if (secKeyAlgorithm.StartsWith("SEED")) + { + // parameters absent + keyEncAlg = new AlgorithmIdentifier(KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap); + } + else if (secKeyAlgorithm.StartsWith("CAMELLIA")) + { + int length = secKey.GetKey().Length * 8; + DerObjectIdentifier wrapOid; + + if (length == 128) + { + wrapOid = NttObjectIdentifiers.IdCamellia128Wrap; + } + else if (length == 192) + { + wrapOid = NttObjectIdentifiers.IdCamellia192Wrap; + } + else if (length == 256) + { + wrapOid = NttObjectIdentifiers.IdCamellia256Wrap; + } + else + { + throw new ArgumentException("illegal keysize in Camellia"); + } + + keyEncAlg = new AlgorithmIdentifier(wrapOid); // parameters must be absent + } + else + { + throw new ArgumentException("unknown algorithm"); + } + } + + public RecipientInf( + string secKeyAlgorithm, // TODO Can get this from secKey? + KeyParameter secKey, + string algorithm, + string wrapOid, + OriginatorIdentifierOrKey originator, + X509Certificate cert) + { + DerSequence paramSeq = new DerSequence( + new DerObjectIdentifier(wrapOid), + DerNull.Instance); + + this.secKeyAlgorithm = secKeyAlgorithm; + this.secKey = secKey; + this.keyEncAlg = new AlgorithmIdentifier(new DerObjectIdentifier(algorithm), paramSeq); + this.originator = originator; + this.cert = cert; + } + + public RecipientInf( + string secKeyAlgorithm, // TODO Can get this from secKey? + KeyParameter secKey, + AlgorithmIdentifier derivationAlg) + { + this.secKeyAlgorithm = secKeyAlgorithm; + this.secKey = secKey; + this.derivationAlg = derivationAlg; + } + + internal RecipientInfo ToRecipientInfo( + KeyParameter key, + SecureRandom random) + { + byte[] keyBytes = key.GetKey(); + + if (pubKey != null) + { + IWrapper keyWrapper = Helper.CreateWrapper(keyEncAlg.ObjectID.Id); + + keyWrapper.Init(true, new ParametersWithRandom(pubKey, random)); + + Asn1OctetString encKey = new DerOctetString( + keyWrapper.Wrap(keyBytes, 0, keyBytes.Length)); + + RecipientIdentifier recipId; + if (cert != null) + { + TbsCertificateStructure tbs = TbsCertificateStructure.GetInstance( + Asn1Object.FromByteArray(cert.GetTbsCertificate())); + + Asn1.Cms.IssuerAndSerialNumber encSid = new Asn1.Cms.IssuerAndSerialNumber( + tbs.Issuer, tbs.SerialNumber.Value); + + recipId = new RecipientIdentifier(encSid); + } + else + { + recipId = new RecipientIdentifier(subKeyId); + } + + return new RecipientInfo(new KeyTransRecipientInfo(recipId, keyEncAlg, encKey)); + } + else if (originator != null) + { + IWrapper keyWrapper = Helper.CreateWrapper( + DerObjectIdentifier.GetInstance( + Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id); + + keyWrapper.Init(true, new ParametersWithRandom(secKey, random)); + + Asn1OctetString encKey = new DerOctetString( + keyWrapper.Wrap(keyBytes, 0, keyBytes.Length)); + + RecipientEncryptedKey rKey = new RecipientEncryptedKey( + new KeyAgreeRecipientIdentifier( + new Asn1.Cms.IssuerAndSerialNumber( + PrincipalUtilities.GetIssuerX509Principal(cert), + cert.SerialNumber)), + encKey); + + return new RecipientInfo( + new KeyAgreeRecipientInfo(originator, ukm, keyEncAlg, new DerSequence(rKey))); + } + else if (derivationAlg != null) + { + string rfc3211WrapperName = Helper.GetRfc3211WrapperName(secKeyAlgorithm); + IWrapper keyWrapper = Helper.CreateWrapper(rfc3211WrapperName); + + + // Note: In Java build, the IV is automatically generated in JCE layer + int ivLength = rfc3211WrapperName.StartsWith("DESEDE") ? 8 : 16; + byte[] iv = new byte[ivLength]; + random.NextBytes(iv); + + + ICipherParameters parameters = new ParametersWithIV(secKey, iv); + keyWrapper.Init(true, new ParametersWithRandom(parameters, random)); + + Asn1OctetString encKey = new DerOctetString( + keyWrapper.Wrap(keyBytes, 0, keyBytes.Length)); + +// byte[] iv = keyWrapper.GetIV(); + + DerSequence seq = new DerSequence( + new DerObjectIdentifier(secKeyAlgorithm), + new DerOctetString(iv)); + + keyEncAlg = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgPwriKek, seq); + + return new RecipientInfo(new PasswordRecipientInfo(derivationAlg, keyEncAlg, encKey)); + } + else + { + IWrapper keyWrapper = Helper.CreateWrapper(keyEncAlg.ObjectID.Id); + + keyWrapper.Init(true, new ParametersWithRandom(secKey, random)); + + Asn1OctetString encKey = new DerOctetString( + keyWrapper.Wrap(keyBytes, 0, keyBytes.Length)); + + return new RecipientInfo(new KekRecipientInfo(secKeyId, keyEncAlg, encKey)); + } + } + } + + public CmsEnvelopedGenerator() + : this(new SecureRandom()) + { + } + + ///
+ * IX509Store certs = s.GetCertificates(); + * SignerInformationStore signers = s.GetSignerInfos(); + * + * foreach (SignerInformation signer in signers.GetSigners()) + * { + * ArrayList certList = new ArrayList(certs.GetMatches(signer.SignerID)); + * X509Certificate cert = (X509Certificate) certList[0]; + * + * if (signer.Verify(cert.GetPublicKey())) + * { + * verified++; + * } + * } + *+ */ + public class CmsSignedData + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private readonly CmsProcessable signedContent; + private SignedData signedData; + private ContentInfo contentInfo; + private SignerInformationStore signerInfoStore; + private IX509Store attrCertStore; + private IX509Store certificateStore; + private IX509Store crlStore; + private IDictionary hashes; + + private CmsSignedData( + CmsSignedData c) + { + this.signedData = c.signedData; + this.contentInfo = c.contentInfo; + this.signedContent = c.signedContent; + this.signerInfoStore = c.signerInfoStore; + } + + public CmsSignedData( + byte[] sigBlock) + : this(CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false))) + { + } + + public CmsSignedData( + CmsProcessable signedContent, + byte[] sigBlock) + : this(signedContent, CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false))) + { + } + + /** + * Content with detached signature, digests precomputed + * + * @param hashes a map of precomputed digests for content indexed by name of hash. + * @param sigBlock the signature object. + */ + public CmsSignedData( + IDictionary hashes, + byte[] sigBlock) + : this(hashes, CmsUtilities.ReadContentInfo(sigBlock)) + { + } + + /** + * base constructor - content with detached signature. + * + * @param signedContent the content that was signed. + * @param sigData the signature object. + */ + public CmsSignedData( + CmsProcessable signedContent, + Stream sigData) + : this(signedContent, CmsUtilities.ReadContentInfo(sigData)) + { + } + + /** + * base constructor - with encapsulated content + */ + public CmsSignedData( + Stream sigData) + : this(CmsUtilities.ReadContentInfo(sigData)) + { + } + + public CmsSignedData( + CmsProcessable signedContent, + ContentInfo sigData) + { + this.signedContent = signedContent; + this.contentInfo = sigData; + this.signedData = SignedData.GetInstance(contentInfo.Content); + } + + public CmsSignedData( + IDictionary hashes, + ContentInfo sigData) + { + this.hashes = hashes; + this.contentInfo = sigData; + this.signedData = SignedData.GetInstance(contentInfo.Content); + } + + public CmsSignedData( + ContentInfo sigData) + { + this.contentInfo = sigData; + this.signedData = SignedData.GetInstance(contentInfo.Content); + + // + // this can happen if the signed message is sent simply to send a + // certificate chain. + // + if (signedData.EncapContentInfo.Content != null) + { + this.signedContent = new CmsProcessableByteArray( + ((Asn1OctetString)(signedData.EncapContentInfo.Content)).GetOctets()); + } +// else +// { +// this.signedContent = null; +// } + } + + ///
+ * A simple example of usage. + * + *
+ * IX509Store certs... + * IX509Store crls... + * CmsSignedDataGenerator gen = new CmsSignedDataGenerator(); + * + * gen.AddSigner(privKey, cert, CmsSignedGenerator.DigestSha1); + * gen.AddCertificates(certs); + * gen.AddCrls(crls); + * + * CmsSignedData data = gen.Generate(content); + *+ * + */ + public class CmsSignedDataGenerator + : CmsSignedGenerator + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private readonly ArrayList signerInfs = new ArrayList(); + + internal class DigOutputStream + : BaseOutputStream + { + private readonly IDigest dig; + + public DigOutputStream( + IDigest dig) + { + this.dig = dig; + } + + public override void Write( + byte[] b, + int off, + int len) + { + dig.BlockUpdate(b, off, len); + } + + public override void WriteByte( + byte b) + { + dig.Update(b); + } + } + + internal class SigOutputStream + : BaseOutputStream + { + private readonly ISigner sig; + + public SigOutputStream( + ISigner sig) + { + this.sig = sig; + } + + public override void Write( + byte[] b, + int off, + int len) + { + try + { + sig.BlockUpdate(b, off, len); + } + catch (SignatureException e) + { + throw new IOException("signature problem: " + e); + } + } + + public override void WriteByte( + byte b) + { + try + { + sig.Update(b); + } + catch (SignatureException e) + { + throw new IOException("signature problem: " + e); + } + } + } + + private class SignerInf + { + CmsSignedGenerator outer; + AsymmetricKeyParameter key; + X509Certificate cert; + string digestOID; + string encOID; + CmsAttributeTableGenerator sAttr; + CmsAttributeTableGenerator unsAttr; + Asn1.Cms.AttributeTable baseSignedTable; + + internal SignerInf( + CmsSignedGenerator outer, + AsymmetricKeyParameter key, + X509Certificate cert, + string digestOID, + string encOID) + { + this.outer = outer; + this.key = key; + this.cert = cert; + this.digestOID = digestOID; + this.encOID = encOID; + } + + internal SignerInf( + CmsSignedGenerator outer, + AsymmetricKeyParameter key, + X509Certificate cert, + string digestOID, + string encOID, + CmsAttributeTableGenerator sAttr, + CmsAttributeTableGenerator unsAttr, + Asn1.Cms.AttributeTable baseSignedTable) + { + this.outer = outer; + this.key = key; + this.cert = cert; + this.digestOID = digestOID; + this.encOID = encOID; + this.sAttr = sAttr; + this.unsAttr = unsAttr; + this.baseSignedTable = baseSignedTable; + } + + internal AsymmetricKeyParameter GetKey() + { + return key; + } + + internal X509Certificate GetCertificate() + { + return cert; + } + + internal AlgorithmIdentifier DigestAlgorithmID + { + get { return new AlgorithmIdentifier(new DerObjectIdentifier(digestOID), null); } + } + + internal string DigestAlgOid + { + get { return digestOID; } + } + + internal Asn1Object DigestAlgParams + { + get { return null; } + } + + internal AlgorithmIdentifier EncryptionAlgorithmID + { + get { return new AlgorithmIdentifier(new DerObjectIdentifier(encOID), DerNull.Instance); } + } + + internal string EncryptionAlgOid + { + get { return encOID; } + } + + internal CmsAttributeTableGenerator SignedAttributes + { + get { return sAttr; } + } + + internal CmsAttributeTableGenerator UnsignedAttributes + { + get { return unsAttr; } + } + + internal Asn1.Cms.SignerInfo ToSignerInfo( + DerObjectIdentifier contentType, + CmsProcessable content, + SecureRandom random, + bool isCounterSignature) + { + AlgorithmIdentifier digAlgId = new AlgorithmIdentifier( + new DerObjectIdentifier(this.DigestAlgOid), DerNull.Instance); + AlgorithmIdentifier encAlgId = CmsSignedGenerator.GetEncAlgorithmIdentifier(this.EncryptionAlgOid); + string digestName = Helper.GetDigestAlgName(digestOID); + string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(encOID); + ISigner sig = Helper.GetSignatureInstance(signatureName); + IDigest dig = Helper.GetDigestInstance(digestName); + + byte[] hash = null; + + if (content != null) + { + content.Write(new DigOutputStream(dig)); + + hash = DigestUtilities.DoFinal(dig); + + outer._digests.Add(digestOID, hash.Clone()); + } + + IDictionary parameters = outer.GetBaseParameters(contentType, digAlgId, hash); + Asn1.Cms.AttributeTable signed = (sAttr != null) +// ? sAttr.GetAttributes(Collections.unmodifiableMap(parameters)) + ? sAttr.GetAttributes(parameters) + : null; + + if (isCounterSignature) + { + Hashtable ats = signed.ToHashtable(); + + ats.Remove(CmsAttributes.ContentType); + + signed = new Asn1.Cms.AttributeTable(ats); + } + + Asn1Set signedAttr = outer.GetAttributeSet(signed); + + + // + // sig must be composed from the DER encoding. + // + byte[] tmp; + if (signedAttr != null) + { + tmp = signedAttr.GetEncoded(Asn1Encodable.Der); + } + else + { + MemoryStream bOut = new MemoryStream(); + content.Write(bOut); + tmp = bOut.ToArray(); + } + + sig.Init(true, new ParametersWithRandom(key, random)); + sig.BlockUpdate(tmp, 0, tmp.Length); + + Asn1OctetString encDigest = new DerOctetString(sig.GenerateSignature()); + + IDictionary baseParameters = outer.GetBaseParameters(contentType, digAlgId, hash); + baseParameters[CmsAttributeTableParameter.Signature] = encDigest.GetOctets().Clone(); + + Asn1.Cms.AttributeTable unsigned = (unsAttr != null) +// ? unsAttr.GetAttributes(Collections.unmodifiableMap(baseParameters)) + ? unsAttr.GetAttributes(baseParameters) + : null; + + Asn1Set unsignedAttr = outer.GetAttributeSet(unsigned); + + X509Certificate cert = this.GetCertificate(); + TbsCertificateStructure tbs = TbsCertificateStructure.GetInstance( + Asn1Object.FromByteArray(cert.GetTbsCertificate())); + Asn1.Cms.IssuerAndSerialNumber encSid = new Asn1.Cms.IssuerAndSerialNumber( + tbs.Issuer, tbs.SerialNumber.Value); + + return new Asn1.Cms.SignerInfo(new SignerIdentifier(encSid), digAlgId, + signedAttr, encAlgId, encDigest, unsignedAttr); + } + } + + public CmsSignedDataGenerator() + { + } + + ///
+ * Note: that because we are in a streaming mode only one signer can be tried and it is important + * that the methods on the parser are called in the appropriate order. + *
+ *+ * A simple example of usage for an encapsulated signature. + *
+ *+ * Two notes: first, in the example below the validity of + * the certificate isn't verified, just the fact that one of the certs + * matches the given signer, and, second, because we are in a streaming + * mode the order of the operations is important. + *
+ *+ * CmsSignedDataParser sp = new CmsSignedDataParser(encapSigData); + * + * sp.GetSignedContent().Drain(); + * + * IX509Store certs = sp.GetCertificates(); + * SignerInformationStore signers = sp.GetSignerInfos(); + * + * foreach (SignerInformation signer in signers.GetSigners()) + * { + * ArrayList certList = new ArrayList(certs.GetMatches(signer.SignerID)); + * X509Certificate cert = (X509Certificate) certList[0]; + * + * Console.WriteLine("verify returns: " + signer.Verify(cert)); + * } + *+ * Note also: this class does not introduce buffering - if you are processing large files you should create + * the parser with: + *
+ * CmsSignedDataParser ep = new CmsSignedDataParser(new BufferedInputStream(encapSigData, bufSize)); + *+ * where bufSize is a suitably large buffer size. + */ + public class CmsSignedDataParser + : CmsContentInfoParser + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private SignedDataParser _signedData; + private CmsTypedStream _signedContent; + private IDictionary _digests; + + private SignerInformationStore _signerInfoStore; + private Asn1Set _certSet, _crlSet; + private bool _isCertCrlParsed; + private IX509Store _attributeStore; + private IX509Store _certificateStore; + private IX509Store _crlStore; + + public CmsSignedDataParser( + byte[] sigBlock) + : this(new MemoryStream(sigBlock, false)) + { + } + + public CmsSignedDataParser( + CmsTypedStream signedContent, + byte[] sigBlock) + : this(signedContent, new MemoryStream(sigBlock, false)) + { + } + + /** + * base constructor - with encapsulated content + */ + public CmsSignedDataParser( + Stream sigData) + : this(null, sigData) + { + } + + /** + * base constructor + * + * @param signedContent the content that was signed. + * @param sigData the signature object. + */ + public CmsSignedDataParser( + CmsTypedStream signedContent, + Stream sigData) + : base(sigData) + { + try + { + this._signedContent = signedContent; + this._signedData = SignedDataParser.GetInstance(this.contentInfo.GetContent(Asn1Tags.Sequence)); + this._digests = new Hashtable(); + + Asn1SetParser digAlgs = _signedData.GetDigestAlgorithms(); + IAsn1Convertible o; + + while ((o = digAlgs.ReadObject()) != null) + { + AlgorithmIdentifier id = AlgorithmIdentifier.GetInstance(o.ToAsn1Object()); + + try + { + string digestName = Helper.GetDigestAlgName(id.ObjectID.Id); + IDigest dig = Helper.GetDigestInstance(digestName); + + this._digests[digestName] = dig; + } + catch (SecurityUtilityException) + { + // ignore + } + } + + // + // If the message is simply a certificate chain message GetContent() may return null. + // + ContentInfoParser cont = _signedData.GetEncapContentInfo(); + Asn1OctetStringParser octs = (Asn1OctetStringParser) + cont.GetContent(Asn1Tags.OctetString); + + if (octs != null) + { + CmsTypedStream ctStr = new CmsTypedStream( + cont.ContentType.Id, octs.GetOctetStream()); + + if (_signedContent == null) + { + this._signedContent = ctStr; + } + else + { + // + // content passed in, need to read past empty encapsulated content info object if present + // + ctStr.Drain(); + } + } + } + catch (IOException e) + { + throw new CmsException("io exception: " + e.Message, e); + } + + if (_digests.Count < 1) + { + throw new CmsException("no digests could be created for message."); + } + } + + /** + * Return the version number for the SignedData object + * + * @return the version number + */ + public int Version + { + get { return _signedData.Version.Value.IntValue; } + } + + /** + * return the collection of signers that are associated with the + * signatures for the message. + * @throws CmsException + */ + public SignerInformationStore GetSignerInfos() + { + if (_signerInfoStore == null) + { + PopulateCertCrlSets(); + + IList signerInfos = new ArrayList(); + IDictionary hashes = new Hashtable(); + + foreach (object digestKey in _digests.Keys) + { + hashes[digestKey] = DigestUtilities.DoFinal( + (IDigest)_digests[digestKey]); + } + + try + { + Asn1SetParser s = _signedData.GetSignerInfos(); + IAsn1Convertible o; + + while ((o = s.ReadObject()) != null) + { + SignerInfo info = SignerInfo.GetInstance(o.ToAsn1Object()); + string digestName = Helper.GetDigestAlgName( + info.DigestAlgorithm.ObjectID.Id); + + byte[] hash = (byte[]) hashes[digestName]; + DerObjectIdentifier oid = new DerObjectIdentifier(_signedContent.ContentType); + + signerInfos.Add(new SignerInformation(info, oid, null, new BaseDigestCalculator(hash))); + } + } + catch (IOException e) + { + throw new CmsException("io exception: " + e.Message, e); + } + + _signerInfoStore = new SignerInformationStore(signerInfos); + } + + return _signerInfoStore; + } + + /** + * return a X509Store containing the attribute certificates, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of attribute certificates + * @exception org.bouncycastle.x509.NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetAttributeCertificates( + string type) + { + if (_attributeStore == null) + { + PopulateCertCrlSets(); + + _attributeStore = Helper.CreateAttributeStore(type, _certSet); + } + + return _attributeStore; + } + + /** + * return a X509Store containing the public key certificates, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of public key certificates + * @exception NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetCertificates( + string type) + { + if (_certificateStore == null) + { + PopulateCertCrlSets(); + + _certificateStore = Helper.CreateCertificateStore(type, _certSet); + } + + return _certificateStore; + } + + /** + * return a X509Store containing CRLs, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of CRLs + * @exception NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetCrls( + string type) + { + if (_crlStore == null) + { + PopulateCertCrlSets(); + + _crlStore = Helper.CreateCrlStore(type, _crlSet); + } + + return _crlStore; + } + + private void PopulateCertCrlSets() + { + if (_isCertCrlParsed) + return; + + _isCertCrlParsed = true; + + try + { + // care! Streaming - Must process the GetCertificates() result before calling GetCrls() + _certSet = GetAsn1Set(_signedData.GetCertificates()); + _crlSet = GetAsn1Set(_signedData.GetCrls()); + } + catch (IOException e) + { + throw new CmsException("problem parsing cert/crl sets", e); + } + } + + public CmsTypedStream GetSignedContent() + { + if (_signedContent == null) + { + return null; + } + + Stream digStream = _signedContent.ContentStream; + + foreach (IDigest digest in _digests.Values) + { + digStream = new DigestStream(digStream, digest, null); + } + + return new CmsTypedStream(_signedContent.ContentType, digStream); + } + + /** + * Replace the signerinformation store associated with the passed + * in message contained in the stream original with the new one passed in. + * You would probably only want to do this if you wanted to change the unsigned + * attributes associated with a signer, or perhaps delete one. + *
+ * The output stream is returned unclosed. + *
+ * @param original the signed data stream to be used as a base. + * @param signerInformationStore the new signer information store to use. + * @param out the stream to Write the new signed data object to. + * @return out. + */ + public static Stream ReplaceSigners( + Stream original, + SignerInformationStore signerInformationStore, + Stream outStr) + { + Asn1StreamParser inStr = new Asn1StreamParser(original, CmsUtilities.MaximumMemory); + ContentInfoParser contentInfo = new ContentInfoParser((Asn1SequenceParser)inStr.ReadObject()); + SignedDataParser signedData = SignedDataParser.GetInstance(contentInfo.GetContent(Asn1Tags.Sequence)); + + BerSequenceGenerator sGen = new BerSequenceGenerator(outStr); + + sGen.AddObject(CmsObjectIdentifiers.SignedData); + + BerSequenceGenerator sigGen = new BerSequenceGenerator(sGen.GetRawOutputStream(), 0, true); + + // version number + sigGen.AddObject(signedData.Version); + + // digests + signedData.GetDigestAlgorithms().ToAsn1Object(); // skip old ones + + Asn1EncodableVector digestAlgs = new Asn1EncodableVector(); + + foreach (SignerInformation signer in signerInformationStore.GetSigners()) + { + digestAlgs.Add(FixAlgID(signer.DigestAlgorithmID)); + } + + WriteToGenerator(sigGen, new DerSet(digestAlgs)); + + // encap content info + ContentInfoParser encapContentInfo = signedData.GetEncapContentInfo(); + + BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream()); + + eiGen.AddObject(encapContentInfo.ContentType); + + Asn1OctetStringParser octs = (Asn1OctetStringParser)encapContentInfo.GetContent(Asn1Tags.OctetString); + + if (octs != null) + { + PipeOctetString(octs, eiGen.GetRawOutputStream()); + } + + eiGen.Close(); + + + WriteSetToGeneratorTagged(sigGen, signedData.GetCertificates(), 0); + WriteSetToGeneratorTagged(sigGen, signedData.GetCrls(), 1); + + + Asn1EncodableVector signerInfos = new Asn1EncodableVector(); + foreach (SignerInformation signer in signerInformationStore.GetSigners()) + { + signerInfos.Add(signer.ToSignerInfo()); + } + + WriteToGenerator(sigGen, new DerSet(signerInfos)); + + sigGen.Close(); + + sGen.Close(); + + return outStr; + } + + /** + * Replace the certificate and CRL information associated with this + * CMSSignedData object with the new one passed in. + *+ * The output stream is returned unclosed. + *
+ * @param original the signed data stream to be used as a base. + * @param certsAndCrls the new certificates and CRLs to be used. + * @param out the stream to Write the new signed data object to. + * @return out. + * @exception CmsException if there is an error processing the CertStore + */ + public static Stream ReplaceCertificatesAndCrls( + Stream original, + IX509Store x509Certs, + IX509Store x509Crls, + IX509Store x509AttrCerts, + Stream outStr) + { + if (x509AttrCerts != null) + throw Platform.CreateNotImplementedException("Currently can't replace attribute certificates"); + + Asn1StreamParser inStr = new Asn1StreamParser(original, CmsUtilities.MaximumMemory); + ContentInfoParser contentInfo = new ContentInfoParser((Asn1SequenceParser)inStr.ReadObject()); + SignedDataParser signedData = SignedDataParser.GetInstance(contentInfo.GetContent(Asn1Tags.Sequence)); + + BerSequenceGenerator sGen = new BerSequenceGenerator(outStr); + + sGen.AddObject(CmsObjectIdentifiers.SignedData); + + BerSequenceGenerator sigGen = new BerSequenceGenerator(sGen.GetRawOutputStream(), 0, true); + + // version number + sigGen.AddObject(signedData.Version); + + // digests + WriteToGenerator(sigGen, signedData.GetDigestAlgorithms().ToAsn1Object()); + + // encap content info + ContentInfoParser encapContentInfo = signedData.GetEncapContentInfo(); + + BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream()); + + eiGen.AddObject(encapContentInfo.ContentType); + + Asn1OctetStringParser octs = (Asn1OctetStringParser) + encapContentInfo.GetContent(Asn1Tags.OctetString); + + if (octs != null) + { + PipeOctetString(octs, eiGen.GetRawOutputStream()); + } + + eiGen.Close(); + + // + // skip existing certs and CRLs + // + GetAsn1Set(signedData.GetCertificates()); + GetAsn1Set(signedData.GetCrls()); + + // + // replace the certs and crls in the SignedData object + // + Asn1Set certs; + try + { + certs = CmsUtilities.CreateBerSetFromList( + CmsUtilities.GetCertificatesFromStore(x509Certs)); + } + catch (X509StoreException e) + { + throw new CmsException("error getting certs from certStore", e); + } + + if (certs.Count > 0) + { + WriteToGenerator(sigGen, new DerTaggedObject(false, 0, certs)); + } + + Asn1Set crls; + try + { + crls = CmsUtilities.CreateBerSetFromList( + CmsUtilities.GetCrlsFromStore(x509Crls)); + } + catch (X509StoreException e) + { + throw new CmsException("error getting crls from certStore", e); + } + + if (crls.Count > 0) + { + WriteToGenerator(sigGen, new DerTaggedObject(false, 1, crls)); + } + + WriteToGenerator(sigGen, signedData.GetSignerInfos().ToAsn1Object()); + + sigGen.Close(); + + sGen.Close(); + + return outStr; + } + + private static AlgorithmIdentifier FixAlgID( + AlgorithmIdentifier algId) + { + if (algId.Parameters == null) + return new AlgorithmIdentifier(algId.ObjectID, DerNull.Instance); + + return algId; + } + + private static void WriteSetToGeneratorTagged( + Asn1Generator asn1Gen, + Asn1SetParser asn1SetParser, + int tagNo) + { + Asn1Set asn1Set = GetAsn1Set(asn1SetParser); + + if (asn1Set != null) + { + Asn1TaggedObject taggedObj = (asn1SetParser is BerSetParser) + ? new BerTaggedObject(false, tagNo, asn1Set) + : new DerTaggedObject(false, tagNo, asn1Set); + + WriteToGenerator(asn1Gen, taggedObj); + } + } + + private static Asn1Set GetAsn1Set( + Asn1SetParser asn1SetParser) + { + return asn1SetParser == null + ? null + : Asn1Set.GetInstance(asn1SetParser.ToAsn1Object()); + } + + private static void WriteToGenerator( + Asn1Generator ag, + Asn1Encodable ae) + { + byte[] encoded = ae.GetEncoded(); + ag.GetRawOutputStream().Write(encoded, 0, encoded.Length); + } + + private static void PipeOctetString( + Asn1OctetStringParser octs, + Stream output) + { + BerOctetStringGenerator octGen = new BerOctetStringGenerator(output, 0, true); + // TODO Allow specification of a specific fragment size? + Stream outOctets = octGen.GetOctetOutputStream(); + Streams.PipeAll(octs.GetOctetStream(), outOctets); + outOctets.Close(); + } + } +} diff --git a/iTechSharp/srcbc/cms/CMSSignedDataStreamGenerator.cs b/iTechSharp/srcbc/cms/CMSSignedDataStreamGenerator.cs new file mode 100644 index 0000000..755c6c7 --- /dev/null +++ b/iTechSharp/srcbc/cms/CMSSignedDataStreamGenerator.cs @@ -0,0 +1,690 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a pkcs7-signature message stream. + *+ * A simple example of usage. + *
+ *+ * IX509Store certs... + * CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); + * + * gen.AddSigner(privateKey, cert, CmsSignedDataStreamGenerator.DIGEST_SHA1); + * + * gen.AddCertificates(certs); + * + * Stream sigOut = gen.Open(bOut); + * + * sigOut.Write(Encoding.UTF8.GetBytes("Hello World!")); + * + * sigOut.Close(); + *+ */ + public class CmsSignedDataStreamGenerator + : CmsSignedGenerator + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private readonly ArrayList _signerInfs = new ArrayList(); + private readonly ArrayList _messageDigests = new ArrayList(); + private int _bufferSize; + + private class SignerInf + { + private readonly CmsSignedDataStreamGenerator outer; + + AsymmetricKeyParameter _key; + X509Certificate _cert; + string _digestOID; + string _encOID; + CmsAttributeTableGenerator _sAttr; + CmsAttributeTableGenerator _unsAttr; + IDigest _digest; + ISigner _signature; + + internal SignerInf( + CmsSignedDataStreamGenerator outer, + AsymmetricKeyParameter key, + X509Certificate cert, + string digestOID, + string encOID, + CmsAttributeTableGenerator sAttr, + CmsAttributeTableGenerator unsAttr, + IDigest digest, + ISigner signature) + { + this.outer = outer; + + _key = key; + _cert = cert; + _digestOID = digestOID; + _encOID = encOID; + _sAttr = sAttr; + _unsAttr = unsAttr; + _digest = digest; + _signature = signature; + } + + internal AsymmetricKeyParameter Key + { + get { return _key; } + } + + internal X509Certificate Certificate + { + get { return _cert; } + } + + internal AlgorithmIdentifier DigestAlgorithmID + { + get { return new AlgorithmIdentifier(new DerObjectIdentifier(_digestOID), null); } + } + + internal string DigestAlgOid + { + get { return _digestOID; } + } + + internal Asn1Object DigestAlgParams + { + get { return null; } + } + + internal string EncryptionAlgOid + { + get { return _encOID; } + } + +// internal Asn1.Cms.AttributeTable SignedAttributes +// { +// get { return _sAttr; } +// } +// +// internal Asn1.Cms.AttributeTable UnsignedAttributes +// { +// get { return _unsAttr; } +// } + + internal SignerInfo ToSignerInfo( + DerObjectIdentifier contentType) + { + AlgorithmIdentifier digAlgId = new AlgorithmIdentifier( + new DerObjectIdentifier(this.DigestAlgOid), DerNull.Instance); + AlgorithmIdentifier encAlgId = CmsSignedGenerator.GetEncAlgorithmIdentifier(this.EncryptionAlgOid); + + byte[] hash = DigestUtilities.DoFinal(_digest); + + outer._digests.Add(_digestOID, hash.Clone()); + + IDictionary parameters = outer.GetBaseParameters(contentType, digAlgId, hash); + + Asn1.Cms.AttributeTable signed = (_sAttr != null) +// ? _sAttr.GetAttributes(Collections.unmodifiableMap(parameters)) + ? _sAttr.GetAttributes(parameters) + : null; + + Asn1Set signedAttr = outer.GetAttributeSet(signed); + + // + // sig must be composed from the DER encoding. + // + byte[] tmp; + if (signedAttr != null) + { + tmp = signedAttr.GetEncoded(Asn1Encodable.Der); + } + else + { + throw new Exception("signatures without signed attributes not implemented."); + } + + _signature.BlockUpdate(tmp, 0, tmp.Length); + + Asn1OctetString encDigest = new DerOctetString(_signature.GenerateSignature()); + + parameters = outer.GetBaseParameters(contentType, digAlgId, hash); + parameters[CmsAttributeTableParameter.Signature] = encDigest.GetOctets().Clone(); + + Asn1.Cms.AttributeTable unsigned = (_unsAttr != null) +// ? _unsAttr.getAttributes(Collections.unmodifiableMap(parameters)) + ? _unsAttr.GetAttributes(parameters) + : null; + + Asn1Set unsignedAttr = outer.GetAttributeSet(unsigned); + + X509Certificate cert = this.Certificate; + TbsCertificateStructure tbs = TbsCertificateStructure.GetInstance( + Asn1Object.FromByteArray(cert.GetTbsCertificate())); + IssuerAndSerialNumber encSid = new IssuerAndSerialNumber( + tbs.Issuer, tbs.SerialNumber.Value); + + return new SignerInfo(new SignerIdentifier(encSid), digAlgId, + signedAttr, encAlgId, encDigest, unsignedAttr); + } + + } + + public CmsSignedDataStreamGenerator() + { + } + + ///
+ * Note: in the case where the underlying cipher is either a CFB cipher or an + * OFB one the last block may not be a multiple of the block size. + *
+ */ + public class BufferedBlockCipher + : BufferedCipherBase + { + internal byte[] buf; + internal int bufOff; + internal bool forEncryption; + internal IBlockCipher cipher; + + /** + * constructor for subclasses + */ + protected BufferedBlockCipher() + { + } + + /** + * Create a buffered block cipher without padding. + * + * @param cipher the underlying block cipher this buffering object wraps. + * false otherwise. + */ + public BufferedBlockCipher( + IBlockCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + // Note: This doubles as the Init in the event that this cipher is being used as an IWrapper + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + Reset(); + + cipher.Init(forEncryption, parameters); + } + + /** + * return the blocksize for the underlying cipher. + * + * @return the blocksize for the underlying cipher. + */ + public override int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + return total - leftOver; + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + if (leftOver == 0) + { + return total; + } + return total - leftOver + buf.Length; + } + + /** + * process a single byte, producing an output block if neccessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + buf[bufOff++] = input; + + if (bufOff == buf.Length) + { + if ((outOff + buf.Length) > output.Length) + throw new DataLengthException("output buffer too short"); + + bufOff = 0; + return cipher.ProcessBlock(buf, 0, output, outOff); + } + + return 0; + } + + public override byte[] ProcessByte( + byte input) + { + int outLength = GetUpdateOutputSize(1); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessByte(input, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (length < 1) + return null; + + int outLength = GetUpdateOutputSize(length); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessBytes(input, inOff, length, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 1) + { + if (length < 0) + throw new ArgumentException("Can't have a negative input length!"); + + return 0; + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + if ((outOff + outLength) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + length -= gapLen; + inOff += gapLen; + while (length > buf.Length) + { + resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); + length -= blockSize; + inOff += blockSize; + } + } + Array.Copy(input, inOff, buf, bufOff, length); + bufOff += length; + if (bufOff == buf.Length) + { + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + bufOff = 0; + } + return resultLen; + } + + public override byte[] DoFinal() + { + byte[] outBytes = EmptyBuffer; + + int length = GetOutputSize(0); + if (length > 0) + { + outBytes = new byte[length]; + + int pos = DoFinal(outBytes, 0); + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + } + + return outBytes; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int inLen) + { + if (input == null) + throw new ArgumentNullException("input"); + + int length = GetOutputSize(inLen); + + byte[] outBytes = EmptyBuffer; + + if (length > 0) + { + outBytes = new byte[length]; + + int pos = (inLen > 0) + ? ProcessBytes(input, inOff, inLen, outBytes, 0) + : 0; + + pos += DoFinal(outBytes, pos); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + } + + return outBytes; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output, or the input is not block size aligned and should be. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + * @exception DataLengthException if the input is not block size + * aligned. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + if (bufOff != 0) + { + if (!cipher.IsPartialBlockOkay) + { + throw new DataLengthException("data not block size aligned"); + } + + if (outOff + bufOff > output.Length) + { + throw new DataLengthException("output buffer too short for DoFinal()"); + } + + // NB: Can't copy directly, or we may write too much output + cipher.ProcessBlock(buf, 0, buf, 0); + Array.Copy(buf, 0, output, outOff, bufOff); + } + + int resultLen = bufOff; + + Reset(); + + return resultLen; + } + + /** + * Reset the buffer and cipher. After resetting the object is in the same + * state as it was after the last init (if there was one). + */ + public override void Reset() + { + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + cipher.Reset(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/BufferedCipherBase.cs b/iTechSharp/srcbc/crypto/BufferedCipherBase.cs new file mode 100644 index 0000000..9d86102 --- /dev/null +++ b/iTechSharp/srcbc/crypto/BufferedCipherBase.cs @@ -0,0 +1,113 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + public abstract class BufferedCipherBase + : IBufferedCipher + { + protected static readonly byte[] EmptyBuffer = new byte[0]; + + public abstract string AlgorithmName { get; } + + public abstract void Init(bool forEncryption, ICipherParameters parameters); + + public abstract int GetBlockSize(); + + public abstract int GetOutputSize(int inputLen); + public abstract int GetUpdateOutputSize(int inputLen); + + public abstract byte[] ProcessByte(byte input); + + public virtual int ProcessByte( + byte input, + byte[] output, + int outOff) + { + byte[] outBytes = ProcessByte(input); + if (outBytes == null) + return 0; + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public virtual byte[] ProcessBytes( + byte[] input) + { + return ProcessBytes(input, 0, input.Length); + } + + public abstract byte[] ProcessBytes(byte[] input, int inOff, int length); + + public virtual int ProcessBytes( + byte[] input, + byte[] output, + int outOff) + { + return ProcessBytes(input, 0, input.Length, output, outOff); + } + + public virtual int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + byte[] outBytes = ProcessBytes(input, inOff, length); + if (outBytes == null) + return 0; + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public abstract byte[] DoFinal(); + + public virtual byte[] DoFinal( + byte[] input) + { + return DoFinal(input, 0, input.Length); + } + + public abstract byte[] DoFinal( + byte[] input, + int inOff, + int length); + + public virtual int DoFinal( + byte[] output, + int outOff) + { + byte[] outBytes = DoFinal(); + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public virtual int DoFinal( + byte[] input, + byte[] output, + int outOff) + { + return DoFinal(input, 0, input.Length, output, outOff); + } + + public virtual int DoFinal( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + int len = ProcessBytes(input, inOff, length, output, outOff); + len += DoFinal(output, outOff + len); + return len; + } + + public abstract void Reset(); + } +} diff --git a/iTechSharp/srcbc/crypto/BufferedIesCipher.cs b/iTechSharp/srcbc/crypto/BufferedIesCipher.cs new file mode 100644 index 0000000..6dab4ae --- /dev/null +++ b/iTechSharp/srcbc/crypto/BufferedIesCipher.cs @@ -0,0 +1,113 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto +{ + public class BufferedIesCipher + : BufferedCipherBase + { + private readonly IesEngine engine; + private bool forEncryption; + private MemoryStream buffer = new MemoryStream(); + + public BufferedIesCipher( + IesEngine engine) + { + if (engine == null) + throw new ArgumentNullException("engine"); + + this.engine = engine; + } + + public override string AlgorithmName + { + // TODO Create IESEngine.AlgorithmName + get { return "IES"; } + } + + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + // TODO + throw Platform.CreateNotImplementedException("IES"); + } + + public override int GetBlockSize() + { + return 0; + } + + public override int GetOutputSize( + int inputLen) + { + if (engine == null) + throw new InvalidOperationException("cipher not initialised"); + + int baseLen = inputLen + (int) buffer.Length; + return forEncryption + ? baseLen + 20 + : baseLen - 20; + } + + public override int GetUpdateOutputSize( + int inputLen) + { + return 0; + } + + public override byte[] ProcessByte( + byte input) + { + buffer.WriteByte(input); + return null; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (inOff < 0) + throw new ArgumentException("inOff"); + if (length < 0) + throw new ArgumentException("length"); + if (inOff + length > input.Length) + throw new ArgumentException("invalid offset/length specified for input array"); + + buffer.Write(input, inOff, length); + return null; + } + + public override byte[] DoFinal() + { + byte[] buf = buffer.ToArray(); + + Reset(); + + return engine.ProcessBlock(buf, 0, buf.Length); + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int length) + { + ProcessBytes(input, inOff, length); + return DoFinal(); + } + + public override void Reset() + { + buffer.SetLength(0); + } + } +} diff --git a/iTechSharp/srcbc/crypto/BufferedStreamCipher.cs b/iTechSharp/srcbc/crypto/BufferedStreamCipher.cs new file mode 100644 index 0000000..2d4987b --- /dev/null +++ b/iTechSharp/srcbc/crypto/BufferedStreamCipher.cs @@ -0,0 +1,131 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + public class BufferedStreamCipher + : BufferedCipherBase + { + private readonly IStreamCipher cipher; + + public BufferedStreamCipher( + IStreamCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + cipher.Init(forEncryption, parameters); + } + + public override int GetBlockSize() + { + return 0; + } + + public override int GetOutputSize( + int inputLen) + { + return inputLen; + } + + public override int GetUpdateOutputSize( + int inputLen) + { + return inputLen; + } + + public override byte[] ProcessByte( + byte input) + { + return new byte[]{ cipher.ReturnByte(input) }; + } + + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + if (outOff >= output.Length) + throw new DataLengthException("output buffer too short"); + + output[outOff] = cipher.ReturnByte(input); + return 1; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (length < 1) + return null; + + byte[] output = new byte[length]; + cipher.ProcessBytes(input, inOff, length, output, 0); + return output; + } + + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 1) + return 0; + + if (length > 0) + { + cipher.ProcessBytes(input, inOff, length, output, outOff); + } + + return length; + } + + public override byte[] DoFinal() + { + Reset(); + + return EmptyBuffer; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int length) + { + if (length < 1) + return EmptyBuffer; + + byte[] output = ProcessBytes(input, inOff, length); + + Reset(); + + return output; + } + + public override void Reset() + { + cipher.Reset(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/CipherKeyGenerator.cs b/iTechSharp/srcbc/crypto/CipherKeyGenerator.cs new file mode 100644 index 0000000..5d00d34 --- /dev/null +++ b/iTechSharp/srcbc/crypto/CipherKeyGenerator.cs @@ -0,0 +1,83 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The base class for symmetric, or secret, cipher key generators. + */ + public class CipherKeyGenerator + { + protected internal SecureRandom random; + protected internal int strength; + private bool uninitialised = true; + private int defaultStrength; + + public CipherKeyGenerator() + { + } + + internal CipherKeyGenerator( + int defaultStrength) + { + if (defaultStrength < 1) + throw new ArgumentException("strength must be a positive value", "defaultStrength"); + + this.defaultStrength = defaultStrength; + } + + public int DefaultStrength + { + get { return defaultStrength; } + } + + /** + * initialise the key generator. + * + * @param param the parameters to be used for key generation + */ + public void Init( + KeyGenerationParameters parameters) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + + this.uninitialised = false; + + engineInit(parameters); + } + + protected virtual void engineInit( + KeyGenerationParameters parameters) + { + this.random = parameters.Random; + this.strength = (parameters.Strength + 7) / 8; + } + + /** + * Generate a secret key. + * + * @return a byte array containing the key value. + */ + public byte[] GenerateKey() + { + if (uninitialised) + { + if (defaultStrength < 1) + throw new InvalidOperationException("Generator has not been initialised"); + + uninitialised = false; + + engineInit(new KeyGenerationParameters(new SecureRandom(), defaultStrength)); + } + + return engineGenerateKey(); + } + + protected virtual byte[] engineGenerateKey() + { + return random.GenerateSeed(strength); + } + } +} diff --git a/iTechSharp/srcbc/crypto/CryptoException.cs b/iTechSharp/srcbc/crypto/CryptoException.cs new file mode 100644 index 0000000..05b6b49 --- /dev/null +++ b/iTechSharp/srcbc/crypto/CryptoException.cs @@ -0,0 +1,25 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + public abstract class CryptoException + : Exception + { + protected CryptoException() + { + } + + protected CryptoException( + string message) + : base(message) + { + } + + protected CryptoException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/iTechSharp/srcbc/crypto/DataLengthException.cs b/iTechSharp/srcbc/crypto/DataLengthException.cs new file mode 100644 index 0000000..8bd695b --- /dev/null +++ b/iTechSharp/srcbc/crypto/DataLengthException.cs @@ -0,0 +1,39 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * this exception is thrown if a buffer that is meant to have output + * copied into it turns out to be too short, or if we've been given + * insufficient input. In general this exception will Get thrown rather + * than an ArrayOutOfBounds exception. + */ + public class DataLengthException + : CryptoException + { + /** + * base constructor. + */ + public DataLengthException() + { + } + + /** + * create a DataLengthException with the given message. + * + * @param message the message to be carried with the exception. + */ + public DataLengthException( + string message) + : base(message) + { + } + + public DataLengthException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/iTechSharp/srcbc/crypto/IAsymmetricBlockCipher.cs b/iTechSharp/srcbc/crypto/IAsymmetricBlockCipher.cs new file mode 100644 index 0000000..455cfaa --- /dev/null +++ b/iTechSharp/srcbc/crypto/IAsymmetricBlockCipher.cs @@ -0,0 +1,30 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + ///+ * doFinal leaves the MAC in the same state it was after the last init. + *
+ * @param out the array the MAC is to be output to. + * @param outOff the offset into the out buffer the output is to start at. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the MAC is not initialised. + */ + int DoFinal(byte[] output, int outOff); + + /** + * Reset the MAC. At the end of resetting the MAC should be in the + * in the same state it was after the last init (if there was one). + */ + void Reset(); + } +} diff --git a/iTechSharp/srcbc/crypto/ISigner.cs b/iTechSharp/srcbc/crypto/ISigner.cs new file mode 100644 index 0000000..e03bbf4 --- /dev/null +++ b/iTechSharp/srcbc/crypto/ISigner.cs @@ -0,0 +1,50 @@ + +using System; +using System.Text; + +namespace Org.BouncyCastle.Crypto +{ + public interface ISigner + { + /** + * Return the name of the algorithm the signer implements. + * + * @return the name of the algorithm the signer implements. + */ + string AlgorithmName { get; } + + /** + * Initialise the signer for signing or verification. + * + * @param forSigning true if for signing, false otherwise + * @param param necessary parameters. + */ + void Init(bool forSigning, ICipherParameters parameters); + + /** + * update the internal digest with the byte b + */ + void Update(byte input); + + /** + * update the internal digest with the byte array in + */ + void BlockUpdate(byte[] input, int inOff, int length); + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + byte[] GenerateSignature(); + /** + * return true if the internal state represents the signature described + * in the passed in array. + */ + bool VerifySignature(byte[] signature); + + /** + * reset the internal state + */ + void Reset(); + } +} diff --git a/iTechSharp/srcbc/crypto/ISignerWithRecovery.cs b/iTechSharp/srcbc/crypto/ISignerWithRecovery.cs new file mode 100644 index 0000000..b78a42a --- /dev/null +++ b/iTechSharp/srcbc/crypto/ISignerWithRecovery.cs @@ -0,0 +1,28 @@ + +using System; +using System.Text; + +namespace Org.BouncyCastle.Crypto +{ + /** + * Signer with message recovery. + */ + public interface ISignerWithRecovery + : ISigner + { + /** + * Returns true if the signer has recovered the full message as + * part of signature verification. + * + * @return true if full message recovered. + */ + bool HasFullMessage(); + + /** + * Returns a reference to what message was recovered (if any). + * + * @return full/partial message, null if nothing. + */ + byte[] GetRecoveredMessage(); + } +} diff --git a/iTechSharp/srcbc/crypto/IStreamCipher.cs b/iTechSharp/srcbc/crypto/IStreamCipher.cs new file mode 100644 index 0000000..8e575a7 --- /dev/null +++ b/iTechSharp/srcbc/crypto/IStreamCipher.cs @@ -0,0 +1,45 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + ///+ * note: This uses MTI/A0 key agreement in order to make the key agreement + * secure against passive attacks. If you're doing Diffie-Hellman and both + * parties have long term public keys you should look at using this. For + * further information have a look at RFC 2631.
+ *+ * It's possible to extend this to more than two parties as well, for the moment + * that is left as an exercise for the reader.
+ */ + public class DHAgreement + { + private DHPrivateKeyParameters key; + private DHParameters dhParams; + private BigInteger privateValue; + private SecureRandom random; + + public void Init( + ICipherParameters parameters) + { + AsymmetricKeyParameter kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + kParam = (AsymmetricKeyParameter)rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + kParam = (AsymmetricKeyParameter)parameters; + } + + if (!(kParam is DHPrivateKeyParameters)) + { + throw new ArgumentException("DHEngine expects DHPrivateKeyParameters"); + } + + this.key = (DHPrivateKeyParameters)kParam; + this.dhParams = key.Parameters; + } + + /** + * calculate our initial message. + */ + public BigInteger CalculateMessage() + { + int bits = dhParams.P.BitLength - 1; + + // TODO Should the generated numbers always have length 'P.BitLength - 1'? + this.privateValue = new BigInteger(bits, random).SetBit(bits - 1); + + return dhParams.G.ModPow(privateValue, dhParams.P); + } + + /** + * given a message from a given party and the corresponding public key + * calculate the next message in the agreement sequence. In this case + * this will represent the shared secret. + */ + public BigInteger CalculateAgreement( + DHPublicKeyParameters pub, + BigInteger message) + { + if (pub == null) + throw new ArgumentNullException("pub"); + if (message == null) + throw new ArgumentNullException("message"); + + if (!pub.Parameters.Equals(dhParams)) + { + throw new ArgumentException("Diffie-Hellman public key has wrong parameters."); + } + + return message.ModPow(key.X, dhParams.P).Multiply(pub.Y.ModPow(privateValue, dhParams.P)).Mod(dhParams.P); + } + } +} diff --git a/iTechSharp/srcbc/crypto/agreement/DHBasicAgreement.cs b/iTechSharp/srcbc/crypto/agreement/DHBasicAgreement.cs new file mode 100644 index 0000000..5a52770 --- /dev/null +++ b/iTechSharp/srcbc/crypto/agreement/DHBasicAgreement.cs @@ -0,0 +1,60 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * a Diffie-Hellman key agreement class. + *+ * note: This is only the basic algorithm, it doesn't take advantage of + * long term public keys if they are available. See the DHAgreement class + * for a "better" implementation.
+ */ + public class DHBasicAgreement + : IBasicAgreement + { + private DHPrivateKeyParameters key; + private DHParameters dhParams; + + public void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + if (!(parameters is DHPrivateKeyParameters)) + { + throw new ArgumentException("DHEngine expects DHPrivateKeyParameters"); + } + + this.key = (DHPrivateKeyParameters) parameters; + this.dhParams = key.Parameters; + } + + /** + * given a short term public key from a given party calculate the next + * message in the agreement sequence. + */ + public BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + if (this.key == null) + throw new InvalidOperationException("Agreement algorithm not initialised"); + + DHPublicKeyParameters pub = (DHPublicKeyParameters)pubKey; + + if (!pub.Parameters.Equals(dhParams)) + { + throw new ArgumentException("Diffie-Hellman public key has wrong parameters."); + } + + return pub.Y.ModPow(key.X, dhParams.P); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/agreement/ECDHBasicAgreement.cs b/iTechSharp/srcbc/crypto/agreement/ECDHBasicAgreement.cs new file mode 100644 index 0000000..0870f8e --- /dev/null +++ b/iTechSharp/srcbc/crypto/agreement/ECDHBasicAgreement.cs @@ -0,0 +1,50 @@ +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * P1363 7.2.1 ECSVDP-DH + * + * ECSVDP-DH is Elliptic Curve Secret Value Derivation Primitive, + * Diffie-Hellman version. It is based on the work of [DH76], [Mil86], + * and [Kob87]. This primitive derives a shared secret value from one + * party's private key and another party's public key, where both have + * the same set of EC domain parameters. If two parties correctly + * execute this primitive, they will produce the same output. This + * primitive can be invoked by a scheme to derive a shared secret key; + * specifically, it may be used with the schemes ECKAS-DH1 and + * DL/ECKAS-DH2. It assumes that the input keys are valid (see also + * Section 7.2.2). + */ + public class ECDHBasicAgreement + : IBasicAgreement + { + private ECPrivateKeyParameters key; + + public void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + this.key = (ECPrivateKeyParameters) parameters; + } + + public virtual BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey; + ECPoint P = pub.Q.Multiply(key.D); + + // if ( p.IsInfinity ) throw new Exception("d*Q == infinity"); + + return P.X.ToBigInteger(); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/agreement/ECDHCBasicAgreement.cs b/iTechSharp/srcbc/crypto/agreement/ECDHCBasicAgreement.cs new file mode 100644 index 0000000..905d241 --- /dev/null +++ b/iTechSharp/srcbc/crypto/agreement/ECDHCBasicAgreement.cs @@ -0,0 +1,58 @@ +using System; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * P1363 7.2.2 ECSVDP-DHC + * + * ECSVDP-DHC is Elliptic Curve Secret Value Derivation Primitive, + * Diffie-Hellman version with cofactor multiplication. It is based on + * the work of [DH76], [Mil86], [Kob87], [LMQ98] and [Kal98a]. This + * primitive derives a shared secret value from one party's private key + * and another party's public key, where both have the same set of EC + * domain parameters. If two parties correctly execute this primitive, + * they will produce the same output. This primitive can be invoked by a + * scheme to derive a shared secret key; specifically, it may be used + * with the schemes ECKAS-DH1 and DL/ECKAS-DH2. It does not assume the + * validity of the input public key (see also Section 7.2.1). + *+ * Note: As stated P1363 compatibility mode with ECDH can be preset, and + * in this case the implementation doesn't have a ECDH compatibility mode + * (if you want that just use ECDHBasicAgreement and note they both implement + * BasicAgreement!).
+ */ + public class ECDHCBasicAgreement + : IBasicAgreement + { + private ECPrivateKeyParameters key; + + public void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + this.key = (ECPrivateKeyParameters)parameters; + } + + public BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey; + ECDomainParameters parameters = pub.Parameters; + ECPoint P = pub.Q.Multiply(parameters.H.Multiply(key.D)); + + // if ( p.IsInfinity ) throw new Exception("Invalid public key"); + + return P.X.ToBigInteger(); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/agreement/ECDHWithKdfBasicAgreement.cs b/iTechSharp/srcbc/crypto/agreement/ECDHWithKdfBasicAgreement.cs new file mode 100644 index 0000000..9c66e95 --- /dev/null +++ b/iTechSharp/srcbc/crypto/agreement/ECDHWithKdfBasicAgreement.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto.Agreement.Kdf; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + public class ECDHWithKdfBasicAgreement + : ECDHBasicAgreement + { + private static readonly Hashtable algorithms = new Hashtable(); + + static ECDHWithKdfBasicAgreement() + { + algorithms.Add(NistObjectIdentifiers.IdAes128Cbc.Id, 128); + algorithms.Add(NistObjectIdentifiers.IdAes192Cbc.Id, 192); + algorithms.Add(NistObjectIdentifiers.IdAes256Cbc.Id, 256); + algorithms.Add(NistObjectIdentifiers.IdAes128Wrap.Id, 128); + algorithms.Add(NistObjectIdentifiers.IdAes192Wrap.Id, 192); + algorithms.Add(NistObjectIdentifiers.IdAes256Wrap.Id, 256); + algorithms.Add(PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id, 192); + } + + private readonly string algorithm; + private readonly IDerivationFunction kdf; + + public ECDHWithKdfBasicAgreement( + string algorithm, + IDerivationFunction kdf) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (!algorithms.Contains(algorithm)) + throw new ArgumentException("Unknown algorithm", "algorithm"); + if (kdf == null) + throw new ArgumentNullException("kdf"); + + this.algorithm = algorithm; + this.kdf = kdf; + } + + public override BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + BigInteger result = base.CalculateAgreement(pubKey); + + int keySize = (int) algorithms[algorithm]; + + DHKdfParameters dhKdfParams = new DHKdfParameters( + new DerObjectIdentifier(algorithm), + keySize, + // TODO Fix the way bytes are derived from the secret + result.ToByteArrayUnsigned()); + + kdf.Init(dhKdfParams); + + byte[] keyBytes = new byte[keySize / 8]; + kdf.GenerateBytes(keyBytes, 0, keyBytes.Length); + + return new BigInteger(1, keyBytes); + } + } +} diff --git a/iTechSharp/srcbc/crypto/agreement/kdf/DHKdfParameters.cs b/iTechSharp/srcbc/crypto/agreement/kdf/DHKdfParameters.cs new file mode 100644 index 0000000..f6c9e60 --- /dev/null +++ b/iTechSharp/srcbc/crypto/agreement/kdf/DHKdfParameters.cs @@ -0,0 +1,57 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Crypto.Agreement.Kdf +{ + public class DHKdfParameters + : IDerivationParameters + { + private readonly DerObjectIdentifier algorithm; + private readonly int keySize; + private readonly byte[] z; + private readonly byte[] extraInfo; + + public DHKdfParameters( + DerObjectIdentifier algorithm, + int keySize, + byte[] z) + : this(algorithm, keySize, z, null) + { + } + + public DHKdfParameters( + DerObjectIdentifier algorithm, + int keySize, + byte[] z, + byte[] extraInfo) + { + this.algorithm = algorithm; + this.keySize = keySize; + this.z = z; // TODO Clone? + this.extraInfo = extraInfo; + } + + public DerObjectIdentifier Algorithm + { + get { return algorithm; } + } + + public int KeySize + { + get { return keySize; } + } + + public byte[] GetZ() + { + // TODO Clone? + return z; + } + + public byte[] GetExtraInfo() + { + // TODO Clone? + return extraInfo; + } + } +} diff --git a/iTechSharp/srcbc/crypto/agreement/kdf/DHKekGenerator.cs b/iTechSharp/srcbc/crypto/agreement/kdf/DHKekGenerator.cs new file mode 100644 index 0000000..fa29215 --- /dev/null +++ b/iTechSharp/srcbc/crypto/agreement/kdf/DHKekGenerator.cs @@ -0,0 +1,129 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Crypto.Agreement.Kdf +{ + /** + * RFC 2631 Diffie-hellman KEK derivation function. + */ + public class DHKekGenerator + : IDerivationFunction + { + private readonly IDigest digest; + + private DerObjectIdentifier algorithm; + private int keySize; + private byte[] z; + private byte[] partyAInfo; + + public DHKekGenerator( + IDigest digest) + { + this.digest = digest; + } + + public void Init( + IDerivationParameters param) + { + DHKdfParameters parameters = (DHKdfParameters)param; + + this.algorithm = parameters.Algorithm; + this.keySize = parameters.KeySize; + this.z = parameters.GetZ(); // TODO Clone? + this.partyAInfo = parameters.GetExtraInfo(); // TODO Clone? + } + + public IDigest Digest + { + get { return digest; } + } + + public int GenerateBytes( + byte[] outBytes, + int outOff, + int len) + { + if ((outBytes.Length - len) < outOff) + { + throw new DataLengthException("output buffer too small"); + } + + long oBytes = len; + int outLen = digest.GetDigestSize(); + + // + // this is at odds with the standard implementation, the + // maximum value should be hBits * (2^32 - 1) where hBits + // is the digest output size in bits. We can't have an + // array with a long index at the moment... + // + if (oBytes > ((2L << 32) - 1)) + { + throw new ArgumentException("Output length too large"); + } + + int cThreshold = (int)((oBytes + outLen - 1) / outLen); + + byte[] dig = new byte[digest.GetDigestSize()]; + + int counter = 1; + + for (int i = 0; i < cThreshold; i++) + { + digest.BlockUpdate(z, 0, z.Length); + + // KeySpecificInfo + DerSequence keyInfo = new DerSequence( + algorithm, + new DerOctetString(integerToBytes(counter))); + + // OtherInfo + Asn1EncodableVector v1 = new Asn1EncodableVector(keyInfo); + + if (partyAInfo != null) + { + v1.Add(new DerTaggedObject(true, 0, new DerOctetString(partyAInfo))); + } + + v1.Add(new DerTaggedObject(true, 2, new DerOctetString(integerToBytes(keySize)))); + + byte[] other = new DerSequence(v1).GetDerEncoded(); + + digest.BlockUpdate(other, 0, other.Length); + + digest.DoFinal(dig, 0); + + if (len > outLen) + { + Array.Copy(dig, 0, outBytes, outOff, outLen); + outOff += outLen; + len -= outLen; + } + else + { + Array.Copy(dig, 0, outBytes, outOff, len); + } + + counter++; + } + + digest.Reset(); + + return len; + } + + private byte[] integerToBytes( + int keySize) + { + byte[] val = new byte[4]; + + val[0] = (byte)(keySize >> 24); + val[1] = (byte)(keySize >> 16); + val[2] = (byte)(keySize >> 8); + val[3] = (byte)keySize; + + return val; + } + } +} diff --git a/iTechSharp/srcbc/crypto/agreement/kdf/ECDHKekGenerator.cs b/iTechSharp/srcbc/crypto/agreement/kdf/ECDHKekGenerator.cs new file mode 100644 index 0000000..1fa893e --- /dev/null +++ b/iTechSharp/srcbc/crypto/agreement/kdf/ECDHKekGenerator.cs @@ -0,0 +1,70 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Agreement.Kdf +{ + /** + * X9.63 based key derivation function for ECDH CMS. + */ + public class ECDHKekGenerator + : IDerivationFunction + { + private readonly IDerivationFunction kdf; + + private DerObjectIdentifier algorithm; + private int keySize; + private byte[] z; + + public ECDHKekGenerator( + IDigest digest) + { + this.kdf = new Kdf2BytesGenerator(digest); + } + + public void Init( + IDerivationParameters param) + { + DHKdfParameters parameters = (DHKdfParameters)param; + + this.algorithm = parameters.Algorithm; + this.keySize = parameters.KeySize; + this.z = parameters.GetZ(); // TODO Clone? + } + + public IDigest Digest + { + get { return kdf.Digest; } + } + + public int GenerateBytes( + byte[] outBytes, + int outOff, + int len) + { + // ECC-CMS-SharedInfo + DerSequence s = new DerSequence( + new AlgorithmIdentifier(algorithm, DerNull.Instance), + new DerTaggedObject(true, 2, new DerOctetString(integerToBytes(keySize)))); + + kdf.Init(new KdfParameters(z, s.GetDerEncoded())); + + return kdf.GenerateBytes(outBytes, outOff, len); + } + + private byte[] integerToBytes(int keySize) + { + byte[] val = new byte[4]; + + val[0] = (byte)(keySize >> 24); + val[1] = (byte)(keySize >> 16); + val[2] = (byte)(keySize >> 8); + val[3] = (byte)keySize; + + return val; + } + } +} diff --git a/iTechSharp/srcbc/crypto/digests/GOST3411Digest.cs b/iTechSharp/srcbc/crypto/digests/GOST3411Digest.cs new file mode 100644 index 0000000..3055733 --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/GOST3411Digest.cs @@ -0,0 +1,338 @@ +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of GOST R 34.11-94 + */ + public class Gost3411Digest + : IDigest + { + private const int DIGEST_LENGTH = 32; + + private byte[] H = new byte[32], L = new byte[32], + M = new byte[32], Sum = new byte[32]; + private byte[][] C = new byte[4][]; + + private byte[] xBuf = new byte[32]; + private int xBufOff; + private long byteCount; + + private readonly IBlockCipher cipher = new Gost28147Engine(); + + /** + * Standard constructor + */ + public Gost3411Digest() + { + // TODO Is it possible to declare multi-dimensional arrays as in Java? + for (int i = 0; i < 4; ++i) + { + C[i] = new byte[32]; + } + + cipher.Init(true, new ParametersWithSBox(null, Gost28147Engine.GetSBox("D-A"))); + + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Gost3411Digest(Gost3411Digest t) + : this() + { +// cipher.Init(true, new ParametersWithSBox(null, Gost28147Engine.GetSBox("D-A"))); +// +// Reset(); + + Array.Copy(t.H, 0, this.H, 0, t.H.Length); + Array.Copy(t.L, 0, this.L, 0, t.L.Length); + Array.Copy(t.M, 0, this.M, 0, t.M.Length); + Array.Copy(t.Sum, 0, this.Sum, 0, t.Sum.Length); + Array.Copy(t.C[1], 0, this.C[1], 0, t.C[1].Length); + Array.Copy(t.C[2], 0, this.C[2], 0, t.C[2].Length); + Array.Copy(t.C[3], 0, this.C[3], 0, t.C[3].Length); + Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.Length); + + this.xBufOff = t.xBufOff; + this.byteCount = t.byteCount; + } + + public string AlgorithmName + { + get { return "Gost3411"; } + } + + public int GetDigestSize() + { + return DIGEST_LENGTH; + } + + public void Update( + byte input) + { + xBuf[xBufOff++] = input; + if (xBufOff == xBuf.Length) + { + sumByteArray(xBuf); // calc sum M + processBlock(xBuf, 0); + xBufOff = 0; + } + byteCount++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + while ((xBufOff != 0) && (length > 0)) + { + Update(input[inOff]); + inOff++; + length--; + } + + while (length > xBuf.Length) + { + Array.Copy(input, inOff, xBuf, 0, xBuf.Length); + + sumByteArray(xBuf); // calc sum M + processBlock(xBuf, 0); + inOff += xBuf.Length; + length -= xBuf.Length; + byteCount += xBuf.Length; + } + + // load in the remainder. + while (length > 0) + { + Update(input[inOff]); + inOff++; + length--; + } + } + + // (i + 1 + 4(k - 1)) = 8i + k i = 0-3, k = 1-8 + private byte[] K = new byte[32]; + + private byte[] P(byte[] input) + { + int fourK = 0; + for(int k = 0; k < 8; k++) + { + K[fourK++] = input[k]; + K[fourK++] = input[8 + k]; + K[fourK++] = input[16 + k]; + K[fourK++] = input[24 + k]; + } + + return K; + } + + //A (x) = (x0 ^ x1) || x3 || x2 || x1 + byte[] a = new byte[8]; + private byte[] A(byte[] input) + { + for(int j=0; j<8; j++) + { + a[j]=(byte)(input[j] ^ input[j+8]); + } + + Array.Copy(input, 8, input, 0, 24); + Array.Copy(a, 0, input, 24, 8); + + return input; + } + + //Encrypt function, ECB mode + private void E(byte[] key, byte[] s, int sOff, byte[] input, int inOff) + { + cipher.Init(true, new KeyParameter(key)); + + cipher.ProcessBlock(input, inOff, s, sOff); + } + + // (in:) n16||..||n1 ==> (out:) n1^n2^n3^n4^n13^n16||n16||..||n2 + internal short[] wS = new short[16], w_S = new short[16]; + + private void fw(byte[] input) + { + cpyBytesToShort(input, wS); + w_S[15] = (short)(wS[0] ^ wS[1] ^ wS[2] ^ wS[3] ^ wS[12] ^ wS[15]); + Array.Copy(wS, 1, w_S, 0, 15); + cpyShortToBytes(w_S, input); + } + + // block processing + internal byte[] S = new byte[32], U = new byte[32], V = new byte[32], W = new byte[32]; + + private void processBlock(byte[] input, int inOff) + { + Array.Copy(input, inOff, M, 0, 32); + + //key step 1 + + // H = h3 || h2 || h1 || h0 + // S = s3 || s2 || s1 || s0 + H.CopyTo(U, 0); + M.CopyTo(V, 0); + for (int j=0; j<32; j++) + { + W[j] = (byte)(U[j]^V[j]); + } + // Encrypt gost28147-ECB + E(P(W), S, 0, H, 0); // s0 = EK0 [h0] + + //keys step 2,3,4 + for (int i=1; i<4; i++) + { + byte[] tmpA = A(U); + for (int j=0; j<32; j++) + { + U[j] = (byte)(tmpA[j] ^ C[i][j]); + } + V = A(A(V)); + for (int j=0; j<32; j++) + { + W[j] = (byte)(U[j]^V[j]); + } + // Encrypt gost28147-ECB + E(P(W), S, i * 8, H, i * 8); // si = EKi [hi] + } + + // x(M, H) = y61(H^y(M^y12(S))) + for(int n = 0; n < 12; n++) + { + fw(S); + } + for(int n = 0; n < 32; n++) + { + S[n] = (byte)(S[n] ^ M[n]); + } + + fw(S); + + for(int n = 0; n < 32; n++) + { + S[n] = (byte)(H[n] ^ S[n]); + } + for(int n = 0; n < 61; n++) + { + fw(S); + } + Array.Copy(S, 0, H, 0, H.Length); + } + + private void finish() + { + LongToBytes(byteCount * 8, L, 0); // get length into L (byteCount * 8 = bitCount) + + while (xBufOff != 0) + { + Update((byte)0); + } + + processBlock(L, 0); + processBlock(Sum, 0); + } + + public int DoFinal( + byte[] output, + int outOff) + { + finish(); + + H.CopyTo(output, outOff); + + Reset(); + + return DIGEST_LENGTH; + } + + /** + * reset the chaining variables to the IV values. + */ + private static readonly byte[] C2 = { + 0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF, + (byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00, + 0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF,0x00,0x00,(byte)0xFF, + (byte)0xFF,0x00,0x00,0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF + }; + + public void Reset() + { + byteCount = 0; + xBufOff = 0; + + Array.Clear(H, 0, H.Length); + Array.Clear(L, 0, L.Length); + Array.Clear(M, 0, M.Length); + Array.Clear(C[1], 0, C[1].Length); // real index C = +1 because index array with 0. + Array.Clear(C[3], 0, C[3].Length); + Array.Clear(Sum, 0, Sum.Length); + Array.Clear(xBuf, 0, xBuf.Length); + + C2.CopyTo(C[2], 0); + } + + // 256 bitsblock modul -> (Sum + a mod (2^256)) + private void sumByteArray( + byte[] input) + { + int carry = 0; + + for (int i = 0; i != Sum.Length; i++) + { + int sum = (Sum[i] & 0xff) + (input[i] & 0xff) + carry; + + Sum[i] = (byte)sum; + + carry = sum >> 8; + } + } + + // TODO Refactor as utility function + private static void LongToBytes( + long r, + byte[] output, + int outOff) + { + output[outOff + 7] = (byte)(r >> 56); + output[outOff + 6] = (byte)(r >> 48); + output[outOff + 5] = (byte)(r >> 40); + output[outOff + 4] = (byte)(r >> 32); + output[outOff + 3] = (byte)(r >> 24); + output[outOff + 2] = (byte)(r >> 16); + output[outOff + 1] = (byte)(r >> 8); + output[outOff] = (byte)r; + } + + private static void cpyBytesToShort(byte[] S, short[] wS) + { + for(int i = 0; i < S.Length / 2; i++) + { + wS[i] = (short)(((S[i*2+1]<<8)&0xFF00)|(S[i*2]&0xFF)); + } + } + + private static void cpyShortToBytes(short[] wS, byte[] S) + { + for(int i=0; i+ * NOTE: This algorithm is only included for backwards compatibility + * with legacy applications, it's not secure, don't use it for anything new!
+ */ + public class MD4Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private int H1, H2, H3, H4; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public MD4Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public MD4Digest(MD4Digest t) : base(t) + { + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "MD4"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H1, output, outOff); + UnpackWord(H2, output, outOff + 4); + UnpackWord(H3, output, outOff + 8); + UnpackWord(H4, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H1 = unchecked((int) 0x67452301); + H2 = unchecked((int) 0xefcdab89); + H3 = unchecked((int) 0x98badcfe); + H4 = unchecked((int) 0x10325476); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + // + // round 1 left rotates + // + private const int S11 = 3; + private const int S12 = 7; + private const int S13 = 11; + private const int S14 = 19; + + // + // round 2 left rotates + // + private const int S21 = 3; + private const int S22 = 5; + private const int S23 = 9; + private const int S24 = 13; + + // + // round 3 left rotates + // + private const int S31 = 3; + private const int S32 = 9; + private const int S33 = 11; + private const int S34 = 15; + + /* + * rotate int x left n bits. + */ + private int RotateLeft( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * F, G, H and I are the basic MD4 functions. + */ + private int F( + int u, + int v, + int w) + { + return (u & v) | (~u & w); + } + + private int G( + int u, + int v, + int w) + { + return (u & v) | (u & w) | (v & w); + } + + private int H( + int u, + int v, + int w) + { + return u ^ v ^ w; + } + + internal override void ProcessBlock() + { + int a = H1; + int b = H2; + int c = H3; + int d = H4; + + // + // Round 1 - F cycle, 16 times. + // + a = RotateLeft((a + F(b, c, d) + X[ 0]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 1]), S12); + c = RotateLeft((c + F(d, a, b) + X[ 2]), S13); + b = RotateLeft((b + F(c, d, a) + X[ 3]), S14); + a = RotateLeft((a + F(b, c, d) + X[ 4]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 5]), S12); + c = RotateLeft((c + F(d, a, b) + X[ 6]), S13); + b = RotateLeft((b + F(c, d, a) + X[ 7]), S14); + a = RotateLeft((a + F(b, c, d) + X[ 8]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 9]), S12); + c = RotateLeft((c + F(d, a, b) + X[10]), S13); + b = RotateLeft((b + F(c, d, a) + X[11]), S14); + a = RotateLeft((a + F(b, c, d) + X[12]), S11); + d = RotateLeft((d + F(a, b, c) + X[13]), S12); + c = RotateLeft((c + F(d, a, b) + X[14]), S13); + b = RotateLeft((b + F(c, d, a) + X[15]), S14); + + // + // Round 2 - G cycle, 16 times. + // + a = RotateLeft((a + G(b, c, d) + X[ 0] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 4] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[ 8] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[12] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 1] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 5] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[ 9] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[13] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 2] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 6] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[10] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[14] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 3] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 7] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[11] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[15] + 0x5a827999), S24); + + // + // Round 3 - H cycle, 16 times. + // + a = RotateLeft((a + H(b, c, d) + X[ 0] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[ 8] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 4] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[12] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 2] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[10] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 6] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[14] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 1] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[ 9] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 5] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[13] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 3] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[11] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 7] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[15] + 0x6ed9eba1), S34); + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/digests/MD5Digest.cs b/iTechSharp/srcbc/crypto/digests/MD5Digest.cs new file mode 100644 index 0000000..50d93e4 --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/MD5Digest.cs @@ -0,0 +1,301 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347. + */ + public class MD5Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private int H1, H2, H3, H4; // IV's + + private int[] X = new int[16]; + private int xOff; + + public MD5Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public MD5Digest(MD5Digest t) + : base(t) + { + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "MD5"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H1, output, outOff); + UnpackWord(H2, output, outOff + 4); + UnpackWord(H3, output, outOff + 8); + UnpackWord(H4, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H1 = unchecked((int) 0x67452301); + H2 = unchecked((int) 0xefcdab89); + H3 = unchecked((int) 0x98badcfe); + H4 = unchecked((int) 0x10325476); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + // + // round 1 left rotates + // + private static readonly int S11 = 7; + private static readonly int S12 = 12; + private static readonly int S13 = 17; + private static readonly int S14 = 22; + + // + // round 2 left rotates + // + private static readonly int S21 = 5; + private static readonly int S22 = 9; + private static readonly int S23 = 14; + private static readonly int S24 = 20; + + // + // round 3 left rotates + // + private static readonly int S31 = 4; + private static readonly int S32 = 11; + private static readonly int S33 = 16; + private static readonly int S34 = 23; + + // + // round 4 left rotates + // + private static readonly int S41 = 6; + private static readonly int S42 = 10; + private static readonly int S43 = 15; + private static readonly int S44 = 21; + + /* + * rotate int x left n bits. + */ + private int RotateLeft( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * F, G, H and I are the basic MD5 functions. + */ + private int F( + int u, + int v, + int w) + { + return (u & v) | (~u & w); + } + + private int G( + int u, + int v, + int w) + { + return (u & w) | (v & ~w); + } + + private int H( + int u, + int v, + int w) + { + return u ^ v ^ w; + } + + private int K( + int u, + int v, + int w) + { + return v ^ (u | ~w); + } + + internal override void ProcessBlock() + { + int a = H1; + int b = H2; + int c = H3; + int d = H4; + + // + // Round 1 - F cycle, 16 times. + // + a = RotateLeft((a + F(b, c, d) + X[ 0] + unchecked((int) 0xd76aa478)), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[ 1] + unchecked((int) 0xe8c7b756)), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[ 2] + unchecked((int) 0x242070db)), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[ 3] + unchecked((int) 0xc1bdceee)), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[ 4] + unchecked((int) 0xf57c0faf)), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[ 5] + unchecked((int) 0x4787c62a)), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[ 6] + unchecked((int) 0xa8304613)), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[ 7] + unchecked((int) 0xfd469501)), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[ 8] + unchecked((int) 0x698098d8)), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[ 9] + unchecked((int) 0x8b44f7af)), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[10] + unchecked((int) 0xffff5bb1)), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[11] + unchecked((int) 0x895cd7be)), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[12] + unchecked((int) 0x6b901122)), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[13] + unchecked((int) 0xfd987193)), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[14] + unchecked((int) 0xa679438e)), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[15] + unchecked((int) 0x49b40821)), S14) + c; + + // + // Round 2 - G cycle, 16 times. + // + a = RotateLeft((a + G(b, c, d) + X[ 1] + unchecked((int) 0xf61e2562)), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[ 6] + unchecked((int) 0xc040b340)), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[11] + unchecked((int) 0x265e5a51)), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[ 0] + unchecked((int) 0xe9b6c7aa)), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[ 5] + unchecked((int) 0xd62f105d)), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[10] + unchecked((int) 0x02441453)), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[15] + unchecked((int) 0xd8a1e681)), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[ 4] + unchecked((int) 0xe7d3fbc8)), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[ 9] + unchecked((int) 0x21e1cde6)), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[14] + unchecked((int) 0xc33707d6)), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[ 3] + unchecked((int) 0xf4d50d87)), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[ 8] + unchecked((int) 0x455a14ed)), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[13] + unchecked((int) 0xa9e3e905)), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[ 2] + unchecked((int) 0xfcefa3f8)), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[ 7] + unchecked((int) 0x676f02d9)), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[12] + unchecked((int) 0x8d2a4c8a)), S24) + c; + + // + // Round 3 - H cycle, 16 times. + // + a = RotateLeft((a + H(b, c, d) + X[ 5] + unchecked((int) 0xfffa3942)), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[ 8] + unchecked((int) 0x8771f681)), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[11] + unchecked((int) 0x6d9d6122)), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[14] + unchecked((int) 0xfde5380c)), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[ 1] + unchecked((int) 0xa4beea44)), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[ 4] + unchecked((int) 0x4bdecfa9)), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[ 7] + unchecked((int) 0xf6bb4b60)), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[10] + unchecked((int) 0xbebfbc70)), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[13] + unchecked((int) 0x289b7ec6)), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[ 0] + unchecked((int) 0xeaa127fa)), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[ 3] + unchecked((int) 0xd4ef3085)), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[ 6] + unchecked((int) 0x04881d05)), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[ 9] + unchecked((int) 0xd9d4d039)), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[12] + unchecked((int) 0xe6db99e5)), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[15] + unchecked((int) 0x1fa27cf8)), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[ 2] + unchecked((int) 0xc4ac5665)), S34) + c; + + // + // Round 4 - K cycle, 16 times. + // + a = RotateLeft((a + K(b, c, d) + X[ 0] + unchecked((int) 0xf4292244)), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[ 7] + unchecked((int) 0x432aff97)), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[14] + unchecked((int) 0xab9423a7)), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[ 5] + unchecked((int) 0xfc93a039)), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[12] + unchecked((int) 0x655b59c3)), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[ 3] + unchecked((int) 0x8f0ccc92)), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[10] + unchecked((int) 0xffeff47d)), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[ 1] + unchecked((int) 0x85845dd1)), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[ 8] + unchecked((int) 0x6fa87e4f)), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[15] + unchecked((int) 0xfe2ce6e0)), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[ 6] + unchecked((int) 0xa3014314)), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[13] + unchecked((int) 0x4e0811a1)), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[ 4] + unchecked((int) 0xf7537e82)), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[11] + unchecked((int) 0xbd3af235)), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[ 2] + unchecked((int) 0x2ad7d2bb)), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[ 9] + unchecked((int) 0xeb86d391)), S44) + c; + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/digests/RipeMD128Digest.cs b/iTechSharp/srcbc/crypto/digests/RipeMD128Digest.cs new file mode 100644 index 0000000..8977583 --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/RipeMD128Digest.cs @@ -0,0 +1,462 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of RipeMD128 + */ + public class RipeMD128Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private int H0, H1, H2, H3; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public RipeMD128Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public RipeMD128Digest(RipeMD128Digest t) : base(t) + { + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "RIPEMD128"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int) 0x67452301); + H1 = unchecked((int) 0xefcdab89); + H2 = unchecked((int) 0x98badcfe); + H3 = unchecked((int) 0x10325476); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * f1,f2,f3,f4 are the basic RipeMD128 functions. + */ + + /* + * F + */ + private int F1( + int x, + int y, + int z) + { + return x ^ y ^ z; + } + + /* + * G + */ + private int F2( + int x, + int y, + int z) + { + return (x & y) | (~x & z); + } + + /* + * H + */ + private int F3( + int x, + int y, + int z) + { + return (x | ~y) ^ z; + } + + /* + * I + */ + private int F4( + int x, + int y, + int z) + { + return (x & z) | (y & ~z); + } + + private int F1( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int F2( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int) 0x5a827999), s); + } + + private int F3( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int) 0x6ed9eba1), s); + } + + private int F4( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int) 0x8f1bbcdc), s); + } + + private int FF1( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int FF2( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int) 0x6d703ef3), s); + } + + private int FF3( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int) 0x5c4dd124), s); + } + + private int FF4( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int) 0x50a28be6), s); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + + a = aa = H0; + b = bb = H1; + c = cc = H2; + d = dd = H3; + + // + // Round 1 + // + a = F1(a, b, c, d, X[ 0], 11); + d = F1(d, a, b, c, X[ 1], 14); + c = F1(c, d, a, b, X[ 2], 15); + b = F1(b, c, d, a, X[ 3], 12); + a = F1(a, b, c, d, X[ 4], 5); + d = F1(d, a, b, c, X[ 5], 8); + c = F1(c, d, a, b, X[ 6], 7); + b = F1(b, c, d, a, X[ 7], 9); + a = F1(a, b, c, d, X[ 8], 11); + d = F1(d, a, b, c, X[ 9], 13); + c = F1(c, d, a, b, X[10], 14); + b = F1(b, c, d, a, X[11], 15); + a = F1(a, b, c, d, X[12], 6); + d = F1(d, a, b, c, X[13], 7); + c = F1(c, d, a, b, X[14], 9); + b = F1(b, c, d, a, X[15], 8); + + // + // Round 2 + // + a = F2(a, b, c, d, X[ 7], 7); + d = F2(d, a, b, c, X[ 4], 6); + c = F2(c, d, a, b, X[13], 8); + b = F2(b, c, d, a, X[ 1], 13); + a = F2(a, b, c, d, X[10], 11); + d = F2(d, a, b, c, X[ 6], 9); + c = F2(c, d, a, b, X[15], 7); + b = F2(b, c, d, a, X[ 3], 15); + a = F2(a, b, c, d, X[12], 7); + d = F2(d, a, b, c, X[ 0], 12); + c = F2(c, d, a, b, X[ 9], 15); + b = F2(b, c, d, a, X[ 5], 9); + a = F2(a, b, c, d, X[ 2], 11); + d = F2(d, a, b, c, X[14], 7); + c = F2(c, d, a, b, X[11], 13); + b = F2(b, c, d, a, X[ 8], 12); + + // + // Round 3 + // + a = F3(a, b, c, d, X[ 3], 11); + d = F3(d, a, b, c, X[10], 13); + c = F3(c, d, a, b, X[14], 6); + b = F3(b, c, d, a, X[ 4], 7); + a = F3(a, b, c, d, X[ 9], 14); + d = F3(d, a, b, c, X[15], 9); + c = F3(c, d, a, b, X[ 8], 13); + b = F3(b, c, d, a, X[ 1], 15); + a = F3(a, b, c, d, X[ 2], 14); + d = F3(d, a, b, c, X[ 7], 8); + c = F3(c, d, a, b, X[ 0], 13); + b = F3(b, c, d, a, X[ 6], 6); + a = F3(a, b, c, d, X[13], 5); + d = F3(d, a, b, c, X[11], 12); + c = F3(c, d, a, b, X[ 5], 7); + b = F3(b, c, d, a, X[12], 5); + + // + // Round 4 + // + a = F4(a, b, c, d, X[ 1], 11); + d = F4(d, a, b, c, X[ 9], 12); + c = F4(c, d, a, b, X[11], 14); + b = F4(b, c, d, a, X[10], 15); + a = F4(a, b, c, d, X[ 0], 14); + d = F4(d, a, b, c, X[ 8], 15); + c = F4(c, d, a, b, X[12], 9); + b = F4(b, c, d, a, X[ 4], 8); + a = F4(a, b, c, d, X[13], 9); + d = F4(d, a, b, c, X[ 3], 14); + c = F4(c, d, a, b, X[ 7], 5); + b = F4(b, c, d, a, X[15], 6); + a = F4(a, b, c, d, X[14], 8); + d = F4(d, a, b, c, X[ 5], 6); + c = F4(c, d, a, b, X[ 6], 5); + b = F4(b, c, d, a, X[ 2], 12); + + // + // Parallel round 1 + // + aa = FF4(aa, bb, cc, dd, X[ 5], 8); + dd = FF4(dd, aa, bb, cc, X[14], 9); + cc = FF4(cc, dd, aa, bb, X[ 7], 9); + bb = FF4(bb, cc, dd, aa, X[ 0], 11); + aa = FF4(aa, bb, cc, dd, X[ 9], 13); + dd = FF4(dd, aa, bb, cc, X[ 2], 15); + cc = FF4(cc, dd, aa, bb, X[11], 15); + bb = FF4(bb, cc, dd, aa, X[ 4], 5); + aa = FF4(aa, bb, cc, dd, X[13], 7); + dd = FF4(dd, aa, bb, cc, X[ 6], 7); + cc = FF4(cc, dd, aa, bb, X[15], 8); + bb = FF4(bb, cc, dd, aa, X[ 8], 11); + aa = FF4(aa, bb, cc, dd, X[ 1], 14); + dd = FF4(dd, aa, bb, cc, X[10], 14); + cc = FF4(cc, dd, aa, bb, X[ 3], 12); + bb = FF4(bb, cc, dd, aa, X[12], 6); + + // + // Parallel round 2 + // + aa = FF3(aa, bb, cc, dd, X[ 6], 9); + dd = FF3(dd, aa, bb, cc, X[11], 13); + cc = FF3(cc, dd, aa, bb, X[ 3], 15); + bb = FF3(bb, cc, dd, aa, X[ 7], 7); + aa = FF3(aa, bb, cc, dd, X[ 0], 12); + dd = FF3(dd, aa, bb, cc, X[13], 8); + cc = FF3(cc, dd, aa, bb, X[ 5], 9); + bb = FF3(bb, cc, dd, aa, X[10], 11); + aa = FF3(aa, bb, cc, dd, X[14], 7); + dd = FF3(dd, aa, bb, cc, X[15], 7); + cc = FF3(cc, dd, aa, bb, X[ 8], 12); + bb = FF3(bb, cc, dd, aa, X[12], 7); + aa = FF3(aa, bb, cc, dd, X[ 4], 6); + dd = FF3(dd, aa, bb, cc, X[ 9], 15); + cc = FF3(cc, dd, aa, bb, X[ 1], 13); + bb = FF3(bb, cc, dd, aa, X[ 2], 11); + + // + // Parallel round 3 + // + aa = FF2(aa, bb, cc, dd, X[15], 9); + dd = FF2(dd, aa, bb, cc, X[ 5], 7); + cc = FF2(cc, dd, aa, bb, X[ 1], 15); + bb = FF2(bb, cc, dd, aa, X[ 3], 11); + aa = FF2(aa, bb, cc, dd, X[ 7], 8); + dd = FF2(dd, aa, bb, cc, X[14], 6); + cc = FF2(cc, dd, aa, bb, X[ 6], 6); + bb = FF2(bb, cc, dd, aa, X[ 9], 14); + aa = FF2(aa, bb, cc, dd, X[11], 12); + dd = FF2(dd, aa, bb, cc, X[ 8], 13); + cc = FF2(cc, dd, aa, bb, X[12], 5); + bb = FF2(bb, cc, dd, aa, X[ 2], 14); + aa = FF2(aa, bb, cc, dd, X[10], 13); + dd = FF2(dd, aa, bb, cc, X[ 0], 13); + cc = FF2(cc, dd, aa, bb, X[ 4], 7); + bb = FF2(bb, cc, dd, aa, X[13], 5); + + // + // Parallel round 4 + // + aa = FF1(aa, bb, cc, dd, X[ 8], 15); + dd = FF1(dd, aa, bb, cc, X[ 6], 5); + cc = FF1(cc, dd, aa, bb, X[ 4], 8); + bb = FF1(bb, cc, dd, aa, X[ 1], 11); + aa = FF1(aa, bb, cc, dd, X[ 3], 14); + dd = FF1(dd, aa, bb, cc, X[11], 14); + cc = FF1(cc, dd, aa, bb, X[15], 6); + bb = FF1(bb, cc, dd, aa, X[ 0], 14); + aa = FF1(aa, bb, cc, dd, X[ 5], 6); + dd = FF1(dd, aa, bb, cc, X[12], 9); + cc = FF1(cc, dd, aa, bb, X[ 2], 12); + bb = FF1(bb, cc, dd, aa, X[13], 9); + aa = FF1(aa, bb, cc, dd, X[ 9], 12); + dd = FF1(dd, aa, bb, cc, X[ 7], 5); + cc = FF1(cc, dd, aa, bb, X[10], 15); + bb = FF1(bb, cc, dd, aa, X[14], 8); + + dd += c + H1; // final result for H0 + + // + // combine the results + // + H1 = H2 + d + aa; + H2 = H3 + a + bb; + H3 = H0 + b + cc; + H0 = dd; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/digests/RipeMD160Digest.cs b/iTechSharp/srcbc/crypto/digests/RipeMD160Digest.cs new file mode 100644 index 0000000..8ce52ae --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/RipeMD160Digest.cs @@ -0,0 +1,423 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of RipeMD see, + * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html + */ + public class RipeMD160Digest + : GeneralDigest + { + private const int DigestLength = 20; + + private int H0, H1, H2, H3, H4; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public RipeMD160Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public RipeMD160Digest(RipeMD160Digest t) : base(t) + { + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "RIPEMD160"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + UnpackWord(H4, output, outOff + 16); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int) 0x67452301); + H1 = unchecked((int) 0xefcdab89); + H2 = unchecked((int) 0x98badcfe); + H3 = unchecked((int) 0x10325476); + H4 = unchecked((int) 0xc3d2e1f0); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * f1,f2,f3,f4,f5 are the basic RipeMD160 functions. + */ + + /* + * rounds 0-15 + */ + private int F1( + int x, + int y, + int z) + { + return x ^ y ^ z; + } + + /* + * rounds 16-31 + */ + private int F2( + int x, + int y, + int z) + { + return (x & y) | (~x & z); + } + + /* + * rounds 32-47 + */ + private int F3( + int x, + int y, + int z) + { + return (x | ~y) ^ z; + } + + /* + * rounds 48-63 + */ + private int F4( + int x, + int y, + int z) + { + return (x & z) | (y & ~z); + } + + /* + * rounds 64-79 + */ + private int F5( + int x, + int y, + int z) + { + return x ^ (y | ~z); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + int e, ee; + + a = aa = H0; + b = bb = H1; + c = cc = H2; + d = dd = H3; + e = ee = H4; + + // + // Rounds 1 - 16 + // + // left + a = RL(a + F1(b,c,d) + X[ 0], 11) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[ 1], 14) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[ 2], 15) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[ 3], 12) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[ 4], 5) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[ 5], 8) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[ 6], 7) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[ 7], 9) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[ 8], 11) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[ 9], 13) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[10], 14) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[11], 15) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[12], 6) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[13], 7) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[14], 9) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[15], 8) + e; c = RL(c, 10); + + // right + aa = RL(aa + F5(bb,cc,dd) + X[ 5] + unchecked((int) 0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[14] + unchecked((int) 0x50a28be6), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 7] + unchecked((int) 0x50a28be6), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[ 0] + unchecked((int) 0x50a28be6), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 9] + unchecked((int) 0x50a28be6), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[ 2] + unchecked((int) 0x50a28be6), 15) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[11] + unchecked((int) 0x50a28be6), 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 4] + unchecked((int) 0x50a28be6), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[13] + unchecked((int) 0x50a28be6), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 6] + unchecked((int) 0x50a28be6), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[15] + unchecked((int) 0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[ 8] + unchecked((int) 0x50a28be6), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 1] + unchecked((int) 0x50a28be6), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[10] + unchecked((int) 0x50a28be6), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 3] + unchecked((int) 0x50a28be6), 12) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[12] + unchecked((int) 0x50a28be6), 6) + ee; cc = RL(cc, 10); + + // + // Rounds 16-31 + // + // left + e = RL(e + F2(a,b,c) + X[ 7] + unchecked((int) 0x5a827999), 7) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[ 4] + unchecked((int) 0x5a827999), 6) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[13] + unchecked((int) 0x5a827999), 8) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[ 1] + unchecked((int) 0x5a827999), 13) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[10] + unchecked((int) 0x5a827999), 11) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 6] + unchecked((int) 0x5a827999), 9) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[15] + unchecked((int) 0x5a827999), 7) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[ 3] + unchecked((int) 0x5a827999), 15) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[12] + unchecked((int) 0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[ 0] + unchecked((int) 0x5a827999), 12) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 9] + unchecked((int) 0x5a827999), 15) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[ 5] + unchecked((int) 0x5a827999), 9) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[ 2] + unchecked((int) 0x5a827999), 11) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[14] + unchecked((int) 0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[11] + unchecked((int) 0x5a827999), 13) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 8] + unchecked((int) 0x5a827999), 12) + d; b = RL(b, 10); + + // right + ee = RL(ee + F4(aa,bb,cc) + X[ 6] + unchecked((int) 0x5c4dd124), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[11] + unchecked((int) 0x5c4dd124), 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[ 3] + unchecked((int) 0x5c4dd124), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[ 7] + unchecked((int) 0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[ 0] + unchecked((int) 0x5c4dd124), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[13] + unchecked((int) 0x5c4dd124), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[ 5] + unchecked((int) 0x5c4dd124), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[10] + unchecked((int) 0x5c4dd124), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[14] + unchecked((int) 0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[15] + unchecked((int) 0x5c4dd124), 7) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[ 8] + unchecked((int) 0x5c4dd124), 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[12] + unchecked((int) 0x5c4dd124), 7) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[ 4] + unchecked((int) 0x5c4dd124), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[ 9] + unchecked((int) 0x5c4dd124), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[ 1] + unchecked((int) 0x5c4dd124), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[ 2] + unchecked((int) 0x5c4dd124), 11) + dd; bb = RL(bb, 10); + + // + // Rounds 32-47 + // + // left + d = RL(d + F3(e,a,b) + X[ 3] + unchecked((int) 0x6ed9eba1), 11) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[10] + unchecked((int) 0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[14] + unchecked((int) 0x6ed9eba1), 6) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[ 4] + unchecked((int) 0x6ed9eba1), 7) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 9] + unchecked((int) 0x6ed9eba1), 14) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[15] + unchecked((int) 0x6ed9eba1), 9) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[ 8] + unchecked((int) 0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[ 1] + unchecked((int) 0x6ed9eba1), 15) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[ 2] + unchecked((int) 0x6ed9eba1), 14) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 7] + unchecked((int) 0x6ed9eba1), 8) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[ 0] + unchecked((int) 0x6ed9eba1), 13) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[ 6] + unchecked((int) 0x6ed9eba1), 6) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[13] + unchecked((int) 0x6ed9eba1), 5) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[11] + unchecked((int) 0x6ed9eba1), 12) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 5] + unchecked((int) 0x6ed9eba1), 7) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[12] + unchecked((int) 0x6ed9eba1), 5) + c; a = RL(a, 10); + + // right + dd = RL(dd + F3(ee,aa,bb) + X[15] + unchecked((int) 0x6d703ef3), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 5] + unchecked((int) 0x6d703ef3), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[ 1] + unchecked((int) 0x6d703ef3), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[ 3] + unchecked((int) 0x6d703ef3), 11) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 7] + unchecked((int) 0x6d703ef3), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[14] + unchecked((int) 0x6d703ef3), 6) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 6] + unchecked((int) 0x6d703ef3), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[ 9] + unchecked((int) 0x6d703ef3), 14) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[11] + unchecked((int) 0x6d703ef3), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 8] + unchecked((int) 0x6d703ef3), 13) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[12] + unchecked((int) 0x6d703ef3), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 2] + unchecked((int) 0x6d703ef3), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[10] + unchecked((int) 0x6d703ef3), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[ 0] + unchecked((int) 0x6d703ef3), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 4] + unchecked((int) 0x6d703ef3), 7) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[13] + unchecked((int) 0x6d703ef3), 5) + cc; aa = RL(aa, 10); + + // + // Rounds 48-63 + // + // left + c = RL(c + F4(d,e,a) + X[ 1] + unchecked((int) 0x8f1bbcdc), 11) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[ 9] + unchecked((int) 0x8f1bbcdc), 12) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[11] + unchecked((int) 0x8f1bbcdc), 14) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[10] + unchecked((int) 0x8f1bbcdc), 15) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 0] + unchecked((int) 0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 8] + unchecked((int) 0x8f1bbcdc), 15) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[12] + unchecked((int) 0x8f1bbcdc), 9) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[ 4] + unchecked((int) 0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[13] + unchecked((int) 0x8f1bbcdc), 9) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 3] + unchecked((int) 0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 7] + unchecked((int) 0x8f1bbcdc), 5) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[15] + unchecked((int) 0x8f1bbcdc), 6) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[14] + unchecked((int) 0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[ 5] + unchecked((int) 0x8f1bbcdc), 6) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 6] + unchecked((int) 0x8f1bbcdc), 5) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 2] + unchecked((int) 0x8f1bbcdc), 12) + b; e = RL(e, 10); + + // right + cc = RL(cc + F2(dd,ee,aa) + X[ 8] + unchecked((int) 0x7a6d76e9), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[ 6] + unchecked((int) 0x7a6d76e9), 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 4] + unchecked((int) 0x7a6d76e9), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 1] + unchecked((int) 0x7a6d76e9), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[ 3] + unchecked((int) 0x7a6d76e9), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[11] + unchecked((int) 0x7a6d76e9), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[15] + unchecked((int) 0x7a6d76e9), 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 0] + unchecked((int) 0x7a6d76e9), 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 5] + unchecked((int) 0x7a6d76e9), 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[12] + unchecked((int) 0x7a6d76e9), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[ 2] + unchecked((int) 0x7a6d76e9), 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[13] + unchecked((int) 0x7a6d76e9), 9) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 9] + unchecked((int) 0x7a6d76e9), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 7] + unchecked((int) 0x7a6d76e9), 5) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[10] + unchecked((int) 0x7a6d76e9), 15) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[14] + unchecked((int) 0x7a6d76e9), 8) + bb; ee = RL(ee, 10); + + // + // Rounds 64-79 + // + // left + b = RL(b + F5(c,d,e) + X[ 4] + unchecked((int) 0xa953fd4e), 9) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 0] + unchecked((int) 0xa953fd4e), 15) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[ 5] + unchecked((int) 0xa953fd4e), 5) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[ 9] + unchecked((int) 0xa953fd4e), 11) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[ 7] + unchecked((int) 0xa953fd4e), 6) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[12] + unchecked((int) 0xa953fd4e), 8) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 2] + unchecked((int) 0xa953fd4e), 13) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[10] + unchecked((int) 0xa953fd4e), 12) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[14] + unchecked((int) 0xa953fd4e), 5) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[ 1] + unchecked((int) 0xa953fd4e), 12) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[ 3] + unchecked((int) 0xa953fd4e), 13) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 8] + unchecked((int) 0xa953fd4e), 14) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[11] + unchecked((int) 0xa953fd4e), 11) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[ 6] + unchecked((int) 0xa953fd4e), 8) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[15] + unchecked((int) 0xa953fd4e), 5) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[13] + unchecked((int) 0xa953fd4e), 6) + a; d = RL(d, 10); + + // right + bb = RL(bb + F1(cc,dd,ee) + X[12], 8) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[15], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[10], 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 4], 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 1], 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[ 5], 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[ 8], 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[ 7], 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 6], 8) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 2], 13) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[13], 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[14], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[ 0], 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 3], 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 9], 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[11], 11) + aa; dd = RL(dd, 10); + + dd += c + H1; + H1 = H2 + d + ee; + H2 = H3 + e + aa; + H3 = H4 + a + bb; + H4 = H0 + b + cc; + H0 = dd; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/digests/RipeMD256Digest.cs b/iTechSharp/srcbc/crypto/digests/RipeMD256Digest.cs new file mode 100644 index 0000000..950e94f --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/RipeMD256Digest.cs @@ -0,0 +1,409 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Digests +{ + ///Implementation of RipeMD256.
+ ///Note: this algorithm offers the same level of security as RipeMD128.
+ ///Implementation of RipeMD 320.
+ ///Note: this algorithm offers the same level of security as RipeMD160.
+ ///+ * block word digest + * SHA-1 512 32 160 + * SHA-224 512 32 224 + * SHA-256 512 32 256 + * SHA-384 1024 64 384 + * SHA-512 1024 64 512 + *+ */ + public class Sha224Digest + : GeneralDigest + { + private const int DigestLength = 28; + + private int H1, H2, H3, H4, H5, H6, H7, H8; + + private int[] X = new int[64]; + private int xOff; + + /** + * Standard constructor + */ + public Sha224Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha224Digest( + Sha224Digest t) + : base(t) + { + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SHA-224"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = ((input[inOff] & 0xff) << 24) | ((input[inOff + 1] & 0xff) << 16) + | ((input[inOff + 2] & 0xff) << 8) | ((input[inOff + 3] & 0xff)); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)((uint) word >> 24); + outBytes[outOff + 1] = (byte)((uint) word >> 16); + outBytes[outOff + 2] = (byte)((uint) word >> 8); + outBytes[outOff + 3] = (byte)word; + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)((ulong) bitLength >> 32); + X[15] = (int)(bitLength & 0xffffffff); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H1, output, outOff); + UnpackWord(H2, output, outOff + 4); + UnpackWord(H3, output, outOff + 8); + UnpackWord(H4, output, outOff + 12); + UnpackWord(H5, output, outOff + 16); + UnpackWord(H6, output, outOff + 20); + UnpackWord(H7, output, outOff + 24); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-224 initial hash value + */ + + unchecked + { + H1 = (int) 0xc1059ed8; + H2 = (int) 0x367cd507; + H3 = (int) 0x3070dd17; + H4 = (int) 0xf70e5939; + H5 = (int) 0xffc00b31; + H6 = (int) 0x68581511; + H7 = (int) 0x64f98fa7; + H8 = (int) 0xbefa4fa4; + } + + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + internal override void ProcessBlock() + { + // + // expand 16 word block into 64 word blocks. + // + for (int ti = 16; ti <= 63; ti++) + { + X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16]; + } + + // + // set up working variables. + // + int a = H1; + int b = H2; + int c = H3; + int d = H4; + int e = H5; + int f = H6; + int g = H7; + int h = H8; + + int t = 0; + for(int i = 0; i < 8; i ++) + { + // t = 8 * i + h += Sum1(e) + Ch(e, f, g) + (int)K[t] + X[t++]; + d += h; + h += Sum0(a) + Maj(a, b, c); + + // t = 8 * i + 1 + g += Sum1(d) + Ch(d, e, f) + (int)K[t] + X[t++]; + c += g; + g += Sum0(h) + Maj(h, a, b); + + // t = 8 * i + 2 + f += Sum1(c) + Ch(c, d, e) + (int)K[t] + X[t++]; + b += f; + f += Sum0(g) + Maj(g, h, a); + + // t = 8 * i + 3 + e += Sum1(b) + Ch(b, c, d) + (int)K[t] + X[t++]; + a += e; + e += Sum0(f) + Maj(f, g, h); + + // t = 8 * i + 4 + d += Sum1(a) + Ch(a, b, c) + (int)K[t] + X[t++]; + h += d; + d += Sum0(e) + Maj(e, f, g); + + // t = 8 * i + 5 + c += Sum1(h) + Ch(h, a, b) + (int)K[t] + X[t++]; + g += c; + c += Sum0(d) + Maj(d, e, f); + + // t = 8 * i + 6 + b += Sum1(g) + Ch(g, h, a) + (int)K[t] + X[t++]; + f += b; + b += Sum0(c) + Maj(c, d, e); + + // t = 8 * i + 7 + a += Sum1(f) + Ch(f, g, h) + (int)K[t] + X[t++]; + e += a; + a += Sum0(b) + Maj(b, c, d); + } + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + H5 += e; + H6 += f; + H7 += g; + H8 += h; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + + Array.Clear(X, 0, 16); + } + + /* SHA-224 functions */ + private static int Ch( + int x, + int y, + int z) + { + return ((x & y) ^ ((~x) & z)); + } + + private static int Maj( + int x, + int y, + int z) + { + return ((x & y) ^ (x & z) ^ (y & z)); + } + + private static int Sum0( + int x) + { + return (((int)((uint)x >> 2)) | (x << 30)) ^ (((int)((uint)x >> 13)) | (x << 19)) ^ (((int)((uint)x >> 22)) | (x << 10)); + } + + private static int Sum1( + int x) + { + return (((int)((uint)x >> 6)) | (x << 26)) ^ (((int)((uint)x >> 11)) | (x << 21)) ^ (((int)((uint)x >> 25)) | (x << 7)); + } + + private static int Theta0( + int x) + { + return (((int)((uint)x >> 7)) | (x << 25)) ^ (((int)((uint)x >> 18)) | (x << 14)) ^ ((int)((uint)x >> 3)); + } + + private static int Theta1( + int x) + { + return (((int)((uint)x >> 17)) | (x << 15)) ^ (((int)((uint)x >> 19)) | (x << 13)) ^ ((int)((uint)x >> 10)); + } + + /* SHA-224 Constants + * (represent the first 32 bits of the fractional parts of the + * cube roots of the first sixty-four prime numbers) + */ + internal static readonly uint[] K = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + }; + } +} diff --git a/iTechSharp/srcbc/crypto/digests/Sha256Digest.cs b/iTechSharp/srcbc/crypto/digests/Sha256Digest.cs new file mode 100644 index 0000000..274116d --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/Sha256Digest.cs @@ -0,0 +1,310 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-256. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+ * block word digest + * SHA-1 512 32 160 + * SHA-256 512 32 256 + * SHA-384 1024 64 384 + * SHA-512 1024 64 512 + *+ */ + public class Sha256Digest + : GeneralDigest + { + private const int DigestLength = 32; + + private int H1, H2, H3, H4, H5, H6, H7, H8; + + private int[] X = new int[64]; + private int xOff; + + public Sha256Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha256Digest(Sha256Digest t) : base(t) + { + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SHA-256"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = ((input[inOff] & 0xff) << 24) | ((input[inOff + 1] & 0xff) << 16) + | ((input[inOff + 2] & 0xff) << 8) | ((input[inOff + 3] & 0xff)); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)((uint) word >> 24); + outBytes[outOff + 1] = (byte)((uint) word >> 16); + outBytes[outOff + 2] = (byte)((uint) word >> 8); + outBytes[outOff + 3] = (byte)word; + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)((ulong) bitLength >> 32); + X[15] = (int)(bitLength & 0xffffffff); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H1, output, outOff); + UnpackWord(H2, output, outOff + 4); + UnpackWord(H3, output, outOff + 8); + UnpackWord(H4, output, outOff + 12); + UnpackWord(H5, output, outOff + 16); + UnpackWord(H6, output, outOff + 20); + UnpackWord(H7, output, outOff + 24); + UnpackWord(H8, output, outOff + 28); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-256 initial hash value + * The first 32 bits of the fractional parts of the square roots + * of the first eight prime numbers + */ + unchecked + { + H1 = (int) 0x6a09e667; + H2 = (int) 0xbb67ae85; + H3 = (int) 0x3c6ef372; + H4 = (int) 0xa54ff53a; + H5 = (int) 0x510e527f; + H6 = (int) 0x9b05688c; + H7 = (int) 0x1f83d9ab; + H8 = (int) 0x5be0cd19; + } + + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + internal override void ProcessBlock() + { + // + // expand 16 word block into 64 word blocks. + // + for (int ti = 16; ti <= 63; ti++) + { + X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16]; + } + + // + // set up working variables. + // + int a = H1; + int b = H2; + int c = H3; + int d = H4; + int e = H5; + int f = H6; + int g = H7; + int h = H8; + + int t = 0; + for(int i = 0; i < 8; i ++) + { + // t = 8 * i + h += Sum1(e) + Ch(e, f, g) + K[t] + X[t++]; + d += h; + h += Sum0(a) + Maj(a, b, c); + + // t = 8 * i + 1 + g += Sum1(d) + Ch(d, e, f) + K[t] + X[t++]; + c += g; + g += Sum0(h) + Maj(h, a, b); + + // t = 8 * i + 2 + f += Sum1(c) + Ch(c, d, e) + K[t] + X[t++]; + b += f; + f += Sum0(g) + Maj(g, h, a); + + // t = 8 * i + 3 + e += Sum1(b) + Ch(b, c, d) + K[t] + X[t++]; + a += e; + e += Sum0(f) + Maj(f, g, h); + + // t = 8 * i + 4 + d += Sum1(a) + Ch(a, b, c) + K[t] + X[t++]; + h += d; + d += Sum0(e) + Maj(e, f, g); + + // t = 8 * i + 5 + c += Sum1(h) + Ch(h, a, b) + K[t] + X[t++]; + g += c; + c += Sum0(d) + Maj(d, e, f); + + // t = 8 * i + 6 + b += Sum1(g) + Ch(g, h, a) + K[t] + X[t++]; + f += b; + b += Sum0(c) + Maj(c, d, e); + + // t = 8 * i + 7 + a += Sum1(f) + Ch(f, g, h) + K[t] + X[t++]; + e += a; + a += Sum0(b) + Maj(b, c, d); + } + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + H5 += e; + H6 += f; + H7 += g; + H8 += h; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + + Array.Clear(X, 0, 16); + } + + /* SHA-256 functions */ + private static int Ch( + int x, + int y, + int z) + { + return ((x & y) ^ ((~x) & z)); + } + + private static int Maj( + int x, + int y, + int z) + { + return ((x & y) ^ (x & z) ^ (y & z)); + } + + private static int Sum0( + int x) + { + return (((int)((uint)x >> 2)) | (x << 30)) ^ (((int)((uint)x >> 13)) | (x << 19)) ^ (((int)((uint)x >> 22)) | (x << 10)); + } + + private static int Sum1( + int x) + { + return (((int)((uint)x >> 6)) | (x << 26)) ^ (((int)((uint)x >> 11)) | (x << 21)) ^ (((int)((uint)x >> 25)) | (x << 7)); + } + + private static int Theta0( + int x) + { + return (((int)((uint)x >> 7)) | (x << 25)) ^ (((int)((uint)x >> 18)) | (x << 14)) ^ ((int)((uint)x >> 3)); + } + + private static int Theta1( + int x) + { + return (((int)((uint)x >> 17)) | (x << 15)) ^ (((int)((uint)x >> 19)) | (x << 13)) ^ ((int)((uint)x >> 10)); + } + + /* SHA-256 Constants + * (represent the first 32 bits of the fractional parts of the + * cube roots of the first sixty-four prime numbers) + */ + internal static readonly int[] K = { + unchecked ((int) 0x428a2f98), unchecked ((int) 0x71374491), + unchecked ((int) 0xb5c0fbcf), unchecked ((int) 0xe9b5dba5), + unchecked ((int) 0x3956c25b), unchecked ((int) 0x59f111f1), + unchecked ((int) 0x923f82a4), unchecked ((int) 0xab1c5ed5), + unchecked ((int) 0xd807aa98), unchecked ((int) 0x12835b01), + unchecked ((int) 0x243185be), unchecked ((int) 0x550c7dc3), + unchecked ((int) 0x72be5d74), unchecked ((int) 0x80deb1fe), + unchecked ((int) 0x9bdc06a7), unchecked ((int) 0xc19bf174), + unchecked ((int) 0xe49b69c1), unchecked ((int) 0xefbe4786), + unchecked ((int) 0x0fc19dc6), unchecked ((int) 0x240ca1cc), + unchecked ((int) 0x2de92c6f), unchecked ((int) 0x4a7484aa), + unchecked ((int) 0x5cb0a9dc), unchecked ((int) 0x76f988da), + unchecked ((int) 0x983e5152), unchecked ((int) 0xa831c66d), + unchecked ((int) 0xb00327c8), unchecked ((int) 0xbf597fc7), + unchecked ((int) 0xc6e00bf3), unchecked ((int) 0xd5a79147), + unchecked ((int) 0x06ca6351), unchecked ((int) 0x14292967), + unchecked ((int) 0x27b70a85), unchecked ((int) 0x2e1b2138), + unchecked ((int) 0x4d2c6dfc), unchecked ((int) 0x53380d13), + unchecked ((int) 0x650a7354), unchecked ((int) 0x766a0abb), + unchecked ((int) 0x81c2c92e), unchecked ((int) 0x92722c85), + unchecked ((int) 0xa2bfe8a1), unchecked ((int) 0xa81a664b), + unchecked ((int) 0xc24b8b70), unchecked ((int) 0xc76c51a3), + unchecked ((int) 0xd192e819), unchecked ((int) 0xd6990624), + unchecked ((int) 0xf40e3585), unchecked ((int) 0x106aa070), + unchecked ((int) 0x19a4c116), unchecked ((int) 0x1e376c08), + unchecked ((int) 0x2748774c), unchecked ((int) 0x34b0bcb5), + unchecked ((int) 0x391c0cb3), unchecked ((int) 0x4ed8aa4a), + unchecked ((int) 0x5b9cca4f), unchecked ((int) 0x682e6ff3), + unchecked ((int) 0x748f82ee), unchecked ((int) 0x78a5636f), + unchecked ((int) 0x84c87814), unchecked ((int) 0x8cc70208), + unchecked ((int) 0x90befffa), unchecked ((int) 0xa4506ceb), + unchecked ((int) 0xbef9a3f7), unchecked ((int) 0xc67178f2) + }; + } +} diff --git a/iTechSharp/srcbc/crypto/digests/Sha384Digest.cs b/iTechSharp/srcbc/crypto/digests/Sha384Digest.cs new file mode 100644 index 0000000..0488c40 --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/Sha384Digest.cs @@ -0,0 +1,85 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-384. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+ * block word digest + * SHA-1 512 32 160 + * SHA-256 512 32 256 + * SHA-384 1024 64 384 + * SHA-512 1024 64 512 + *+ */ + public class Sha384Digest + : LongDigest + { + private const int DigestLength = 48; + + public Sha384Digest() + { + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha384Digest( + Sha384Digest t) + : base(t) + { + } + + public override string AlgorithmName + { + get { return "SHA-384"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H1, output, outOff); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 16); + UnpackWord(H4, output, outOff + 24); + UnpackWord(H5, output, outOff + 32); + UnpackWord(H6, output, outOff + 40); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-384 initial hash value + * The first 64 bits of the fractional parts of the square roots + * of the 9th through 16th prime numbers + */ + H1 = unchecked((long) 0xcbbb9d5dc1059ed8L); + H2 = unchecked((long) 0x629a292a367cd507L); + H3 = unchecked((long) 0x9159015a3070dd17L); + H4 = unchecked((long) 0x152fecd8f70e5939L); + H5 = unchecked((long) 0x67332667ffc00b31L); + H6 = unchecked((long) 0x8eb44a8768581511L); + H7 = unchecked((long) 0xdb0c2e0d64f98fa7L); + H8 = unchecked((long) 0x47b5481dbefa4fa4L); + } + } +} diff --git a/iTechSharp/srcbc/crypto/digests/Sha512Digest.cs b/iTechSharp/srcbc/crypto/digests/Sha512Digest.cs new file mode 100644 index 0000000..30eefdd --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/Sha512Digest.cs @@ -0,0 +1,88 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-512. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+ * block word digest + * SHA-1 512 32 160 + * SHA-256 512 32 256 + * SHA-384 1024 64 384 + * SHA-512 1024 64 512 + *+ */ + public class Sha512Digest + : LongDigest + { + private const int DigestLength = 64; + + public Sha512Digest() + { + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha512Digest( + Sha512Digest t) + : base(t) + { + } + + public override string AlgorithmName + { + get { return "SHA-512"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H1, output, outOff); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 16); + UnpackWord(H4, output, outOff + 24); + UnpackWord(H5, output, outOff + 32); + UnpackWord(H6, output, outOff + 40); + UnpackWord(H7, output, outOff + 48); + UnpackWord(H8, output, outOff + 56); + + Reset(); + + return DigestLength; + + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-512 initial hash value + * The first 64 bits of the fractional parts of the square roots + * of the first eight prime numbers + */ + H1 = unchecked((long) 0x6a09e667f3bcc908L); + H2 = unchecked((long) 0xbb67ae8584caa73bL); + H3 = unchecked((long) 0x3c6ef372fe94f82bL); + H4 = unchecked((long) 0xa54ff53a5f1d36f1L); + H5 = unchecked((long) 0x510e527fade682d1L); + H6 = unchecked((long) 0x9b05688c2b3e6c1fL); + H7 = unchecked((long) 0x1f83d9abfb41bd6bL); + H8 = unchecked((long) 0x5be0cd19137e2179L); + } + } +} diff --git a/iTechSharp/srcbc/crypto/digests/ShortenedDigest.cs b/iTechSharp/srcbc/crypto/digests/ShortenedDigest.cs new file mode 100644 index 0000000..9e4d99e --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/ShortenedDigest.cs @@ -0,0 +1,82 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Wrapper class that reduces the output length of a particular digest to + * only the first n bytes of the digest function. + */ + public class ShortenedDigest + : IDigest + { + private IDigest baseDigest; + private int length; + + /** + * Base constructor. + * + * @param baseDigest underlying digest to use. + * @param length length in bytes of the output of doFinal. + * @exception ArgumentException if baseDigest is null, or length is greater than baseDigest.GetDigestSize(). + */ + public ShortenedDigest( + IDigest baseDigest, + int length) + { + if (baseDigest == null) + { + throw new ArgumentNullException("baseDigest"); + } + + if (length > baseDigest.GetDigestSize()) + { + throw new ArgumentException("baseDigest output not large enough to support length"); + } + + this.baseDigest = baseDigest; + this.length = length; + } + + public string AlgorithmName + { + get { return baseDigest.AlgorithmName + "(" + length * 8 + ")"; } + } + + public int GetDigestSize() + { + return length; + } + + public void Update(byte input) + { + baseDigest.Update(input); + } + + public void BlockUpdate(byte[] input, int inOff, int length) + { + baseDigest.BlockUpdate(input, inOff, length); + } + + public int DoFinal(byte[] output, int outOff) + { + byte[] tmp = new byte[baseDigest.GetDigestSize()]; + + baseDigest.DoFinal(tmp, 0); + + Array.Copy(tmp, 0, output, outOff, length); + + return length; + } + + public void Reset() + { + baseDigest.Reset(); + } + + public int GetByteLength() + { + return baseDigest.GetByteLength(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/digests/TigerDigest.cs b/iTechSharp/srcbc/crypto/digests/TigerDigest.cs new file mode 100644 index 0000000..b8c9a76 --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/TigerDigest.cs @@ -0,0 +1,868 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of Tiger based on: + * + * http://www.cs.technion.ac.il/~biham/Reports/Tiger + */ + public class TigerDigest + : IDigest + { + private const int MyByteLength = 64; + + /* + * S-Boxes. + */ + private static readonly long[] t1 = { + unchecked((long) 0x02AAB17CF7E90C5EL) /* 0 */, unchecked((long) 0xAC424B03E243A8ECL) /* 1 */, + unchecked((long) 0x72CD5BE30DD5FCD3L) /* 2 */, unchecked((long) 0x6D019B93F6F97F3AL) /* 3 */, + unchecked((long) 0xCD9978FFD21F9193L) /* 4 */, unchecked((long) 0x7573A1C9708029E2L) /* 5 */, + unchecked((long) 0xB164326B922A83C3L) /* 6 */, unchecked((long) 0x46883EEE04915870L) /* 7 */, + unchecked((long) 0xEAACE3057103ECE6L) /* 8 */, unchecked((long) 0xC54169B808A3535CL) /* 9 */, + unchecked((long) 0x4CE754918DDEC47CL) /* 10 */, unchecked((long) 0x0AA2F4DFDC0DF40CL) /* 11 */, + unchecked((long) 0x10B76F18A74DBEFAL) /* 12 */, unchecked((long) 0xC6CCB6235AD1AB6AL) /* 13 */, + unchecked((long) 0x13726121572FE2FFL) /* 14 */, unchecked((long) 0x1A488C6F199D921EL) /* 15 */, + unchecked((long) 0x4BC9F9F4DA0007CAL) /* 16 */, unchecked((long) 0x26F5E6F6E85241C7L) /* 17 */, + unchecked((long) 0x859079DBEA5947B6L) /* 18 */, unchecked((long) 0x4F1885C5C99E8C92L) /* 19 */, + unchecked((long) 0xD78E761EA96F864BL) /* 20 */, unchecked((long) 0x8E36428C52B5C17DL) /* 21 */, + unchecked((long) 0x69CF6827373063C1L) /* 22 */, unchecked((long) 0xB607C93D9BB4C56EL) /* 23 */, + unchecked((long) 0x7D820E760E76B5EAL) /* 24 */, unchecked((long) 0x645C9CC6F07FDC42L) /* 25 */, + unchecked((long) 0xBF38A078243342E0L) /* 26 */, unchecked((long) 0x5F6B343C9D2E7D04L) /* 27 */, + unchecked((long) 0xF2C28AEB600B0EC6L) /* 28 */, unchecked((long) 0x6C0ED85F7254BCACL) /* 29 */, + unchecked((long) 0x71592281A4DB4FE5L) /* 30 */, unchecked((long) 0x1967FA69CE0FED9FL) /* 31 */, + unchecked((long) 0xFD5293F8B96545DBL) /* 32 */, unchecked((long) 0xC879E9D7F2A7600BL) /* 33 */, + unchecked((long) 0x860248920193194EL) /* 34 */, unchecked((long) 0xA4F9533B2D9CC0B3L) /* 35 */, + unchecked((long) 0x9053836C15957613L) /* 36 */, unchecked((long) 0xDB6DCF8AFC357BF1L) /* 37 */, + unchecked((long) 0x18BEEA7A7A370F57L) /* 38 */, unchecked((long) 0x037117CA50B99066L) /* 39 */, + unchecked((long) 0x6AB30A9774424A35L) /* 40 */, unchecked((long) 0xF4E92F02E325249BL) /* 41 */, + unchecked((long) 0x7739DB07061CCAE1L) /* 42 */, unchecked((long) 0xD8F3B49CECA42A05L) /* 43 */, + unchecked((long) 0xBD56BE3F51382F73L) /* 44 */, unchecked((long) 0x45FAED5843B0BB28L) /* 45 */, + unchecked((long) 0x1C813D5C11BF1F83L) /* 46 */, unchecked((long) 0x8AF0E4B6D75FA169L) /* 47 */, + unchecked((long) 0x33EE18A487AD9999L) /* 48 */, unchecked((long) 0x3C26E8EAB1C94410L) /* 49 */, + unchecked((long) 0xB510102BC0A822F9L) /* 50 */, unchecked((long) 0x141EEF310CE6123BL) /* 51 */, + unchecked((long) 0xFC65B90059DDB154L) /* 52 */, unchecked((long) 0xE0158640C5E0E607L) /* 53 */, + unchecked((long) 0x884E079826C3A3CFL) /* 54 */, unchecked((long) 0x930D0D9523C535FDL) /* 55 */, + unchecked((long) 0x35638D754E9A2B00L) /* 56 */, unchecked((long) 0x4085FCCF40469DD5L) /* 57 */, + unchecked((long) 0xC4B17AD28BE23A4CL) /* 58 */, unchecked((long) 0xCAB2F0FC6A3E6A2EL) /* 59 */, + unchecked((long) 0x2860971A6B943FCDL) /* 60 */, unchecked((long) 0x3DDE6EE212E30446L) /* 61 */, + unchecked((long) 0x6222F32AE01765AEL) /* 62 */, unchecked((long) 0x5D550BB5478308FEL) /* 63 */, + unchecked((long) 0xA9EFA98DA0EDA22AL) /* 64 */, unchecked((long) 0xC351A71686C40DA7L) /* 65 */, + unchecked((long) 0x1105586D9C867C84L) /* 66 */, unchecked((long) 0xDCFFEE85FDA22853L) /* 67 */, + unchecked((long) 0xCCFBD0262C5EEF76L) /* 68 */, unchecked((long) 0xBAF294CB8990D201L) /* 69 */, + unchecked((long) 0xE69464F52AFAD975L) /* 70 */, unchecked((long) 0x94B013AFDF133E14L) /* 71 */, + unchecked((long) 0x06A7D1A32823C958L) /* 72 */, unchecked((long) 0x6F95FE5130F61119L) /* 73 */, + unchecked((long) 0xD92AB34E462C06C0L) /* 74 */, unchecked((long) 0xED7BDE33887C71D2L) /* 75 */, + unchecked((long) 0x79746D6E6518393EL) /* 76 */, unchecked((long) 0x5BA419385D713329L) /* 77 */, + unchecked((long) 0x7C1BA6B948A97564L) /* 78 */, unchecked((long) 0x31987C197BFDAC67L) /* 79 */, + unchecked((long) 0xDE6C23C44B053D02L) /* 80 */, unchecked((long) 0x581C49FED002D64DL) /* 81 */, + unchecked((long) 0xDD474D6338261571L) /* 82 */, unchecked((long) 0xAA4546C3E473D062L) /* 83 */, + unchecked((long) 0x928FCE349455F860L) /* 84 */, unchecked((long) 0x48161BBACAAB94D9L) /* 85 */, + unchecked((long) 0x63912430770E6F68L) /* 86 */, unchecked((long) 0x6EC8A5E602C6641CL) /* 87 */, + unchecked((long) 0x87282515337DDD2BL) /* 88 */, unchecked((long) 0x2CDA6B42034B701BL) /* 89 */, + unchecked((long) 0xB03D37C181CB096DL) /* 90 */, unchecked((long) 0xE108438266C71C6FL) /* 91 */, + unchecked((long) 0x2B3180C7EB51B255L) /* 92 */, unchecked((long) 0xDF92B82F96C08BBCL) /* 93 */, + unchecked((long) 0x5C68C8C0A632F3BAL) /* 94 */, unchecked((long) 0x5504CC861C3D0556L) /* 95 */, + unchecked((long) 0xABBFA4E55FB26B8FL) /* 96 */, unchecked((long) 0x41848B0AB3BACEB4L) /* 97 */, + unchecked((long) 0xB334A273AA445D32L) /* 98 */, unchecked((long) 0xBCA696F0A85AD881L) /* 99 */, + unchecked((long) 0x24F6EC65B528D56CL) /* 100 */, unchecked((long) 0x0CE1512E90F4524AL) /* 101 */, + unchecked((long) 0x4E9DD79D5506D35AL) /* 102 */, unchecked((long) 0x258905FAC6CE9779L) /* 103 */, + unchecked((long) 0x2019295B3E109B33L) /* 104 */, unchecked((long) 0xF8A9478B73A054CCL) /* 105 */, + unchecked((long) 0x2924F2F934417EB0L) /* 106 */, unchecked((long) 0x3993357D536D1BC4L) /* 107 */, + unchecked((long) 0x38A81AC21DB6FF8BL) /* 108 */, unchecked((long) 0x47C4FBF17D6016BFL) /* 109 */, + unchecked((long) 0x1E0FAADD7667E3F5L) /* 110 */, unchecked((long) 0x7ABCFF62938BEB96L) /* 111 */, + unchecked((long) 0xA78DAD948FC179C9L) /* 112 */, unchecked((long) 0x8F1F98B72911E50DL) /* 113 */, + unchecked((long) 0x61E48EAE27121A91L) /* 114 */, unchecked((long) 0x4D62F7AD31859808L) /* 115 */, + unchecked((long) 0xECEBA345EF5CEAEBL) /* 116 */, unchecked((long) 0xF5CEB25EBC9684CEL) /* 117 */, + unchecked((long) 0xF633E20CB7F76221L) /* 118 */, unchecked((long) 0xA32CDF06AB8293E4L) /* 119 */, + unchecked((long) 0x985A202CA5EE2CA4L) /* 120 */, unchecked((long) 0xCF0B8447CC8A8FB1L) /* 121 */, + unchecked((long) 0x9F765244979859A3L) /* 122 */, unchecked((long) 0xA8D516B1A1240017L) /* 123 */, + unchecked((long) 0x0BD7BA3EBB5DC726L) /* 124 */, unchecked((long) 0xE54BCA55B86ADB39L) /* 125 */, + unchecked((long) 0x1D7A3AFD6C478063L) /* 126 */, unchecked((long) 0x519EC608E7669EDDL) /* 127 */, + unchecked((long) 0x0E5715A2D149AA23L) /* 128 */, unchecked((long) 0x177D4571848FF194L) /* 129 */, + unchecked((long) 0xEEB55F3241014C22L) /* 130 */, unchecked((long) 0x0F5E5CA13A6E2EC2L) /* 131 */, + unchecked((long) 0x8029927B75F5C361L) /* 132 */, unchecked((long) 0xAD139FABC3D6E436L) /* 133 */, + unchecked((long) 0x0D5DF1A94CCF402FL) /* 134 */, unchecked((long) 0x3E8BD948BEA5DFC8L) /* 135 */, + unchecked((long) 0xA5A0D357BD3FF77EL) /* 136 */, unchecked((long) 0xA2D12E251F74F645L) /* 137 */, + unchecked((long) 0x66FD9E525E81A082L) /* 138 */, unchecked((long) 0x2E0C90CE7F687A49L) /* 139 */, + unchecked((long) 0xC2E8BCBEBA973BC5L) /* 140 */, unchecked((long) 0x000001BCE509745FL) /* 141 */, + unchecked((long) 0x423777BBE6DAB3D6L) /* 142 */, unchecked((long) 0xD1661C7EAEF06EB5L) /* 143 */, + unchecked((long) 0xA1781F354DAACFD8L) /* 144 */, unchecked((long) 0x2D11284A2B16AFFCL) /* 145 */, + unchecked((long) 0xF1FC4F67FA891D1FL) /* 146 */, unchecked((long) 0x73ECC25DCB920ADAL) /* 147 */, + unchecked((long) 0xAE610C22C2A12651L) /* 148 */, unchecked((long) 0x96E0A810D356B78AL) /* 149 */, + unchecked((long) 0x5A9A381F2FE7870FL) /* 150 */, unchecked((long) 0xD5AD62EDE94E5530L) /* 151 */, + unchecked((long) 0xD225E5E8368D1427L) /* 152 */, unchecked((long) 0x65977B70C7AF4631L) /* 153 */, + unchecked((long) 0x99F889B2DE39D74FL) /* 154 */, unchecked((long) 0x233F30BF54E1D143L) /* 155 */, + unchecked((long) 0x9A9675D3D9A63C97L) /* 156 */, unchecked((long) 0x5470554FF334F9A8L) /* 157 */, + unchecked((long) 0x166ACB744A4F5688L) /* 158 */, unchecked((long) 0x70C74CAAB2E4AEADL) /* 159 */, + unchecked((long) 0xF0D091646F294D12L) /* 160 */, unchecked((long) 0x57B82A89684031D1L) /* 161 */, + unchecked((long) 0xEFD95A5A61BE0B6BL) /* 162 */, unchecked((long) 0x2FBD12E969F2F29AL) /* 163 */, + unchecked((long) 0x9BD37013FEFF9FE8L) /* 164 */, unchecked((long) 0x3F9B0404D6085A06L) /* 165 */, + unchecked((long) 0x4940C1F3166CFE15L) /* 166 */, unchecked((long) 0x09542C4DCDF3DEFBL) /* 167 */, + unchecked((long) 0xB4C5218385CD5CE3L) /* 168 */, unchecked((long) 0xC935B7DC4462A641L) /* 169 */, + unchecked((long) 0x3417F8A68ED3B63FL) /* 170 */, unchecked((long) 0xB80959295B215B40L) /* 171 */, + unchecked((long) 0xF99CDAEF3B8C8572L) /* 172 */, unchecked((long) 0x018C0614F8FCB95DL) /* 173 */, + unchecked((long) 0x1B14ACCD1A3ACDF3L) /* 174 */, unchecked((long) 0x84D471F200BB732DL) /* 175 */, + unchecked((long) 0xC1A3110E95E8DA16L) /* 176 */, unchecked((long) 0x430A7220BF1A82B8L) /* 177 */, + unchecked((long) 0xB77E090D39DF210EL) /* 178 */, unchecked((long) 0x5EF4BD9F3CD05E9DL) /* 179 */, + unchecked((long) 0x9D4FF6DA7E57A444L) /* 180 */, unchecked((long) 0xDA1D60E183D4A5F8L) /* 181 */, + unchecked((long) 0xB287C38417998E47L) /* 182 */, unchecked((long) 0xFE3EDC121BB31886L) /* 183 */, + unchecked((long) 0xC7FE3CCC980CCBEFL) /* 184 */, unchecked((long) 0xE46FB590189BFD03L) /* 185 */, + unchecked((long) 0x3732FD469A4C57DCL) /* 186 */, unchecked((long) 0x7EF700A07CF1AD65L) /* 187 */, + unchecked((long) 0x59C64468A31D8859L) /* 188 */, unchecked((long) 0x762FB0B4D45B61F6L) /* 189 */, + unchecked((long) 0x155BAED099047718L) /* 190 */, unchecked((long) 0x68755E4C3D50BAA6L) /* 191 */, + unchecked((long) 0xE9214E7F22D8B4DFL) /* 192 */, unchecked((long) 0x2ADDBF532EAC95F4L) /* 193 */, + unchecked((long) 0x32AE3909B4BD0109L) /* 194 */, unchecked((long) 0x834DF537B08E3450L) /* 195 */, + unchecked((long) 0xFA209DA84220728DL) /* 196 */, unchecked((long) 0x9E691D9B9EFE23F7L) /* 197 */, + unchecked((long) 0x0446D288C4AE8D7FL) /* 198 */, unchecked((long) 0x7B4CC524E169785BL) /* 199 */, + unchecked((long) 0x21D87F0135CA1385L) /* 200 */, unchecked((long) 0xCEBB400F137B8AA5L) /* 201 */, + unchecked((long) 0x272E2B66580796BEL) /* 202 */, unchecked((long) 0x3612264125C2B0DEL) /* 203 */, + unchecked((long) 0x057702BDAD1EFBB2L) /* 204 */, unchecked((long) 0xD4BABB8EACF84BE9L) /* 205 */, + unchecked((long) 0x91583139641BC67BL) /* 206 */, unchecked((long) 0x8BDC2DE08036E024L) /* 207 */, + unchecked((long) 0x603C8156F49F68EDL) /* 208 */, unchecked((long) 0xF7D236F7DBEF5111L) /* 209 */, + unchecked((long) 0x9727C4598AD21E80L) /* 210 */, unchecked((long) 0xA08A0896670A5FD7L) /* 211 */, + unchecked((long) 0xCB4A8F4309EBA9CBL) /* 212 */, unchecked((long) 0x81AF564B0F7036A1L) /* 213 */, + unchecked((long) 0xC0B99AA778199ABDL) /* 214 */, unchecked((long) 0x959F1EC83FC8E952L) /* 215 */, + unchecked((long) 0x8C505077794A81B9L) /* 216 */, unchecked((long) 0x3ACAAF8F056338F0L) /* 217 */, + unchecked((long) 0x07B43F50627A6778L) /* 218 */, unchecked((long) 0x4A44AB49F5ECCC77L) /* 219 */, + unchecked((long) 0x3BC3D6E4B679EE98L) /* 220 */, unchecked((long) 0x9CC0D4D1CF14108CL) /* 221 */, + unchecked((long) 0x4406C00B206BC8A0L) /* 222 */, unchecked((long) 0x82A18854C8D72D89L) /* 223 */, + unchecked((long) 0x67E366B35C3C432CL) /* 224 */, unchecked((long) 0xB923DD61102B37F2L) /* 225 */, + unchecked((long) 0x56AB2779D884271DL) /* 226 */, unchecked((long) 0xBE83E1B0FF1525AFL) /* 227 */, + unchecked((long) 0xFB7C65D4217E49A9L) /* 228 */, unchecked((long) 0x6BDBE0E76D48E7D4L) /* 229 */, + unchecked((long) 0x08DF828745D9179EL) /* 230 */, unchecked((long) 0x22EA6A9ADD53BD34L) /* 231 */, + unchecked((long) 0xE36E141C5622200AL) /* 232 */, unchecked((long) 0x7F805D1B8CB750EEL) /* 233 */, + unchecked((long) 0xAFE5C7A59F58E837L) /* 234 */, unchecked((long) 0xE27F996A4FB1C23CL) /* 235 */, + unchecked((long) 0xD3867DFB0775F0D0L) /* 236 */, unchecked((long) 0xD0E673DE6E88891AL) /* 237 */, + unchecked((long) 0x123AEB9EAFB86C25L) /* 238 */, unchecked((long) 0x30F1D5D5C145B895L) /* 239 */, + unchecked((long) 0xBB434A2DEE7269E7L) /* 240 */, unchecked((long) 0x78CB67ECF931FA38L) /* 241 */, + unchecked((long) 0xF33B0372323BBF9CL) /* 242 */, unchecked((long) 0x52D66336FB279C74L) /* 243 */, + unchecked((long) 0x505F33AC0AFB4EAAL) /* 244 */, unchecked((long) 0xE8A5CD99A2CCE187L) /* 245 */, + unchecked((long) 0x534974801E2D30BBL) /* 246 */, unchecked((long) 0x8D2D5711D5876D90L) /* 247 */, + unchecked((long) 0x1F1A412891BC038EL) /* 248 */, unchecked((long) 0xD6E2E71D82E56648L) /* 249 */, + unchecked((long) 0x74036C3A497732B7L) /* 250 */, unchecked((long) 0x89B67ED96361F5ABL) /* 251 */, + unchecked((long) 0xFFED95D8F1EA02A2L) /* 252 */, unchecked((long) 0xE72B3BD61464D43DL) /* 253 */, + unchecked((long) 0xA6300F170BDC4820L) /* 254 */, unchecked((long) 0xEBC18760ED78A77AL) /* 255 */, + }; + + private static readonly long[] t2 = { + unchecked((long) 0xE6A6BE5A05A12138L) /* 256 */, unchecked((long) 0xB5A122A5B4F87C98L) /* 257 */, + unchecked((long) 0x563C6089140B6990L) /* 258 */, unchecked((long) 0x4C46CB2E391F5DD5L) /* 259 */, + unchecked((long) 0xD932ADDBC9B79434L) /* 260 */, unchecked((long) 0x08EA70E42015AFF5L) /* 261 */, + unchecked((long) 0xD765A6673E478CF1L) /* 262 */, unchecked((long) 0xC4FB757EAB278D99L) /* 263 */, + unchecked((long) 0xDF11C6862D6E0692L) /* 264 */, unchecked((long) 0xDDEB84F10D7F3B16L) /* 265 */, + unchecked((long) 0x6F2EF604A665EA04L) /* 266 */, unchecked((long) 0x4A8E0F0FF0E0DFB3L) /* 267 */, + unchecked((long) 0xA5EDEEF83DBCBA51L) /* 268 */, unchecked((long) 0xFC4F0A2A0EA4371EL) /* 269 */, + unchecked((long) 0xE83E1DA85CB38429L) /* 270 */, unchecked((long) 0xDC8FF882BA1B1CE2L) /* 271 */, + unchecked((long) 0xCD45505E8353E80DL) /* 272 */, unchecked((long) 0x18D19A00D4DB0717L) /* 273 */, + unchecked((long) 0x34A0CFEDA5F38101L) /* 274 */, unchecked((long) 0x0BE77E518887CAF2L) /* 275 */, + unchecked((long) 0x1E341438B3C45136L) /* 276 */, unchecked((long) 0xE05797F49089CCF9L) /* 277 */, + unchecked((long) 0xFFD23F9DF2591D14L) /* 278 */, unchecked((long) 0x543DDA228595C5CDL) /* 279 */, + unchecked((long) 0x661F81FD99052A33L) /* 280 */, unchecked((long) 0x8736E641DB0F7B76L) /* 281 */, + unchecked((long) 0x15227725418E5307L) /* 282 */, unchecked((long) 0xE25F7F46162EB2FAL) /* 283 */, + unchecked((long) 0x48A8B2126C13D9FEL) /* 284 */, unchecked((long) 0xAFDC541792E76EEAL) /* 285 */, + unchecked((long) 0x03D912BFC6D1898FL) /* 286 */, unchecked((long) 0x31B1AAFA1B83F51BL) /* 287 */, + unchecked((long) 0xF1AC2796E42AB7D9L) /* 288 */, unchecked((long) 0x40A3A7D7FCD2EBACL) /* 289 */, + unchecked((long) 0x1056136D0AFBBCC5L) /* 290 */, unchecked((long) 0x7889E1DD9A6D0C85L) /* 291 */, + unchecked((long) 0xD33525782A7974AAL) /* 292 */, unchecked((long) 0xA7E25D09078AC09BL) /* 293 */, + unchecked((long) 0xBD4138B3EAC6EDD0L) /* 294 */, unchecked((long) 0x920ABFBE71EB9E70L) /* 295 */, + unchecked((long) 0xA2A5D0F54FC2625CL) /* 296 */, unchecked((long) 0xC054E36B0B1290A3L) /* 297 */, + unchecked((long) 0xF6DD59FF62FE932BL) /* 298 */, unchecked((long) 0x3537354511A8AC7DL) /* 299 */, + unchecked((long) 0xCA845E9172FADCD4L) /* 300 */, unchecked((long) 0x84F82B60329D20DCL) /* 301 */, + unchecked((long) 0x79C62CE1CD672F18L) /* 302 */, unchecked((long) 0x8B09A2ADD124642CL) /* 303 */, + unchecked((long) 0xD0C1E96A19D9E726L) /* 304 */, unchecked((long) 0x5A786A9B4BA9500CL) /* 305 */, + unchecked((long) 0x0E020336634C43F3L) /* 306 */, unchecked((long) 0xC17B474AEB66D822L) /* 307 */, + unchecked((long) 0x6A731AE3EC9BAAC2L) /* 308 */, unchecked((long) 0x8226667AE0840258L) /* 309 */, + unchecked((long) 0x67D4567691CAECA5L) /* 310 */, unchecked((long) 0x1D94155C4875ADB5L) /* 311 */, + unchecked((long) 0x6D00FD985B813FDFL) /* 312 */, unchecked((long) 0x51286EFCB774CD06L) /* 313 */, + unchecked((long) 0x5E8834471FA744AFL) /* 314 */, unchecked((long) 0xF72CA0AEE761AE2EL) /* 315 */, + unchecked((long) 0xBE40E4CDAEE8E09AL) /* 316 */, unchecked((long) 0xE9970BBB5118F665L) /* 317 */, + unchecked((long) 0x726E4BEB33DF1964L) /* 318 */, unchecked((long) 0x703B000729199762L) /* 319 */, + unchecked((long) 0x4631D816F5EF30A7L) /* 320 */, unchecked((long) 0xB880B5B51504A6BEL) /* 321 */, + unchecked((long) 0x641793C37ED84B6CL) /* 322 */, unchecked((long) 0x7B21ED77F6E97D96L) /* 323 */, + unchecked((long) 0x776306312EF96B73L) /* 324 */, unchecked((long) 0xAE528948E86FF3F4L) /* 325 */, + unchecked((long) 0x53DBD7F286A3F8F8L) /* 326 */, unchecked((long) 0x16CADCE74CFC1063L) /* 327 */, + unchecked((long) 0x005C19BDFA52C6DDL) /* 328 */, unchecked((long) 0x68868F5D64D46AD3L) /* 329 */, + unchecked((long) 0x3A9D512CCF1E186AL) /* 330 */, unchecked((long) 0x367E62C2385660AEL) /* 331 */, + unchecked((long) 0xE359E7EA77DCB1D7L) /* 332 */, unchecked((long) 0x526C0773749ABE6EL) /* 333 */, + unchecked((long) 0x735AE5F9D09F734BL) /* 334 */, unchecked((long) 0x493FC7CC8A558BA8L) /* 335 */, + unchecked((long) 0xB0B9C1533041AB45L) /* 336 */, unchecked((long) 0x321958BA470A59BDL) /* 337 */, + unchecked((long) 0x852DB00B5F46C393L) /* 338 */, unchecked((long) 0x91209B2BD336B0E5L) /* 339 */, + unchecked((long) 0x6E604F7D659EF19FL) /* 340 */, unchecked((long) 0xB99A8AE2782CCB24L) /* 341 */, + unchecked((long) 0xCCF52AB6C814C4C7L) /* 342 */, unchecked((long) 0x4727D9AFBE11727BL) /* 343 */, + unchecked((long) 0x7E950D0C0121B34DL) /* 344 */, unchecked((long) 0x756F435670AD471FL) /* 345 */, + unchecked((long) 0xF5ADD442615A6849L) /* 346 */, unchecked((long) 0x4E87E09980B9957AL) /* 347 */, + unchecked((long) 0x2ACFA1DF50AEE355L) /* 348 */, unchecked((long) 0xD898263AFD2FD556L) /* 349 */, + unchecked((long) 0xC8F4924DD80C8FD6L) /* 350 */, unchecked((long) 0xCF99CA3D754A173AL) /* 351 */, + unchecked((long) 0xFE477BACAF91BF3CL) /* 352 */, unchecked((long) 0xED5371F6D690C12DL) /* 353 */, + unchecked((long) 0x831A5C285E687094L) /* 354 */, unchecked((long) 0xC5D3C90A3708A0A4L) /* 355 */, + unchecked((long) 0x0F7F903717D06580L) /* 356 */, unchecked((long) 0x19F9BB13B8FDF27FL) /* 357 */, + unchecked((long) 0xB1BD6F1B4D502843L) /* 358 */, unchecked((long) 0x1C761BA38FFF4012L) /* 359 */, + unchecked((long) 0x0D1530C4E2E21F3BL) /* 360 */, unchecked((long) 0x8943CE69A7372C8AL) /* 361 */, + unchecked((long) 0xE5184E11FEB5CE66L) /* 362 */, unchecked((long) 0x618BDB80BD736621L) /* 363 */, + unchecked((long) 0x7D29BAD68B574D0BL) /* 364 */, unchecked((long) 0x81BB613E25E6FE5BL) /* 365 */, + unchecked((long) 0x071C9C10BC07913FL) /* 366 */, unchecked((long) 0xC7BEEB7909AC2D97L) /* 367 */, + unchecked((long) 0xC3E58D353BC5D757L) /* 368 */, unchecked((long) 0xEB017892F38F61E8L) /* 369 */, + unchecked((long) 0xD4EFFB9C9B1CC21AL) /* 370 */, unchecked((long) 0x99727D26F494F7ABL) /* 371 */, + unchecked((long) 0xA3E063A2956B3E03L) /* 372 */, unchecked((long) 0x9D4A8B9A4AA09C30L) /* 373 */, + unchecked((long) 0x3F6AB7D500090FB4L) /* 374 */, unchecked((long) 0x9CC0F2A057268AC0L) /* 375 */, + unchecked((long) 0x3DEE9D2DEDBF42D1L) /* 376 */, unchecked((long) 0x330F49C87960A972L) /* 377 */, + unchecked((long) 0xC6B2720287421B41L) /* 378 */, unchecked((long) 0x0AC59EC07C00369CL) /* 379 */, + unchecked((long) 0xEF4EAC49CB353425L) /* 380 */, unchecked((long) 0xF450244EEF0129D8L) /* 381 */, + unchecked((long) 0x8ACC46E5CAF4DEB6L) /* 382 */, unchecked((long) 0x2FFEAB63989263F7L) /* 383 */, + unchecked((long) 0x8F7CB9FE5D7A4578L) /* 384 */, unchecked((long) 0x5BD8F7644E634635L) /* 385 */, + unchecked((long) 0x427A7315BF2DC900L) /* 386 */, unchecked((long) 0x17D0C4AA2125261CL) /* 387 */, + unchecked((long) 0x3992486C93518E50L) /* 388 */, unchecked((long) 0xB4CBFEE0A2D7D4C3L) /* 389 */, + unchecked((long) 0x7C75D6202C5DDD8DL) /* 390 */, unchecked((long) 0xDBC295D8E35B6C61L) /* 391 */, + unchecked((long) 0x60B369D302032B19L) /* 392 */, unchecked((long) 0xCE42685FDCE44132L) /* 393 */, + unchecked((long) 0x06F3DDB9DDF65610L) /* 394 */, unchecked((long) 0x8EA4D21DB5E148F0L) /* 395 */, + unchecked((long) 0x20B0FCE62FCD496FL) /* 396 */, unchecked((long) 0x2C1B912358B0EE31L) /* 397 */, + unchecked((long) 0xB28317B818F5A308L) /* 398 */, unchecked((long) 0xA89C1E189CA6D2CFL) /* 399 */, + unchecked((long) 0x0C6B18576AAADBC8L) /* 400 */, unchecked((long) 0xB65DEAA91299FAE3L) /* 401 */, + unchecked((long) 0xFB2B794B7F1027E7L) /* 402 */, unchecked((long) 0x04E4317F443B5BEBL) /* 403 */, + unchecked((long) 0x4B852D325939D0A6L) /* 404 */, unchecked((long) 0xD5AE6BEEFB207FFCL) /* 405 */, + unchecked((long) 0x309682B281C7D374L) /* 406 */, unchecked((long) 0xBAE309A194C3B475L) /* 407 */, + unchecked((long) 0x8CC3F97B13B49F05L) /* 408 */, unchecked((long) 0x98A9422FF8293967L) /* 409 */, + unchecked((long) 0x244B16B01076FF7CL) /* 410 */, unchecked((long) 0xF8BF571C663D67EEL) /* 411 */, + unchecked((long) 0x1F0D6758EEE30DA1L) /* 412 */, unchecked((long) 0xC9B611D97ADEB9B7L) /* 413 */, + unchecked((long) 0xB7AFD5887B6C57A2L) /* 414 */, unchecked((long) 0x6290AE846B984FE1L) /* 415 */, + unchecked((long) 0x94DF4CDEACC1A5FDL) /* 416 */, unchecked((long) 0x058A5BD1C5483AFFL) /* 417 */, + unchecked((long) 0x63166CC142BA3C37L) /* 418 */, unchecked((long) 0x8DB8526EB2F76F40L) /* 419 */, + unchecked((long) 0xE10880036F0D6D4EL) /* 420 */, unchecked((long) 0x9E0523C9971D311DL) /* 421 */, + unchecked((long) 0x45EC2824CC7CD691L) /* 422 */, unchecked((long) 0x575B8359E62382C9L) /* 423 */, + unchecked((long) 0xFA9E400DC4889995L) /* 424 */, unchecked((long) 0xD1823ECB45721568L) /* 425 */, + unchecked((long) 0xDAFD983B8206082FL) /* 426 */, unchecked((long) 0xAA7D29082386A8CBL) /* 427 */, + unchecked((long) 0x269FCD4403B87588L) /* 428 */, unchecked((long) 0x1B91F5F728BDD1E0L) /* 429 */, + unchecked((long) 0xE4669F39040201F6L) /* 430 */, unchecked((long) 0x7A1D7C218CF04ADEL) /* 431 */, + unchecked((long) 0x65623C29D79CE5CEL) /* 432 */, unchecked((long) 0x2368449096C00BB1L) /* 433 */, + unchecked((long) 0xAB9BF1879DA503BAL) /* 434 */, unchecked((long) 0xBC23ECB1A458058EL) /* 435 */, + unchecked((long) 0x9A58DF01BB401ECCL) /* 436 */, unchecked((long) 0xA070E868A85F143DL) /* 437 */, + unchecked((long) 0x4FF188307DF2239EL) /* 438 */, unchecked((long) 0x14D565B41A641183L) /* 439 */, + unchecked((long) 0xEE13337452701602L) /* 440 */, unchecked((long) 0x950E3DCF3F285E09L) /* 441 */, + unchecked((long) 0x59930254B9C80953L) /* 442 */, unchecked((long) 0x3BF299408930DA6DL) /* 443 */, + unchecked((long) 0xA955943F53691387L) /* 444 */, unchecked((long) 0xA15EDECAA9CB8784L) /* 445 */, + unchecked((long) 0x29142127352BE9A0L) /* 446 */, unchecked((long) 0x76F0371FFF4E7AFBL) /* 447 */, + unchecked((long) 0x0239F450274F2228L) /* 448 */, unchecked((long) 0xBB073AF01D5E868BL) /* 449 */, + unchecked((long) 0xBFC80571C10E96C1L) /* 450 */, unchecked((long) 0xD267088568222E23L) /* 451 */, + unchecked((long) 0x9671A3D48E80B5B0L) /* 452 */, unchecked((long) 0x55B5D38AE193BB81L) /* 453 */, + unchecked((long) 0x693AE2D0A18B04B8L) /* 454 */, unchecked((long) 0x5C48B4ECADD5335FL) /* 455 */, + unchecked((long) 0xFD743B194916A1CAL) /* 456 */, unchecked((long) 0x2577018134BE98C4L) /* 457 */, + unchecked((long) 0xE77987E83C54A4ADL) /* 458 */, unchecked((long) 0x28E11014DA33E1B9L) /* 459 */, + unchecked((long) 0x270CC59E226AA213L) /* 460 */, unchecked((long) 0x71495F756D1A5F60L) /* 461 */, + unchecked((long) 0x9BE853FB60AFEF77L) /* 462 */, unchecked((long) 0xADC786A7F7443DBFL) /* 463 */, + unchecked((long) 0x0904456173B29A82L) /* 464 */, unchecked((long) 0x58BC7A66C232BD5EL) /* 465 */, + unchecked((long) 0xF306558C673AC8B2L) /* 466 */, unchecked((long) 0x41F639C6B6C9772AL) /* 467 */, + unchecked((long) 0x216DEFE99FDA35DAL) /* 468 */, unchecked((long) 0x11640CC71C7BE615L) /* 469 */, + unchecked((long) 0x93C43694565C5527L) /* 470 */, unchecked((long) 0xEA038E6246777839L) /* 471 */, + unchecked((long) 0xF9ABF3CE5A3E2469L) /* 472 */, unchecked((long) 0x741E768D0FD312D2L) /* 473 */, + unchecked((long) 0x0144B883CED652C6L) /* 474 */, unchecked((long) 0xC20B5A5BA33F8552L) /* 475 */, + unchecked((long) 0x1AE69633C3435A9DL) /* 476 */, unchecked((long) 0x97A28CA4088CFDECL) /* 477 */, + unchecked((long) 0x8824A43C1E96F420L) /* 478 */, unchecked((long) 0x37612FA66EEEA746L) /* 479 */, + unchecked((long) 0x6B4CB165F9CF0E5AL) /* 480 */, unchecked((long) 0x43AA1C06A0ABFB4AL) /* 481 */, + unchecked((long) 0x7F4DC26FF162796BL) /* 482 */, unchecked((long) 0x6CBACC8E54ED9B0FL) /* 483 */, + unchecked((long) 0xA6B7FFEFD2BB253EL) /* 484 */, unchecked((long) 0x2E25BC95B0A29D4FL) /* 485 */, + unchecked((long) 0x86D6A58BDEF1388CL) /* 486 */, unchecked((long) 0xDED74AC576B6F054L) /* 487 */, + unchecked((long) 0x8030BDBC2B45805DL) /* 488 */, unchecked((long) 0x3C81AF70E94D9289L) /* 489 */, + unchecked((long) 0x3EFF6DDA9E3100DBL) /* 490 */, unchecked((long) 0xB38DC39FDFCC8847L) /* 491 */, + unchecked((long) 0x123885528D17B87EL) /* 492 */, unchecked((long) 0xF2DA0ED240B1B642L) /* 493 */, + unchecked((long) 0x44CEFADCD54BF9A9L) /* 494 */, unchecked((long) 0x1312200E433C7EE6L) /* 495 */, + unchecked((long) 0x9FFCC84F3A78C748L) /* 496 */, unchecked((long) 0xF0CD1F72248576BBL) /* 497 */, + unchecked((long) 0xEC6974053638CFE4L) /* 498 */, unchecked((long) 0x2BA7B67C0CEC4E4CL) /* 499 */, + unchecked((long) 0xAC2F4DF3E5CE32EDL) /* 500 */, unchecked((long) 0xCB33D14326EA4C11L) /* 501 */, + unchecked((long) 0xA4E9044CC77E58BCL) /* 502 */, unchecked((long) 0x5F513293D934FCEFL) /* 503 */, + unchecked((long) 0x5DC9645506E55444L) /* 504 */, unchecked((long) 0x50DE418F317DE40AL) /* 505 */, + unchecked((long) 0x388CB31A69DDE259L) /* 506 */, unchecked((long) 0x2DB4A83455820A86L) /* 507 */, + unchecked((long) 0x9010A91E84711AE9L) /* 508 */, unchecked((long) 0x4DF7F0B7B1498371L) /* 509 */, + unchecked((long) 0xD62A2EABC0977179L) /* 510 */, unchecked((long) 0x22FAC097AA8D5C0EL) /* 511 */, + }; + + private static readonly long[] t3 = { + unchecked((long) 0xF49FCC2FF1DAF39BL) /* 512 */, unchecked((long) 0x487FD5C66FF29281L) /* 513 */, + unchecked((long) 0xE8A30667FCDCA83FL) /* 514 */, unchecked((long) 0x2C9B4BE3D2FCCE63L) /* 515 */, + unchecked((long) 0xDA3FF74B93FBBBC2L) /* 516 */, unchecked((long) 0x2FA165D2FE70BA66L) /* 517 */, + unchecked((long) 0xA103E279970E93D4L) /* 518 */, unchecked((long) 0xBECDEC77B0E45E71L) /* 519 */, + unchecked((long) 0xCFB41E723985E497L) /* 520 */, unchecked((long) 0xB70AAA025EF75017L) /* 521 */, + unchecked((long) 0xD42309F03840B8E0L) /* 522 */, unchecked((long) 0x8EFC1AD035898579L) /* 523 */, + unchecked((long) 0x96C6920BE2B2ABC5L) /* 524 */, unchecked((long) 0x66AF4163375A9172L) /* 525 */, + unchecked((long) 0x2174ABDCCA7127FBL) /* 526 */, unchecked((long) 0xB33CCEA64A72FF41L) /* 527 */, + unchecked((long) 0xF04A4933083066A5L) /* 528 */, unchecked((long) 0x8D970ACDD7289AF5L) /* 529 */, + unchecked((long) 0x8F96E8E031C8C25EL) /* 530 */, unchecked((long) 0xF3FEC02276875D47L) /* 531 */, + unchecked((long) 0xEC7BF310056190DDL) /* 532 */, unchecked((long) 0xF5ADB0AEBB0F1491L) /* 533 */, + unchecked((long) 0x9B50F8850FD58892L) /* 534 */, unchecked((long) 0x4975488358B74DE8L) /* 535 */, + unchecked((long) 0xA3354FF691531C61L) /* 536 */, unchecked((long) 0x0702BBE481D2C6EEL) /* 537 */, + unchecked((long) 0x89FB24057DEDED98L) /* 538 */, unchecked((long) 0xAC3075138596E902L) /* 539 */, + unchecked((long) 0x1D2D3580172772EDL) /* 540 */, unchecked((long) 0xEB738FC28E6BC30DL) /* 541 */, + unchecked((long) 0x5854EF8F63044326L) /* 542 */, unchecked((long) 0x9E5C52325ADD3BBEL) /* 543 */, + unchecked((long) 0x90AA53CF325C4623L) /* 544 */, unchecked((long) 0xC1D24D51349DD067L) /* 545 */, + unchecked((long) 0x2051CFEEA69EA624L) /* 546 */, unchecked((long) 0x13220F0A862E7E4FL) /* 547 */, + unchecked((long) 0xCE39399404E04864L) /* 548 */, unchecked((long) 0xD9C42CA47086FCB7L) /* 549 */, + unchecked((long) 0x685AD2238A03E7CCL) /* 550 */, unchecked((long) 0x066484B2AB2FF1DBL) /* 551 */, + unchecked((long) 0xFE9D5D70EFBF79ECL) /* 552 */, unchecked((long) 0x5B13B9DD9C481854L) /* 553 */, + unchecked((long) 0x15F0D475ED1509ADL) /* 554 */, unchecked((long) 0x0BEBCD060EC79851L) /* 555 */, + unchecked((long) 0xD58C6791183AB7F8L) /* 556 */, unchecked((long) 0xD1187C5052F3EEE4L) /* 557 */, + unchecked((long) 0xC95D1192E54E82FFL) /* 558 */, unchecked((long) 0x86EEA14CB9AC6CA2L) /* 559 */, + unchecked((long) 0x3485BEB153677D5DL) /* 560 */, unchecked((long) 0xDD191D781F8C492AL) /* 561 */, + unchecked((long) 0xF60866BAA784EBF9L) /* 562 */, unchecked((long) 0x518F643BA2D08C74L) /* 563 */, + unchecked((long) 0x8852E956E1087C22L) /* 564 */, unchecked((long) 0xA768CB8DC410AE8DL) /* 565 */, + unchecked((long) 0x38047726BFEC8E1AL) /* 566 */, unchecked((long) 0xA67738B4CD3B45AAL) /* 567 */, + unchecked((long) 0xAD16691CEC0DDE19L) /* 568 */, unchecked((long) 0xC6D4319380462E07L) /* 569 */, + unchecked((long) 0xC5A5876D0BA61938L) /* 570 */, unchecked((long) 0x16B9FA1FA58FD840L) /* 571 */, + unchecked((long) 0x188AB1173CA74F18L) /* 572 */, unchecked((long) 0xABDA2F98C99C021FL) /* 573 */, + unchecked((long) 0x3E0580AB134AE816L) /* 574 */, unchecked((long) 0x5F3B05B773645ABBL) /* 575 */, + unchecked((long) 0x2501A2BE5575F2F6L) /* 576 */, unchecked((long) 0x1B2F74004E7E8BA9L) /* 577 */, + unchecked((long) 0x1CD7580371E8D953L) /* 578 */, unchecked((long) 0x7F6ED89562764E30L) /* 579 */, + unchecked((long) 0xB15926FF596F003DL) /* 580 */, unchecked((long) 0x9F65293DA8C5D6B9L) /* 581 */, + unchecked((long) 0x6ECEF04DD690F84CL) /* 582 */, unchecked((long) 0x4782275FFF33AF88L) /* 583 */, + unchecked((long) 0xE41433083F820801L) /* 584 */, unchecked((long) 0xFD0DFE409A1AF9B5L) /* 585 */, + unchecked((long) 0x4325A3342CDB396BL) /* 586 */, unchecked((long) 0x8AE77E62B301B252L) /* 587 */, + unchecked((long) 0xC36F9E9F6655615AL) /* 588 */, unchecked((long) 0x85455A2D92D32C09L) /* 589 */, + unchecked((long) 0xF2C7DEA949477485L) /* 590 */, unchecked((long) 0x63CFB4C133A39EBAL) /* 591 */, + unchecked((long) 0x83B040CC6EBC5462L) /* 592 */, unchecked((long) 0x3B9454C8FDB326B0L) /* 593 */, + unchecked((long) 0x56F56A9E87FFD78CL) /* 594 */, unchecked((long) 0x2DC2940D99F42BC6L) /* 595 */, + unchecked((long) 0x98F7DF096B096E2DL) /* 596 */, unchecked((long) 0x19A6E01E3AD852BFL) /* 597 */, + unchecked((long) 0x42A99CCBDBD4B40BL) /* 598 */, unchecked((long) 0xA59998AF45E9C559L) /* 599 */, + unchecked((long) 0x366295E807D93186L) /* 600 */, unchecked((long) 0x6B48181BFAA1F773L) /* 601 */, + unchecked((long) 0x1FEC57E2157A0A1DL) /* 602 */, unchecked((long) 0x4667446AF6201AD5L) /* 603 */, + unchecked((long) 0xE615EBCACFB0F075L) /* 604 */, unchecked((long) 0xB8F31F4F68290778L) /* 605 */, + unchecked((long) 0x22713ED6CE22D11EL) /* 606 */, unchecked((long) 0x3057C1A72EC3C93BL) /* 607 */, + unchecked((long) 0xCB46ACC37C3F1F2FL) /* 608 */, unchecked((long) 0xDBB893FD02AAF50EL) /* 609 */, + unchecked((long) 0x331FD92E600B9FCFL) /* 610 */, unchecked((long) 0xA498F96148EA3AD6L) /* 611 */, + unchecked((long) 0xA8D8426E8B6A83EAL) /* 612 */, unchecked((long) 0xA089B274B7735CDCL) /* 613 */, + unchecked((long) 0x87F6B3731E524A11L) /* 614 */, unchecked((long) 0x118808E5CBC96749L) /* 615 */, + unchecked((long) 0x9906E4C7B19BD394L) /* 616 */, unchecked((long) 0xAFED7F7E9B24A20CL) /* 617 */, + unchecked((long) 0x6509EADEEB3644A7L) /* 618 */, unchecked((long) 0x6C1EF1D3E8EF0EDEL) /* 619 */, + unchecked((long) 0xB9C97D43E9798FB4L) /* 620 */, unchecked((long) 0xA2F2D784740C28A3L) /* 621 */, + unchecked((long) 0x7B8496476197566FL) /* 622 */, unchecked((long) 0x7A5BE3E6B65F069DL) /* 623 */, + unchecked((long) 0xF96330ED78BE6F10L) /* 624 */, unchecked((long) 0xEEE60DE77A076A15L) /* 625 */, + unchecked((long) 0x2B4BEE4AA08B9BD0L) /* 626 */, unchecked((long) 0x6A56A63EC7B8894EL) /* 627 */, + unchecked((long) 0x02121359BA34FEF4L) /* 628 */, unchecked((long) 0x4CBF99F8283703FCL) /* 629 */, + unchecked((long) 0x398071350CAF30C8L) /* 630 */, unchecked((long) 0xD0A77A89F017687AL) /* 631 */, + unchecked((long) 0xF1C1A9EB9E423569L) /* 632 */, unchecked((long) 0x8C7976282DEE8199L) /* 633 */, + unchecked((long) 0x5D1737A5DD1F7ABDL) /* 634 */, unchecked((long) 0x4F53433C09A9FA80L) /* 635 */, + unchecked((long) 0xFA8B0C53DF7CA1D9L) /* 636 */, unchecked((long) 0x3FD9DCBC886CCB77L) /* 637 */, + unchecked((long) 0xC040917CA91B4720L) /* 638 */, unchecked((long) 0x7DD00142F9D1DCDFL) /* 639 */, + unchecked((long) 0x8476FC1D4F387B58L) /* 640 */, unchecked((long) 0x23F8E7C5F3316503L) /* 641 */, + unchecked((long) 0x032A2244E7E37339L) /* 642 */, unchecked((long) 0x5C87A5D750F5A74BL) /* 643 */, + unchecked((long) 0x082B4CC43698992EL) /* 644 */, unchecked((long) 0xDF917BECB858F63CL) /* 645 */, + unchecked((long) 0x3270B8FC5BF86DDAL) /* 646 */, unchecked((long) 0x10AE72BB29B5DD76L) /* 647 */, + unchecked((long) 0x576AC94E7700362BL) /* 648 */, unchecked((long) 0x1AD112DAC61EFB8FL) /* 649 */, + unchecked((long) 0x691BC30EC5FAA427L) /* 650 */, unchecked((long) 0xFF246311CC327143L) /* 651 */, + unchecked((long) 0x3142368E30E53206L) /* 652 */, unchecked((long) 0x71380E31E02CA396L) /* 653 */, + unchecked((long) 0x958D5C960AAD76F1L) /* 654 */, unchecked((long) 0xF8D6F430C16DA536L) /* 655 */, + unchecked((long) 0xC8FFD13F1BE7E1D2L) /* 656 */, unchecked((long) 0x7578AE66004DDBE1L) /* 657 */, + unchecked((long) 0x05833F01067BE646L) /* 658 */, unchecked((long) 0xBB34B5AD3BFE586DL) /* 659 */, + unchecked((long) 0x095F34C9A12B97F0L) /* 660 */, unchecked((long) 0x247AB64525D60CA8L) /* 661 */, + unchecked((long) 0xDCDBC6F3017477D1L) /* 662 */, unchecked((long) 0x4A2E14D4DECAD24DL) /* 663 */, + unchecked((long) 0xBDB5E6D9BE0A1EEBL) /* 664 */, unchecked((long) 0x2A7E70F7794301ABL) /* 665 */, + unchecked((long) 0xDEF42D8A270540FDL) /* 666 */, unchecked((long) 0x01078EC0A34C22C1L) /* 667 */, + unchecked((long) 0xE5DE511AF4C16387L) /* 668 */, unchecked((long) 0x7EBB3A52BD9A330AL) /* 669 */, + unchecked((long) 0x77697857AA7D6435L) /* 670 */, unchecked((long) 0x004E831603AE4C32L) /* 671 */, + unchecked((long) 0xE7A21020AD78E312L) /* 672 */, unchecked((long) 0x9D41A70C6AB420F2L) /* 673 */, + unchecked((long) 0x28E06C18EA1141E6L) /* 674 */, unchecked((long) 0xD2B28CBD984F6B28L) /* 675 */, + unchecked((long) 0x26B75F6C446E9D83L) /* 676 */, unchecked((long) 0xBA47568C4D418D7FL) /* 677 */, + unchecked((long) 0xD80BADBFE6183D8EL) /* 678 */, unchecked((long) 0x0E206D7F5F166044L) /* 679 */, + unchecked((long) 0xE258A43911CBCA3EL) /* 680 */, unchecked((long) 0x723A1746B21DC0BCL) /* 681 */, + unchecked((long) 0xC7CAA854F5D7CDD3L) /* 682 */, unchecked((long) 0x7CAC32883D261D9CL) /* 683 */, + unchecked((long) 0x7690C26423BA942CL) /* 684 */, unchecked((long) 0x17E55524478042B8L) /* 685 */, + unchecked((long) 0xE0BE477656A2389FL) /* 686 */, unchecked((long) 0x4D289B5E67AB2DA0L) /* 687 */, + unchecked((long) 0x44862B9C8FBBFD31L) /* 688 */, unchecked((long) 0xB47CC8049D141365L) /* 689 */, + unchecked((long) 0x822C1B362B91C793L) /* 690 */, unchecked((long) 0x4EB14655FB13DFD8L) /* 691 */, + unchecked((long) 0x1ECBBA0714E2A97BL) /* 692 */, unchecked((long) 0x6143459D5CDE5F14L) /* 693 */, + unchecked((long) 0x53A8FBF1D5F0AC89L) /* 694 */, unchecked((long) 0x97EA04D81C5E5B00L) /* 695 */, + unchecked((long) 0x622181A8D4FDB3F3L) /* 696 */, unchecked((long) 0xE9BCD341572A1208L) /* 697 */, + unchecked((long) 0x1411258643CCE58AL) /* 698 */, unchecked((long) 0x9144C5FEA4C6E0A4L) /* 699 */, + unchecked((long) 0x0D33D06565CF620FL) /* 700 */, unchecked((long) 0x54A48D489F219CA1L) /* 701 */, + unchecked((long) 0xC43E5EAC6D63C821L) /* 702 */, unchecked((long) 0xA9728B3A72770DAFL) /* 703 */, + unchecked((long) 0xD7934E7B20DF87EFL) /* 704 */, unchecked((long) 0xE35503B61A3E86E5L) /* 705 */, + unchecked((long) 0xCAE321FBC819D504L) /* 706 */, unchecked((long) 0x129A50B3AC60BFA6L) /* 707 */, + unchecked((long) 0xCD5E68EA7E9FB6C3L) /* 708 */, unchecked((long) 0xB01C90199483B1C7L) /* 709 */, + unchecked((long) 0x3DE93CD5C295376CL) /* 710 */, unchecked((long) 0xAED52EDF2AB9AD13L) /* 711 */, + unchecked((long) 0x2E60F512C0A07884L) /* 712 */, unchecked((long) 0xBC3D86A3E36210C9L) /* 713 */, + unchecked((long) 0x35269D9B163951CEL) /* 714 */, unchecked((long) 0x0C7D6E2AD0CDB5FAL) /* 715 */, + unchecked((long) 0x59E86297D87F5733L) /* 716 */, unchecked((long) 0x298EF221898DB0E7L) /* 717 */, + unchecked((long) 0x55000029D1A5AA7EL) /* 718 */, unchecked((long) 0x8BC08AE1B5061B45L) /* 719 */, + unchecked((long) 0xC2C31C2B6C92703AL) /* 720 */, unchecked((long) 0x94CC596BAF25EF42L) /* 721 */, + unchecked((long) 0x0A1D73DB22540456L) /* 722 */, unchecked((long) 0x04B6A0F9D9C4179AL) /* 723 */, + unchecked((long) 0xEFFDAFA2AE3D3C60L) /* 724 */, unchecked((long) 0xF7C8075BB49496C4L) /* 725 */, + unchecked((long) 0x9CC5C7141D1CD4E3L) /* 726 */, unchecked((long) 0x78BD1638218E5534L) /* 727 */, + unchecked((long) 0xB2F11568F850246AL) /* 728 */, unchecked((long) 0xEDFABCFA9502BC29L) /* 729 */, + unchecked((long) 0x796CE5F2DA23051BL) /* 730 */, unchecked((long) 0xAAE128B0DC93537CL) /* 731 */, + unchecked((long) 0x3A493DA0EE4B29AEL) /* 732 */, unchecked((long) 0xB5DF6B2C416895D7L) /* 733 */, + unchecked((long) 0xFCABBD25122D7F37L) /* 734 */, unchecked((long) 0x70810B58105DC4B1L) /* 735 */, + unchecked((long) 0xE10FDD37F7882A90L) /* 736 */, unchecked((long) 0x524DCAB5518A3F5CL) /* 737 */, + unchecked((long) 0x3C9E85878451255BL) /* 738 */, unchecked((long) 0x4029828119BD34E2L) /* 739 */, + unchecked((long) 0x74A05B6F5D3CECCBL) /* 740 */, unchecked((long) 0xB610021542E13ECAL) /* 741 */, + unchecked((long) 0x0FF979D12F59E2ACL) /* 742 */, unchecked((long) 0x6037DA27E4F9CC50L) /* 743 */, + unchecked((long) 0x5E92975A0DF1847DL) /* 744 */, unchecked((long) 0xD66DE190D3E623FEL) /* 745 */, + unchecked((long) 0x5032D6B87B568048L) /* 746 */, unchecked((long) 0x9A36B7CE8235216EL) /* 747 */, + unchecked((long) 0x80272A7A24F64B4AL) /* 748 */, unchecked((long) 0x93EFED8B8C6916F7L) /* 749 */, + unchecked((long) 0x37DDBFF44CCE1555L) /* 750 */, unchecked((long) 0x4B95DB5D4B99BD25L) /* 751 */, + unchecked((long) 0x92D3FDA169812FC0L) /* 752 */, unchecked((long) 0xFB1A4A9A90660BB6L) /* 753 */, + unchecked((long) 0x730C196946A4B9B2L) /* 754 */, unchecked((long) 0x81E289AA7F49DA68L) /* 755 */, + unchecked((long) 0x64669A0F83B1A05FL) /* 756 */, unchecked((long) 0x27B3FF7D9644F48BL) /* 757 */, + unchecked((long) 0xCC6B615C8DB675B3L) /* 758 */, unchecked((long) 0x674F20B9BCEBBE95L) /* 759 */, + unchecked((long) 0x6F31238275655982L) /* 760 */, unchecked((long) 0x5AE488713E45CF05L) /* 761 */, + unchecked((long) 0xBF619F9954C21157L) /* 762 */, unchecked((long) 0xEABAC46040A8EAE9L) /* 763 */, + unchecked((long) 0x454C6FE9F2C0C1CDL) /* 764 */, unchecked((long) 0x419CF6496412691CL) /* 765 */, + unchecked((long) 0xD3DC3BEF265B0F70L) /* 766 */, unchecked((long) 0x6D0E60F5C3578A9EL) /* 767 */, + }; + + private static readonly long[] t4 = { + unchecked((long) 0x5B0E608526323C55L) /* 768 */, unchecked((long) 0x1A46C1A9FA1B59F5L) /* 769 */, + unchecked((long) 0xA9E245A17C4C8FFAL) /* 770 */, unchecked((long) 0x65CA5159DB2955D7L) /* 771 */, + unchecked((long) 0x05DB0A76CE35AFC2L) /* 772 */, unchecked((long) 0x81EAC77EA9113D45L) /* 773 */, + unchecked((long) 0x528EF88AB6AC0A0DL) /* 774 */, unchecked((long) 0xA09EA253597BE3FFL) /* 775 */, + unchecked((long) 0x430DDFB3AC48CD56L) /* 776 */, unchecked((long) 0xC4B3A67AF45CE46FL) /* 777 */, + unchecked((long) 0x4ECECFD8FBE2D05EL) /* 778 */, unchecked((long) 0x3EF56F10B39935F0L) /* 779 */, + unchecked((long) 0x0B22D6829CD619C6L) /* 780 */, unchecked((long) 0x17FD460A74DF2069L) /* 781 */, + unchecked((long) 0x6CF8CC8E8510ED40L) /* 782 */, unchecked((long) 0xD6C824BF3A6ECAA7L) /* 783 */, + unchecked((long) 0x61243D581A817049L) /* 784 */, unchecked((long) 0x048BACB6BBC163A2L) /* 785 */, + unchecked((long) 0xD9A38AC27D44CC32L) /* 786 */, unchecked((long) 0x7FDDFF5BAAF410ABL) /* 787 */, + unchecked((long) 0xAD6D495AA804824BL) /* 788 */, unchecked((long) 0xE1A6A74F2D8C9F94L) /* 789 */, + unchecked((long) 0xD4F7851235DEE8E3L) /* 790 */, unchecked((long) 0xFD4B7F886540D893L) /* 791 */, + unchecked((long) 0x247C20042AA4BFDAL) /* 792 */, unchecked((long) 0x096EA1C517D1327CL) /* 793 */, + unchecked((long) 0xD56966B4361A6685L) /* 794 */, unchecked((long) 0x277DA5C31221057DL) /* 795 */, + unchecked((long) 0x94D59893A43ACFF7L) /* 796 */, unchecked((long) 0x64F0C51CCDC02281L) /* 797 */, + unchecked((long) 0x3D33BCC4FF6189DBL) /* 798 */, unchecked((long) 0xE005CB184CE66AF1L) /* 799 */, + unchecked((long) 0xFF5CCD1D1DB99BEAL) /* 800 */, unchecked((long) 0xB0B854A7FE42980FL) /* 801 */, + unchecked((long) 0x7BD46A6A718D4B9FL) /* 802 */, unchecked((long) 0xD10FA8CC22A5FD8CL) /* 803 */, + unchecked((long) 0xD31484952BE4BD31L) /* 804 */, unchecked((long) 0xC7FA975FCB243847L) /* 805 */, + unchecked((long) 0x4886ED1E5846C407L) /* 806 */, unchecked((long) 0x28CDDB791EB70B04L) /* 807 */, + unchecked((long) 0xC2B00BE2F573417FL) /* 808 */, unchecked((long) 0x5C9590452180F877L) /* 809 */, + unchecked((long) 0x7A6BDDFFF370EB00L) /* 810 */, unchecked((long) 0xCE509E38D6D9D6A4L) /* 811 */, + unchecked((long) 0xEBEB0F00647FA702L) /* 812 */, unchecked((long) 0x1DCC06CF76606F06L) /* 813 */, + unchecked((long) 0xE4D9F28BA286FF0AL) /* 814 */, unchecked((long) 0xD85A305DC918C262L) /* 815 */, + unchecked((long) 0x475B1D8732225F54L) /* 816 */, unchecked((long) 0x2D4FB51668CCB5FEL) /* 817 */, + unchecked((long) 0xA679B9D9D72BBA20L) /* 818 */, unchecked((long) 0x53841C0D912D43A5L) /* 819 */, + unchecked((long) 0x3B7EAA48BF12A4E8L) /* 820 */, unchecked((long) 0x781E0E47F22F1DDFL) /* 821 */, + unchecked((long) 0xEFF20CE60AB50973L) /* 822 */, unchecked((long) 0x20D261D19DFFB742L) /* 823 */, + unchecked((long) 0x16A12B03062A2E39L) /* 824 */, unchecked((long) 0x1960EB2239650495L) /* 825 */, + unchecked((long) 0x251C16FED50EB8B8L) /* 826 */, unchecked((long) 0x9AC0C330F826016EL) /* 827 */, + unchecked((long) 0xED152665953E7671L) /* 828 */, unchecked((long) 0x02D63194A6369570L) /* 829 */, + unchecked((long) 0x5074F08394B1C987L) /* 830 */, unchecked((long) 0x70BA598C90B25CE1L) /* 831 */, + unchecked((long) 0x794A15810B9742F6L) /* 832 */, unchecked((long) 0x0D5925E9FCAF8C6CL) /* 833 */, + unchecked((long) 0x3067716CD868744EL) /* 834 */, unchecked((long) 0x910AB077E8D7731BL) /* 835 */, + unchecked((long) 0x6A61BBDB5AC42F61L) /* 836 */, unchecked((long) 0x93513EFBF0851567L) /* 837 */, + unchecked((long) 0xF494724B9E83E9D5L) /* 838 */, unchecked((long) 0xE887E1985C09648DL) /* 839 */, + unchecked((long) 0x34B1D3C675370CFDL) /* 840 */, unchecked((long) 0xDC35E433BC0D255DL) /* 841 */, + unchecked((long) 0xD0AAB84234131BE0L) /* 842 */, unchecked((long) 0x08042A50B48B7EAFL) /* 843 */, + unchecked((long) 0x9997C4EE44A3AB35L) /* 844 */, unchecked((long) 0x829A7B49201799D0L) /* 845 */, + unchecked((long) 0x263B8307B7C54441L) /* 846 */, unchecked((long) 0x752F95F4FD6A6CA6L) /* 847 */, + unchecked((long) 0x927217402C08C6E5L) /* 848 */, unchecked((long) 0x2A8AB754A795D9EEL) /* 849 */, + unchecked((long) 0xA442F7552F72943DL) /* 850 */, unchecked((long) 0x2C31334E19781208L) /* 851 */, + unchecked((long) 0x4FA98D7CEAEE6291L) /* 852 */, unchecked((long) 0x55C3862F665DB309L) /* 853 */, + unchecked((long) 0xBD0610175D53B1F3L) /* 854 */, unchecked((long) 0x46FE6CB840413F27L) /* 855 */, + unchecked((long) 0x3FE03792DF0CFA59L) /* 856 */, unchecked((long) 0xCFE700372EB85E8FL) /* 857 */, + unchecked((long) 0xA7BE29E7ADBCE118L) /* 858 */, unchecked((long) 0xE544EE5CDE8431DDL) /* 859 */, + unchecked((long) 0x8A781B1B41F1873EL) /* 860 */, unchecked((long) 0xA5C94C78A0D2F0E7L) /* 861 */, + unchecked((long) 0x39412E2877B60728L) /* 862 */, unchecked((long) 0xA1265EF3AFC9A62CL) /* 863 */, + unchecked((long) 0xBCC2770C6A2506C5L) /* 864 */, unchecked((long) 0x3AB66DD5DCE1CE12L) /* 865 */, + unchecked((long) 0xE65499D04A675B37L) /* 866 */, unchecked((long) 0x7D8F523481BFD216L) /* 867 */, + unchecked((long) 0x0F6F64FCEC15F389L) /* 868 */, unchecked((long) 0x74EFBE618B5B13C8L) /* 869 */, + unchecked((long) 0xACDC82B714273E1DL) /* 870 */, unchecked((long) 0xDD40BFE003199D17L) /* 871 */, + unchecked((long) 0x37E99257E7E061F8L) /* 872 */, unchecked((long) 0xFA52626904775AAAL) /* 873 */, + unchecked((long) 0x8BBBF63A463D56F9L) /* 874 */, unchecked((long) 0xF0013F1543A26E64L) /* 875 */, + unchecked((long) 0xA8307E9F879EC898L) /* 876 */, unchecked((long) 0xCC4C27A4150177CCL) /* 877 */, + unchecked((long) 0x1B432F2CCA1D3348L) /* 878 */, unchecked((long) 0xDE1D1F8F9F6FA013L) /* 879 */, + unchecked((long) 0x606602A047A7DDD6L) /* 880 */, unchecked((long) 0xD237AB64CC1CB2C7L) /* 881 */, + unchecked((long) 0x9B938E7225FCD1D3L) /* 882 */, unchecked((long) 0xEC4E03708E0FF476L) /* 883 */, + unchecked((long) 0xFEB2FBDA3D03C12DL) /* 884 */, unchecked((long) 0xAE0BCED2EE43889AL) /* 885 */, + unchecked((long) 0x22CB8923EBFB4F43L) /* 886 */, unchecked((long) 0x69360D013CF7396DL) /* 887 */, + unchecked((long) 0x855E3602D2D4E022L) /* 888 */, unchecked((long) 0x073805BAD01F784CL) /* 889 */, + unchecked((long) 0x33E17A133852F546L) /* 890 */, unchecked((long) 0xDF4874058AC7B638L) /* 891 */, + unchecked((long) 0xBA92B29C678AA14AL) /* 892 */, unchecked((long) 0x0CE89FC76CFAADCDL) /* 893 */, + unchecked((long) 0x5F9D4E0908339E34L) /* 894 */, unchecked((long) 0xF1AFE9291F5923B9L) /* 895 */, + unchecked((long) 0x6E3480F60F4A265FL) /* 896 */, unchecked((long) 0xEEBF3A2AB29B841CL) /* 897 */, + unchecked((long) 0xE21938A88F91B4ADL) /* 898 */, unchecked((long) 0x57DFEFF845C6D3C3L) /* 899 */, + unchecked((long) 0x2F006B0BF62CAAF2L) /* 900 */, unchecked((long) 0x62F479EF6F75EE78L) /* 901 */, + unchecked((long) 0x11A55AD41C8916A9L) /* 902 */, unchecked((long) 0xF229D29084FED453L) /* 903 */, + unchecked((long) 0x42F1C27B16B000E6L) /* 904 */, unchecked((long) 0x2B1F76749823C074L) /* 905 */, + unchecked((long) 0x4B76ECA3C2745360L) /* 906 */, unchecked((long) 0x8C98F463B91691BDL) /* 907 */, + unchecked((long) 0x14BCC93CF1ADE66AL) /* 908 */, unchecked((long) 0x8885213E6D458397L) /* 909 */, + unchecked((long) 0x8E177DF0274D4711L) /* 910 */, unchecked((long) 0xB49B73B5503F2951L) /* 911 */, + unchecked((long) 0x10168168C3F96B6BL) /* 912 */, unchecked((long) 0x0E3D963B63CAB0AEL) /* 913 */, + unchecked((long) 0x8DFC4B5655A1DB14L) /* 914 */, unchecked((long) 0xF789F1356E14DE5CL) /* 915 */, + unchecked((long) 0x683E68AF4E51DAC1L) /* 916 */, unchecked((long) 0xC9A84F9D8D4B0FD9L) /* 917 */, + unchecked((long) 0x3691E03F52A0F9D1L) /* 918 */, unchecked((long) 0x5ED86E46E1878E80L) /* 919 */, + unchecked((long) 0x3C711A0E99D07150L) /* 920 */, unchecked((long) 0x5A0865B20C4E9310L) /* 921 */, + unchecked((long) 0x56FBFC1FE4F0682EL) /* 922 */, unchecked((long) 0xEA8D5DE3105EDF9BL) /* 923 */, + unchecked((long) 0x71ABFDB12379187AL) /* 924 */, unchecked((long) 0x2EB99DE1BEE77B9CL) /* 925 */, + unchecked((long) 0x21ECC0EA33CF4523L) /* 926 */, unchecked((long) 0x59A4D7521805C7A1L) /* 927 */, + unchecked((long) 0x3896F5EB56AE7C72L) /* 928 */, unchecked((long) 0xAA638F3DB18F75DCL) /* 929 */, + unchecked((long) 0x9F39358DABE9808EL) /* 930 */, unchecked((long) 0xB7DEFA91C00B72ACL) /* 931 */, + unchecked((long) 0x6B5541FD62492D92L) /* 932 */, unchecked((long) 0x6DC6DEE8F92E4D5BL) /* 933 */, + unchecked((long) 0x353F57ABC4BEEA7EL) /* 934 */, unchecked((long) 0x735769D6DA5690CEL) /* 935 */, + unchecked((long) 0x0A234AA642391484L) /* 936 */, unchecked((long) 0xF6F9508028F80D9DL) /* 937 */, + unchecked((long) 0xB8E319A27AB3F215L) /* 938 */, unchecked((long) 0x31AD9C1151341A4DL) /* 939 */, + unchecked((long) 0x773C22A57BEF5805L) /* 940 */, unchecked((long) 0x45C7561A07968633L) /* 941 */, + unchecked((long) 0xF913DA9E249DBE36L) /* 942 */, unchecked((long) 0xDA652D9B78A64C68L) /* 943 */, + unchecked((long) 0x4C27A97F3BC334EFL) /* 944 */, unchecked((long) 0x76621220E66B17F4L) /* 945 */, + unchecked((long) 0x967743899ACD7D0BL) /* 946 */, unchecked((long) 0xF3EE5BCAE0ED6782L) /* 947 */, + unchecked((long) 0x409F753600C879FCL) /* 948 */, unchecked((long) 0x06D09A39B5926DB6L) /* 949 */, + unchecked((long) 0x6F83AEB0317AC588L) /* 950 */, unchecked((long) 0x01E6CA4A86381F21L) /* 951 */, + unchecked((long) 0x66FF3462D19F3025L) /* 952 */, unchecked((long) 0x72207C24DDFD3BFBL) /* 953 */, + unchecked((long) 0x4AF6B6D3E2ECE2EBL) /* 954 */, unchecked((long) 0x9C994DBEC7EA08DEL) /* 955 */, + unchecked((long) 0x49ACE597B09A8BC4L) /* 956 */, unchecked((long) 0xB38C4766CF0797BAL) /* 957 */, + unchecked((long) 0x131B9373C57C2A75L) /* 958 */, unchecked((long) 0xB1822CCE61931E58L) /* 959 */, + unchecked((long) 0x9D7555B909BA1C0CL) /* 960 */, unchecked((long) 0x127FAFDD937D11D2L) /* 961 */, + unchecked((long) 0x29DA3BADC66D92E4L) /* 962 */, unchecked((long) 0xA2C1D57154C2ECBCL) /* 963 */, + unchecked((long) 0x58C5134D82F6FE24L) /* 964 */, unchecked((long) 0x1C3AE3515B62274FL) /* 965 */, + unchecked((long) 0xE907C82E01CB8126L) /* 966 */, unchecked((long) 0xF8ED091913E37FCBL) /* 967 */, + unchecked((long) 0x3249D8F9C80046C9L) /* 968 */, unchecked((long) 0x80CF9BEDE388FB63L) /* 969 */, + unchecked((long) 0x1881539A116CF19EL) /* 970 */, unchecked((long) 0x5103F3F76BD52457L) /* 971 */, + unchecked((long) 0x15B7E6F5AE47F7A8L) /* 972 */, unchecked((long) 0xDBD7C6DED47E9CCFL) /* 973 */, + unchecked((long) 0x44E55C410228BB1AL) /* 974 */, unchecked((long) 0xB647D4255EDB4E99L) /* 975 */, + unchecked((long) 0x5D11882BB8AAFC30L) /* 976 */, unchecked((long) 0xF5098BBB29D3212AL) /* 977 */, + unchecked((long) 0x8FB5EA14E90296B3L) /* 978 */, unchecked((long) 0x677B942157DD025AL) /* 979 */, + unchecked((long) 0xFB58E7C0A390ACB5L) /* 980 */, unchecked((long) 0x89D3674C83BD4A01L) /* 981 */, + unchecked((long) 0x9E2DA4DF4BF3B93BL) /* 982 */, unchecked((long) 0xFCC41E328CAB4829L) /* 983 */, + unchecked((long) 0x03F38C96BA582C52L) /* 984 */, unchecked((long) 0xCAD1BDBD7FD85DB2L) /* 985 */, + unchecked((long) 0xBBB442C16082AE83L) /* 986 */, unchecked((long) 0xB95FE86BA5DA9AB0L) /* 987 */, + unchecked((long) 0xB22E04673771A93FL) /* 988 */, unchecked((long) 0x845358C9493152D8L) /* 989 */, + unchecked((long) 0xBE2A488697B4541EL) /* 990 */, unchecked((long) 0x95A2DC2DD38E6966L) /* 991 */, + unchecked((long) 0xC02C11AC923C852BL) /* 992 */, unchecked((long) 0x2388B1990DF2A87BL) /* 993 */, + unchecked((long) 0x7C8008FA1B4F37BEL) /* 994 */, unchecked((long) 0x1F70D0C84D54E503L) /* 995 */, + unchecked((long) 0x5490ADEC7ECE57D4L) /* 996 */, unchecked((long) 0x002B3C27D9063A3AL) /* 997 */, + unchecked((long) 0x7EAEA3848030A2BFL) /* 998 */, unchecked((long) 0xC602326DED2003C0L) /* 999 */, + unchecked((long) 0x83A7287D69A94086L) /* 1000 */, unchecked((long) 0xC57A5FCB30F57A8AL) /* 1001 */, + unchecked((long) 0xB56844E479EBE779L) /* 1002 */, unchecked((long) 0xA373B40F05DCBCE9L) /* 1003 */, + unchecked((long) 0xD71A786E88570EE2L) /* 1004 */, unchecked((long) 0x879CBACDBDE8F6A0L) /* 1005 */, + unchecked((long) 0x976AD1BCC164A32FL) /* 1006 */, unchecked((long) 0xAB21E25E9666D78BL) /* 1007 */, + unchecked((long) 0x901063AAE5E5C33CL) /* 1008 */, unchecked((long) 0x9818B34448698D90L) /* 1009 */, + unchecked((long) 0xE36487AE3E1E8ABBL) /* 1010 */, unchecked((long) 0xAFBDF931893BDCB4L) /* 1011 */, + unchecked((long) 0x6345A0DC5FBBD519L) /* 1012 */, unchecked((long) 0x8628FE269B9465CAL) /* 1013 */, + unchecked((long) 0x1E5D01603F9C51ECL) /* 1014 */, unchecked((long) 0x4DE44006A15049B7L) /* 1015 */, + unchecked((long) 0xBF6C70E5F776CBB1L) /* 1016 */, unchecked((long) 0x411218F2EF552BEDL) /* 1017 */, + unchecked((long) 0xCB0C0708705A36A3L) /* 1018 */, unchecked((long) 0xE74D14754F986044L) /* 1019 */, + unchecked((long) 0xCD56D9430EA8280EL) /* 1020 */, unchecked((long) 0xC12591D7535F5065L) /* 1021 */, + unchecked((long) 0xC83223F1720AEF96L) /* 1022 */, unchecked((long) 0xC3A0396F7363A51FL) /* 1023 */ + }; + + private const int DigestLength = 24; + + // + // registers + // + private long a, b, c; + private long byteCount; + + // + // buffers + // + private byte[] Buffer = new byte[8]; + private int bOff; + + private long[] x = new long[8]; + private int xOff; + + /** + * Standard constructor + */ + public TigerDigest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public TigerDigest(TigerDigest t) + { + a = t.a; + b = t.b; + c = t.c; + + Array.Copy(t.x, 0, x, 0, t.x.Length); + xOff = t.xOff; + + Array.Copy(t.Buffer, 0, Buffer, 0, t.Buffer.Length); + bOff = t.bOff; + + byteCount = t.byteCount; + } + + public string AlgorithmName + { + get { return "Tiger"; } + } + + public int GetDigestSize() + { + return DigestLength; + } + + public int GetByteLength() + { + return MyByteLength; + } + + private void ProcessWord( + byte[] b, + int off) + { + x[xOff++] = ((long)(b[off + 7] & 0xff) << 56) + | ((long)(b[off + 6] & 0xff) << 48) + | ((long)(b[off + 5] & 0xff) << 40) + | ((long)(b[off + 4] & 0xff) << 32) + | ((long)(b[off + 3] & 0xff) << 24) + | ((long)(b[off + 2] & 0xff) << 16) + | ((long)(b[off + 1] & 0xff) << 8) + | ((uint)(b[off + 0] & 0xff)); + + if (xOff == x.Length) + { + ProcessBlock(); + } + + bOff = 0; + } + + public void Update( + byte input) + { + Buffer[bOff++] = input; + + if (bOff == Buffer.Length) + { + ProcessWord(Buffer, 0); + } + + byteCount++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + // + // fill the current word + // + while ((bOff != 0) && (length > 0)) + { + Update(input[inOff]); + + inOff++; + length--; + } + + // + // process whole words. + // + while (length > 8) + { + ProcessWord(input, inOff); + + inOff += 8; + length -= 8; + byteCount += 8; + } + + // + // load in the remainder. + // + while (length > 0) + { + Update(input[inOff]); + + inOff++; + length--; + } + } + + private void RoundABC( + long x, + long mul) + { + c ^= x ; + a -= t1[(int)c & 0xff] ^ t2[(int)(c >> 16) & 0xff] + ^ t3[(int)(c >> 32) & 0xff] ^ t4[(int)(c >> 48) & 0xff]; + b += t4[(int)(c >> 8) & 0xff] ^ t3[(int)(c >> 24) & 0xff] + ^ t2[(int)(c >> 40) & 0xff] ^ t1[(int)(c >> 56) & 0xff]; + b *= mul; + } + + private void RoundBCA( + long x, + long mul) + { + a ^= x ; + b -= t1[(int)a & 0xff] ^ t2[(int)(a >> 16) & 0xff] + ^ t3[(int)(a >> 32) & 0xff] ^ t4[(int)(a >> 48) & 0xff]; + c += t4[(int)(a >> 8) & 0xff] ^ t3[(int)(a >> 24) & 0xff] + ^ t2[(int)(a >> 40) & 0xff] ^ t1[(int)(a >> 56) & 0xff]; + c *= mul; + } + + private void RoundCAB( + long x, + long mul) + { + b ^= x ; + c -= t1[(int)b & 0xff] ^ t2[(int)(b >> 16) & 0xff] + ^ t3[(int)(b >> 32) & 0xff] ^ t4[(int)(b >> 48) & 0xff]; + a += t4[(int)(b >> 8) & 0xff] ^ t3[(int)(b >> 24) & 0xff] + ^ t2[(int)(b >> 40) & 0xff] ^ t1[(int)(b >> 56) & 0xff]; + a *= mul; + } + + private void KeySchedule() + { + x[0] -= x[7] ^ unchecked ((long) 0xA5A5A5A5A5A5A5A5L); + x[1] ^= x[0]; + x[2] += x[1]; + x[3] -= x[2] ^ ((~x[1]) << 19); + x[4] ^= x[3]; + x[5] += x[4]; + x[6] -= x[5] ^ (long) ((ulong) (~x[4]) >> 23); + x[7] ^= x[6]; + x[0] += x[7]; + x[1] -= x[0] ^ ((~x[7]) << 19); + x[2] ^= x[1]; + x[3] += x[2]; + x[4] -= x[3] ^ (long) ((ulong) (~x[2]) >> 23); + x[5] ^= x[4]; + x[6] += x[5]; + x[7] -= x[6] ^ 0x0123456789ABCDEFL; + } + + private void ProcessBlock() + { + // + // save abc + // + long aa = a; + long bb = b; + long cc = c; + + // + // rounds and schedule + // + RoundABC(x[0], 5); + RoundBCA(x[1], 5); + RoundCAB(x[2], 5); + RoundABC(x[3], 5); + RoundBCA(x[4], 5); + RoundCAB(x[5], 5); + RoundABC(x[6], 5); + RoundBCA(x[7], 5); + + KeySchedule(); + + RoundCAB(x[0], 7); + RoundABC(x[1], 7); + RoundBCA(x[2], 7); + RoundCAB(x[3], 7); + RoundABC(x[4], 7); + RoundBCA(x[5], 7); + RoundCAB(x[6], 7); + RoundABC(x[7], 7); + + KeySchedule(); + + RoundBCA(x[0], 9); + RoundCAB(x[1], 9); + RoundABC(x[2], 9); + RoundBCA(x[3], 9); + RoundCAB(x[4], 9); + RoundABC(x[5], 9); + RoundBCA(x[6], 9); + RoundCAB(x[7], 9); + + // + // feed forward + // + a ^= aa; + b -= bb; + c += cc; + + // + // clear the x buffer + // + xOff = 0; + for (int i = 0; i != x.Length; i++) + { + x[i] = 0; + } + } + + private void UnpackWord( + long r, + byte[] output, + int outOff) + { + output[outOff + 7] = (byte)(r >> 56); + output[outOff + 6] = (byte)(r >> 48); + output[outOff + 5] = (byte)(r >> 40); + output[outOff + 4] = (byte)(r >> 32); + output[outOff + 3] = (byte)(r >> 24); + output[outOff + 2] = (byte)(r >> 16); + output[outOff + 1] = (byte)(r >> 8); + output[outOff] = (byte)r; + } + + private void ProcessLength( + long bitLength) + { + x[7] = bitLength; + } + + private void Finish() + { + long bitLength = (byteCount << 3); + + Update((byte)0x01); + + while (bOff != 0) + { + Update((byte)0); + } + + ProcessLength(bitLength); + + ProcessBlock(); + } + + public int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(a, output, outOff); + UnpackWord(b, output, outOff + 8); + UnpackWord(c, output, outOff + 16); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public void Reset() + { + a = unchecked((long) 0x0123456789ABCDEFL); + b = unchecked((long) 0xFEDCBA9876543210L); + c = unchecked((long) 0xF096A5B4C3B2E187L); + + xOff = 0; + for (int i = 0; i != x.Length; i++) + { + x[i] = 0; + } + + bOff = 0; + for (int i = 0; i != Buffer.Length; i++) + { + Buffer[i] = 0; + } + + byteCount = 0; + } + } +} diff --git a/iTechSharp/srcbc/crypto/digests/WhirlpoolDigest.cs b/iTechSharp/srcbc/crypto/digests/WhirlpoolDigest.cs new file mode 100644 index 0000000..df83f45 --- /dev/null +++ b/iTechSharp/srcbc/crypto/digests/WhirlpoolDigest.cs @@ -0,0 +1,397 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Implementation of WhirlpoolDigest, based on Java source published by Barreto + * and Rijmen. + * + */ + public sealed class WhirlpoolDigest : IDigest + { + private const int BYTE_LENGTH = 64; + + private const int DIGEST_LENGTH_BYTES = 512 / 8; + private const int ROUNDS = 10; + private const int REDUCTION_POLYNOMIAL = 0x011d; // 2^8 + 2^4 + 2^3 + 2 + 1; + + private static readonly int[] SBOX = + { + 0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, + 0x60, 0xbc, 0x9b, 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, 0xfe, 0x57, + 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, + 0xbd, 0x5d, 0x10, 0xf4, 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, 0xd8, + 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33, + 0x63, 0x02, 0xaa, 0x71, 0xc8, 0x19, 0x49, 0xd9, 0xf2, 0xe3, 0x5b, 0x88, 0x9a, 0x26, 0x32, 0xb0, + 0xe9, 0x0f, 0xd5, 0x80, 0xbe, 0xcd, 0x34, 0x48, 0xff, 0x7a, 0x90, 0x5f, 0x20, 0x68, 0x1a, 0xae, + 0xb4, 0x54, 0x93, 0x22, 0x64, 0xf1, 0x73, 0x12, 0x40, 0x08, 0xc3, 0xec, 0xdb, 0xa1, 0x8d, 0x3d, + 0x97, 0x00, 0xcf, 0x2b, 0x76, 0x82, 0xd6, 0x1b, 0xb5, 0xaf, 0x6a, 0x50, 0x45, 0xf3, 0x30, 0xef, + 0x3f, 0x55, 0xa2, 0xea, 0x65, 0xba, 0x2f, 0xc0, 0xde, 0x1c, 0xfd, 0x4d, 0x92, 0x75, 0x06, 0x8a, + 0xb2, 0xe6, 0x0e, 0x1f, 0x62, 0xd4, 0xa8, 0x96, 0xf9, 0xc5, 0x25, 0x59, 0x84, 0x72, 0x39, 0x4c, + 0x5e, 0x78, 0x38, 0x8c, 0xd1, 0xa5, 0xe2, 0x61, 0xb3, 0x21, 0x9c, 0x1e, 0x43, 0xc7, 0xfc, 0x04, + 0x51, 0x99, 0x6d, 0x0d, 0xfa, 0xdf, 0x7e, 0x24, 0x3b, 0xab, 0xce, 0x11, 0x8f, 0x4e, 0xb7, 0xeb, + 0x3c, 0x81, 0x94, 0xf7, 0xb9, 0x13, 0x2c, 0xd3, 0xe7, 0x6e, 0xc4, 0x03, 0x56, 0x44, 0x7f, 0xa9, + 0x2a, 0xbb, 0xc1, 0x53, 0xdc, 0x0b, 0x9d, 0x6c, 0x31, 0x74, 0xf6, 0x46, 0xac, 0x89, 0x14, 0xe1, + 0x16, 0x3a, 0x69, 0x09, 0x70, 0xb6, 0xd0, 0xed, 0xcc, 0x42, 0x98, 0xa4, 0x28, 0x5c, 0xf8, 0x86 + }; + + private static readonly long[] C0 = new long[256]; + private static readonly long[] C1 = new long[256]; + private static readonly long[] C2 = new long[256]; + private static readonly long[] C3 = new long[256]; + private static readonly long[] C4 = new long[256]; + private static readonly long[] C5 = new long[256]; + private static readonly long[] C6 = new long[256]; + private static readonly long[] C7 = new long[256]; + + private readonly long[] _rc = new long[ROUNDS + 1]; + + /* + * increment() can be implemented in this way using 2 arrays or + * by having some temporary variables that are used to set the + * value provided by EIGHT[i] and carry within the loop. + * + * not having done any timing, this seems likely to be faster + * at the slight expense of 32*(sizeof short) bytes + */ + private static readonly short[] EIGHT = new short[BITCOUNT_ARRAY_SIZE]; + + static WhirlpoolDigest() + { + EIGHT[BITCOUNT_ARRAY_SIZE - 1] = 8; + + for (int i = 0; i < 256; i++) + { + int v1 = SBOX[i]; + int v2 = maskWithReductionPolynomial(v1 << 1); + int v4 = maskWithReductionPolynomial(v2 << 1); + int v5 = v4 ^ v1; + int v8 = maskWithReductionPolynomial(v4 << 1); + int v9 = v8 ^ v1; + + C0[i] = packIntoLong(v1, v1, v4, v1, v8, v5, v2, v9); + C1[i] = packIntoLong(v9, v1, v1, v4, v1, v8, v5, v2); + C2[i] = packIntoLong(v2, v9, v1, v1, v4, v1, v8, v5); + C3[i] = packIntoLong(v5, v2, v9, v1, v1, v4, v1, v8); + C4[i] = packIntoLong(v8, v5, v2, v9, v1, v1, v4, v1); + C5[i] = packIntoLong(v1, v8, v5, v2, v9, v1, v1, v4); + C6[i] = packIntoLong(v4, v1, v8, v5, v2, v9, v1, v1); + C7[i] = packIntoLong(v1, v4, v1, v8, v5, v2, v9, v1); + } + } + + public WhirlpoolDigest() + { + _rc[0] = 0L; + for (int r = 1; r <= ROUNDS; r++) + { + int i = 8 * (r - 1); + _rc[r] = (long)((ulong)C0[i] & 0xff00000000000000L) ^ + (C1[i + 1] & (long) 0x00ff000000000000L) ^ + (C2[i + 2] & (long) 0x0000ff0000000000L) ^ + (C3[i + 3] & (long) 0x000000ff00000000L) ^ + (C4[i + 4] & (long) 0x00000000ff000000L) ^ + (C5[i + 5] & (long) 0x0000000000ff0000L) ^ + (C6[i + 6] & (long) 0x000000000000ff00L) ^ + (C7[i + 7] & (long) 0x00000000000000ffL); + } + } + + private static long packIntoLong(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0) + { + return + ((long)b7 << 56) ^ + ((long)b6 << 48) ^ + ((long)b5 << 40) ^ + ((long)b4 << 32) ^ + ((long)b3 << 24) ^ + ((long)b2 << 16) ^ + ((long)b1 << 8) ^ + b0; + } + + /* + * int's are used to prevent sign extension. The values that are really being used are + * actually just 0..255 + */ + private static int maskWithReductionPolynomial(int input) + { + int rv = input; + if (rv >= 0x100L) // high bit set + { + rv ^= REDUCTION_POLYNOMIAL; // reduced by the polynomial + } + return rv; + } + + // --------------------------------------------------------------------------------------// + + // -- buffer information -- + private const int BITCOUNT_ARRAY_SIZE = 32; + private byte[] _buffer = new byte[64]; + private int _bufferPos; + private short[] _bitCount = new short[BITCOUNT_ARRAY_SIZE]; + + // -- internal hash state -- + private long[] _hash = new long[8]; + private long[] _K = new long[8]; // the round key + private long[] _L = new long[8]; + private long[] _block = new long[8]; // mu (buffer) + private long[] _state = new long[8]; // the current "cipher" state + + + + /** + * Copy constructor. This will copy the state of the provided message + * digest. + */ + public WhirlpoolDigest(WhirlpoolDigest originalDigest) + { + Array.Copy(originalDigest._rc, 0, _rc, 0, _rc.Length); + + Array.Copy(originalDigest._buffer, 0, _buffer, 0, _buffer.Length); + + this._bufferPos = originalDigest._bufferPos; + Array.Copy(originalDigest._bitCount, 0, _bitCount, 0, _bitCount.Length); + + // -- internal hash state -- + Array.Copy(originalDigest._hash, 0, _hash, 0, _hash.Length); + Array.Copy(originalDigest._K, 0, _K, 0, _K.Length); + Array.Copy(originalDigest._L, 0, _L, 0, _L.Length); + Array.Copy(originalDigest._block, 0, _block, 0, _block.Length); + Array.Copy(originalDigest._state, 0, _state, 0, _state.Length); + } + + public string AlgorithmName + { + get { return "Whirlpool"; } + } + + public int GetDigestSize() + { + return DIGEST_LENGTH_BYTES; + } + + public int DoFinal(byte[] output, int outOff) + { + // sets output[outOff] .. output[outOff+DIGEST_LENGTH_BYTES] + finish(); + + for (int i = 0; i < 8; i++) + { + convertLongToByteArray(_hash[i], output, outOff + (i * 8)); + } + + Reset(); + + return GetDigestSize(); + } + + /** + * Reset the chaining variables + */ + public void Reset() + { + // set variables to null, blank, whatever + _bufferPos = 0; + Array.Clear(_bitCount, 0, _bitCount.Length); + Array.Clear(_buffer, 0, _buffer.Length); + Array.Clear(_hash, 0, _hash.Length); + Array.Clear(_K, 0, _K.Length); + Array.Clear(_L, 0, _L.Length); + Array.Clear(_block, 0, _block.Length); + Array.Clear(_state, 0, _state.Length); + } + + // this takes a buffer of information and fills the block + private void processFilledBuffer() + { + // copies into the block... + for (int i = 0; i < _state.Length; i++) + { + _block[i] = bytesToLongFromBuffer(_buffer, i * 8); + } + processBlock(); + _bufferPos = 0; + Array.Clear(_buffer, 0, _buffer.Length); + } + + private static long bytesToLongFromBuffer(byte[] buffer, int startPos) + { + long rv = (((buffer[startPos + 0] & 0xffL) << 56) | + ((buffer[startPos + 1] & 0xffL) << 48) | + ((buffer[startPos + 2] & 0xffL) << 40) | + ((buffer[startPos + 3] & 0xffL) << 32) | + ((buffer[startPos + 4] & 0xffL) << 24) | + ((buffer[startPos + 5] & 0xffL) << 16) | + ((buffer[startPos + 6] & 0xffL) << 8) | + ((buffer[startPos + 7]) & 0xffL)); + + return rv; + } + + private static void convertLongToByteArray(long inputLong, byte[] outputArray, int offSet) + { + for (int i = 0; i < 8; i++) + { + outputArray[offSet + i] = (byte)((inputLong >> (56 - (i * 8))) & 0xff); + } + } + + private void processBlock() + { + // buffer contents have been transferred to the _block[] array via + // processFilledBuffer + + // compute and apply K^0 + for (int i = 0; i < 8; i++) + { + _state[i] = _block[i] ^ (_K[i] = _hash[i]); + } + + // iterate over the rounds + for (int round = 1; round <= ROUNDS; round++) + { + for (int i = 0; i < 8; i++) + { + _L[i] = 0; + _L[i] ^= C0[(int)(_K[(i - 0) & 7] >> 56) & 0xff]; + _L[i] ^= C1[(int)(_K[(i - 1) & 7] >> 48) & 0xff]; + _L[i] ^= C2[(int)(_K[(i - 2) & 7] >> 40) & 0xff]; + _L[i] ^= C3[(int)(_K[(i - 3) & 7] >> 32) & 0xff]; + _L[i] ^= C4[(int)(_K[(i - 4) & 7] >> 24) & 0xff]; + _L[i] ^= C5[(int)(_K[(i - 5) & 7] >> 16) & 0xff]; + _L[i] ^= C6[(int)(_K[(i - 6) & 7] >> 8) & 0xff]; + _L[i] ^= C7[(int)(_K[(i - 7) & 7]) & 0xff]; + } + + Array.Copy(_L, 0, _K, 0, _K.Length); + + _K[0] ^= _rc[round]; + + // apply the round transformation + for (int i = 0; i < 8; i++) + { + _L[i] = _K[i]; + + _L[i] ^= C0[(int)(_state[(i - 0) & 7] >> 56) & 0xff]; + _L[i] ^= C1[(int)(_state[(i - 1) & 7] >> 48) & 0xff]; + _L[i] ^= C2[(int)(_state[(i - 2) & 7] >> 40) & 0xff]; + _L[i] ^= C3[(int)(_state[(i - 3) & 7] >> 32) & 0xff]; + _L[i] ^= C4[(int)(_state[(i - 4) & 7] >> 24) & 0xff]; + _L[i] ^= C5[(int)(_state[(i - 5) & 7] >> 16) & 0xff]; + _L[i] ^= C6[(int)(_state[(i - 6) & 7] >> 8) & 0xff]; + _L[i] ^= C7[(int)(_state[(i - 7) & 7]) & 0xff]; + } + + // save the current state + Array.Copy(_L, 0, _state, 0, _state.Length); + } + + // apply Miuaguchi-Preneel compression + for (int i = 0; i < 8; i++) + { + _hash[i] ^= _state[i] ^ _block[i]; + } + + } + + public void Update(byte input) + { + _buffer[_bufferPos] = input; + + //Console.WriteLine("adding to buffer = "+_buffer[_bufferPos]); + + ++_bufferPos; + + if (_bufferPos == _buffer.Length) + { + processFilledBuffer(); + } + + increment(); + } + + private void increment() + { + int carry = 0; + for (int i = _bitCount.Length - 1; i >= 0; i--) + { + int sum = (_bitCount[i] & 0xff) + EIGHT[i] + carry; + + carry = sum >> 8; + _bitCount[i] = (short)(sum & 0xff); + } + } + + public void BlockUpdate(byte[] input, int inOff, int length) + { + while (length > 0) + { + Update(input[inOff]); + ++inOff; + --length; + } + + } + + private void finish() + { + /* + * this makes a copy of the current bit length. at the expense of an + * object creation of 32 bytes rather than providing a _stopCounting + * boolean which was the alternative I could think of. + */ + byte[] bitLength = copyBitLength(); + + _buffer[_bufferPos++] |= 0x80; + + if (_bufferPos == _buffer.Length) + { + processFilledBuffer(); + } + + /* + * Final block contains + * [ ... data .... ][0][0][0][ length ] + * + * if [ length ] cannot fit. Need to create a new block. + */ + if (_bufferPos > 32) + { + while (_bufferPos != 0) + { + Update((byte)0); + } + } + + while (_bufferPos <= 32) + { + Update((byte)0); + } + + // copy the length information to the final 32 bytes of the + // 64 byte block.... + Array.Copy(bitLength, 0, _buffer, 32, bitLength.Length); + + processFilledBuffer(); + } + + private byte[] copyBitLength() + { + byte[] rv = new byte[BITCOUNT_ARRAY_SIZE]; + for (int i = 0; i < rv.Length; i++) + { + rv[i] = (byte)(_bitCount[i] & 0xff); + } + return rv; + } + + public int GetByteLength() + { + return BYTE_LENGTH; + } + } +} diff --git a/iTechSharp/srcbc/crypto/encodings/ISO9796d1Encoding.cs b/iTechSharp/srcbc/crypto/encodings/ISO9796d1Encoding.cs new file mode 100644 index 0000000..586a5b9 --- /dev/null +++ b/iTechSharp/srcbc/crypto/encodings/ISO9796d1Encoding.cs @@ -0,0 +1,253 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * ISO 9796-1 padding. Note in the light of recent results you should + * only use this with RSA (rather than the "simpler" Rabin keys) and you + * should never use it with anything other than a hash (ie. even if the + * message is small don't sign the message, sign it's hash) or some "random" + * value. See your favorite search engine for details. + */ + public class ISO9796d1Encoding + : IAsymmetricBlockCipher + { + private static readonly byte[] shadows = { 0xe, 0x3, 0x5, 0x8, 0x9, 0x4, 0x2, 0xf, + 0x0, 0xd, 0xb, 0x6, 0x7, 0xa, 0xc, 0x1 }; + private static readonly byte[] inverse = { 0x8, 0xf, 0x6, 0x1, 0x5, 0x2, 0xb, 0xc, + 0x3, 0x4, 0xd, 0xa, 0xe, 0x9, 0x0, 0x7 }; + + private readonly IAsymmetricBlockCipher engine; + private bool forEncryption; + private int bitSize; + private int padBits = 0; + + public ISO9796d1Encoding( + IAsymmetricBlockCipher cipher) + { + this.engine = cipher; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/ISO9796-1Padding"; } + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + RsaKeyParameters kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + kParam = (RsaKeyParameters)rParam.Parameters; + } + else + { + kParam = (RsaKeyParameters)parameters; + } + + engine.Init(forEncryption, parameters); + + bitSize = kParam.Modulus.BitLength; + + this.forEncryption = forEncryption; + } + + /** + * return the input block size. The largest message we can process + * is (key_size_in_bits + 3)/16, which in our world comes to + * key_size_in_bytes / 2. + */ + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + if (forEncryption) + { + return (baseBlockSize + 1) / 2; + } + else + { + return baseBlockSize; + } + } + + /** + * return the maximum possible size for the output. + */ + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + if (forEncryption) + { + return baseBlockSize; + } + else + { + return (baseBlockSize + 1) / 2; + } + } + + /** + * set the number of bits in the next message to be treated as + * pad bits. + */ + public void SetPadBits( + int padBits) + { + if (padBits > 7) + { + throw new ArgumentException("padBits > 7"); + } + + this.padBits = padBits; + } + + /** + * retrieve the number of pad bits in the last decoded message. + */ + public int GetPadBits() + { + return padBits; + } + + public byte[] ProcessBlock( + byte[] input, + int inOff, + int length) + { + if (forEncryption) + { + return EncodeBlock(input, inOff, length); + } + else + { + return DecodeBlock(input, inOff, length); + } + } + + private byte[] EncodeBlock( + byte[] input, + int inOff, + int inLen) + { + byte[] block = new byte[(bitSize + 7) / 8]; + int r = padBits + 1; + int z = inLen; + int t = (bitSize + 13) / 16; + + for (int i = 0; i < t; i += z) + { + if (i > t - z) + { + Array.Copy(input, inOff + inLen - (t - i), + block, block.Length - t, t - i); + } + else + { + Array.Copy(input, inOff, block, block.Length - (i + z), z); + } + } + + for (int i = block.Length - 2 * t; i != block.Length; i += 2) + { + byte val = block[block.Length - t + i / 2]; + + block[i] = (byte)((shadows[(uint) (val & 0xff) >> 4] << 4) + | shadows[val & 0x0f]); + block[i + 1] = val; + } + + block[block.Length - 2 * z] ^= (byte) r; + block[block.Length - 1] = (byte)((block[block.Length - 1] << 4) | 0x06); + + int maxBit = (8 - (bitSize - 1) % 8); + int offSet = 0; + + if (maxBit != 8) + { + block[0] &= (byte) ((ushort) 0xff >> maxBit); + block[0] |= (byte) ((ushort) 0x80 >> maxBit); + } + else + { + block[0] = 0x00; + block[1] |= 0x80; + offSet = 1; + } + + return engine.ProcessBlock(block, offSet, block.Length - offSet); + } + + /** + * @exception InvalidCipherTextException if the decrypted block is not a valid ISO 9796 bit string + */ + private byte[] DecodeBlock( + byte[] input, + int inOff, + int inLen) + { + byte[] block = engine.ProcessBlock(input, inOff, inLen); + int r = 1; + int t = (bitSize + 13) / 16; + + if ((block[block.Length - 1] & 0x0f) != 0x6) + { + throw new InvalidCipherTextException("invalid forcing byte in block"); + } + + block[block.Length - 1] = + (byte)(((ushort)(block[block.Length - 1] & 0xff) >> 4) + | ((inverse[(block[block.Length - 2] & 0xff) >> 4]) << 4)); + + block[0] = (byte)((shadows[(uint) (block[1] & 0xff) >> 4] << 4) + | shadows[block[1] & 0x0f]); + + bool boundaryFound = false; + int boundary = 0; + + for (int i = block.Length - 1; i >= block.Length - 2 * t; i -= 2) + { + int val = ((shadows[(uint) (block[i] & 0xff) >> 4] << 4) + | shadows[block[i] & 0x0f]); + + if (((block[i - 1] ^ val) & 0xff) != 0) + { + if (!boundaryFound) + { + boundaryFound = true; + r = (block[i - 1] ^ val) & 0xff; + boundary = i - 1; + } + else + { + throw new InvalidCipherTextException("invalid tsums in block"); + } + } + } + + block[boundary] = 0; + + byte[] nblock = new byte[(block.Length - boundary) / 2]; + + for (int i = 0; i < nblock.Length; i++) + { + nblock[i] = block[2 * i + boundary + 1]; + } + + padBits = r - 1; + + return nblock; + } + } +} diff --git a/iTechSharp/srcbc/crypto/encodings/OaepEncoding.cs b/iTechSharp/srcbc/crypto/encodings/OaepEncoding.cs new file mode 100644 index 0000000..aff4a79 --- /dev/null +++ b/iTechSharp/srcbc/crypto/encodings/OaepEncoding.cs @@ -0,0 +1,334 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2. + */ + public class OaepEncoding + : IAsymmetricBlockCipher + { + private byte[] defHash; + private IDigest hash; + + private IAsymmetricBlockCipher engine; + private SecureRandom random; + private bool forEncryption; + + public OaepEncoding( + IAsymmetricBlockCipher cipher) + : this(cipher, new Sha1Digest(), null) + { + } + + public OaepEncoding( + IAsymmetricBlockCipher cipher, + IDigest hash) + : this(cipher, hash, null) + { + } + + public OaepEncoding( + IAsymmetricBlockCipher cipher, + IDigest hash, + byte[] encodingParams) + { + this.engine = cipher; + this.hash = hash; + this.defHash = new byte[hash.GetDigestSize()]; + + if (encodingParams != null) + { + hash.BlockUpdate(encodingParams, 0, encodingParams.Length); + } + + hash.DoFinal(defHash, 0); + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/OAEPPadding"; } + } + + public void Init( + bool forEncryption, + ICipherParameters param) + { + if (param is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + this.random = rParam.Random; + } + else + { + this.random = new SecureRandom(); + } + + engine.Init(forEncryption, param); + + this.forEncryption = forEncryption; + } + + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + if (forEncryption) + { + return baseBlockSize - 1 - 2 * defHash.Length; + } + else + { + return baseBlockSize; + } + } + + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + if (forEncryption) + { + return baseBlockSize; + } + else + { + return baseBlockSize - 1 - 2 * defHash.Length; + } + } + + public byte[] ProcessBlock( + byte[] inBytes, + int inOff, + int inLen) + { + if (forEncryption) + { + return encodeBlock(inBytes, inOff, inLen); + } + else + { + return decodeBlock(inBytes, inOff, inLen); + } + } + + private byte[] encodeBlock( + byte[] inBytes, + int inOff, + int inLen) + { + byte[] block = new byte[GetInputBlockSize() + 1 + 2 * defHash.Length]; + + // + // copy in the message + // + Array.Copy(inBytes, inOff, block, block.Length - inLen, inLen); + + // + // add sentinel + // + block[block.Length - inLen - 1] = 0x01; + + // + // as the block is already zeroed - there's no need to add PS (the >= 0 pad of 0) + // + + // + // add the hash of the encoding params. + // + Array.Copy(defHash, 0, block, defHash.Length, defHash.Length); + + // + // generate the seed. + // + byte[] seed = random.GenerateSeed(defHash.Length); + + // + // mask the message block. + // + byte[] mask = maskGeneratorFunction1(seed, 0, seed.Length, block.Length - defHash.Length); + + for (int i = defHash.Length; i != block.Length; i++) + { + block[i] ^= mask[i - defHash.Length]; + } + + // + // add in the seed + // + Array.Copy(seed, 0, block, 0, defHash.Length); + + // + // mask the seed. + // + mask = maskGeneratorFunction1( + block, defHash.Length, block.Length - defHash.Length, defHash.Length); + + for (int i = 0; i != defHash.Length; i++) + { + block[i] ^= mask[i]; + } + + return engine.ProcessBlock(block, 0, block.Length); + } + + /** + * @exception InvalidCipherTextException if the decrypted block turns out to + * be badly formatted. + */ + private byte[] decodeBlock( + byte[] inBytes, + int inOff, + int inLen) + { + byte[] data = engine.ProcessBlock(inBytes, inOff, inLen); + byte[] block = null; + + // + // as we may have zeros in our leading bytes for the block we produced + // on encryption, we need to make sure our decrypted block comes back + // the same size. + // + if (data.Length < engine.GetOutputBlockSize()) + { + block = new byte[engine.GetOutputBlockSize()]; + + Array.Copy(data, 0, block, block.Length - data.Length, data.Length); + } + else + { + block = data; + } + + if (block.Length < (2 * defHash.Length) + 1) + { + throw new InvalidCipherTextException("data too short"); + } + + // + // unmask the seed. + // + byte[] mask = maskGeneratorFunction1( + block, defHash.Length, block.Length - defHash.Length, defHash.Length); + + for (int i = 0; i != defHash.Length; i++) + { + block[i] ^= mask[i]; + } + + // + // unmask the message block. + // + mask = maskGeneratorFunction1(block, 0, defHash.Length, block.Length - defHash.Length); + + for (int i = defHash.Length; i != block.Length; i++) + { + block[i] ^= mask[i - defHash.Length]; + } + + // + // check the hash of the encoding params. + // + for (int i = 0; i != defHash.Length; i++) + { + if (defHash[i] != block[defHash.Length + i]) + { + throw new InvalidCipherTextException("data hash wrong"); + } + } + + // + // find the data block + // + int start; + for (start = 2 * defHash.Length; start != block.Length; start++) + { + if (block[start] == 1 || block[start] != 0) + { + break; + } + } + + if (start >= (block.Length - 1) || block[start] != 1) + { + throw new InvalidCipherTextException("data start wrong " + start); + } + + start++; + + // + // extract the data block + // + byte[] output = new byte[block.Length - start]; + + Array.Copy(block, start, output, 0, output.Length); + + return output; + } + + /** + * int to octet string. + */ + private void ItoOSP( + int i, + byte[] sp) + { + sp[0] = (byte)((uint)i >> 24); + sp[1] = (byte)((uint)i >> 16); + sp[2] = (byte)((uint)i >> 8); + sp[3] = (byte)((uint)i >> 0); + } + + /** + * mask generator function, as described in PKCS1v2. + */ + private byte[] maskGeneratorFunction1( + byte[] Z, + int zOff, + int zLen, + int length) + { + byte[] mask = new byte[length]; + byte[] hashBuf = new byte[defHash.Length]; + byte[] C = new byte[4]; + int counter = 0; + + hash.Reset(); + + do + { + ItoOSP(counter, C); + + hash.BlockUpdate(Z, zOff, zLen); + hash.BlockUpdate(C, 0, C.Length); + hash.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * defHash.Length, defHash.Length); + } + while (++counter < (length / defHash.Length)); + + if ((counter * defHash.Length) < length) + { + ItoOSP(counter, C); + + hash.BlockUpdate(Z, zOff, zLen); + hash.BlockUpdate(C, 0, C.Length); + hash.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * defHash.Length, mask.Length - (counter * defHash.Length)); + } + + return mask; + } + } +} + diff --git a/iTechSharp/srcbc/crypto/encodings/Pkcs1Encoding.cs b/iTechSharp/srcbc/crypto/encodings/Pkcs1Encoding.cs new file mode 100644 index 0000000..f8204c2 --- /dev/null +++ b/iTechSharp/srcbc/crypto/encodings/Pkcs1Encoding.cs @@ -0,0 +1,229 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * this does your basic Pkcs 1 v1.5 padding - whether or not you should be using this + * depends on your application - see Pkcs1 Version 2 for details. + */ + public class Pkcs1Encoding + : IAsymmetricBlockCipher + { + /** + * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to + * work with one of these set the system property Org.BouncyCastle.Pkcs1.Strict to false. + */ + public const string StrictLengthEnabledProperty = "Org.BouncyCastle.Pkcs1.Strict"; + + private const int HeaderLength = 10; + + /** + * The same effect can be achieved by setting the static property directly + *
+ * The static property is checked during construction of the encoding object, it is set to + * true by default. + *
+ */ + public static bool StrictLengthEnabled + { + get { return strictLengthEnabled[0]; } + set { strictLengthEnabled[0] = value; } + } + + private static readonly bool[] strictLengthEnabled; + + static Pkcs1Encoding() + { + string strictProperty = Platform.GetEnvironmentVariable(StrictLengthEnabledProperty); + + strictLengthEnabled = new bool[]{ strictProperty == null || strictProperty.Equals("true")}; + } + + + private SecureRandom random; + private IAsymmetricBlockCipher engine; + private bool forEncryption; + private bool forPrivateKey; + private bool useStrictLength; + + /** + * Basic constructor. + * @param cipher + */ + public Pkcs1Encoding( + IAsymmetricBlockCipher cipher) + { + this.engine = cipher; + this.useStrictLength = StrictLengthEnabled; + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/PKCS1Padding"; } + } + + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + AsymmetricKeyParameter kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + kParam = (AsymmetricKeyParameter)rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + kParam = (AsymmetricKeyParameter)parameters; + } + + engine.Init(forEncryption, parameters); + + this.forPrivateKey = kParam.IsPrivate; + this.forEncryption = forEncryption; + } + + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + return forEncryption + ? baseBlockSize - HeaderLength + : baseBlockSize; + } + + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + return forEncryption + ? baseBlockSize + : baseBlockSize - HeaderLength; + } + + public byte[] ProcessBlock( + byte[] input, + int inOff, + int length) + { + return forEncryption + ? EncodeBlock(input, inOff, length) + : DecodeBlock(input, inOff, length); + } + + private byte[] EncodeBlock( + byte[] input, + int inOff, + int inLen) + { + byte[] block = new byte[engine.GetInputBlockSize()]; + + if (forPrivateKey) + { + block[0] = 0x01; // type code 1 + + for (int i = 1; i != block.Length - inLen - 1; i++) + { + block[i] = (byte)0xFF; + } + } + else + { + random.NextBytes(block); // random fill + + block[0] = 0x02; // type code 2 + + // + // a zero byte marks the end of the padding, so all + // the pad bytes must be non-zero. + // + for (int i = 1; i != block.Length - inLen - 1; i++) + { + while (block[i] == 0) + { + block[i] = (byte)random.NextInt(); + } + } + } + + block[block.Length - inLen - 1] = 0x00; // mark the end of the padding + Array.Copy(input, inOff, block, block.Length - inLen, inLen); + + return engine.ProcessBlock(block, 0, block.Length); + } + + /** + * @exception InvalidCipherTextException if the decrypted block is not in Pkcs1 format. + */ + private byte[] DecodeBlock( + byte[] input, + int inOff, + int inLen) + { + byte[] block = engine.ProcessBlock(input, inOff, inLen); + + if (block.Length < GetOutputBlockSize()) + { + throw new InvalidCipherTextException("block truncated"); + } + + byte type = block[0]; + + if (type != 1 && type != 2) + { + throw new InvalidCipherTextException("unknown block type"); + } + + if (useStrictLength && block.Length != engine.GetOutputBlockSize()) + { + throw new InvalidCipherTextException("block incorrect size"); + } + + // + // find and extract the message block. + // + int start; + for (start = 1; start != block.Length; start++) + { + byte pad = block[start]; + + if (pad == 0) + { + break; + } + + if (type == 1 && pad != (byte)0xff) + { + throw new InvalidCipherTextException("block padding incorrect"); + } + } + + start++; // data should start at the next byte + + if (start >= block.Length || start < HeaderLength) + { + throw new InvalidCipherTextException("no data in block"); + } + + byte[] result = new byte[block.Length - start]; + + Array.Copy(block, start, result, 0, result.Length); + + return result; + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/AesEngine.cs b/iTechSharp/srcbc/crypto/engines/AesEngine.cs new file mode 100644 index 0000000..676d7dd --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/AesEngine.cs @@ -0,0 +1,550 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + + /** + * an implementation of the AES (Rijndael), from FIPS-197. + *+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor, they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first. + * + * The slowest version uses no static tables at all and computes the values in each round. + *
+ *+ * This file contains the middle performance version with 2Kbytes of static tables for round precomputation. + *
+ */ + public class AesEngine + : IBlockCipher + { + // The S box + private static readonly byte[] S = + { + 99, 124, 119, 123, 242, 107, 111, 197, + 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, + 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, + 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, + 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, + 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, + 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, + 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, + 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, + 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, + 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, + 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, + 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, + 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, + 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, + 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, + 65, 153, 45, 15, 176, 84, 187, 22, + }; + + // The inverse S-box + private static readonly byte[] Si = + { + 82, 9, 106, 213, 48, 54, 165, 56, + 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, + 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, + 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, + 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, + 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, + 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, + 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, + 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, + 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, + 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, + 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, + 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, + 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, + 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, + 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, + 225, 105, 20, 99, 85, 33, 12, 125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static readonly int[] rcon = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; + + // precomputation tables of calculations for rounds + private static readonly int[] T0 = + { + unchecked((int) 0xa56363c6), unchecked((int) 0x847c7cf8), unchecked((int) 0x997777ee), unchecked((int) 0x8d7b7bf6), unchecked((int) 0x0df2f2ff), + unchecked((int) 0xbd6b6bd6), unchecked((int) 0xb16f6fde), unchecked((int) 0x54c5c591), unchecked((int) 0x50303060), unchecked((int) 0x03010102), + unchecked((int) 0xa96767ce), unchecked((int) 0x7d2b2b56), unchecked((int) 0x19fefee7), unchecked((int) 0x62d7d7b5), unchecked((int) 0xe6abab4d), + unchecked((int) 0x9a7676ec), unchecked((int) 0x45caca8f), unchecked((int) 0x9d82821f), unchecked((int) 0x40c9c989), unchecked((int) 0x877d7dfa), + unchecked((int) 0x15fafaef), unchecked((int) 0xeb5959b2), unchecked((int) 0xc947478e), unchecked((int) 0x0bf0f0fb), unchecked((int) 0xecadad41), + unchecked((int) 0x67d4d4b3), unchecked((int) 0xfda2a25f), unchecked((int) 0xeaafaf45), unchecked((int) 0xbf9c9c23), unchecked((int) 0xf7a4a453), + unchecked((int) 0x967272e4), unchecked((int) 0x5bc0c09b), unchecked((int) 0xc2b7b775), unchecked((int) 0x1cfdfde1), unchecked((int) 0xae93933d), + unchecked((int) 0x6a26264c), unchecked((int) 0x5a36366c), unchecked((int) 0x413f3f7e), unchecked((int) 0x02f7f7f5), unchecked((int) 0x4fcccc83), + unchecked((int) 0x5c343468), unchecked((int) 0xf4a5a551), unchecked((int) 0x34e5e5d1), unchecked((int) 0x08f1f1f9), unchecked((int) 0x937171e2), + unchecked((int) 0x73d8d8ab), unchecked((int) 0x53313162), unchecked((int) 0x3f15152a), unchecked((int) 0x0c040408), unchecked((int) 0x52c7c795), + unchecked((int) 0x65232346), unchecked((int) 0x5ec3c39d), unchecked((int) 0x28181830), unchecked((int) 0xa1969637), unchecked((int) 0x0f05050a), + unchecked((int) 0xb59a9a2f), unchecked((int) 0x0907070e), unchecked((int) 0x36121224), unchecked((int) 0x9b80801b), unchecked((int) 0x3de2e2df), + unchecked((int) 0x26ebebcd), unchecked((int) 0x6927274e), unchecked((int) 0xcdb2b27f), unchecked((int) 0x9f7575ea), unchecked((int) 0x1b090912), + unchecked((int) 0x9e83831d), unchecked((int) 0x742c2c58), unchecked((int) 0x2e1a1a34), unchecked((int) 0x2d1b1b36), unchecked((int) 0xb26e6edc), + unchecked((int) 0xee5a5ab4), unchecked((int) 0xfba0a05b), unchecked((int) 0xf65252a4), unchecked((int) 0x4d3b3b76), unchecked((int) 0x61d6d6b7), + unchecked((int) 0xceb3b37d), unchecked((int) 0x7b292952), unchecked((int) 0x3ee3e3dd), unchecked((int) 0x712f2f5e), unchecked((int) 0x97848413), + unchecked((int) 0xf55353a6), unchecked((int) 0x68d1d1b9), unchecked((int) 0x00000000), unchecked((int) 0x2cededc1), unchecked((int) 0x60202040), + unchecked((int) 0x1ffcfce3), unchecked((int) 0xc8b1b179), unchecked((int) 0xed5b5bb6), unchecked((int) 0xbe6a6ad4), unchecked((int) 0x46cbcb8d), + unchecked((int) 0xd9bebe67), unchecked((int) 0x4b393972), unchecked((int) 0xde4a4a94), unchecked((int) 0xd44c4c98), unchecked((int) 0xe85858b0), + unchecked((int) 0x4acfcf85), unchecked((int) 0x6bd0d0bb), unchecked((int) 0x2aefefc5), unchecked((int) 0xe5aaaa4f), unchecked((int) 0x16fbfbed), + unchecked((int) 0xc5434386), unchecked((int) 0xd74d4d9a), unchecked((int) 0x55333366), unchecked((int) 0x94858511), unchecked((int) 0xcf45458a), + unchecked((int) 0x10f9f9e9), unchecked((int) 0x06020204), unchecked((int) 0x817f7ffe), unchecked((int) 0xf05050a0), unchecked((int) 0x443c3c78), + unchecked((int) 0xba9f9f25), unchecked((int) 0xe3a8a84b), unchecked((int) 0xf35151a2), unchecked((int) 0xfea3a35d), unchecked((int) 0xc0404080), + unchecked((int) 0x8a8f8f05), unchecked((int) 0xad92923f), unchecked((int) 0xbc9d9d21), unchecked((int) 0x48383870), unchecked((int) 0x04f5f5f1), + unchecked((int) 0xdfbcbc63), unchecked((int) 0xc1b6b677), unchecked((int) 0x75dadaaf), unchecked((int) 0x63212142), unchecked((int) 0x30101020), + unchecked((int) 0x1affffe5), unchecked((int) 0x0ef3f3fd), unchecked((int) 0x6dd2d2bf), unchecked((int) 0x4ccdcd81), unchecked((int) 0x140c0c18), + unchecked((int) 0x35131326), unchecked((int) 0x2fececc3), unchecked((int) 0xe15f5fbe), unchecked((int) 0xa2979735), unchecked((int) 0xcc444488), + unchecked((int) 0x3917172e), unchecked((int) 0x57c4c493), unchecked((int) 0xf2a7a755), unchecked((int) 0x827e7efc), unchecked((int) 0x473d3d7a), + unchecked((int) 0xac6464c8), unchecked((int) 0xe75d5dba), unchecked((int) 0x2b191932), unchecked((int) 0x957373e6), unchecked((int) 0xa06060c0), + unchecked((int) 0x98818119), unchecked((int) 0xd14f4f9e), unchecked((int) 0x7fdcdca3), unchecked((int) 0x66222244), unchecked((int) 0x7e2a2a54), + unchecked((int) 0xab90903b), unchecked((int) 0x8388880b), unchecked((int) 0xca46468c), unchecked((int) 0x29eeeec7), unchecked((int) 0xd3b8b86b), + unchecked((int) 0x3c141428), unchecked((int) 0x79dedea7), unchecked((int) 0xe25e5ebc), unchecked((int) 0x1d0b0b16), unchecked((int) 0x76dbdbad), + unchecked((int) 0x3be0e0db), unchecked((int) 0x56323264), unchecked((int) 0x4e3a3a74), unchecked((int) 0x1e0a0a14), unchecked((int) 0xdb494992), + unchecked((int) 0x0a06060c), unchecked((int) 0x6c242448), unchecked((int) 0xe45c5cb8), unchecked((int) 0x5dc2c29f), unchecked((int) 0x6ed3d3bd), + unchecked((int) 0xefacac43), unchecked((int) 0xa66262c4), unchecked((int) 0xa8919139), unchecked((int) 0xa4959531), unchecked((int) 0x37e4e4d3), + unchecked((int) 0x8b7979f2), unchecked((int) 0x32e7e7d5), unchecked((int) 0x43c8c88b), unchecked((int) 0x5937376e), unchecked((int) 0xb76d6dda), + unchecked((int) 0x8c8d8d01), unchecked((int) 0x64d5d5b1), unchecked((int) 0xd24e4e9c), unchecked((int) 0xe0a9a949), unchecked((int) 0xb46c6cd8), + unchecked((int) 0xfa5656ac), unchecked((int) 0x07f4f4f3), unchecked((int) 0x25eaeacf), unchecked((int) 0xaf6565ca), unchecked((int) 0x8e7a7af4), + unchecked((int) 0xe9aeae47), unchecked((int) 0x18080810), unchecked((int) 0xd5baba6f), unchecked((int) 0x887878f0), unchecked((int) 0x6f25254a), + unchecked((int) 0x722e2e5c), unchecked((int) 0x241c1c38), unchecked((int) 0xf1a6a657), unchecked((int) 0xc7b4b473), unchecked((int) 0x51c6c697), + unchecked((int) 0x23e8e8cb), unchecked((int) 0x7cdddda1), unchecked((int) 0x9c7474e8), unchecked((int) 0x211f1f3e), unchecked((int) 0xdd4b4b96), + unchecked((int) 0xdcbdbd61), unchecked((int) 0x868b8b0d), unchecked((int) 0x858a8a0f), unchecked((int) 0x907070e0), unchecked((int) 0x423e3e7c), + unchecked((int) 0xc4b5b571), unchecked((int) 0xaa6666cc), unchecked((int) 0xd8484890), unchecked((int) 0x05030306), unchecked((int) 0x01f6f6f7), + unchecked((int) 0x120e0e1c), unchecked((int) 0xa36161c2), unchecked((int) 0x5f35356a), unchecked((int) 0xf95757ae), unchecked((int) 0xd0b9b969), + unchecked((int) 0x91868617), unchecked((int) 0x58c1c199), unchecked((int) 0x271d1d3a), unchecked((int) 0xb99e9e27), unchecked((int) 0x38e1e1d9), + unchecked((int) 0x13f8f8eb), unchecked((int) 0xb398982b), unchecked((int) 0x33111122), unchecked((int) 0xbb6969d2), unchecked((int) 0x70d9d9a9), + unchecked((int) 0x898e8e07), unchecked((int) 0xa7949433), unchecked((int) 0xb69b9b2d), unchecked((int) 0x221e1e3c), unchecked((int) 0x92878715), + unchecked((int) 0x20e9e9c9), unchecked((int) 0x49cece87), unchecked((int) 0xff5555aa), unchecked((int) 0x78282850), unchecked((int) 0x7adfdfa5), + unchecked((int) 0x8f8c8c03), unchecked((int) 0xf8a1a159), unchecked((int) 0x80898909), unchecked((int) 0x170d0d1a), unchecked((int) 0xdabfbf65), + unchecked((int) 0x31e6e6d7), unchecked((int) 0xc6424284), unchecked((int) 0xb86868d0), unchecked((int) 0xc3414182), unchecked((int) 0xb0999929), + unchecked((int) 0x772d2d5a), unchecked((int) 0x110f0f1e), unchecked((int) 0xcbb0b07b), unchecked((int) 0xfc5454a8), unchecked((int) 0xd6bbbb6d), + unchecked((int) 0x3a16162c) + }; + + private static readonly int[] Tinv0 = + { + unchecked((int) 0x50a7f451), unchecked((int) 0x5365417e), unchecked((int) 0xc3a4171a), unchecked((int) 0x965e273a), unchecked((int) 0xcb6bab3b), + unchecked((int) 0xf1459d1f), unchecked((int) 0xab58faac), unchecked((int) 0x9303e34b), unchecked((int) 0x55fa3020), unchecked((int) 0xf66d76ad), + unchecked((int) 0x9176cc88), unchecked((int) 0x254c02f5), unchecked((int) 0xfcd7e54f), unchecked((int) 0xd7cb2ac5), unchecked((int) 0x80443526), + unchecked((int) 0x8fa362b5), unchecked((int) 0x495ab1de), unchecked((int) 0x671bba25), unchecked((int) 0x980eea45), unchecked((int) 0xe1c0fe5d), + unchecked((int) 0x02752fc3), unchecked((int) 0x12f04c81), unchecked((int) 0xa397468d), unchecked((int) 0xc6f9d36b), unchecked((int) 0xe75f8f03), + unchecked((int) 0x959c9215), unchecked((int) 0xeb7a6dbf), unchecked((int) 0xda595295), unchecked((int) 0x2d83bed4), unchecked((int) 0xd3217458), + unchecked((int) 0x2969e049), unchecked((int) 0x44c8c98e), unchecked((int) 0x6a89c275), unchecked((int) 0x78798ef4), unchecked((int) 0x6b3e5899), + unchecked((int) 0xdd71b927), unchecked((int) 0xb64fe1be), unchecked((int) 0x17ad88f0), unchecked((int) 0x66ac20c9), unchecked((int) 0xb43ace7d), + unchecked((int) 0x184adf63), unchecked((int) 0x82311ae5), unchecked((int) 0x60335197), unchecked((int) 0x457f5362), unchecked((int) 0xe07764b1), + unchecked((int) 0x84ae6bbb), unchecked((int) 0x1ca081fe), unchecked((int) 0x942b08f9), unchecked((int) 0x58684870), unchecked((int) 0x19fd458f), + unchecked((int) 0x876cde94), unchecked((int) 0xb7f87b52), unchecked((int) 0x23d373ab), unchecked((int) 0xe2024b72), unchecked((int) 0x578f1fe3), + unchecked((int) 0x2aab5566), unchecked((int) 0x0728ebb2), unchecked((int) 0x03c2b52f), unchecked((int) 0x9a7bc586), unchecked((int) 0xa50837d3), + unchecked((int) 0xf2872830), unchecked((int) 0xb2a5bf23), unchecked((int) 0xba6a0302), unchecked((int) 0x5c8216ed), unchecked((int) 0x2b1ccf8a), + unchecked((int) 0x92b479a7), unchecked((int) 0xf0f207f3), unchecked((int) 0xa1e2694e), unchecked((int) 0xcdf4da65), unchecked((int) 0xd5be0506), + unchecked((int) 0x1f6234d1), unchecked((int) 0x8afea6c4), unchecked((int) 0x9d532e34), unchecked((int) 0xa055f3a2), unchecked((int) 0x32e18a05), + unchecked((int) 0x75ebf6a4), unchecked((int) 0x39ec830b), unchecked((int) 0xaaef6040), unchecked((int) 0x069f715e), unchecked((int) 0x51106ebd), + unchecked((int) 0xf98a213e), unchecked((int) 0x3d06dd96), unchecked((int) 0xae053edd), unchecked((int) 0x46bde64d), unchecked((int) 0xb58d5491), + unchecked((int) 0x055dc471), unchecked((int) 0x6fd40604), unchecked((int) 0xff155060), unchecked((int) 0x24fb9819), unchecked((int) 0x97e9bdd6), + unchecked((int) 0xcc434089), unchecked((int) 0x779ed967), unchecked((int) 0xbd42e8b0), unchecked((int) 0x888b8907), unchecked((int) 0x385b19e7), + unchecked((int) 0xdbeec879), unchecked((int) 0x470a7ca1), unchecked((int) 0xe90f427c), unchecked((int) 0xc91e84f8), unchecked((int) 0x00000000), + unchecked((int) 0x83868009), unchecked((int) 0x48ed2b32), unchecked((int) 0xac70111e), unchecked((int) 0x4e725a6c), unchecked((int) 0xfbff0efd), + unchecked((int) 0x5638850f), unchecked((int) 0x1ed5ae3d), unchecked((int) 0x27392d36), unchecked((int) 0x64d90f0a), unchecked((int) 0x21a65c68), + unchecked((int) 0xd1545b9b), unchecked((int) 0x3a2e3624), unchecked((int) 0xb1670a0c), unchecked((int) 0x0fe75793), unchecked((int) 0xd296eeb4), + unchecked((int) 0x9e919b1b), unchecked((int) 0x4fc5c080), unchecked((int) 0xa220dc61), unchecked((int) 0x694b775a), unchecked((int) 0x161a121c), + unchecked((int) 0x0aba93e2), unchecked((int) 0xe52aa0c0), unchecked((int) 0x43e0223c), unchecked((int) 0x1d171b12), unchecked((int) 0x0b0d090e), + unchecked((int) 0xadc78bf2), unchecked((int) 0xb9a8b62d), unchecked((int) 0xc8a91e14), unchecked((int) 0x8519f157), unchecked((int) 0x4c0775af), + unchecked((int) 0xbbdd99ee), unchecked((int) 0xfd607fa3), unchecked((int) 0x9f2601f7), unchecked((int) 0xbcf5725c), unchecked((int) 0xc53b6644), + unchecked((int) 0x347efb5b), unchecked((int) 0x7629438b), unchecked((int) 0xdcc623cb), unchecked((int) 0x68fcedb6), unchecked((int) 0x63f1e4b8), + unchecked((int) 0xcadc31d7), unchecked((int) 0x10856342), unchecked((int) 0x40229713), unchecked((int) 0x2011c684), unchecked((int) 0x7d244a85), + unchecked((int) 0xf83dbbd2), unchecked((int) 0x1132f9ae), unchecked((int) 0x6da129c7), unchecked((int) 0x4b2f9e1d), unchecked((int) 0xf330b2dc), + unchecked((int) 0xec52860d), unchecked((int) 0xd0e3c177), unchecked((int) 0x6c16b32b), unchecked((int) 0x99b970a9), unchecked((int) 0xfa489411), + unchecked((int) 0x2264e947), unchecked((int) 0xc48cfca8), unchecked((int) 0x1a3ff0a0), unchecked((int) 0xd82c7d56), unchecked((int) 0xef903322), + unchecked((int) 0xc74e4987), unchecked((int) 0xc1d138d9), unchecked((int) 0xfea2ca8c), unchecked((int) 0x360bd498), unchecked((int) 0xcf81f5a6), + unchecked((int) 0x28de7aa5), unchecked((int) 0x268eb7da), unchecked((int) 0xa4bfad3f), unchecked((int) 0xe49d3a2c), unchecked((int) 0x0d927850), + unchecked((int) 0x9bcc5f6a), unchecked((int) 0x62467e54), unchecked((int) 0xc2138df6), unchecked((int) 0xe8b8d890), unchecked((int) 0x5ef7392e), + unchecked((int) 0xf5afc382), unchecked((int) 0xbe805d9f), unchecked((int) 0x7c93d069), unchecked((int) 0xa92dd56f), unchecked((int) 0xb31225cf), + unchecked((int) 0x3b99acc8), unchecked((int) 0xa77d1810), unchecked((int) 0x6e639ce8), unchecked((int) 0x7bbb3bdb), unchecked((int) 0x097826cd), + unchecked((int) 0xf418596e), unchecked((int) 0x01b79aec), unchecked((int) 0xa89a4f83), unchecked((int) 0x656e95e6), unchecked((int) 0x7ee6ffaa), + unchecked((int) 0x08cfbc21), unchecked((int) 0xe6e815ef), unchecked((int) 0xd99be7ba), unchecked((int) 0xce366f4a), unchecked((int) 0xd4099fea), + unchecked((int) 0xd67cb029), unchecked((int) 0xafb2a431), unchecked((int) 0x31233f2a), unchecked((int) 0x3094a5c6), unchecked((int) 0xc066a235), + unchecked((int) 0x37bc4e74), unchecked((int) 0xa6ca82fc), unchecked((int) 0xb0d090e0), unchecked((int) 0x15d8a733), unchecked((int) 0x4a9804f1), + unchecked((int) 0xf7daec41), unchecked((int) 0x0e50cd7f), unchecked((int) 0x2ff69117), unchecked((int) 0x8dd64d76), unchecked((int) 0x4db0ef43), + unchecked((int) 0x544daacc), unchecked((int) 0xdf0496e4), unchecked((int) 0xe3b5d19e), unchecked((int) 0x1b886a4c), unchecked((int) 0xb81f2cc1), + unchecked((int) 0x7f516546), unchecked((int) 0x04ea5e9d), unchecked((int) 0x5d358c01), unchecked((int) 0x737487fa), unchecked((int) 0x2e410bfb), + unchecked((int) 0x5a1d67b3), unchecked((int) 0x52d2db92), unchecked((int) 0x335610e9), unchecked((int) 0x1347d66d), unchecked((int) 0x8c61d79a), + unchecked((int) 0x7a0ca137), unchecked((int) 0x8e14f859), unchecked((int) 0x893c13eb), unchecked((int) 0xee27a9ce), unchecked((int) 0x35c961b7), + unchecked((int) 0xede51ce1), unchecked((int) 0x3cb1477a), unchecked((int) 0x59dfd29c), unchecked((int) 0x3f73f255), unchecked((int) 0x79ce1418), + unchecked((int) 0xbf37c773), unchecked((int) 0xeacdf753), unchecked((int) 0x5baafd5f), unchecked((int) 0x146f3ddf), unchecked((int) 0x86db4478), + unchecked((int) 0x81f3afca), unchecked((int) 0x3ec468b9), unchecked((int) 0x2c342438), unchecked((int) 0x5f40a3c2), unchecked((int) 0x72c31d16), + unchecked((int) 0x0c25e2bc), unchecked((int) 0x8b493c28), unchecked((int) 0x41950dff), unchecked((int) 0x7101a839), unchecked((int) 0xdeb30c08), + unchecked((int) 0x9ce4b4d8), unchecked((int) 0x90c15664), unchecked((int) 0x6184cb7b), unchecked((int) 0x70b632d5), unchecked((int) 0x745c6c48), + unchecked((int) 0x4257b8d0) + }; + + private int Shift( + int r, + int shift) + { + return ((int)(((uint) r >> shift) | (uint)(r << (32 - shift)))); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private const int m1 = unchecked((int) 0x80808080); + private const int m2 = unchecked((int) 0x7f7f7f7f); + private const int m3 = unchecked((int) 0x0000001b); + + private int FFmulX( + int x) + { + return ((int) (((x & m2) << 1) ^ (( (uint) (x & m1) >> 7) * m3))); + } + + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private int Inv_Mcol( + int x) + { + int f2 = FFmulX(x); + int f4 = FFmulX(f2); + int f8 = FFmulX(f4); + int f9 = x ^ f8; + + return f2 ^ f4 ^ f8 ^ Shift(f2 ^ f9, 8) ^ Shift(f4 ^ f9, 16) ^ Shift(f9, 24); + } + + private int SubWord(int x) { + return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private int[,] GenerateWorkingKey( + byte[] key, + bool forEncryption) + { + int KC = key.Length / 4; // key length in words + int t; + + if ((KC != 4) && (KC != 6) && (KC != 8)) { + throw new ArgumentException("Key length not 128/192/256 bits."); + } + + ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + int[,] W = new int[ROUNDS+1, 4]; // 4 words in a block + + // + // copy the key into the round key array + // + + t = 0; + for (int i = 0; i < key.Length; t++) + { + W[t >> 2, t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24); + i+=4; + } + + // + // while not enough round key material calculated + // calculate new values + // + int k = (ROUNDS + 1) << 2; + for (int i = KC; (i < k); i++) + { + int temp = W[(i-1)>>2, (i-1)&3]; + if ((i % KC) == 0) { + temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC)-1]; + } else if ((KC > 6) && ((i % KC) == 4)) { + temp = SubWord(temp); + } + + W[i>>2, i&3] = W[(i - KC)>>2, (i-KC)&3] ^ temp; + } + + if (!forEncryption) + { + for (int j = 1; j < ROUNDS; j++) + { + for (int i = 0; i < 4; i++) + { + W[j, i] = Inv_Mcol(W[j, i]); + } + } + } + + return W; + } + + private int ROUNDS; + private int[,] WorkingKey; + private int C0, C1, C2, C3; + private bool forEncryption; + + private const int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AesEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + + if (keyParameter == null) + throw new ArgumentException("invalid parameter passed to AES init - " + parameters.GetType().Name); + + WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption); + + this.forEncryption = forEncryption; + } + + public string AlgorithmName + { + get { return "AES"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (WorkingKey == null) + { + throw new InvalidOperationException("AES engine not initialised"); + } + + if ((inOff + (32 / 2)) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + (32 / 2)) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + UnPackBlock(input, inOff); + + if (forEncryption) + { + EncryptBlock(WorkingKey); + } + else + { + DecryptBlock(WorkingKey); + } + + PackBlock(output, outOff); + + return BLOCK_SIZE; + } + + public void Reset() + { + } + + private void UnPackBlock( + byte[] bytes, + int off) + { + int index = off; + + C0 = (bytes[index++] & 0xff); + C0 |= (bytes[index++] & 0xff) << 8; + C0 |= (bytes[index++] & 0xff) << 16; + C0 |= bytes[index++] << 24; + + C1 = (bytes[index++] & 0xff); + C1 |= (bytes[index++] & 0xff) << 8; + C1 |= (bytes[index++] & 0xff) << 16; + C1 |= bytes[index++] << 24; + + C2 = (bytes[index++] & 0xff); + C2 |= (bytes[index++] & 0xff) << 8; + C2 |= (bytes[index++] & 0xff) << 16; + C2 |= bytes[index++] << 24; + + C3 = (bytes[index++] & 0xff); + C3 |= (bytes[index++] & 0xff) << 8; + C3 |= (bytes[index++] & 0xff) << 16; + C3 |= bytes[index++] << 24; + } + + private void PackBlock( + byte[] bytes, + int off) + { + int index = off; + + bytes[index++] = (byte)C0; + bytes[index++] = (byte)(C0 >> 8); + bytes[index++] = (byte)(C0 >> 16); + bytes[index++] = (byte)(C0 >> 24); + + bytes[index++] = (byte)C1; + bytes[index++] = (byte)(C1 >> 8); + bytes[index++] = (byte)(C1 >> 16); + bytes[index++] = (byte)(C1 >> 24); + + bytes[index++] = (byte)C2; + bytes[index++] = (byte)(C2 >> 8); + bytes[index++] = (byte)(C2 >> 16); + bytes[index++] = (byte)(C2 >> 24); + + bytes[index++] = (byte)C3; + bytes[index++] = (byte)(C3 >> 8); + bytes[index++] = (byte)(C3 >> 16); + bytes[index++] = (byte)(C3 >> 24); + } + + private void EncryptBlock( + int[,] KW) + { + int r, r0, r1, r2, r3; + + C0 ^= KW[0, 0]; + C1 ^= KW[0, 1]; + C2 ^= KW[0, 2]; + C3 ^= KW[0, 3]; + + for (r = 1; r < ROUNDS - 1;) + { + r0 = T0[C0&255] ^ Shift(T0[(C1>>8)&255], 24) ^ Shift(T0[(C2>>16)&255],16) ^ Shift(T0[(C3>>24)&255],8) ^ KW[r,0]; + r1 = T0[C1&255] ^ Shift(T0[(C2>>8)&255], 24) ^ Shift(T0[(C3>>16)&255], 16) ^ Shift(T0[(C0>>24)&255], 8) ^ KW[r,1]; + r2 = T0[C2&255] ^ Shift(T0[(C3>>8)&255], 24) ^ Shift(T0[(C0>>16)&255], 16) ^ Shift(T0[(C1>>24)&255], 8) ^ KW[r,2]; + r3 = T0[C3&255] ^ Shift(T0[(C0>>8)&255], 24) ^ Shift(T0[(C1>>16)&255], 16) ^ Shift(T0[(C2>>24)&255], 8) ^ KW[r++,3]; + C0 = T0[r0&255] ^ Shift(T0[(r1>>8)&255], 24) ^ Shift(T0[(r2>>16)&255], 16) ^ Shift(T0[(r3>>24)&255], 8) ^ KW[r,0]; + C1 = T0[r1&255] ^ Shift(T0[(r2>>8)&255], 24) ^ Shift(T0[(r3>>16)&255], 16) ^ Shift(T0[(r0>>24)&255], 8) ^ KW[r,1]; + C2 = T0[r2&255] ^ Shift(T0[(r3>>8)&255], 24) ^ Shift(T0[(r0>>16)&255], 16) ^ Shift(T0[(r1>>24)&255], 8) ^ KW[r,2]; + C3 = T0[r3&255] ^ Shift(T0[(r0>>8)&255], 24) ^ Shift(T0[(r1>>16)&255], 16) ^ Shift(T0[(r2>>24)&255], 8) ^ KW[r++,3]; + } + + r0 = T0[C0&255] ^ Shift(T0[(C1>>8)&255], 24) ^ Shift(T0[(C2>>16)&255], 16) ^ Shift(T0[(C3>>24)&255], 8) ^ KW[r,0]; + r1 = T0[C1&255] ^ Shift(T0[(C2>>8)&255], 24) ^ Shift(T0[(C3>>16)&255], 16) ^ Shift(T0[(C0>>24)&255], 8) ^ KW[r,1]; + r2 = T0[C2&255] ^ Shift(T0[(C3>>8)&255], 24) ^ Shift(T0[(C0>>16)&255], 16) ^ Shift(T0[(C1>>24)&255], 8) ^ KW[r,2]; + r3 = T0[C3&255] ^ Shift(T0[(C0>>8)&255], 24) ^ Shift(T0[(C1>>16)&255], 16) ^ Shift(T0[(C2>>24)&255], 8) ^ KW[r++,3]; + + // the final round's table is a simple function of S so we don't use a whole other four tables for it + + C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r,0]; + C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r,1]; + C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r,2]; + C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r,3]; + } + + private void DecryptBlock( + int[,] KW) + { + int r, r0, r1, r2, r3; + + C0 ^= KW[ROUNDS,0]; + C1 ^= KW[ROUNDS,1]; + C2 ^= KW[ROUNDS,2]; + C3 ^= KW[ROUNDS,3]; + + for (r = ROUNDS-1; r>1;) + { + r0 = Tinv0[C0&255] ^ Shift(Tinv0[(C3>>8)&255], 24) ^ Shift(Tinv0[(C2>>16)&255], 16) ^ Shift(Tinv0[(C1>>24)&255], 8) ^ KW[r,0]; + r1 = Tinv0[C1&255] ^ Shift(Tinv0[(C0>>8)&255], 24) ^ Shift(Tinv0[(C3>>16)&255], 16) ^ Shift(Tinv0[(C2>>24)&255], 8) ^ KW[r,1]; + r2 = Tinv0[C2&255] ^ Shift(Tinv0[(C1>>8)&255], 24) ^ Shift(Tinv0[(C0>>16)&255], 16) ^ Shift(Tinv0[(C3>>24)&255], 8) ^ KW[r,2]; + r3 = Tinv0[C3&255] ^ Shift(Tinv0[(C2>>8)&255], 24) ^ Shift(Tinv0[(C1>>16)&255], 16) ^ Shift(Tinv0[(C0>>24)&255], 8) ^ KW[r--,3]; + C0 = Tinv0[r0&255] ^ Shift(Tinv0[(r3>>8)&255], 24) ^ Shift(Tinv0[(r2>>16)&255], 16) ^ Shift(Tinv0[(r1>>24)&255], 8) ^ KW[r,0]; + C1 = Tinv0[r1&255] ^ Shift(Tinv0[(r0>>8)&255], 24) ^ Shift(Tinv0[(r3>>16)&255], 16) ^ Shift(Tinv0[(r2>>24)&255], 8) ^ KW[r,1]; + C2 = Tinv0[r2&255] ^ Shift(Tinv0[(r1>>8)&255], 24) ^ Shift(Tinv0[(r0>>16)&255], 16) ^ Shift(Tinv0[(r3>>24)&255], 8) ^ KW[r,2]; + C3 = Tinv0[r3&255] ^ Shift(Tinv0[(r2>>8)&255], 24) ^ Shift(Tinv0[(r1>>16)&255], 16) ^ Shift(Tinv0[(r0>>24)&255], 8) ^ KW[r--,3]; + } + + r0 = Tinv0[C0&255] ^ Shift(Tinv0[(C3>>8)&255], 24) ^ Shift(Tinv0[(C2>>16)&255], 16) ^ Shift(Tinv0[(C1>>24)&255], 8) ^ KW[r,0]; + r1 = Tinv0[C1&255] ^ Shift(Tinv0[(C0>>8)&255], 24) ^ Shift(Tinv0[(C3>>16)&255], 16) ^ Shift(Tinv0[(C2>>24)&255], 8) ^ KW[r,1]; + r2 = Tinv0[C2&255] ^ Shift(Tinv0[(C1>>8)&255], 24) ^ Shift(Tinv0[(C0>>16)&255], 16) ^ Shift(Tinv0[(C3>>24)&255], 8) ^ KW[r,2]; + r3 = Tinv0[C3&255] ^ Shift(Tinv0[(C2>>8)&255], 24) ^ Shift(Tinv0[(C1>>16)&255], 16) ^ Shift(Tinv0[(C0>>24)&255], 8) ^ KW[r,3]; + + // the final round's table is a simple function of Si so we don't use a whole other four tables for it + + C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0,0]; + C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0,1]; + C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0,2]; + C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0,3]; + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/AesFastEngine.cs b/iTechSharp/srcbc/crypto/engines/AesFastEngine.cs new file mode 100644 index 0000000..624f4d1 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/AesFastEngine.cs @@ -0,0 +1,865 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the AES (Rijndael)), from FIPS-197. + *+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor), they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations), 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each), for a total of 2Kbytes), + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first + * + * The slowest version uses no static tables at all and computes the values in each round + *
+ *+ * This file contains the fast version with 8Kbytes of static tables for round precomputation + *
+ */ + public class AesFastEngine + : IBlockCipher + { + // The S box + private static readonly byte[] S = { + (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, + (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, + (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, + (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, + (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, + (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, + (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, + (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, + (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, + (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, + (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, + (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, + (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, + (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, + (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, + (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, + (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, + (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, + (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, + (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, + (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, + (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, + (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, + (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, + (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, + (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, + (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, + (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, + (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, + (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, + (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, + (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, + }; + + // The inverse S-box + private static readonly byte[] Si = { + (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, + (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, + (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, + (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, + (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, + (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, + (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, + (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, + (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, + (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, + (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, + (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, + (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, + (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, + (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, + (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, + (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, + (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, + (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, + (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, + (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, + (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, + (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, + (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, + (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, + (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, + (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, + (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, + (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, + (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, + (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, + (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static readonly int[] rcon = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; + + // precomputation tables of calculations for rounds + private static readonly int[] T0 = + { + unchecked((int) 0xa56363c6), unchecked((int) 0x847c7cf8), unchecked((int) 0x997777ee), unchecked((int) 0x8d7b7bf6), unchecked((int) 0x0df2f2ff), + unchecked((int) 0xbd6b6bd6), unchecked((int) 0xb16f6fde), unchecked((int) 0x54c5c591), unchecked((int) 0x50303060), unchecked((int) 0x03010102), + unchecked((int) 0xa96767ce), unchecked((int) 0x7d2b2b56), unchecked((int) 0x19fefee7), unchecked((int) 0x62d7d7b5), unchecked((int) 0xe6abab4d), + unchecked((int) 0x9a7676ec), unchecked((int) 0x45caca8f), unchecked((int) 0x9d82821f), unchecked((int) 0x40c9c989), unchecked((int) 0x877d7dfa), + unchecked((int) 0x15fafaef), unchecked((int) 0xeb5959b2), unchecked((int) 0xc947478e), unchecked((int) 0x0bf0f0fb), unchecked((int) 0xecadad41), + unchecked((int) 0x67d4d4b3), unchecked((int) 0xfda2a25f), unchecked((int) 0xeaafaf45), unchecked((int) 0xbf9c9c23), unchecked((int) 0xf7a4a453), + unchecked((int) 0x967272e4), unchecked((int) 0x5bc0c09b), unchecked((int) 0xc2b7b775), unchecked((int) 0x1cfdfde1), unchecked((int) 0xae93933d), + unchecked((int) 0x6a26264c), unchecked((int) 0x5a36366c), unchecked((int) 0x413f3f7e), unchecked((int) 0x02f7f7f5), unchecked((int) 0x4fcccc83), + unchecked((int) 0x5c343468), unchecked((int) 0xf4a5a551), unchecked((int) 0x34e5e5d1), unchecked((int) 0x08f1f1f9), unchecked((int) 0x937171e2), + unchecked((int) 0x73d8d8ab), unchecked((int) 0x53313162), unchecked((int) 0x3f15152a), unchecked((int) 0x0c040408), unchecked((int) 0x52c7c795), + unchecked((int) 0x65232346), unchecked((int) 0x5ec3c39d), unchecked((int) 0x28181830), unchecked((int) 0xa1969637), unchecked((int) 0x0f05050a), + unchecked((int) 0xb59a9a2f), unchecked((int) 0x0907070e), unchecked((int) 0x36121224), unchecked((int) 0x9b80801b), unchecked((int) 0x3de2e2df), + unchecked((int) 0x26ebebcd), unchecked((int) 0x6927274e), unchecked((int) 0xcdb2b27f), unchecked((int) 0x9f7575ea), unchecked((int) 0x1b090912), + unchecked((int) 0x9e83831d), unchecked((int) 0x742c2c58), unchecked((int) 0x2e1a1a34), unchecked((int) 0x2d1b1b36), unchecked((int) 0xb26e6edc), + unchecked((int) 0xee5a5ab4), unchecked((int) 0xfba0a05b), unchecked((int) 0xf65252a4), unchecked((int) 0x4d3b3b76), unchecked((int) 0x61d6d6b7), + unchecked((int) 0xceb3b37d), unchecked((int) 0x7b292952), unchecked((int) 0x3ee3e3dd), unchecked((int) 0x712f2f5e), unchecked((int) 0x97848413), + unchecked((int) 0xf55353a6), unchecked((int) 0x68d1d1b9), unchecked((int) 0x00000000), unchecked((int) 0x2cededc1), unchecked((int) 0x60202040), + unchecked((int) 0x1ffcfce3), unchecked((int) 0xc8b1b179), unchecked((int) 0xed5b5bb6), unchecked((int) 0xbe6a6ad4), unchecked((int) 0x46cbcb8d), + unchecked((int) 0xd9bebe67), unchecked((int) 0x4b393972), unchecked((int) 0xde4a4a94), unchecked((int) 0xd44c4c98), unchecked((int) 0xe85858b0), + unchecked((int) 0x4acfcf85), unchecked((int) 0x6bd0d0bb), unchecked((int) 0x2aefefc5), unchecked((int) 0xe5aaaa4f), unchecked((int) 0x16fbfbed), + unchecked((int) 0xc5434386), unchecked((int) 0xd74d4d9a), unchecked((int) 0x55333366), unchecked((int) 0x94858511), unchecked((int) 0xcf45458a), + unchecked((int) 0x10f9f9e9), unchecked((int) 0x06020204), unchecked((int) 0x817f7ffe), unchecked((int) 0xf05050a0), unchecked((int) 0x443c3c78), + unchecked((int) 0xba9f9f25), unchecked((int) 0xe3a8a84b), unchecked((int) 0xf35151a2), unchecked((int) 0xfea3a35d), unchecked((int) 0xc0404080), + unchecked((int) 0x8a8f8f05), unchecked((int) 0xad92923f), unchecked((int) 0xbc9d9d21), unchecked((int) 0x48383870), unchecked((int) 0x04f5f5f1), + unchecked((int) 0xdfbcbc63), unchecked((int) 0xc1b6b677), unchecked((int) 0x75dadaaf), unchecked((int) 0x63212142), unchecked((int) 0x30101020), + unchecked((int) 0x1affffe5), unchecked((int) 0x0ef3f3fd), unchecked((int) 0x6dd2d2bf), unchecked((int) 0x4ccdcd81), unchecked((int) 0x140c0c18), + unchecked((int) 0x35131326), unchecked((int) 0x2fececc3), unchecked((int) 0xe15f5fbe), unchecked((int) 0xa2979735), unchecked((int) 0xcc444488), + unchecked((int) 0x3917172e), unchecked((int) 0x57c4c493), unchecked((int) 0xf2a7a755), unchecked((int) 0x827e7efc), unchecked((int) 0x473d3d7a), + unchecked((int) 0xac6464c8), unchecked((int) 0xe75d5dba), unchecked((int) 0x2b191932), unchecked((int) 0x957373e6), unchecked((int) 0xa06060c0), + unchecked((int) 0x98818119), unchecked((int) 0xd14f4f9e), unchecked((int) 0x7fdcdca3), unchecked((int) 0x66222244), unchecked((int) 0x7e2a2a54), + unchecked((int) 0xab90903b), unchecked((int) 0x8388880b), unchecked((int) 0xca46468c), unchecked((int) 0x29eeeec7), unchecked((int) 0xd3b8b86b), + unchecked((int) 0x3c141428), unchecked((int) 0x79dedea7), unchecked((int) 0xe25e5ebc), unchecked((int) 0x1d0b0b16), unchecked((int) 0x76dbdbad), + unchecked((int) 0x3be0e0db), unchecked((int) 0x56323264), unchecked((int) 0x4e3a3a74), unchecked((int) 0x1e0a0a14), unchecked((int) 0xdb494992), + unchecked((int) 0x0a06060c), unchecked((int) 0x6c242448), unchecked((int) 0xe45c5cb8), unchecked((int) 0x5dc2c29f), unchecked((int) 0x6ed3d3bd), + unchecked((int) 0xefacac43), unchecked((int) 0xa66262c4), unchecked((int) 0xa8919139), unchecked((int) 0xa4959531), unchecked((int) 0x37e4e4d3), + unchecked((int) 0x8b7979f2), unchecked((int) 0x32e7e7d5), unchecked((int) 0x43c8c88b), unchecked((int) 0x5937376e), unchecked((int) 0xb76d6dda), + unchecked((int) 0x8c8d8d01), unchecked((int) 0x64d5d5b1), unchecked((int) 0xd24e4e9c), unchecked((int) 0xe0a9a949), unchecked((int) 0xb46c6cd8), + unchecked((int) 0xfa5656ac), unchecked((int) 0x07f4f4f3), unchecked((int) 0x25eaeacf), unchecked((int) 0xaf6565ca), unchecked((int) 0x8e7a7af4), + unchecked((int) 0xe9aeae47), unchecked((int) 0x18080810), unchecked((int) 0xd5baba6f), unchecked((int) 0x887878f0), unchecked((int) 0x6f25254a), + unchecked((int) 0x722e2e5c), unchecked((int) 0x241c1c38), unchecked((int) 0xf1a6a657), unchecked((int) 0xc7b4b473), unchecked((int) 0x51c6c697), + unchecked((int) 0x23e8e8cb), unchecked((int) 0x7cdddda1), unchecked((int) 0x9c7474e8), unchecked((int) 0x211f1f3e), unchecked((int) 0xdd4b4b96), + unchecked((int) 0xdcbdbd61), unchecked((int) 0x868b8b0d), unchecked((int) 0x858a8a0f), unchecked((int) 0x907070e0), unchecked((int) 0x423e3e7c), + unchecked((int) 0xc4b5b571), unchecked((int) 0xaa6666cc), unchecked((int) 0xd8484890), unchecked((int) 0x05030306), unchecked((int) 0x01f6f6f7), + unchecked((int) 0x120e0e1c), unchecked((int) 0xa36161c2), unchecked((int) 0x5f35356a), unchecked((int) 0xf95757ae), unchecked((int) 0xd0b9b969), + unchecked((int) 0x91868617), unchecked((int) 0x58c1c199), unchecked((int) 0x271d1d3a), unchecked((int) 0xb99e9e27), unchecked((int) 0x38e1e1d9), + unchecked((int) 0x13f8f8eb), unchecked((int) 0xb398982b), unchecked((int) 0x33111122), unchecked((int) 0xbb6969d2), unchecked((int) 0x70d9d9a9), + unchecked((int) 0x898e8e07), unchecked((int) 0xa7949433), unchecked((int) 0xb69b9b2d), unchecked((int) 0x221e1e3c), unchecked((int) 0x92878715), + unchecked((int) 0x20e9e9c9), unchecked((int) 0x49cece87), unchecked((int) 0xff5555aa), unchecked((int) 0x78282850), unchecked((int) 0x7adfdfa5), + unchecked((int) 0x8f8c8c03), unchecked((int) 0xf8a1a159), unchecked((int) 0x80898909), unchecked((int) 0x170d0d1a), unchecked((int) 0xdabfbf65), + unchecked((int) 0x31e6e6d7), unchecked((int) 0xc6424284), unchecked((int) 0xb86868d0), unchecked((int) 0xc3414182), unchecked((int) 0xb0999929), + unchecked((int) 0x772d2d5a), unchecked((int) 0x110f0f1e), unchecked((int) 0xcbb0b07b), unchecked((int) 0xfc5454a8), unchecked((int) 0xd6bbbb6d), + unchecked((int) 0x3a16162c)}; + + private static readonly int[] T1 = + { + unchecked((int) 0x6363c6a5), unchecked((int) 0x7c7cf884), unchecked((int) 0x7777ee99), unchecked((int) 0x7b7bf68d), unchecked((int) 0xf2f2ff0d), + unchecked((int) 0x6b6bd6bd), unchecked((int) 0x6f6fdeb1), unchecked((int) 0xc5c59154), unchecked((int) 0x30306050), unchecked((int) 0x01010203), + unchecked((int) 0x6767cea9), unchecked((int) 0x2b2b567d), unchecked((int) 0xfefee719), unchecked((int) 0xd7d7b562), unchecked((int) 0xabab4de6), + unchecked((int) 0x7676ec9a), unchecked((int) 0xcaca8f45), unchecked((int) 0x82821f9d), unchecked((int) 0xc9c98940), unchecked((int) 0x7d7dfa87), + unchecked((int) 0xfafaef15), unchecked((int) 0x5959b2eb), unchecked((int) 0x47478ec9), unchecked((int) 0xf0f0fb0b), unchecked((int) 0xadad41ec), + unchecked((int) 0xd4d4b367), unchecked((int) 0xa2a25ffd), unchecked((int) 0xafaf45ea), unchecked((int) 0x9c9c23bf), unchecked((int) 0xa4a453f7), + unchecked((int) 0x7272e496), unchecked((int) 0xc0c09b5b), unchecked((int) 0xb7b775c2), unchecked((int) 0xfdfde11c), unchecked((int) 0x93933dae), + unchecked((int) 0x26264c6a), unchecked((int) 0x36366c5a), unchecked((int) 0x3f3f7e41), unchecked((int) 0xf7f7f502), unchecked((int) 0xcccc834f), + unchecked((int) 0x3434685c), unchecked((int) 0xa5a551f4), unchecked((int) 0xe5e5d134), unchecked((int) 0xf1f1f908), unchecked((int) 0x7171e293), + unchecked((int) 0xd8d8ab73), unchecked((int) 0x31316253), unchecked((int) 0x15152a3f), unchecked((int) 0x0404080c), unchecked((int) 0xc7c79552), + unchecked((int) 0x23234665), unchecked((int) 0xc3c39d5e), unchecked((int) 0x18183028), unchecked((int) 0x969637a1), unchecked((int) 0x05050a0f), + unchecked((int) 0x9a9a2fb5), unchecked((int) 0x07070e09), unchecked((int) 0x12122436), unchecked((int) 0x80801b9b), unchecked((int) 0xe2e2df3d), + unchecked((int) 0xebebcd26), unchecked((int) 0x27274e69), unchecked((int) 0xb2b27fcd), unchecked((int) 0x7575ea9f), unchecked((int) 0x0909121b), + unchecked((int) 0x83831d9e), unchecked((int) 0x2c2c5874), unchecked((int) 0x1a1a342e), unchecked((int) 0x1b1b362d), unchecked((int) 0x6e6edcb2), + unchecked((int) 0x5a5ab4ee), unchecked((int) 0xa0a05bfb), unchecked((int) 0x5252a4f6), unchecked((int) 0x3b3b764d), unchecked((int) 0xd6d6b761), + unchecked((int) 0xb3b37dce), unchecked((int) 0x2929527b), unchecked((int) 0xe3e3dd3e), unchecked((int) 0x2f2f5e71), unchecked((int) 0x84841397), + unchecked((int) 0x5353a6f5), unchecked((int) 0xd1d1b968), unchecked((int) 0x00000000), unchecked((int) 0xededc12c), unchecked((int) 0x20204060), + unchecked((int) 0xfcfce31f), unchecked((int) 0xb1b179c8), unchecked((int) 0x5b5bb6ed), unchecked((int) 0x6a6ad4be), unchecked((int) 0xcbcb8d46), + unchecked((int) 0xbebe67d9), unchecked((int) 0x3939724b), unchecked((int) 0x4a4a94de), unchecked((int) 0x4c4c98d4), unchecked((int) 0x5858b0e8), + unchecked((int) 0xcfcf854a), unchecked((int) 0xd0d0bb6b), unchecked((int) 0xefefc52a), unchecked((int) 0xaaaa4fe5), unchecked((int) 0xfbfbed16), + unchecked((int) 0x434386c5), unchecked((int) 0x4d4d9ad7), unchecked((int) 0x33336655), unchecked((int) 0x85851194), unchecked((int) 0x45458acf), + unchecked((int) 0xf9f9e910), unchecked((int) 0x02020406), unchecked((int) 0x7f7ffe81), unchecked((int) 0x5050a0f0), unchecked((int) 0x3c3c7844), + unchecked((int) 0x9f9f25ba), unchecked((int) 0xa8a84be3), unchecked((int) 0x5151a2f3), unchecked((int) 0xa3a35dfe), unchecked((int) 0x404080c0), + unchecked((int) 0x8f8f058a), unchecked((int) 0x92923fad), unchecked((int) 0x9d9d21bc), unchecked((int) 0x38387048), unchecked((int) 0xf5f5f104), + unchecked((int) 0xbcbc63df), unchecked((int) 0xb6b677c1), unchecked((int) 0xdadaaf75), unchecked((int) 0x21214263), unchecked((int) 0x10102030), + unchecked((int) 0xffffe51a), unchecked((int) 0xf3f3fd0e), unchecked((int) 0xd2d2bf6d), unchecked((int) 0xcdcd814c), unchecked((int) 0x0c0c1814), + unchecked((int) 0x13132635), unchecked((int) 0xececc32f), unchecked((int) 0x5f5fbee1), unchecked((int) 0x979735a2), unchecked((int) 0x444488cc), + unchecked((int) 0x17172e39), unchecked((int) 0xc4c49357), unchecked((int) 0xa7a755f2), unchecked((int) 0x7e7efc82), unchecked((int) 0x3d3d7a47), + unchecked((int) 0x6464c8ac), unchecked((int) 0x5d5dbae7), unchecked((int) 0x1919322b), unchecked((int) 0x7373e695), unchecked((int) 0x6060c0a0), + unchecked((int) 0x81811998), unchecked((int) 0x4f4f9ed1), unchecked((int) 0xdcdca37f), unchecked((int) 0x22224466), unchecked((int) 0x2a2a547e), + unchecked((int) 0x90903bab), unchecked((int) 0x88880b83), unchecked((int) 0x46468cca), unchecked((int) 0xeeeec729), unchecked((int) 0xb8b86bd3), + unchecked((int) 0x1414283c), unchecked((int) 0xdedea779), unchecked((int) 0x5e5ebce2), unchecked((int) 0x0b0b161d), unchecked((int) 0xdbdbad76), + unchecked((int) 0xe0e0db3b), unchecked((int) 0x32326456), unchecked((int) 0x3a3a744e), unchecked((int) 0x0a0a141e), unchecked((int) 0x494992db), + unchecked((int) 0x06060c0a), unchecked((int) 0x2424486c), unchecked((int) 0x5c5cb8e4), unchecked((int) 0xc2c29f5d), unchecked((int) 0xd3d3bd6e), + unchecked((int) 0xacac43ef), unchecked((int) 0x6262c4a6), unchecked((int) 0x919139a8), unchecked((int) 0x959531a4), unchecked((int) 0xe4e4d337), + unchecked((int) 0x7979f28b), unchecked((int) 0xe7e7d532), unchecked((int) 0xc8c88b43), unchecked((int) 0x37376e59), unchecked((int) 0x6d6ddab7), + unchecked((int) 0x8d8d018c), unchecked((int) 0xd5d5b164), unchecked((int) 0x4e4e9cd2), unchecked((int) 0xa9a949e0), unchecked((int) 0x6c6cd8b4), + unchecked((int) 0x5656acfa), unchecked((int) 0xf4f4f307), unchecked((int) 0xeaeacf25), unchecked((int) 0x6565caaf), unchecked((int) 0x7a7af48e), + unchecked((int) 0xaeae47e9), unchecked((int) 0x08081018), unchecked((int) 0xbaba6fd5), unchecked((int) 0x7878f088), unchecked((int) 0x25254a6f), + unchecked((int) 0x2e2e5c72), unchecked((int) 0x1c1c3824), unchecked((int) 0xa6a657f1), unchecked((int) 0xb4b473c7), unchecked((int) 0xc6c69751), + unchecked((int) 0xe8e8cb23), unchecked((int) 0xdddda17c), unchecked((int) 0x7474e89c), unchecked((int) 0x1f1f3e21), unchecked((int) 0x4b4b96dd), + unchecked((int) 0xbdbd61dc), unchecked((int) 0x8b8b0d86), unchecked((int) 0x8a8a0f85), unchecked((int) 0x7070e090), unchecked((int) 0x3e3e7c42), + unchecked((int) 0xb5b571c4), unchecked((int) 0x6666ccaa), unchecked((int) 0x484890d8), unchecked((int) 0x03030605), unchecked((int) 0xf6f6f701), + unchecked((int) 0x0e0e1c12), unchecked((int) 0x6161c2a3), unchecked((int) 0x35356a5f), unchecked((int) 0x5757aef9), unchecked((int) 0xb9b969d0), + unchecked((int) 0x86861791), unchecked((int) 0xc1c19958), unchecked((int) 0x1d1d3a27), unchecked((int) 0x9e9e27b9), unchecked((int) 0xe1e1d938), + unchecked((int) 0xf8f8eb13), unchecked((int) 0x98982bb3), unchecked((int) 0x11112233), unchecked((int) 0x6969d2bb), unchecked((int) 0xd9d9a970), + unchecked((int) 0x8e8e0789), unchecked((int) 0x949433a7), unchecked((int) 0x9b9b2db6), unchecked((int) 0x1e1e3c22), unchecked((int) 0x87871592), + unchecked((int) 0xe9e9c920), unchecked((int) 0xcece8749), unchecked((int) 0x5555aaff), unchecked((int) 0x28285078), unchecked((int) 0xdfdfa57a), + unchecked((int) 0x8c8c038f), unchecked((int) 0xa1a159f8), unchecked((int) 0x89890980), unchecked((int) 0x0d0d1a17), unchecked((int) 0xbfbf65da), + unchecked((int) 0xe6e6d731), unchecked((int) 0x424284c6), unchecked((int) 0x6868d0b8), unchecked((int) 0x414182c3), unchecked((int) 0x999929b0), + unchecked((int) 0x2d2d5a77), unchecked((int) 0x0f0f1e11), unchecked((int) 0xb0b07bcb), unchecked((int) 0x5454a8fc), unchecked((int) 0xbbbb6dd6), + unchecked((int) 0x16162c3a)}; + + private static readonly int[] T2 = + { + unchecked((int) 0x63c6a563), unchecked((int) 0x7cf8847c), unchecked((int) 0x77ee9977), unchecked((int) 0x7bf68d7b), unchecked((int) 0xf2ff0df2), + unchecked((int) 0x6bd6bd6b), unchecked((int) 0x6fdeb16f), unchecked((int) 0xc59154c5), unchecked((int) 0x30605030), unchecked((int) 0x01020301), + unchecked((int) 0x67cea967), unchecked((int) 0x2b567d2b), unchecked((int) 0xfee719fe), unchecked((int) 0xd7b562d7), unchecked((int) 0xab4de6ab), + unchecked((int) 0x76ec9a76), unchecked((int) 0xca8f45ca), unchecked((int) 0x821f9d82), unchecked((int) 0xc98940c9), unchecked((int) 0x7dfa877d), + unchecked((int) 0xfaef15fa), unchecked((int) 0x59b2eb59), unchecked((int) 0x478ec947), unchecked((int) 0xf0fb0bf0), unchecked((int) 0xad41ecad), + unchecked((int) 0xd4b367d4), unchecked((int) 0xa25ffda2), unchecked((int) 0xaf45eaaf), unchecked((int) 0x9c23bf9c), unchecked((int) 0xa453f7a4), + unchecked((int) 0x72e49672), unchecked((int) 0xc09b5bc0), unchecked((int) 0xb775c2b7), unchecked((int) 0xfde11cfd), unchecked((int) 0x933dae93), + unchecked((int) 0x264c6a26), unchecked((int) 0x366c5a36), unchecked((int) 0x3f7e413f), unchecked((int) 0xf7f502f7), unchecked((int) 0xcc834fcc), + unchecked((int) 0x34685c34), unchecked((int) 0xa551f4a5), unchecked((int) 0xe5d134e5), unchecked((int) 0xf1f908f1), unchecked((int) 0x71e29371), + unchecked((int) 0xd8ab73d8), unchecked((int) 0x31625331), unchecked((int) 0x152a3f15), unchecked((int) 0x04080c04), unchecked((int) 0xc79552c7), + unchecked((int) 0x23466523), unchecked((int) 0xc39d5ec3), unchecked((int) 0x18302818), unchecked((int) 0x9637a196), unchecked((int) 0x050a0f05), + unchecked((int) 0x9a2fb59a), unchecked((int) 0x070e0907), unchecked((int) 0x12243612), unchecked((int) 0x801b9b80), unchecked((int) 0xe2df3de2), + unchecked((int) 0xebcd26eb), unchecked((int) 0x274e6927), unchecked((int) 0xb27fcdb2), unchecked((int) 0x75ea9f75), unchecked((int) 0x09121b09), + unchecked((int) 0x831d9e83), unchecked((int) 0x2c58742c), unchecked((int) 0x1a342e1a), unchecked((int) 0x1b362d1b), unchecked((int) 0x6edcb26e), + unchecked((int) 0x5ab4ee5a), unchecked((int) 0xa05bfba0), unchecked((int) 0x52a4f652), unchecked((int) 0x3b764d3b), unchecked((int) 0xd6b761d6), + unchecked((int) 0xb37dceb3), unchecked((int) 0x29527b29), unchecked((int) 0xe3dd3ee3), unchecked((int) 0x2f5e712f), unchecked((int) 0x84139784), + unchecked((int) 0x53a6f553), unchecked((int) 0xd1b968d1), unchecked((int) 0x00000000), unchecked((int) 0xedc12ced), unchecked((int) 0x20406020), + unchecked((int) 0xfce31ffc), unchecked((int) 0xb179c8b1), unchecked((int) 0x5bb6ed5b), unchecked((int) 0x6ad4be6a), unchecked((int) 0xcb8d46cb), + unchecked((int) 0xbe67d9be), unchecked((int) 0x39724b39), unchecked((int) 0x4a94de4a), unchecked((int) 0x4c98d44c), unchecked((int) 0x58b0e858), + unchecked((int) 0xcf854acf), unchecked((int) 0xd0bb6bd0), unchecked((int) 0xefc52aef), unchecked((int) 0xaa4fe5aa), unchecked((int) 0xfbed16fb), + unchecked((int) 0x4386c543), unchecked((int) 0x4d9ad74d), unchecked((int) 0x33665533), unchecked((int) 0x85119485), unchecked((int) 0x458acf45), + unchecked((int) 0xf9e910f9), unchecked((int) 0x02040602), unchecked((int) 0x7ffe817f), unchecked((int) 0x50a0f050), unchecked((int) 0x3c78443c), + unchecked((int) 0x9f25ba9f), unchecked((int) 0xa84be3a8), unchecked((int) 0x51a2f351), unchecked((int) 0xa35dfea3), unchecked((int) 0x4080c040), + unchecked((int) 0x8f058a8f), unchecked((int) 0x923fad92), unchecked((int) 0x9d21bc9d), unchecked((int) 0x38704838), unchecked((int) 0xf5f104f5), + unchecked((int) 0xbc63dfbc), unchecked((int) 0xb677c1b6), unchecked((int) 0xdaaf75da), unchecked((int) 0x21426321), unchecked((int) 0x10203010), + unchecked((int) 0xffe51aff), unchecked((int) 0xf3fd0ef3), unchecked((int) 0xd2bf6dd2), unchecked((int) 0xcd814ccd), unchecked((int) 0x0c18140c), + unchecked((int) 0x13263513), unchecked((int) 0xecc32fec), unchecked((int) 0x5fbee15f), unchecked((int) 0x9735a297), unchecked((int) 0x4488cc44), + unchecked((int) 0x172e3917), unchecked((int) 0xc49357c4), unchecked((int) 0xa755f2a7), unchecked((int) 0x7efc827e), unchecked((int) 0x3d7a473d), + unchecked((int) 0x64c8ac64), unchecked((int) 0x5dbae75d), unchecked((int) 0x19322b19), unchecked((int) 0x73e69573), unchecked((int) 0x60c0a060), + unchecked((int) 0x81199881), unchecked((int) 0x4f9ed14f), unchecked((int) 0xdca37fdc), unchecked((int) 0x22446622), unchecked((int) 0x2a547e2a), + unchecked((int) 0x903bab90), unchecked((int) 0x880b8388), unchecked((int) 0x468cca46), unchecked((int) 0xeec729ee), unchecked((int) 0xb86bd3b8), + unchecked((int) 0x14283c14), unchecked((int) 0xdea779de), unchecked((int) 0x5ebce25e), unchecked((int) 0x0b161d0b), unchecked((int) 0xdbad76db), + unchecked((int) 0xe0db3be0), unchecked((int) 0x32645632), unchecked((int) 0x3a744e3a), unchecked((int) 0x0a141e0a), unchecked((int) 0x4992db49), + unchecked((int) 0x060c0a06), unchecked((int) 0x24486c24), unchecked((int) 0x5cb8e45c), unchecked((int) 0xc29f5dc2), unchecked((int) 0xd3bd6ed3), + unchecked((int) 0xac43efac), unchecked((int) 0x62c4a662), unchecked((int) 0x9139a891), unchecked((int) 0x9531a495), unchecked((int) 0xe4d337e4), + unchecked((int) 0x79f28b79), unchecked((int) 0xe7d532e7), unchecked((int) 0xc88b43c8), unchecked((int) 0x376e5937), unchecked((int) 0x6ddab76d), + unchecked((int) 0x8d018c8d), unchecked((int) 0xd5b164d5), unchecked((int) 0x4e9cd24e), unchecked((int) 0xa949e0a9), unchecked((int) 0x6cd8b46c), + unchecked((int) 0x56acfa56), unchecked((int) 0xf4f307f4), unchecked((int) 0xeacf25ea), unchecked((int) 0x65caaf65), unchecked((int) 0x7af48e7a), + unchecked((int) 0xae47e9ae), unchecked((int) 0x08101808), unchecked((int) 0xba6fd5ba), unchecked((int) 0x78f08878), unchecked((int) 0x254a6f25), + unchecked((int) 0x2e5c722e), unchecked((int) 0x1c38241c), unchecked((int) 0xa657f1a6), unchecked((int) 0xb473c7b4), unchecked((int) 0xc69751c6), + unchecked((int) 0xe8cb23e8), unchecked((int) 0xdda17cdd), unchecked((int) 0x74e89c74), unchecked((int) 0x1f3e211f), unchecked((int) 0x4b96dd4b), + unchecked((int) 0xbd61dcbd), unchecked((int) 0x8b0d868b), unchecked((int) 0x8a0f858a), unchecked((int) 0x70e09070), unchecked((int) 0x3e7c423e), + unchecked((int) 0xb571c4b5), unchecked((int) 0x66ccaa66), unchecked((int) 0x4890d848), unchecked((int) 0x03060503), unchecked((int) 0xf6f701f6), + unchecked((int) 0x0e1c120e), unchecked((int) 0x61c2a361), unchecked((int) 0x356a5f35), unchecked((int) 0x57aef957), unchecked((int) 0xb969d0b9), + unchecked((int) 0x86179186), unchecked((int) 0xc19958c1), unchecked((int) 0x1d3a271d), unchecked((int) 0x9e27b99e), unchecked((int) 0xe1d938e1), + unchecked((int) 0xf8eb13f8), unchecked((int) 0x982bb398), unchecked((int) 0x11223311), unchecked((int) 0x69d2bb69), unchecked((int) 0xd9a970d9), + unchecked((int) 0x8e07898e), unchecked((int) 0x9433a794), unchecked((int) 0x9b2db69b), unchecked((int) 0x1e3c221e), unchecked((int) 0x87159287), + unchecked((int) 0xe9c920e9), unchecked((int) 0xce8749ce), unchecked((int) 0x55aaff55), unchecked((int) 0x28507828), unchecked((int) 0xdfa57adf), + unchecked((int) 0x8c038f8c), unchecked((int) 0xa159f8a1), unchecked((int) 0x89098089), unchecked((int) 0x0d1a170d), unchecked((int) 0xbf65dabf), + unchecked((int) 0xe6d731e6), unchecked((int) 0x4284c642), unchecked((int) 0x68d0b868), unchecked((int) 0x4182c341), unchecked((int) 0x9929b099), + unchecked((int) 0x2d5a772d), unchecked((int) 0x0f1e110f), unchecked((int) 0xb07bcbb0), unchecked((int) 0x54a8fc54), unchecked((int) 0xbb6dd6bb), + unchecked((int) 0x162c3a16)}; + + private static readonly int[] T3 = + { + unchecked((int) 0xc6a56363), unchecked((int) 0xf8847c7c), unchecked((int) 0xee997777), unchecked((int) 0xf68d7b7b), unchecked((int) 0xff0df2f2), + unchecked((int) 0xd6bd6b6b), unchecked((int) 0xdeb16f6f), unchecked((int) 0x9154c5c5), unchecked((int) 0x60503030), unchecked((int) 0x02030101), + unchecked((int) 0xcea96767), unchecked((int) 0x567d2b2b), unchecked((int) 0xe719fefe), unchecked((int) 0xb562d7d7), unchecked((int) 0x4de6abab), + unchecked((int) 0xec9a7676), unchecked((int) 0x8f45caca), unchecked((int) 0x1f9d8282), unchecked((int) 0x8940c9c9), unchecked((int) 0xfa877d7d), + unchecked((int) 0xef15fafa), unchecked((int) 0xb2eb5959), unchecked((int) 0x8ec94747), unchecked((int) 0xfb0bf0f0), unchecked((int) 0x41ecadad), + unchecked((int) 0xb367d4d4), unchecked((int) 0x5ffda2a2), unchecked((int) 0x45eaafaf), unchecked((int) 0x23bf9c9c), unchecked((int) 0x53f7a4a4), + unchecked((int) 0xe4967272), unchecked((int) 0x9b5bc0c0), unchecked((int) 0x75c2b7b7), unchecked((int) 0xe11cfdfd), unchecked((int) 0x3dae9393), + unchecked((int) 0x4c6a2626), unchecked((int) 0x6c5a3636), unchecked((int) 0x7e413f3f), unchecked((int) 0xf502f7f7), unchecked((int) 0x834fcccc), + unchecked((int) 0x685c3434), unchecked((int) 0x51f4a5a5), unchecked((int) 0xd134e5e5), unchecked((int) 0xf908f1f1), unchecked((int) 0xe2937171), + unchecked((int) 0xab73d8d8), unchecked((int) 0x62533131), unchecked((int) 0x2a3f1515), unchecked((int) 0x080c0404), unchecked((int) 0x9552c7c7), + unchecked((int) 0x46652323), unchecked((int) 0x9d5ec3c3), unchecked((int) 0x30281818), unchecked((int) 0x37a19696), unchecked((int) 0x0a0f0505), + unchecked((int) 0x2fb59a9a), unchecked((int) 0x0e090707), unchecked((int) 0x24361212), unchecked((int) 0x1b9b8080), unchecked((int) 0xdf3de2e2), + unchecked((int) 0xcd26ebeb), unchecked((int) 0x4e692727), unchecked((int) 0x7fcdb2b2), unchecked((int) 0xea9f7575), unchecked((int) 0x121b0909), + unchecked((int) 0x1d9e8383), unchecked((int) 0x58742c2c), unchecked((int) 0x342e1a1a), unchecked((int) 0x362d1b1b), unchecked((int) 0xdcb26e6e), + unchecked((int) 0xb4ee5a5a), unchecked((int) 0x5bfba0a0), unchecked((int) 0xa4f65252), unchecked((int) 0x764d3b3b), unchecked((int) 0xb761d6d6), + unchecked((int) 0x7dceb3b3), unchecked((int) 0x527b2929), unchecked((int) 0xdd3ee3e3), unchecked((int) 0x5e712f2f), unchecked((int) 0x13978484), + unchecked((int) 0xa6f55353), unchecked((int) 0xb968d1d1), unchecked((int) 0x00000000), unchecked((int) 0xc12ceded), unchecked((int) 0x40602020), + unchecked((int) 0xe31ffcfc), unchecked((int) 0x79c8b1b1), unchecked((int) 0xb6ed5b5b), unchecked((int) 0xd4be6a6a), unchecked((int) 0x8d46cbcb), + unchecked((int) 0x67d9bebe), unchecked((int) 0x724b3939), unchecked((int) 0x94de4a4a), unchecked((int) 0x98d44c4c), unchecked((int) 0xb0e85858), + unchecked((int) 0x854acfcf), unchecked((int) 0xbb6bd0d0), unchecked((int) 0xc52aefef), unchecked((int) 0x4fe5aaaa), unchecked((int) 0xed16fbfb), + unchecked((int) 0x86c54343), unchecked((int) 0x9ad74d4d), unchecked((int) 0x66553333), unchecked((int) 0x11948585), unchecked((int) 0x8acf4545), + unchecked((int) 0xe910f9f9), unchecked((int) 0x04060202), unchecked((int) 0xfe817f7f), unchecked((int) 0xa0f05050), unchecked((int) 0x78443c3c), + unchecked((int) 0x25ba9f9f), unchecked((int) 0x4be3a8a8), unchecked((int) 0xa2f35151), unchecked((int) 0x5dfea3a3), unchecked((int) 0x80c04040), + unchecked((int) 0x058a8f8f), unchecked((int) 0x3fad9292), unchecked((int) 0x21bc9d9d), unchecked((int) 0x70483838), unchecked((int) 0xf104f5f5), + unchecked((int) 0x63dfbcbc), unchecked((int) 0x77c1b6b6), unchecked((int) 0xaf75dada), unchecked((int) 0x42632121), unchecked((int) 0x20301010), + unchecked((int) 0xe51affff), unchecked((int) 0xfd0ef3f3), unchecked((int) 0xbf6dd2d2), unchecked((int) 0x814ccdcd), unchecked((int) 0x18140c0c), + unchecked((int) 0x26351313), unchecked((int) 0xc32fecec), unchecked((int) 0xbee15f5f), unchecked((int) 0x35a29797), unchecked((int) 0x88cc4444), + unchecked((int) 0x2e391717), unchecked((int) 0x9357c4c4), unchecked((int) 0x55f2a7a7), unchecked((int) 0xfc827e7e), unchecked((int) 0x7a473d3d), + unchecked((int) 0xc8ac6464), unchecked((int) 0xbae75d5d), unchecked((int) 0x322b1919), unchecked((int) 0xe6957373), unchecked((int) 0xc0a06060), + unchecked((int) 0x19988181), unchecked((int) 0x9ed14f4f), unchecked((int) 0xa37fdcdc), unchecked((int) 0x44662222), unchecked((int) 0x547e2a2a), + unchecked((int) 0x3bab9090), unchecked((int) 0x0b838888), unchecked((int) 0x8cca4646), unchecked((int) 0xc729eeee), unchecked((int) 0x6bd3b8b8), + unchecked((int) 0x283c1414), unchecked((int) 0xa779dede), unchecked((int) 0xbce25e5e), unchecked((int) 0x161d0b0b), unchecked((int) 0xad76dbdb), + unchecked((int) 0xdb3be0e0), unchecked((int) 0x64563232), unchecked((int) 0x744e3a3a), unchecked((int) 0x141e0a0a), unchecked((int) 0x92db4949), + unchecked((int) 0x0c0a0606), unchecked((int) 0x486c2424), unchecked((int) 0xb8e45c5c), unchecked((int) 0x9f5dc2c2), unchecked((int) 0xbd6ed3d3), + unchecked((int) 0x43efacac), unchecked((int) 0xc4a66262), unchecked((int) 0x39a89191), unchecked((int) 0x31a49595), unchecked((int) 0xd337e4e4), + unchecked((int) 0xf28b7979), unchecked((int) 0xd532e7e7), unchecked((int) 0x8b43c8c8), unchecked((int) 0x6e593737), unchecked((int) 0xdab76d6d), + unchecked((int) 0x018c8d8d), unchecked((int) 0xb164d5d5), unchecked((int) 0x9cd24e4e), unchecked((int) 0x49e0a9a9), unchecked((int) 0xd8b46c6c), + unchecked((int) 0xacfa5656), unchecked((int) 0xf307f4f4), unchecked((int) 0xcf25eaea), unchecked((int) 0xcaaf6565), unchecked((int) 0xf48e7a7a), + unchecked((int) 0x47e9aeae), unchecked((int) 0x10180808), unchecked((int) 0x6fd5baba), unchecked((int) 0xf0887878), unchecked((int) 0x4a6f2525), + unchecked((int) 0x5c722e2e), unchecked((int) 0x38241c1c), unchecked((int) 0x57f1a6a6), unchecked((int) 0x73c7b4b4), unchecked((int) 0x9751c6c6), + unchecked((int) 0xcb23e8e8), unchecked((int) 0xa17cdddd), unchecked((int) 0xe89c7474), unchecked((int) 0x3e211f1f), unchecked((int) 0x96dd4b4b), + unchecked((int) 0x61dcbdbd), unchecked((int) 0x0d868b8b), unchecked((int) 0x0f858a8a), unchecked((int) 0xe0907070), unchecked((int) 0x7c423e3e), + unchecked((int) 0x71c4b5b5), unchecked((int) 0xccaa6666), unchecked((int) 0x90d84848), unchecked((int) 0x06050303), unchecked((int) 0xf701f6f6), + unchecked((int) 0x1c120e0e), unchecked((int) 0xc2a36161), unchecked((int) 0x6a5f3535), unchecked((int) 0xaef95757), unchecked((int) 0x69d0b9b9), + unchecked((int) 0x17918686), unchecked((int) 0x9958c1c1), unchecked((int) 0x3a271d1d), unchecked((int) 0x27b99e9e), unchecked((int) 0xd938e1e1), + unchecked((int) 0xeb13f8f8), unchecked((int) 0x2bb39898), unchecked((int) 0x22331111), unchecked((int) 0xd2bb6969), unchecked((int) 0xa970d9d9), + unchecked((int) 0x07898e8e), unchecked((int) 0x33a79494), unchecked((int) 0x2db69b9b), unchecked((int) 0x3c221e1e), unchecked((int) 0x15928787), + unchecked((int) 0xc920e9e9), unchecked((int) 0x8749cece), unchecked((int) 0xaaff5555), unchecked((int) 0x50782828), unchecked((int) 0xa57adfdf), + unchecked((int) 0x038f8c8c), unchecked((int) 0x59f8a1a1), unchecked((int) 0x09808989), unchecked((int) 0x1a170d0d), unchecked((int) 0x65dabfbf), + unchecked((int) 0xd731e6e6), unchecked((int) 0x84c64242), unchecked((int) 0xd0b86868), unchecked((int) 0x82c34141), unchecked((int) 0x29b09999), + unchecked((int) 0x5a772d2d), unchecked((int) 0x1e110f0f), unchecked((int) 0x7bcbb0b0), unchecked((int) 0xa8fc5454), unchecked((int) 0x6dd6bbbb), + unchecked((int) 0x2c3a1616)}; + + private static readonly int[] Tinv0 = + { + unchecked((int) 0x50a7f451), unchecked((int) 0x5365417e), unchecked((int) 0xc3a4171a), unchecked((int) 0x965e273a), unchecked((int) 0xcb6bab3b), + unchecked((int) 0xf1459d1f), unchecked((int) 0xab58faac), unchecked((int) 0x9303e34b), unchecked((int) 0x55fa3020), unchecked((int) 0xf66d76ad), + unchecked((int) 0x9176cc88), unchecked((int) 0x254c02f5), unchecked((int) 0xfcd7e54f), unchecked((int) 0xd7cb2ac5), unchecked((int) 0x80443526), + unchecked((int) 0x8fa362b5), unchecked((int) 0x495ab1de), unchecked((int) 0x671bba25), unchecked((int) 0x980eea45), unchecked((int) 0xe1c0fe5d), + unchecked((int) 0x02752fc3), unchecked((int) 0x12f04c81), unchecked((int) 0xa397468d), unchecked((int) 0xc6f9d36b), unchecked((int) 0xe75f8f03), + unchecked((int) 0x959c9215), unchecked((int) 0xeb7a6dbf), unchecked((int) 0xda595295), unchecked((int) 0x2d83bed4), unchecked((int) 0xd3217458), + unchecked((int) 0x2969e049), unchecked((int) 0x44c8c98e), unchecked((int) 0x6a89c275), unchecked((int) 0x78798ef4), unchecked((int) 0x6b3e5899), + unchecked((int) 0xdd71b927), unchecked((int) 0xb64fe1be), unchecked((int) 0x17ad88f0), unchecked((int) 0x66ac20c9), unchecked((int) 0xb43ace7d), + unchecked((int) 0x184adf63), unchecked((int) 0x82311ae5), unchecked((int) 0x60335197), unchecked((int) 0x457f5362), unchecked((int) 0xe07764b1), + unchecked((int) 0x84ae6bbb), unchecked((int) 0x1ca081fe), unchecked((int) 0x942b08f9), unchecked((int) 0x58684870), unchecked((int) 0x19fd458f), + unchecked((int) 0x876cde94), unchecked((int) 0xb7f87b52), unchecked((int) 0x23d373ab), unchecked((int) 0xe2024b72), unchecked((int) 0x578f1fe3), + unchecked((int) 0x2aab5566), unchecked((int) 0x0728ebb2), unchecked((int) 0x03c2b52f), unchecked((int) 0x9a7bc586), unchecked((int) 0xa50837d3), + unchecked((int) 0xf2872830), unchecked((int) 0xb2a5bf23), unchecked((int) 0xba6a0302), unchecked((int) 0x5c8216ed), unchecked((int) 0x2b1ccf8a), + unchecked((int) 0x92b479a7), unchecked((int) 0xf0f207f3), unchecked((int) 0xa1e2694e), unchecked((int) 0xcdf4da65), unchecked((int) 0xd5be0506), + unchecked((int) 0x1f6234d1), unchecked((int) 0x8afea6c4), unchecked((int) 0x9d532e34), unchecked((int) 0xa055f3a2), unchecked((int) 0x32e18a05), + unchecked((int) 0x75ebf6a4), unchecked((int) 0x39ec830b), unchecked((int) 0xaaef6040), unchecked((int) 0x069f715e), unchecked((int) 0x51106ebd), + unchecked((int) 0xf98a213e), unchecked((int) 0x3d06dd96), unchecked((int) 0xae053edd), unchecked((int) 0x46bde64d), unchecked((int) 0xb58d5491), + unchecked((int) 0x055dc471), unchecked((int) 0x6fd40604), unchecked((int) 0xff155060), unchecked((int) 0x24fb9819), unchecked((int) 0x97e9bdd6), + unchecked((int) 0xcc434089), unchecked((int) 0x779ed967), unchecked((int) 0xbd42e8b0), unchecked((int) 0x888b8907), unchecked((int) 0x385b19e7), + unchecked((int) 0xdbeec879), unchecked((int) 0x470a7ca1), unchecked((int) 0xe90f427c), unchecked((int) 0xc91e84f8), unchecked((int) 0x00000000), + unchecked((int) 0x83868009), unchecked((int) 0x48ed2b32), unchecked((int) 0xac70111e), unchecked((int) 0x4e725a6c), unchecked((int) 0xfbff0efd), + unchecked((int) 0x5638850f), unchecked((int) 0x1ed5ae3d), unchecked((int) 0x27392d36), unchecked((int) 0x64d90f0a), unchecked((int) 0x21a65c68), + unchecked((int) 0xd1545b9b), unchecked((int) 0x3a2e3624), unchecked((int) 0xb1670a0c), unchecked((int) 0x0fe75793), unchecked((int) 0xd296eeb4), + unchecked((int) 0x9e919b1b), unchecked((int) 0x4fc5c080), unchecked((int) 0xa220dc61), unchecked((int) 0x694b775a), unchecked((int) 0x161a121c), + unchecked((int) 0x0aba93e2), unchecked((int) 0xe52aa0c0), unchecked((int) 0x43e0223c), unchecked((int) 0x1d171b12), unchecked((int) 0x0b0d090e), + unchecked((int) 0xadc78bf2), unchecked((int) 0xb9a8b62d), unchecked((int) 0xc8a91e14), unchecked((int) 0x8519f157), unchecked((int) 0x4c0775af), + unchecked((int) 0xbbdd99ee), unchecked((int) 0xfd607fa3), unchecked((int) 0x9f2601f7), unchecked((int) 0xbcf5725c), unchecked((int) 0xc53b6644), + unchecked((int) 0x347efb5b), unchecked((int) 0x7629438b), unchecked((int) 0xdcc623cb), unchecked((int) 0x68fcedb6), unchecked((int) 0x63f1e4b8), + unchecked((int) 0xcadc31d7), unchecked((int) 0x10856342), unchecked((int) 0x40229713), unchecked((int) 0x2011c684), unchecked((int) 0x7d244a85), + unchecked((int) 0xf83dbbd2), unchecked((int) 0x1132f9ae), unchecked((int) 0x6da129c7), unchecked((int) 0x4b2f9e1d), unchecked((int) 0xf330b2dc), + unchecked((int) 0xec52860d), unchecked((int) 0xd0e3c177), unchecked((int) 0x6c16b32b), unchecked((int) 0x99b970a9), unchecked((int) 0xfa489411), + unchecked((int) 0x2264e947), unchecked((int) 0xc48cfca8), unchecked((int) 0x1a3ff0a0), unchecked((int) 0xd82c7d56), unchecked((int) 0xef903322), + unchecked((int) 0xc74e4987), unchecked((int) 0xc1d138d9), unchecked((int) 0xfea2ca8c), unchecked((int) 0x360bd498), unchecked((int) 0xcf81f5a6), + unchecked((int) 0x28de7aa5), unchecked((int) 0x268eb7da), unchecked((int) 0xa4bfad3f), unchecked((int) 0xe49d3a2c), unchecked((int) 0x0d927850), + unchecked((int) 0x9bcc5f6a), unchecked((int) 0x62467e54), unchecked((int) 0xc2138df6), unchecked((int) 0xe8b8d890), unchecked((int) 0x5ef7392e), + unchecked((int) 0xf5afc382), unchecked((int) 0xbe805d9f), unchecked((int) 0x7c93d069), unchecked((int) 0xa92dd56f), unchecked((int) 0xb31225cf), + unchecked((int) 0x3b99acc8), unchecked((int) 0xa77d1810), unchecked((int) 0x6e639ce8), unchecked((int) 0x7bbb3bdb), unchecked((int) 0x097826cd), + unchecked((int) 0xf418596e), unchecked((int) 0x01b79aec), unchecked((int) 0xa89a4f83), unchecked((int) 0x656e95e6), unchecked((int) 0x7ee6ffaa), + unchecked((int) 0x08cfbc21), unchecked((int) 0xe6e815ef), unchecked((int) 0xd99be7ba), unchecked((int) 0xce366f4a), unchecked((int) 0xd4099fea), + unchecked((int) 0xd67cb029), unchecked((int) 0xafb2a431), unchecked((int) 0x31233f2a), unchecked((int) 0x3094a5c6), unchecked((int) 0xc066a235), + unchecked((int) 0x37bc4e74), unchecked((int) 0xa6ca82fc), unchecked((int) 0xb0d090e0), unchecked((int) 0x15d8a733), unchecked((int) 0x4a9804f1), + unchecked((int) 0xf7daec41), unchecked((int) 0x0e50cd7f), unchecked((int) 0x2ff69117), unchecked((int) 0x8dd64d76), unchecked((int) 0x4db0ef43), + unchecked((int) 0x544daacc), unchecked((int) 0xdf0496e4), unchecked((int) 0xe3b5d19e), unchecked((int) 0x1b886a4c), unchecked((int) 0xb81f2cc1), + unchecked((int) 0x7f516546), unchecked((int) 0x04ea5e9d), unchecked((int) 0x5d358c01), unchecked((int) 0x737487fa), unchecked((int) 0x2e410bfb), + unchecked((int) 0x5a1d67b3), unchecked((int) 0x52d2db92), unchecked((int) 0x335610e9), unchecked((int) 0x1347d66d), unchecked((int) 0x8c61d79a), + unchecked((int) 0x7a0ca137), unchecked((int) 0x8e14f859), unchecked((int) 0x893c13eb), unchecked((int) 0xee27a9ce), unchecked((int) 0x35c961b7), + unchecked((int) 0xede51ce1), unchecked((int) 0x3cb1477a), unchecked((int) 0x59dfd29c), unchecked((int) 0x3f73f255), unchecked((int) 0x79ce1418), + unchecked((int) 0xbf37c773), unchecked((int) 0xeacdf753), unchecked((int) 0x5baafd5f), unchecked((int) 0x146f3ddf), unchecked((int) 0x86db4478), + unchecked((int) 0x81f3afca), unchecked((int) 0x3ec468b9), unchecked((int) 0x2c342438), unchecked((int) 0x5f40a3c2), unchecked((int) 0x72c31d16), + unchecked((int) 0x0c25e2bc), unchecked((int) 0x8b493c28), unchecked((int) 0x41950dff), unchecked((int) 0x7101a839), unchecked((int) 0xdeb30c08), + unchecked((int) 0x9ce4b4d8), unchecked((int) 0x90c15664), unchecked((int) 0x6184cb7b), unchecked((int) 0x70b632d5), unchecked((int) 0x745c6c48), + unchecked((int) 0x4257b8d0)}; + + private static readonly int[] Tinv1 = + { + unchecked((int) 0xa7f45150), unchecked((int) 0x65417e53), unchecked((int) 0xa4171ac3), unchecked((int) 0x5e273a96), unchecked((int) 0x6bab3bcb), + unchecked((int) 0x459d1ff1), unchecked((int) 0x58faacab), unchecked((int) 0x03e34b93), unchecked((int) 0xfa302055), unchecked((int) 0x6d76adf6), + unchecked((int) 0x76cc8891), unchecked((int) 0x4c02f525), unchecked((int) 0xd7e54ffc), unchecked((int) 0xcb2ac5d7), unchecked((int) 0x44352680), + unchecked((int) 0xa362b58f), unchecked((int) 0x5ab1de49), unchecked((int) 0x1bba2567), unchecked((int) 0x0eea4598), unchecked((int) 0xc0fe5de1), + unchecked((int) 0x752fc302), unchecked((int) 0xf04c8112), unchecked((int) 0x97468da3), unchecked((int) 0xf9d36bc6), unchecked((int) 0x5f8f03e7), + unchecked((int) 0x9c921595), unchecked((int) 0x7a6dbfeb), unchecked((int) 0x595295da), unchecked((int) 0x83bed42d), unchecked((int) 0x217458d3), + unchecked((int) 0x69e04929), unchecked((int) 0xc8c98e44), unchecked((int) 0x89c2756a), unchecked((int) 0x798ef478), unchecked((int) 0x3e58996b), + unchecked((int) 0x71b927dd), unchecked((int) 0x4fe1beb6), unchecked((int) 0xad88f017), unchecked((int) 0xac20c966), unchecked((int) 0x3ace7db4), + unchecked((int) 0x4adf6318), unchecked((int) 0x311ae582), unchecked((int) 0x33519760), unchecked((int) 0x7f536245), unchecked((int) 0x7764b1e0), + unchecked((int) 0xae6bbb84), unchecked((int) 0xa081fe1c), unchecked((int) 0x2b08f994), unchecked((int) 0x68487058), unchecked((int) 0xfd458f19), + unchecked((int) 0x6cde9487), unchecked((int) 0xf87b52b7), unchecked((int) 0xd373ab23), unchecked((int) 0x024b72e2), unchecked((int) 0x8f1fe357), + unchecked((int) 0xab55662a), unchecked((int) 0x28ebb207), unchecked((int) 0xc2b52f03), unchecked((int) 0x7bc5869a), unchecked((int) 0x0837d3a5), + unchecked((int) 0x872830f2), unchecked((int) 0xa5bf23b2), unchecked((int) 0x6a0302ba), unchecked((int) 0x8216ed5c), unchecked((int) 0x1ccf8a2b), + unchecked((int) 0xb479a792), unchecked((int) 0xf207f3f0), unchecked((int) 0xe2694ea1), unchecked((int) 0xf4da65cd), unchecked((int) 0xbe0506d5), + unchecked((int) 0x6234d11f), unchecked((int) 0xfea6c48a), unchecked((int) 0x532e349d), unchecked((int) 0x55f3a2a0), unchecked((int) 0xe18a0532), + unchecked((int) 0xebf6a475), unchecked((int) 0xec830b39), unchecked((int) 0xef6040aa), unchecked((int) 0x9f715e06), unchecked((int) 0x106ebd51), + unchecked((int) 0x8a213ef9), unchecked((int) 0x06dd963d), unchecked((int) 0x053eddae), unchecked((int) 0xbde64d46), unchecked((int) 0x8d5491b5), + unchecked((int) 0x5dc47105), unchecked((int) 0xd406046f), unchecked((int) 0x155060ff), unchecked((int) 0xfb981924), unchecked((int) 0xe9bdd697), + unchecked((int) 0x434089cc), unchecked((int) 0x9ed96777), unchecked((int) 0x42e8b0bd), unchecked((int) 0x8b890788), unchecked((int) 0x5b19e738), + unchecked((int) 0xeec879db), unchecked((int) 0x0a7ca147), unchecked((int) 0x0f427ce9), unchecked((int) 0x1e84f8c9), unchecked((int) 0x00000000), + unchecked((int) 0x86800983), unchecked((int) 0xed2b3248), unchecked((int) 0x70111eac), unchecked((int) 0x725a6c4e), unchecked((int) 0xff0efdfb), + unchecked((int) 0x38850f56), unchecked((int) 0xd5ae3d1e), unchecked((int) 0x392d3627), unchecked((int) 0xd90f0a64), unchecked((int) 0xa65c6821), + unchecked((int) 0x545b9bd1), unchecked((int) 0x2e36243a), unchecked((int) 0x670a0cb1), unchecked((int) 0xe757930f), unchecked((int) 0x96eeb4d2), + unchecked((int) 0x919b1b9e), unchecked((int) 0xc5c0804f), unchecked((int) 0x20dc61a2), unchecked((int) 0x4b775a69), unchecked((int) 0x1a121c16), + unchecked((int) 0xba93e20a), unchecked((int) 0x2aa0c0e5), unchecked((int) 0xe0223c43), unchecked((int) 0x171b121d), unchecked((int) 0x0d090e0b), + unchecked((int) 0xc78bf2ad), unchecked((int) 0xa8b62db9), unchecked((int) 0xa91e14c8), unchecked((int) 0x19f15785), unchecked((int) 0x0775af4c), + unchecked((int) 0xdd99eebb), unchecked((int) 0x607fa3fd), unchecked((int) 0x2601f79f), unchecked((int) 0xf5725cbc), unchecked((int) 0x3b6644c5), + unchecked((int) 0x7efb5b34), unchecked((int) 0x29438b76), unchecked((int) 0xc623cbdc), unchecked((int) 0xfcedb668), unchecked((int) 0xf1e4b863), + unchecked((int) 0xdc31d7ca), unchecked((int) 0x85634210), unchecked((int) 0x22971340), unchecked((int) 0x11c68420), unchecked((int) 0x244a857d), + unchecked((int) 0x3dbbd2f8), unchecked((int) 0x32f9ae11), unchecked((int) 0xa129c76d), unchecked((int) 0x2f9e1d4b), unchecked((int) 0x30b2dcf3), + unchecked((int) 0x52860dec), unchecked((int) 0xe3c177d0), unchecked((int) 0x16b32b6c), unchecked((int) 0xb970a999), unchecked((int) 0x489411fa), + unchecked((int) 0x64e94722), unchecked((int) 0x8cfca8c4), unchecked((int) 0x3ff0a01a), unchecked((int) 0x2c7d56d8), unchecked((int) 0x903322ef), + unchecked((int) 0x4e4987c7), unchecked((int) 0xd138d9c1), unchecked((int) 0xa2ca8cfe), unchecked((int) 0x0bd49836), unchecked((int) 0x81f5a6cf), + unchecked((int) 0xde7aa528), unchecked((int) 0x8eb7da26), unchecked((int) 0xbfad3fa4), unchecked((int) 0x9d3a2ce4), unchecked((int) 0x9278500d), + unchecked((int) 0xcc5f6a9b), unchecked((int) 0x467e5462), unchecked((int) 0x138df6c2), unchecked((int) 0xb8d890e8), unchecked((int) 0xf7392e5e), + unchecked((int) 0xafc382f5), unchecked((int) 0x805d9fbe), unchecked((int) 0x93d0697c), unchecked((int) 0x2dd56fa9), unchecked((int) 0x1225cfb3), + unchecked((int) 0x99acc83b), unchecked((int) 0x7d1810a7), unchecked((int) 0x639ce86e), unchecked((int) 0xbb3bdb7b), unchecked((int) 0x7826cd09), + unchecked((int) 0x18596ef4), unchecked((int) 0xb79aec01), unchecked((int) 0x9a4f83a8), unchecked((int) 0x6e95e665), unchecked((int) 0xe6ffaa7e), + unchecked((int) 0xcfbc2108), unchecked((int) 0xe815efe6), unchecked((int) 0x9be7bad9), unchecked((int) 0x366f4ace), unchecked((int) 0x099fead4), + unchecked((int) 0x7cb029d6), unchecked((int) 0xb2a431af), unchecked((int) 0x233f2a31), unchecked((int) 0x94a5c630), unchecked((int) 0x66a235c0), + unchecked((int) 0xbc4e7437), unchecked((int) 0xca82fca6), unchecked((int) 0xd090e0b0), unchecked((int) 0xd8a73315), unchecked((int) 0x9804f14a), + unchecked((int) 0xdaec41f7), unchecked((int) 0x50cd7f0e), unchecked((int) 0xf691172f), unchecked((int) 0xd64d768d), unchecked((int) 0xb0ef434d), + unchecked((int) 0x4daacc54), unchecked((int) 0x0496e4df), unchecked((int) 0xb5d19ee3), unchecked((int) 0x886a4c1b), unchecked((int) 0x1f2cc1b8), + unchecked((int) 0x5165467f), unchecked((int) 0xea5e9d04), unchecked((int) 0x358c015d), unchecked((int) 0x7487fa73), unchecked((int) 0x410bfb2e), + unchecked((int) 0x1d67b35a), unchecked((int) 0xd2db9252), unchecked((int) 0x5610e933), unchecked((int) 0x47d66d13), unchecked((int) 0x61d79a8c), + unchecked((int) 0x0ca1377a), unchecked((int) 0x14f8598e), unchecked((int) 0x3c13eb89), unchecked((int) 0x27a9ceee), unchecked((int) 0xc961b735), + unchecked((int) 0xe51ce1ed), unchecked((int) 0xb1477a3c), unchecked((int) 0xdfd29c59), unchecked((int) 0x73f2553f), unchecked((int) 0xce141879), + unchecked((int) 0x37c773bf), unchecked((int) 0xcdf753ea), unchecked((int) 0xaafd5f5b), unchecked((int) 0x6f3ddf14), unchecked((int) 0xdb447886), + unchecked((int) 0xf3afca81), unchecked((int) 0xc468b93e), unchecked((int) 0x3424382c), unchecked((int) 0x40a3c25f), unchecked((int) 0xc31d1672), + unchecked((int) 0x25e2bc0c), unchecked((int) 0x493c288b), unchecked((int) 0x950dff41), unchecked((int) 0x01a83971), unchecked((int) 0xb30c08de), + unchecked((int) 0xe4b4d89c), unchecked((int) 0xc1566490), unchecked((int) 0x84cb7b61), unchecked((int) 0xb632d570), unchecked((int) 0x5c6c4874), + unchecked((int) 0x57b8d042)}; + + private static readonly int[] Tinv2 = + { + unchecked((int) 0xf45150a7), unchecked((int) 0x417e5365), unchecked((int) 0x171ac3a4), unchecked((int) 0x273a965e), unchecked((int) 0xab3bcb6b), + unchecked((int) 0x9d1ff145), unchecked((int) 0xfaacab58), unchecked((int) 0xe34b9303), unchecked((int) 0x302055fa), unchecked((int) 0x76adf66d), + unchecked((int) 0xcc889176), unchecked((int) 0x02f5254c), unchecked((int) 0xe54ffcd7), unchecked((int) 0x2ac5d7cb), unchecked((int) 0x35268044), + unchecked((int) 0x62b58fa3), unchecked((int) 0xb1de495a), unchecked((int) 0xba25671b), unchecked((int) 0xea45980e), unchecked((int) 0xfe5de1c0), + unchecked((int) 0x2fc30275), unchecked((int) 0x4c8112f0), unchecked((int) 0x468da397), unchecked((int) 0xd36bc6f9), unchecked((int) 0x8f03e75f), + unchecked((int) 0x9215959c), unchecked((int) 0x6dbfeb7a), unchecked((int) 0x5295da59), unchecked((int) 0xbed42d83), unchecked((int) 0x7458d321), + unchecked((int) 0xe0492969), unchecked((int) 0xc98e44c8), unchecked((int) 0xc2756a89), unchecked((int) 0x8ef47879), unchecked((int) 0x58996b3e), + unchecked((int) 0xb927dd71), unchecked((int) 0xe1beb64f), unchecked((int) 0x88f017ad), unchecked((int) 0x20c966ac), unchecked((int) 0xce7db43a), + unchecked((int) 0xdf63184a), unchecked((int) 0x1ae58231), unchecked((int) 0x51976033), unchecked((int) 0x5362457f), unchecked((int) 0x64b1e077), + unchecked((int) 0x6bbb84ae), unchecked((int) 0x81fe1ca0), unchecked((int) 0x08f9942b), unchecked((int) 0x48705868), unchecked((int) 0x458f19fd), + unchecked((int) 0xde94876c), unchecked((int) 0x7b52b7f8), unchecked((int) 0x73ab23d3), unchecked((int) 0x4b72e202), unchecked((int) 0x1fe3578f), + unchecked((int) 0x55662aab), unchecked((int) 0xebb20728), unchecked((int) 0xb52f03c2), unchecked((int) 0xc5869a7b), unchecked((int) 0x37d3a508), + unchecked((int) 0x2830f287), unchecked((int) 0xbf23b2a5), unchecked((int) 0x0302ba6a), unchecked((int) 0x16ed5c82), unchecked((int) 0xcf8a2b1c), + unchecked((int) 0x79a792b4), unchecked((int) 0x07f3f0f2), unchecked((int) 0x694ea1e2), unchecked((int) 0xda65cdf4), unchecked((int) 0x0506d5be), + unchecked((int) 0x34d11f62), unchecked((int) 0xa6c48afe), unchecked((int) 0x2e349d53), unchecked((int) 0xf3a2a055), unchecked((int) 0x8a0532e1), + unchecked((int) 0xf6a475eb), unchecked((int) 0x830b39ec), unchecked((int) 0x6040aaef), unchecked((int) 0x715e069f), unchecked((int) 0x6ebd5110), + unchecked((int) 0x213ef98a), unchecked((int) 0xdd963d06), unchecked((int) 0x3eddae05), unchecked((int) 0xe64d46bd), unchecked((int) 0x5491b58d), + unchecked((int) 0xc471055d), unchecked((int) 0x06046fd4), unchecked((int) 0x5060ff15), unchecked((int) 0x981924fb), unchecked((int) 0xbdd697e9), + unchecked((int) 0x4089cc43), unchecked((int) 0xd967779e), unchecked((int) 0xe8b0bd42), unchecked((int) 0x8907888b), unchecked((int) 0x19e7385b), + unchecked((int) 0xc879dbee), unchecked((int) 0x7ca1470a), unchecked((int) 0x427ce90f), unchecked((int) 0x84f8c91e), unchecked((int) 0x00000000), + unchecked((int) 0x80098386), unchecked((int) 0x2b3248ed), unchecked((int) 0x111eac70), unchecked((int) 0x5a6c4e72), unchecked((int) 0x0efdfbff), + unchecked((int) 0x850f5638), unchecked((int) 0xae3d1ed5), unchecked((int) 0x2d362739), unchecked((int) 0x0f0a64d9), unchecked((int) 0x5c6821a6), + unchecked((int) 0x5b9bd154), unchecked((int) 0x36243a2e), unchecked((int) 0x0a0cb167), unchecked((int) 0x57930fe7), unchecked((int) 0xeeb4d296), + unchecked((int) 0x9b1b9e91), unchecked((int) 0xc0804fc5), unchecked((int) 0xdc61a220), unchecked((int) 0x775a694b), unchecked((int) 0x121c161a), + unchecked((int) 0x93e20aba), unchecked((int) 0xa0c0e52a), unchecked((int) 0x223c43e0), unchecked((int) 0x1b121d17), unchecked((int) 0x090e0b0d), + unchecked((int) 0x8bf2adc7), unchecked((int) 0xb62db9a8), unchecked((int) 0x1e14c8a9), unchecked((int) 0xf1578519), unchecked((int) 0x75af4c07), + unchecked((int) 0x99eebbdd), unchecked((int) 0x7fa3fd60), unchecked((int) 0x01f79f26), unchecked((int) 0x725cbcf5), unchecked((int) 0x6644c53b), + unchecked((int) 0xfb5b347e), unchecked((int) 0x438b7629), unchecked((int) 0x23cbdcc6), unchecked((int) 0xedb668fc), unchecked((int) 0xe4b863f1), + unchecked((int) 0x31d7cadc), unchecked((int) 0x63421085), unchecked((int) 0x97134022), unchecked((int) 0xc6842011), unchecked((int) 0x4a857d24), + unchecked((int) 0xbbd2f83d), unchecked((int) 0xf9ae1132), unchecked((int) 0x29c76da1), unchecked((int) 0x9e1d4b2f), unchecked((int) 0xb2dcf330), + unchecked((int) 0x860dec52), unchecked((int) 0xc177d0e3), unchecked((int) 0xb32b6c16), unchecked((int) 0x70a999b9), unchecked((int) 0x9411fa48), + unchecked((int) 0xe9472264), unchecked((int) 0xfca8c48c), unchecked((int) 0xf0a01a3f), unchecked((int) 0x7d56d82c), unchecked((int) 0x3322ef90), + unchecked((int) 0x4987c74e), unchecked((int) 0x38d9c1d1), unchecked((int) 0xca8cfea2), unchecked((int) 0xd498360b), unchecked((int) 0xf5a6cf81), + unchecked((int) 0x7aa528de), unchecked((int) 0xb7da268e), unchecked((int) 0xad3fa4bf), unchecked((int) 0x3a2ce49d), unchecked((int) 0x78500d92), + unchecked((int) 0x5f6a9bcc), unchecked((int) 0x7e546246), unchecked((int) 0x8df6c213), unchecked((int) 0xd890e8b8), unchecked((int) 0x392e5ef7), + unchecked((int) 0xc382f5af), unchecked((int) 0x5d9fbe80), unchecked((int) 0xd0697c93), unchecked((int) 0xd56fa92d), unchecked((int) 0x25cfb312), + unchecked((int) 0xacc83b99), unchecked((int) 0x1810a77d), unchecked((int) 0x9ce86e63), unchecked((int) 0x3bdb7bbb), unchecked((int) 0x26cd0978), + unchecked((int) 0x596ef418), unchecked((int) 0x9aec01b7), unchecked((int) 0x4f83a89a), unchecked((int) 0x95e6656e), unchecked((int) 0xffaa7ee6), + unchecked((int) 0xbc2108cf), unchecked((int) 0x15efe6e8), unchecked((int) 0xe7bad99b), unchecked((int) 0x6f4ace36), unchecked((int) 0x9fead409), + unchecked((int) 0xb029d67c), unchecked((int) 0xa431afb2), unchecked((int) 0x3f2a3123), unchecked((int) 0xa5c63094), unchecked((int) 0xa235c066), + unchecked((int) 0x4e7437bc), unchecked((int) 0x82fca6ca), unchecked((int) 0x90e0b0d0), unchecked((int) 0xa73315d8), unchecked((int) 0x04f14a98), + unchecked((int) 0xec41f7da), unchecked((int) 0xcd7f0e50), unchecked((int) 0x91172ff6), unchecked((int) 0x4d768dd6), unchecked((int) 0xef434db0), + unchecked((int) 0xaacc544d), unchecked((int) 0x96e4df04), unchecked((int) 0xd19ee3b5), unchecked((int) 0x6a4c1b88), unchecked((int) 0x2cc1b81f), + unchecked((int) 0x65467f51), unchecked((int) 0x5e9d04ea), unchecked((int) 0x8c015d35), unchecked((int) 0x87fa7374), unchecked((int) 0x0bfb2e41), + unchecked((int) 0x67b35a1d), unchecked((int) 0xdb9252d2), unchecked((int) 0x10e93356), unchecked((int) 0xd66d1347), unchecked((int) 0xd79a8c61), + unchecked((int) 0xa1377a0c), unchecked((int) 0xf8598e14), unchecked((int) 0x13eb893c), unchecked((int) 0xa9ceee27), unchecked((int) 0x61b735c9), + unchecked((int) 0x1ce1ede5), unchecked((int) 0x477a3cb1), unchecked((int) 0xd29c59df), unchecked((int) 0xf2553f73), unchecked((int) 0x141879ce), + unchecked((int) 0xc773bf37), unchecked((int) 0xf753eacd), unchecked((int) 0xfd5f5baa), unchecked((int) 0x3ddf146f), unchecked((int) 0x447886db), + unchecked((int) 0xafca81f3), unchecked((int) 0x68b93ec4), unchecked((int) 0x24382c34), unchecked((int) 0xa3c25f40), unchecked((int) 0x1d1672c3), + unchecked((int) 0xe2bc0c25), unchecked((int) 0x3c288b49), unchecked((int) 0x0dff4195), unchecked((int) 0xa8397101), unchecked((int) 0x0c08deb3), + unchecked((int) 0xb4d89ce4), unchecked((int) 0x566490c1), unchecked((int) 0xcb7b6184), unchecked((int) 0x32d570b6), unchecked((int) 0x6c48745c), + unchecked((int) 0xb8d04257)}; + + private static readonly int[] Tinv3 = + { + unchecked((int) 0x5150a7f4), unchecked((int) 0x7e536541), unchecked((int) 0x1ac3a417), unchecked((int) 0x3a965e27), unchecked((int) 0x3bcb6bab), + unchecked((int) 0x1ff1459d), unchecked((int) 0xacab58fa), unchecked((int) 0x4b9303e3), unchecked((int) 0x2055fa30), unchecked((int) 0xadf66d76), + unchecked((int) 0x889176cc), unchecked((int) 0xf5254c02), unchecked((int) 0x4ffcd7e5), unchecked((int) 0xc5d7cb2a), unchecked((int) 0x26804435), + unchecked((int) 0xb58fa362), unchecked((int) 0xde495ab1), unchecked((int) 0x25671bba), unchecked((int) 0x45980eea), unchecked((int) 0x5de1c0fe), + unchecked((int) 0xc302752f), unchecked((int) 0x8112f04c), unchecked((int) 0x8da39746), unchecked((int) 0x6bc6f9d3), unchecked((int) 0x03e75f8f), + unchecked((int) 0x15959c92), unchecked((int) 0xbfeb7a6d), unchecked((int) 0x95da5952), unchecked((int) 0xd42d83be), unchecked((int) 0x58d32174), + unchecked((int) 0x492969e0), unchecked((int) 0x8e44c8c9), unchecked((int) 0x756a89c2), unchecked((int) 0xf478798e), unchecked((int) 0x996b3e58), + unchecked((int) 0x27dd71b9), unchecked((int) 0xbeb64fe1), unchecked((int) 0xf017ad88), unchecked((int) 0xc966ac20), unchecked((int) 0x7db43ace), + unchecked((int) 0x63184adf), unchecked((int) 0xe582311a), unchecked((int) 0x97603351), unchecked((int) 0x62457f53), unchecked((int) 0xb1e07764), + unchecked((int) 0xbb84ae6b), unchecked((int) 0xfe1ca081), unchecked((int) 0xf9942b08), unchecked((int) 0x70586848), unchecked((int) 0x8f19fd45), + unchecked((int) 0x94876cde), unchecked((int) 0x52b7f87b), unchecked((int) 0xab23d373), unchecked((int) 0x72e2024b), unchecked((int) 0xe3578f1f), + unchecked((int) 0x662aab55), unchecked((int) 0xb20728eb), unchecked((int) 0x2f03c2b5), unchecked((int) 0x869a7bc5), unchecked((int) 0xd3a50837), + unchecked((int) 0x30f28728), unchecked((int) 0x23b2a5bf), unchecked((int) 0x02ba6a03), unchecked((int) 0xed5c8216), unchecked((int) 0x8a2b1ccf), + unchecked((int) 0xa792b479), unchecked((int) 0xf3f0f207), unchecked((int) 0x4ea1e269), unchecked((int) 0x65cdf4da), unchecked((int) 0x06d5be05), + unchecked((int) 0xd11f6234), unchecked((int) 0xc48afea6), unchecked((int) 0x349d532e), unchecked((int) 0xa2a055f3), unchecked((int) 0x0532e18a), + unchecked((int) 0xa475ebf6), unchecked((int) 0x0b39ec83), unchecked((int) 0x40aaef60), unchecked((int) 0x5e069f71), unchecked((int) 0xbd51106e), + unchecked((int) 0x3ef98a21), unchecked((int) 0x963d06dd), unchecked((int) 0xddae053e), unchecked((int) 0x4d46bde6), unchecked((int) 0x91b58d54), + unchecked((int) 0x71055dc4), unchecked((int) 0x046fd406), unchecked((int) 0x60ff1550), unchecked((int) 0x1924fb98), unchecked((int) 0xd697e9bd), + unchecked((int) 0x89cc4340), unchecked((int) 0x67779ed9), unchecked((int) 0xb0bd42e8), unchecked((int) 0x07888b89), unchecked((int) 0xe7385b19), + unchecked((int) 0x79dbeec8), unchecked((int) 0xa1470a7c), unchecked((int) 0x7ce90f42), unchecked((int) 0xf8c91e84), unchecked((int) 0x00000000), + unchecked((int) 0x09838680), unchecked((int) 0x3248ed2b), unchecked((int) 0x1eac7011), unchecked((int) 0x6c4e725a), unchecked((int) 0xfdfbff0e), + unchecked((int) 0x0f563885), unchecked((int) 0x3d1ed5ae), unchecked((int) 0x3627392d), unchecked((int) 0x0a64d90f), unchecked((int) 0x6821a65c), + unchecked((int) 0x9bd1545b), unchecked((int) 0x243a2e36), unchecked((int) 0x0cb1670a), unchecked((int) 0x930fe757), unchecked((int) 0xb4d296ee), + unchecked((int) 0x1b9e919b), unchecked((int) 0x804fc5c0), unchecked((int) 0x61a220dc), unchecked((int) 0x5a694b77), unchecked((int) 0x1c161a12), + unchecked((int) 0xe20aba93), unchecked((int) 0xc0e52aa0), unchecked((int) 0x3c43e022), unchecked((int) 0x121d171b), unchecked((int) 0x0e0b0d09), + unchecked((int) 0xf2adc78b), unchecked((int) 0x2db9a8b6), unchecked((int) 0x14c8a91e), unchecked((int) 0x578519f1), unchecked((int) 0xaf4c0775), + unchecked((int) 0xeebbdd99), unchecked((int) 0xa3fd607f), unchecked((int) 0xf79f2601), unchecked((int) 0x5cbcf572), unchecked((int) 0x44c53b66), + unchecked((int) 0x5b347efb), unchecked((int) 0x8b762943), unchecked((int) 0xcbdcc623), unchecked((int) 0xb668fced), unchecked((int) 0xb863f1e4), + unchecked((int) 0xd7cadc31), unchecked((int) 0x42108563), unchecked((int) 0x13402297), unchecked((int) 0x842011c6), unchecked((int) 0x857d244a), + unchecked((int) 0xd2f83dbb), unchecked((int) 0xae1132f9), unchecked((int) 0xc76da129), unchecked((int) 0x1d4b2f9e), unchecked((int) 0xdcf330b2), + unchecked((int) 0x0dec5286), unchecked((int) 0x77d0e3c1), unchecked((int) 0x2b6c16b3), unchecked((int) 0xa999b970), unchecked((int) 0x11fa4894), + unchecked((int) 0x472264e9), unchecked((int) 0xa8c48cfc), unchecked((int) 0xa01a3ff0), unchecked((int) 0x56d82c7d), unchecked((int) 0x22ef9033), + unchecked((int) 0x87c74e49), unchecked((int) 0xd9c1d138), unchecked((int) 0x8cfea2ca), unchecked((int) 0x98360bd4), unchecked((int) 0xa6cf81f5), + unchecked((int) 0xa528de7a), unchecked((int) 0xda268eb7), unchecked((int) 0x3fa4bfad), unchecked((int) 0x2ce49d3a), unchecked((int) 0x500d9278), + unchecked((int) 0x6a9bcc5f), unchecked((int) 0x5462467e), unchecked((int) 0xf6c2138d), unchecked((int) 0x90e8b8d8), unchecked((int) 0x2e5ef739), + unchecked((int) 0x82f5afc3), unchecked((int) 0x9fbe805d), unchecked((int) 0x697c93d0), unchecked((int) 0x6fa92dd5), unchecked((int) 0xcfb31225), + unchecked((int) 0xc83b99ac), unchecked((int) 0x10a77d18), unchecked((int) 0xe86e639c), unchecked((int) 0xdb7bbb3b), unchecked((int) 0xcd097826), + unchecked((int) 0x6ef41859), unchecked((int) 0xec01b79a), unchecked((int) 0x83a89a4f), unchecked((int) 0xe6656e95), unchecked((int) 0xaa7ee6ff), + unchecked((int) 0x2108cfbc), unchecked((int) 0xefe6e815), unchecked((int) 0xbad99be7), unchecked((int) 0x4ace366f), unchecked((int) 0xead4099f), + unchecked((int) 0x29d67cb0), unchecked((int) 0x31afb2a4), unchecked((int) 0x2a31233f), unchecked((int) 0xc63094a5), unchecked((int) 0x35c066a2), + unchecked((int) 0x7437bc4e), unchecked((int) 0xfca6ca82), unchecked((int) 0xe0b0d090), unchecked((int) 0x3315d8a7), unchecked((int) 0xf14a9804), + unchecked((int) 0x41f7daec), unchecked((int) 0x7f0e50cd), unchecked((int) 0x172ff691), unchecked((int) 0x768dd64d), unchecked((int) 0x434db0ef), + unchecked((int) 0xcc544daa), unchecked((int) 0xe4df0496), unchecked((int) 0x9ee3b5d1), unchecked((int) 0x4c1b886a), unchecked((int) 0xc1b81f2c), + unchecked((int) 0x467f5165), unchecked((int) 0x9d04ea5e), unchecked((int) 0x015d358c), unchecked((int) 0xfa737487), unchecked((int) 0xfb2e410b), + unchecked((int) 0xb35a1d67), unchecked((int) 0x9252d2db), unchecked((int) 0xe9335610), unchecked((int) 0x6d1347d6), unchecked((int) 0x9a8c61d7), + unchecked((int) 0x377a0ca1), unchecked((int) 0x598e14f8), unchecked((int) 0xeb893c13), unchecked((int) 0xceee27a9), unchecked((int) 0xb735c961), + unchecked((int) 0xe1ede51c), unchecked((int) 0x7a3cb147), unchecked((int) 0x9c59dfd2), unchecked((int) 0x553f73f2), unchecked((int) 0x1879ce14), + unchecked((int) 0x73bf37c7), unchecked((int) 0x53eacdf7), unchecked((int) 0x5f5baafd), unchecked((int) 0xdf146f3d), unchecked((int) 0x7886db44), + unchecked((int) 0xca81f3af), unchecked((int) 0xb93ec468), unchecked((int) 0x382c3424), unchecked((int) 0xc25f40a3), unchecked((int) 0x1672c31d), + unchecked((int) 0xbc0c25e2), unchecked((int) 0x288b493c), unchecked((int) 0xff41950d), unchecked((int) 0x397101a8), unchecked((int) 0x08deb30c), + unchecked((int) 0xd89ce4b4), unchecked((int) 0x6490c156), unchecked((int) 0x7b6184cb), unchecked((int) 0xd570b632), unchecked((int) 0x48745c6c), + unchecked((int) 0xd04257b8)}; + + private int Shift( + int r, + int shift) + { + return ((int) ( ( (uint) r >> shift) | + (uint) (r << (32 - shift)) + )); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private const int m1 = unchecked((int) 0x80808080); + private const int m2 = unchecked((int) 0x7f7f7f7f); + private const int m3 = unchecked((int) 0x0000001b); + private int FFmulX(int x) { + return ( (int) ( ((x & m2) << 1) ^ + (( (uint)(x & m1) >> 7) * m3) + ) ); + } + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private int Inv_Mcol(int x) { + int f2 = FFmulX(x); + int f4 = FFmulX(f2); + int f8 = FFmulX(f4); + int f9 = x ^ f8; + + return f2 ^ f4 ^ f8 ^ Shift(f2 ^ f9, 8) ^ Shift(f4 ^ f9, 16) ^ Shift(f9, 24); + } + + + private int SubWord(int x) { + return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private int[,] GenerateWorkingKey( + byte[] key, + bool forEncryption) + { + int KC = key.Length / 4; // key length in words + int t; + + if ((KC != 4) && (KC != 6) && (KC != 8)) { + throw new ArgumentException("Key length not 128/192/256 bits."); + } + + ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + int[,] W = new int[ROUNDS+1,4]; // 4 words in a block + + // + // copy the key into the round key array + // + + t = 0; + for (int i = 0; i < key.Length; t++) + { + W[t >> 2,t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24); + i+=4; + } + + // + // while not enough round key material calculated + // calculate new values + // + int k = (ROUNDS + 1) << 2; + for (int i = KC; (i < k); i++) + { + int temp = W[(i-1)>>2,(i-1)&3]; + if ((i % KC) == 0) { + temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC)-1]; + } else if ((KC > 6) && ((i % KC) == 4)) { + temp = SubWord(temp); + } + + W[i>>2,i&3] = W[(i - KC)>>2,(i-KC)&3] ^ temp; + } + + if (!forEncryption) { + for (int j = 1; j < ROUNDS; j++) { + for (int i = 0; i < 4; i++){ + W[j,i] = Inv_Mcol(W[j,i]); + } + } + } + + return W; + } + + private int ROUNDS; + private int[,] WorkingKey; + private int C0, C1, C2, C3; + private bool forEncryption; + + private const int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AesFastEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to AES init - " + parameters.GetType().ToString()); + + WorkingKey = GenerateWorkingKey(((KeyParameter)parameters).GetKey(), forEncryption); + this.forEncryption = forEncryption; + } + + public string AlgorithmName + { + get { return "AES"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (WorkingKey == null) + { + throw new InvalidOperationException("AES engine not initialised"); + } + + if ((inOff + (32 / 2)) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + (32 / 2)) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (forEncryption) + { + UnPackBlock(input, inOff); + EncryptBlock(WorkingKey); + PackBlock(output, outOff); + } + else + { + UnPackBlock(input, inOff); + DecryptBlock(WorkingKey); + PackBlock(output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + } + + private void UnPackBlock( + byte[] bytes, + int off) + { + int index = off; + + C0 = (bytes[index++] & 0xff); + C0 |= (bytes[index++] & 0xff) << 8; + C0 |= (bytes[index++] & 0xff) << 16; + C0 |= bytes[index++] << 24; + + C1 = (bytes[index++] & 0xff); + C1 |= (bytes[index++] & 0xff) << 8; + C1 |= (bytes[index++] & 0xff) << 16; + C1 |= bytes[index++] << 24; + + C2 = (bytes[index++] & 0xff); + C2 |= (bytes[index++] & 0xff) << 8; + C2 |= (bytes[index++] & 0xff) << 16; + C2 |= bytes[index++] << 24; + + C3 = (bytes[index++] & 0xff); + C3 |= (bytes[index++] & 0xff) << 8; + C3 |= (bytes[index++] & 0xff) << 16; + C3 |= bytes[index++] << 24; + } + + private void PackBlock( + byte[] bytes, + int off) + { + int index = off; + + bytes[index++] = (byte)C0; + bytes[index++] = (byte)(C0 >> 8); + bytes[index++] = (byte)(C0 >> 16); + bytes[index++] = (byte)(C0 >> 24); + + bytes[index++] = (byte)C1; + bytes[index++] = (byte)(C1 >> 8); + bytes[index++] = (byte)(C1 >> 16); + bytes[index++] = (byte)(C1 >> 24); + + bytes[index++] = (byte)C2; + bytes[index++] = (byte)(C2 >> 8); + bytes[index++] = (byte)(C2 >> 16); + bytes[index++] = (byte)(C2 >> 24); + + bytes[index++] = (byte)C3; + bytes[index++] = (byte)(C3 >> 8); + bytes[index++] = (byte)(C3 >> 16); + bytes[index++] = (byte)(C3 >> 24); + } + + private void EncryptBlock(int[,] KW) + { + int r, r0, r1, r2, r3; + + C0 ^= KW[0,0]; + C1 ^= KW[0,1]; + C2 ^= KW[0,2]; + C3 ^= KW[0,3]; + + for (r = 1; r < ROUNDS - 1;) { + r0 = T0[C0&255] ^ T1[(C1>>8)&255] ^ T2[(C2>>16)&255] ^ T3[(C3>>24)&255] ^ KW[r,0]; + r1 = T0[C1&255] ^ T1[(C2>>8)&255] ^ T2[(C3>>16)&255] ^ T3[(C0>>24)&255] ^ KW[r,1]; + r2 = T0[C2&255] ^ T1[(C3>>8)&255] ^ T2[(C0>>16)&255] ^ T3[(C1>>24)&255] ^ KW[r,2]; + r3 = T0[C3&255] ^ T1[(C0>>8)&255] ^ T2[(C1>>16)&255] ^ T3[(C2>>24)&255] ^ KW[r++,3]; + C0 = T0[r0&255] ^ T1[(r1>>8)&255] ^ T2[(r2>>16)&255] ^ T3[(r3>>24)&255] ^ KW[r,0]; + C1 = T0[r1&255] ^ T1[(r2>>8)&255] ^ T2[(r3>>16)&255] ^ T3[(r0>>24)&255] ^ KW[r,1]; + C2 = T0[r2&255] ^ T1[(r3>>8)&255] ^ T2[(r0>>16)&255] ^ T3[(r1>>24)&255] ^ KW[r,2]; + C3 = T0[r3&255] ^ T1[(r0>>8)&255] ^ T2[(r1>>16)&255] ^ T3[(r2>>24)&255] ^ KW[r++,3]; + } + + r0 = T0[C0&255] ^ T1[(C1>>8)&255] ^ T2[(C2>>16)&255] ^ T3[(C3>>24)&255] ^ KW[r,0]; + r1 = T0[C1&255] ^ T1[(C2>>8)&255] ^ T2[(C3>>16)&255] ^ T3[(C0>>24)&255] ^ KW[r,1]; + r2 = T0[C2&255] ^ T1[(C3>>8)&255] ^ T2[(C0>>16)&255] ^ T3[(C1>>24)&255] ^ KW[r,2]; + r3 = T0[C3&255] ^ T1[(C0>>8)&255] ^ T2[(C1>>16)&255] ^ T3[(C2>>24)&255] ^ KW[r++,3]; + + // the final round's table is a simple function of S so we don't use a whole other four tables for it + + C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r,0]; + C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r,1]; + C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r,2]; + C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r,3]; + + } + + private void DecryptBlock(int[,] KW) + { + int r, r0, r1, r2, r3; + + C0 ^= KW[ROUNDS,0]; + C1 ^= KW[ROUNDS,1]; + C2 ^= KW[ROUNDS,2]; + C3 ^= KW[ROUNDS,3]; + + for (r = ROUNDS-1; r>1;) { + r0 = Tinv0[C0&255] ^ Tinv1[(C3>>8)&255] ^ Tinv2[(C2>>16)&255] ^ Tinv3[(C1>>24)&255] ^ KW[r,0]; + r1 = Tinv0[C1&255] ^ Tinv1[(C0>>8)&255] ^ Tinv2[(C3>>16)&255] ^ Tinv3[(C2>>24)&255] ^ KW[r,1]; + r2 = Tinv0[C2&255] ^ Tinv1[(C1>>8)&255] ^ Tinv2[(C0>>16)&255] ^ Tinv3[(C3>>24)&255] ^ KW[r,2]; + r3 = Tinv0[C3&255] ^ Tinv1[(C2>>8)&255] ^ Tinv2[(C1>>16)&255] ^ Tinv3[(C0>>24)&255] ^ KW[r--,3]; + C0 = Tinv0[r0&255] ^ Tinv1[(r3>>8)&255] ^ Tinv2[(r2>>16)&255] ^ Tinv3[(r1>>24)&255] ^ KW[r,0]; + C1 = Tinv0[r1&255] ^ Tinv1[(r0>>8)&255] ^ Tinv2[(r3>>16)&255] ^ Tinv3[(r2>>24)&255] ^ KW[r,1]; + C2 = Tinv0[r2&255] ^ Tinv1[(r1>>8)&255] ^ Tinv2[(r0>>16)&255] ^ Tinv3[(r3>>24)&255] ^ KW[r,2]; + C3 = Tinv0[r3&255] ^ Tinv1[(r2>>8)&255] ^ Tinv2[(r1>>16)&255] ^ Tinv3[(r0>>24)&255] ^ KW[r--,3]; + } + + r0 = Tinv0[C0&255] ^ Tinv1[(C3>>8)&255] ^ Tinv2[(C2>>16)&255] ^ Tinv3[(C1>>24)&255] ^ KW[r,0]; + r1 = Tinv0[C1&255] ^ Tinv1[(C0>>8)&255] ^ Tinv2[(C3>>16)&255] ^ Tinv3[(C2>>24)&255] ^ KW[r,1]; + r2 = Tinv0[C2&255] ^ Tinv1[(C1>>8)&255] ^ Tinv2[(C0>>16)&255] ^ Tinv3[(C3>>24)&255] ^ KW[r,2]; + r3 = Tinv0[C3&255] ^ Tinv1[(C2>>8)&255] ^ Tinv2[(C1>>16)&255] ^ Tinv3[(C0>>24)&255] ^ KW[r,3]; + + // the final round's table is a simple function of Si so we don't use a whole other four tables for it + + C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0,0]; + C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0,1]; + C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0,2]; + C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0,3]; + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/AesLightEngine.cs b/iTechSharp/srcbc/crypto/engines/AesLightEngine.cs new file mode 100644 index 0000000..40269c6 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/AesLightEngine.cs @@ -0,0 +1,438 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the AES (Rijndael), from FIPS-197. + *+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor, they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first + * + * The slowest version uses no static tables at all and computes the values + * in each round. + *
+ *+ * This file contains the slowest performance version with no static tables + * for round precomputation, but it has the smallest foot print. + *
+ */ + public class AesLightEngine + : IBlockCipher + { + // The S box + private static readonly byte[] S = { + (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, + (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, + (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, + (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, + (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, + (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, + (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, + (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, + (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, + (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, + (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, + (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, + (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, + (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, + (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, + (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, + (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, + (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, + (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, + (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, + (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, + (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, + (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, + (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, + (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, + (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, + (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, + (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, + (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, + (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, + (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, + (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, + }; + + // The inverse S-box + private static readonly byte[] Si = { + (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, + (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, + (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, + (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, + (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, + (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, + (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, + (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, + (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, + (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, + (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, + (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, + (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, + (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, + (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, + (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, + (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, + (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, + (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, + (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, + (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, + (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, + (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, + (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, + (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, + (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, + (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, + (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, + (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, + (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, + (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, + (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static readonly int[] rcon = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; + + private int Shift( + int r, + int shift) + { + return ((int) ( ( (uint) r >> shift) | + (uint) (r << (32 - shift)) ) + ); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private const int m1 = unchecked((int) 0x80808080); + private const int m2 = unchecked((int) 0x7f7f7f7f); + private const int m3 = unchecked((int) 0x0000001b); + + private int FFmulX(int x) + { + return ( (int) ( ((x & m2) << 1) ^ + (( (uint)(x & m1) >> 7) * m3) + ) + ); + } + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private int Mcol(int x) + { + int f2 = FFmulX(x); + return f2 ^ Shift(x ^ f2, 8) ^ Shift(x, 16) ^ Shift(x, 24); + } + + private int Inv_Mcol(int x) + { + int f2 = FFmulX(x); + int f4 = FFmulX(f2); + int f8 = FFmulX(f4); + int f9 = x ^ f8; + + return f2 ^ f4 ^ f8 ^ Shift(f2 ^ f9, 8) ^ Shift(f4 ^ f9, 16) ^ Shift(f9, 24); + } + + + private int SubWord(int x) + { + return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private int[,] GenerateWorkingKey( + byte[] key, + bool forEncryption) + { + int KC = key.Length / 4; // key length in words + int t; + + if ((KC != 4) && (KC != 6) && (KC != 8)) { + throw new ArgumentException("Key length not 128/192/256 bits."); + } + + ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + int[,] W = new int[ROUNDS+1,4]; // 4 words in a block + + // + // copy the key into the round key array + // + + t = 0; + for (int i = 0; i < key.Length; t++) + { + W[t >> 2,t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24); + i+=4; + } + + // + // while not enough round key material calculated + // calculate new values + // + int k = (ROUNDS + 1) << 2; + for (int i = KC; (i < k); i++) + { + int temp = W[(i-1)>>2,(i-1)&3]; + if ((i % KC) == 0) { + temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC)-1]; + } else if ((KC > 6) && ((i % KC) == 4)) { + temp = SubWord(temp); + } + + W[i>>2,i&3] = W[(i - KC)>>2,(i-KC)&3] ^ temp; + } + + if (!forEncryption) { + for (int j = 1; j < ROUNDS; j++) { + for (int i = 0; i < 4; i++){ + W[j,i] = Inv_Mcol(W[j,i]); + } + } + } + + return W; + } + + private int ROUNDS; + private int[,] WorkingKey; + private int C0, C1, C2, C3; + private bool forEncryption; + + private const int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AesLightEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to AES init - " + parameters.GetType().ToString()); + + WorkingKey = GenerateWorkingKey(((KeyParameter)parameters).GetKey(), forEncryption); + this.forEncryption = forEncryption; + } + + public string AlgorithmName + { + get { return "AES"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (WorkingKey == null) + { + throw new InvalidOperationException("AES engine not initialised"); + } + + if ((inOff + (32 / 2)) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + (32 / 2)) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (forEncryption) + { + UnPackBlock(input, inOff); + EncryptBlock(WorkingKey); + PackBlock(output, outOff); + } + else + { + UnPackBlock(input, inOff); + DecryptBlock(WorkingKey); + PackBlock(output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + } + + private void UnPackBlock( + byte[] bytes, + int off) + { + int index = off; + + C0 = (bytes[index++] & 0xff); + C0 |= (bytes[index++] & 0xff) << 8; + C0 |= (bytes[index++] & 0xff) << 16; + C0 |= bytes[index++] << 24; + + C1 = (bytes[index++] & 0xff); + C1 |= (bytes[index++] & 0xff) << 8; + C1 |= (bytes[index++] & 0xff) << 16; + C1 |= bytes[index++] << 24; + + C2 = (bytes[index++] & 0xff); + C2 |= (bytes[index++] & 0xff) << 8; + C2 |= (bytes[index++] & 0xff) << 16; + C2 |= bytes[index++] << 24; + + C3 = (bytes[index++] & 0xff); + C3 |= (bytes[index++] & 0xff) << 8; + C3 |= (bytes[index++] & 0xff) << 16; + C3 |= bytes[index++] << 24; + } + + private void PackBlock( + byte[] bytes, + int off) + { + int index = off; + + bytes[index++] = (byte)C0; + bytes[index++] = (byte)(C0 >> 8); + bytes[index++] = (byte)(C0 >> 16); + bytes[index++] = (byte)(C0 >> 24); + + bytes[index++] = (byte)C1; + bytes[index++] = (byte)(C1 >> 8); + bytes[index++] = (byte)(C1 >> 16); + bytes[index++] = (byte)(C1 >> 24); + + bytes[index++] = (byte)C2; + bytes[index++] = (byte)(C2 >> 8); + bytes[index++] = (byte)(C2 >> 16); + bytes[index++] = (byte)(C2 >> 24); + + bytes[index++] = (byte)C3; + bytes[index++] = (byte)(C3 >> 8); + bytes[index++] = (byte)(C3 >> 16); + bytes[index++] = (byte)(C3 >> 24); + } + + private void EncryptBlock(int[,] KW) + { + int r, r0, r1, r2, r3; + + C0 ^= KW[0,0]; + C1 ^= KW[0,1]; + C2 ^= KW[0,2]; + C3 ^= KW[0,3]; + + for (r = 1; r < ROUNDS - 1;) { + r0 = Mcol((S[C0&255]&255) ^ ((S[(C1>>8)&255]&255)<<8) ^ ((S[(C2>>16)&255]&255)<<16) ^ (S[(C3>>24)&255]<<24)) ^ KW[r,0]; + r1 = Mcol((S[C1&255]&255) ^ ((S[(C2>>8)&255]&255)<<8) ^ ((S[(C3>>16)&255]&255)<<16) ^ (S[(C0>>24)&255]<<24)) ^ KW[r,1]; + r2 = Mcol((S[C2&255]&255) ^ ((S[(C3>>8)&255]&255)<<8) ^ ((S[(C0>>16)&255]&255)<<16) ^ (S[(C1>>24)&255]<<24)) ^ KW[r,2]; + r3 = Mcol((S[C3&255]&255) ^ ((S[(C0>>8)&255]&255)<<8) ^ ((S[(C1>>16)&255]&255)<<16) ^ (S[(C2>>24)&255]<<24)) ^ KW[r++,3]; + C0 = Mcol((S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24)) ^ KW[r,0]; + C1 = Mcol((S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24)) ^ KW[r,1]; + C2 = Mcol((S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24)) ^ KW[r,2]; + C3 = Mcol((S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24)) ^ KW[r++,3]; + } + + r0 = Mcol((S[C0&255]&255) ^ ((S[(C1>>8)&255]&255)<<8) ^ ((S[(C2>>16)&255]&255)<<16) ^ (S[(C3>>24)&255]<<24)) ^ KW[r,0]; + r1 = Mcol((S[C1&255]&255) ^ ((S[(C2>>8)&255]&255)<<8) ^ ((S[(C3>>16)&255]&255)<<16) ^ (S[(C0>>24)&255]<<24)) ^ KW[r,1]; + r2 = Mcol((S[C2&255]&255) ^ ((S[(C3>>8)&255]&255)<<8) ^ ((S[(C0>>16)&255]&255)<<16) ^ (S[(C1>>24)&255]<<24)) ^ KW[r,2]; + r3 = Mcol((S[C3&255]&255) ^ ((S[(C0>>8)&255]&255)<<8) ^ ((S[(C1>>16)&255]&255)<<16) ^ (S[(C2>>24)&255]<<24)) ^ KW[r++,3]; + + // the final round is a simple function of S + + C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r,0]; + C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r,1]; + C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r,2]; + C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r,3]; + + } + + private void DecryptBlock(int[,] KW) + { + int r, r0, r1, r2, r3; + + C0 ^= KW[ROUNDS,0]; + C1 ^= KW[ROUNDS,1]; + C2 ^= KW[ROUNDS,2]; + C3 ^= KW[ROUNDS,3]; + + for (r = ROUNDS-1; r>1;) { + r0 = Inv_Mcol((Si[C0&255]&255) ^ ((Si[(C3>>8)&255]&255)<<8) ^ ((Si[(C2>>16)&255]&255)<<16) ^ (Si[(C1>>24)&255]<<24)) ^ KW[r,0]; + r1 = Inv_Mcol((Si[C1&255]&255) ^ ((Si[(C0>>8)&255]&255)<<8) ^ ((Si[(C3>>16)&255]&255)<<16) ^ (Si[(C2>>24)&255]<<24)) ^ KW[r,1]; + r2 = Inv_Mcol((Si[C2&255]&255) ^ ((Si[(C1>>8)&255]&255)<<8) ^ ((Si[(C0>>16)&255]&255)<<16) ^ (Si[(C3>>24)&255]<<24)) ^ KW[r,2]; + r3 = Inv_Mcol((Si[C3&255]&255) ^ ((Si[(C2>>8)&255]&255)<<8) ^ ((Si[(C1>>16)&255]&255)<<16) ^ (Si[(C0>>24)&255]<<24)) ^ KW[r--,3]; + C0 = Inv_Mcol((Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24)) ^ KW[r,0]; + C1 = Inv_Mcol((Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24)) ^ KW[r,1]; + C2 = Inv_Mcol((Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24)) ^ KW[r,2]; + C3 = Inv_Mcol((Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24)) ^ KW[r--,3]; + } + + r0 = Inv_Mcol((Si[C0&255]&255) ^ ((Si[(C3>>8)&255]&255)<<8) ^ ((Si[(C2>>16)&255]&255)<<16) ^ (Si[(C1>>24)&255]<<24)) ^ KW[r,0]; + r1 = Inv_Mcol((Si[C1&255]&255) ^ ((Si[(C0>>8)&255]&255)<<8) ^ ((Si[(C3>>16)&255]&255)<<16) ^ (Si[(C2>>24)&255]<<24)) ^ KW[r,1]; + r2 = Inv_Mcol((Si[C2&255]&255) ^ ((Si[(C1>>8)&255]&255)<<8) ^ ((Si[(C0>>16)&255]&255)<<16) ^ (Si[(C3>>24)&255]<<24)) ^ KW[r,2]; + r3 = Inv_Mcol((Si[C3&255]&255) ^ ((Si[(C2>>8)&255]&255)<<8) ^ ((Si[(C1>>16)&255]&255)<<16) ^ (Si[(C0>>24)&255]<<24)) ^ KW[r,3]; + + // the final round's table is a simple function of Si + + C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0,0]; + C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0,1]; + C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0,2]; + C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0,3]; + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/AesWrapEngine.cs b/iTechSharp/srcbc/crypto/engines/AesWrapEngine.cs new file mode 100644 index 0000000..1ce0154 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/AesWrapEngine.cs @@ -0,0 +1,16 @@ +namespace Org.BouncyCastle.Crypto.Engines +{ + ///+ * Note: + *
+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf + *
+ * It is a third phase candidate in the eStream contest, and is patent-free. + * No attacks are known as of today (April 2007). See + * + * http://www.ecrypt.eu.org/stream/hcp3.html + *
+ */ + public class HC128Engine + : IStreamCipher + { + private uint[] p = new uint[512]; + private uint[] q = new uint[512]; + private uint cnt = 0; + + private static uint F1(uint x) + { + return RotateRight(x, 7) ^ RotateRight(x, 18) ^ (x >> 3); + } + + private static uint F2(uint x) + { + return RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10); + } + + private uint G1(uint x, uint y, uint z) + { + return (RotateRight(x, 10) ^ RotateRight(z, 23)) + RotateRight(y, 8); + } + + private uint G2(uint x, uint y, uint z) + { + return (RotateLeft(x, 10) ^ RotateLeft(z, 23)) + RotateLeft(y, 8); + } + + private static uint RotateLeft(uint x, int bits) + { + return (x << bits) | (x >> -bits); + } + + private static uint RotateRight(uint x, int bits) + { + return (x >> bits) | (x << -bits); + } + + private uint H1(uint x) + { + return q[x & 0xFF] + q[((x >> 16) & 0xFF) + 256]; + } + + private uint H2(uint x) + { + return p[x & 0xFF] + p[((x >> 16) & 0xFF) + 256]; + } + + private static uint Mod1024(uint x) + { + return x & 0x3FF; + } + + private static uint Mod512(uint x) + { + return x & 0x1FF; + } + + private static uint Dim(uint x, uint y) + { + return Mod512(x - y); + } + + private uint Step() + { + uint j = Mod512(cnt); + uint ret; + if (cnt < 512) + { + p[j] += G1(p[Dim(j, 3)], p[Dim(j, 10)], p[Dim(j, 511)]); + ret = H1(p[Dim(j, 12)]) ^ p[j]; + } + else + { + q[j] += G2(q[Dim(j, 3)], q[Dim(j, 10)], q[Dim(j, 511)]); + ret = H2(q[Dim(j, 12)]) ^ q[j]; + } + cnt = Mod1024(cnt + 1); + return ret; + } + + private byte[] key, iv; + private bool initialised; + + private void Init() + { + if (key.Length != 16) + throw new ArgumentException("The key must be 128 bit long"); + + cnt = 0; + + uint[] w = new uint[1280]; + + for (int i = 0; i < 16; i++) + { + w[i >> 3] |= ((uint)key[i] << (i & 0x7)); + } + Array.Copy(w, 0, w, 4, 4); + + for (int i = 0; i < iv.Length && i < 16; i++) + { + w[(i >> 3) + 8] |= ((uint)iv[i] << (i & 0x7)); + } + Array.Copy(w, 8, w, 12, 4); + + for (uint i = 16; i < 1280; i++) + { + w[i] = F2(w[i - 2]) + w[i - 7] + F1(w[i - 15]) + w[i - 16] + i; + } + + Array.Copy(w, 256, p, 0, 512); + Array.Copy(w, 768, q, 0, 512); + + for (int i = 0; i < 512; i++) + { + p[i] = Step(); + } + for (int i = 0; i < 512; i++) + { + q[i] = Step(); + } + + cnt = 0; + } + + public string AlgorithmName + { + get { return "HC-128"; } + } + + /** + * Initialise a HC-128 cipher. + * + * @param forEncryption whether or not we are for encryption. Irrelevant, as + * encryption and decryption are the same. + * @param params the parameters required to set up the cipher. + * @throws ArgumentException if the params argument is + * inappropriate (ie. the key is not 128 bit long). + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + ICipherParameters keyParam = parameters; + + if (parameters is ParametersWithIV) + { + iv = ((ParametersWithIV)parameters).GetIV(); + keyParam = ((ParametersWithIV)parameters).Parameters; + } + else + { + iv = new byte[0]; + } + + if (keyParam is KeyParameter) + { + key = ((KeyParameter)keyParam).GetKey(); + Init(); + } + else + { + throw new ArgumentException( + "Invalid parameter passed to HC128 init - " + parameters.GetType().Name, + "parameters"); + } + + initialised = true; + } + + private byte[] buf = new byte[4]; + private int idx = 0; + + private byte GetByte() + { + if (idx == 0) + { + uint step = Step(); + buf[3] = (byte)step; + step >>= 8; + buf[2] = (byte)step; + step >>= 8; + buf[1] = (byte)step; + step >>= 8; + buf[0] = (byte)step; + } + byte ret = buf[idx]; + idx = idx + 1 & 0x3; + return ret; + } + + public void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + if ((inOff + len) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + len) > output.Length) + throw new DataLengthException("output buffer too short"); + + for (int i = 0; i < len; i++) + { + output[outOff + i] = (byte)(input[inOff + i] ^ GetByte()); + } + } + + public void Reset() + { + idx = 0; + Init(); + } + + public byte ReturnByte(byte input) + { + return (byte)(input ^ GetByte()); + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/HC256Engine.cs b/iTechSharp/srcbc/crypto/engines/HC256Engine.cs new file mode 100644 index 0000000..8b18d5d --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/HC256Engine.cs @@ -0,0 +1,207 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * HC-256 is a software-efficient stream cipher created by Hongjun Wu. It + * generates keystream from a 256-bit secret key and a 256-bit initialization + * vector. + *+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf + *
+ * Its brother, HC-128, is a third phase candidate in the eStream contest. + * The algorithm is patent-free. No attacks are known as of today (April 2007). + * See + * + * http://www.ecrypt.eu.org/stream/hcp3.html + *
+ */ + public class HC256Engine + : IStreamCipher + { + private uint[] p = new uint[1024]; + private uint[] q = new uint[1024]; + private uint cnt = 0; + + private uint Step() + { + uint j = cnt & 0x3FF; + uint ret; + if (cnt < 1024) + { + uint x = p[(j - 3 & 0x3FF)]; + uint y = p[(j - 1023 & 0x3FF)]; + p[j] += p[(j - 10 & 0x3FF)] + + (RotateRight(x, 10) ^ RotateRight(y, 23)) + + q[((x ^ y) & 0x3FF)]; + + x = p[(j - 12 & 0x3FF)]; + ret = (q[x & 0xFF] + q[((x >> 8) & 0xFF) + 256] + + q[((x >> 16) & 0xFF) + 512] + q[((x >> 24) & 0xFF) + 768]) + ^ p[j]; + } + else + { + uint x = q[(j - 3 & 0x3FF)]; + uint y = q[(j - 1023 & 0x3FF)]; + q[j] += q[(j - 10 & 0x3FF)] + + (RotateRight(x, 10) ^ RotateRight(y, 23)) + + p[((x ^ y) & 0x3FF)]; + + x = q[(j - 12 & 0x3FF)]; + ret = (p[x & 0xFF] + p[((x >> 8) & 0xFF) + 256] + + p[((x >> 16) & 0xFF) + 512] + p[((x >> 24) & 0xFF) + 768]) + ^ q[j]; + } + cnt = cnt + 1 & 0x7FF; + return ret; + } + + private byte[] key, iv; + private bool initialised; + + private void Init() + { + if (key.Length != 32) + throw new ArgumentException("The key must be 256 bit long"); + + cnt = 0; + + uint[] w = new uint[2560]; + + for (int i = 0; i < 32; i++) + { + w[i >> 3] |= ((uint)key[i] << (i & 0x7)); + } + + for (int i = 0; i < iv.Length && i < 32; i++) + { + w[(i >> 3) + 8] |= ((uint)iv[i] << (i & 0x7)); + } + + for (uint i = 16; i < 2560; i++) + { + uint x = w[i - 2]; + uint y = w[i - 15]; + w[i] = (RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10)) + + w[i - 7] + + (RotateRight(y, 7) ^ RotateRight(y, 18) ^ (y >> 3)) + + w[i - 16] + i; + } + + Array.Copy(w, 512, p, 0, 1024); + Array.Copy(w, 1536, q, 0, 1024); + + for (int i = 0; i < 4096; i++) + { + Step(); + } + + cnt = 0; + } + + public string AlgorithmName + { + get { return "HC-256"; } + } + + /** + * Initialise a HC-256 cipher. + * + * @param forEncryption whether or not we are for encryption. Irrelevant, as + * encryption and decryption are the same. + * @param params the parameters required to set up the cipher. + * @throws ArgumentException if the params argument is + * inappropriate (ie. the key is not 256 bit long). + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + ICipherParameters keyParam = parameters; + + if (parameters is ParametersWithIV) + { + iv = ((ParametersWithIV)parameters).GetIV(); + keyParam = ((ParametersWithIV)parameters).Parameters; + } + else + { + iv = new byte[0]; + } + + if (keyParam is KeyParameter) + { + key = ((KeyParameter)keyParam).GetKey(); + Init(); + } + else + { + throw new ArgumentException( + "Invalid parameter passed to HC256 init - " + parameters.GetType().Name, + "parameters"); + } + + initialised = true; + } + + private byte[] buf = new byte[4]; + private int idx = 0; + + private byte GetByte() + { + if (idx == 0) + { + uint step = Step(); + buf[3] = (byte)step; + step >>= 8; + buf[2] = (byte)step; + step >>= 8; + buf[1] = (byte)step; + step >>= 8; + buf[0] = (byte)step; + } + byte ret = buf[idx]; + idx = idx + 1 & 0x3; + return ret; + } + + public void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + if ((inOff + len) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + len) > output.Length) + throw new DataLengthException("output buffer too short"); + + for (int i = 0; i < len; i++) + { + output[outOff + i] = (byte)(input[inOff + i] ^ GetByte()); + } + } + + public void Reset() + { + idx = 0; + Init(); + } + + public byte ReturnByte(byte input) + { + return (byte)(input ^ GetByte()); + } + + private static uint RotateRight(uint x, int bits) + { + return (x >> bits) | (x << -bits); + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/ISAACEngine.cs b/iTechSharp/srcbc/crypto/engines/ISAACEngine.cs new file mode 100644 index 0000000..1120a41 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/ISAACEngine.cs @@ -0,0 +1,252 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Implementation of Bob Jenkin's ISAAC (Indirection Shift Accumulate Add and Count). + * see: http://www.burtleburtle.net/bob/rand/isaacafa.html + */ + public class IsaacEngine + : IStreamCipher + { + // Constants + private static readonly int sizeL = 8, + stateArraySize = sizeL<<5; // 256 + + // Cipher's internal state + private uint[] engineState = null, // mm + results = null; // randrsl + private uint a = 0, b = 0, c = 0; + + // Engine state + private int index = 0; + private byte[] keyStream = new byte[stateArraySize<<2], // results expanded into bytes + workingKey = null; + private bool initialised = false; + + /** + * initialise an ISAAC cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException( + "invalid parameter passed to ISAAC Init - " + parameters.GetType().Name, + "parameters"); + + /* + * ISAAC encryption and decryption is completely + * symmetrical, so the 'forEncryption' is + * irrelevant. + */ + KeyParameter p = (KeyParameter) parameters; + setKey(p.GetKey()); + } + + public byte ReturnByte( + byte input) + { + if (index == 0) + { + isaac(); + keyStream = intToByteLittle(results); + } + + byte output = (byte)(keyStream[index]^input); + index = (index + 1) & 1023; + + return output; + } + + public void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + if ((inOff + len) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + len) > output.Length) + throw new DataLengthException("output buffer too short"); + + for (int i = 0; i < len; i++) + { + if (index == 0) + { + isaac(); + keyStream = intToByteLittle(results); + } + output[i+outOff] = (byte)(keyStream[index]^input[i+inOff]); + index = (index + 1) & 1023; + } + } + + public string AlgorithmName + { + get { return "ISAAC"; } + } + + public void Reset() + { + setKey(workingKey); + } + + // Private implementation + private void setKey( + byte[] keyBytes) + { + workingKey = keyBytes; + + if (engineState == null) + { + engineState = new uint[stateArraySize]; + } + + if (results == null) + { + results = new uint[stateArraySize]; + } + + int i, j, k; + + // Reset state + for (i = 0; i < stateArraySize; i++) + { + engineState[i] = results[i] = 0; + } + a = b = c = 0; + + // Reset index counter for output + index = 0; + + // Convert the key bytes to ints and put them into results[] for initialization + byte[] t = new byte[keyBytes.Length + (keyBytes.Length & 3)]; + Array.Copy(keyBytes, 0, t, 0, keyBytes.Length); + for (i = 0; i < t.Length; i+=4) + { + results[i>>2] = byteToIntLittle(t, i); + } + + // It has begun? + uint[] abcdefgh = new uint[sizeL]; + + for (i = 0; i < sizeL; i++) + { + abcdefgh[i] = 0x9e3779b9; // Phi (golden ratio) + } + + for (i = 0; i < 4; i++) + { + mix(abcdefgh); + } + + for (i = 0; i < 2; i++) + { + for (j = 0; j < stateArraySize; j+=sizeL) + { + for (k = 0; k < sizeL; k++) + { + abcdefgh[k] += (i<1) ? results[j+k] : engineState[j+k]; + } + + mix(abcdefgh); + + for (k = 0; k < sizeL; k++) + { + engineState[j+k] = abcdefgh[k]; + } + } + } + + isaac(); + + initialised = true; + } + + private void isaac() + { + uint x, y; + + b += ++c; + for (int i = 0; i < stateArraySize; i++) + { + x = engineState[i]; + switch (i & 3) + { + case 0: a ^= (a << 13); break; + case 1: a ^= (a >> 6); break; + case 2: a ^= (a << 2); break; + case 3: a ^= (a >> 16); break; + } + a += engineState[(i+128) & 0xFF]; + engineState[i] = y = engineState[(int)((uint)x >> 2) & 0xFF] + a + b; + results[i] = b = engineState[(int)((uint)y >> 10) & 0xFF] + x; + } + } + + private void mix(uint[] x) + { +// x[0]^=x[1]<< 11; x[3]+=x[0]; x[1]+=x[2]; +// x[1]^=x[2]>>> 2; x[4]+=x[1]; x[2]+=x[3]; +// x[2]^=x[3]<< 8; x[5]+=x[2]; x[3]+=x[4]; +// x[3]^=x[4]>>>16; x[6]+=x[3]; x[4]+=x[5]; +// x[4]^=x[5]<< 10; x[7]+=x[4]; x[5]+=x[6]; +// x[5]^=x[6]>>> 4; x[0]+=x[5]; x[6]+=x[7]; +// x[6]^=x[7]<< 8; x[1]+=x[6]; x[7]+=x[0]; +// x[7]^=x[0]>>> 9; x[2]+=x[7]; x[0]+=x[1]; + x[0]^=x[1]<< 11; x[3]+=x[0]; x[1]+=x[2]; + x[1]^=x[2]>> 2; x[4]+=x[1]; x[2]+=x[3]; + x[2]^=x[3]<< 8; x[5]+=x[2]; x[3]+=x[4]; + x[3]^=x[4]>> 16; x[6]+=x[3]; x[4]+=x[5]; + x[4]^=x[5]<< 10; x[7]+=x[4]; x[5]+=x[6]; + x[5]^=x[6]>> 4; x[0]+=x[5]; x[6]+=x[7]; + x[6]^=x[7]<< 8; x[1]+=x[6]; x[7]+=x[0]; + x[7]^=x[0]>> 9; x[2]+=x[7]; x[0]+=x[1]; + } + + private uint byteToIntLittle( + byte[] x, + int offset) + { + uint result = (byte) x[offset + 3]; + result = (result << 8) | x[offset + 2]; + result = (result << 8) | x[offset + 1]; + result = (result << 8) | x[offset + 0]; + return result; + } + + private byte[] intToByteLittle( + uint x) + { + byte[] output = new byte[4]; + output[3] = (byte)x; + output[2] = (byte)(x >> 8); + output[1] = (byte)(x >> 16); + output[0] = (byte)(x >> 24); + return output; + } + + private byte[] intToByteLittle( + uint[] x) + { + byte[] output = new byte[4*x.Length]; + for (int i = 0, j = 0; i < x.Length; i++,j+=4) + { + Array.Copy(intToByteLittle(x[i]), 0, output, j, 4); + } + return output; + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/IdeaEngine.cs b/iTechSharp/srcbc/crypto/engines/IdeaEngine.cs new file mode 100644 index 0000000..9d2a376 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/IdeaEngine.cs @@ -0,0 +1,333 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides a basic International Data Encryption Algorithm (IDEA) engine. + *+ * This implementation is based on the "HOWTO: INTERNATIONAL DATA ENCRYPTION ALGORITHM" + * implementation summary by Fauzan Mirza (F.U.Mirza@sheffield.ac.uk). (baring 1 typo at the + * end of the mulinv function!). + *
+ *+ * It can be found at ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/idea/ + *
+ *+ * Note: This algorithm is patented in the USA, Japan, and Europe including + * at least Austria, France, Germany, Italy, Netherlands, Spain, Sweden, Switzerland + * and the United Kingdom. Non-commercial use is free, however any commercial + * products are liable for royalties. Please see + * www.mediacrypt.com for + * further details. This announcement has been included at the request of + * the patent holders. + *
+ */ + public class IdeaEngine + : IBlockCipher + { + private const int BLOCK_SIZE = 8; + private int[] workingKey; + /** + * standard constructor. + */ + public IdeaEngine() + { + } + /** + * initialise an IDEA cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to IDEA init - " + parameters.GetType().ToString()); + + workingKey = GenerateWorkingKey(forEncryption, + ((KeyParameter)parameters).GetKey()); + } + + public string AlgorithmName + { + get { return "IDEA"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + { + throw new InvalidOperationException("IDEA engine not initialised"); + } + if ((inOff + BLOCK_SIZE) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + if ((outOff + BLOCK_SIZE) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + IdeaFunc(workingKey, input, inOff, output, outOff); + return BLOCK_SIZE; + } + public void Reset() + { + } + private static readonly int MASK = 0xffff; + private static readonly int BASE = 0x10001; + private int BytesToWord( + byte[] input, + int inOff) + { + return ((input[inOff] << 8) & 0xff00) + (input[inOff + 1] & 0xff); + } + private void WordToBytes( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)((uint) word >> 8); + outBytes[outOff + 1] = (byte)word; + } + /** + * return x = x * y where the multiplication is done modulo + * 65537 (0x10001) (as defined in the IDEA specification) and + * a zero input is taken to be 65536 (0x10000). + * + * @param x the x value + * @param y the y value + * @return x = x * y + */ + private int Mul( + int x, + int y) + { + if (x == 0) + { + x = (BASE - y); + } + else if (y == 0) + { + x = (BASE - x); + } + else + { + int p = x * y; + y = p & MASK; + x = (int) ((uint) p >> 16); + x = y - x + ((y < x) ? 1 : 0); + } + return x & MASK; + } + private void IdeaFunc( + int[] workingKey, + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x0, x1, x2, x3, t0, t1; + int keyOff = 0; + x0 = BytesToWord(input, inOff); + x1 = BytesToWord(input, inOff + 2); + x2 = BytesToWord(input, inOff + 4); + x3 = BytesToWord(input, inOff + 6); + for (int round = 0; round < 8; round++) + { + x0 = Mul(x0, workingKey[keyOff++]); + x1 += workingKey[keyOff++]; + x1 &= MASK; + x2 += workingKey[keyOff++]; + x2 &= MASK; + x3 = Mul(x3, workingKey[keyOff++]); + t0 = x1; + t1 = x2; + x2 ^= x0; + x1 ^= x3; + x2 = Mul(x2, workingKey[keyOff++]); + x1 += x2; + x1 &= MASK; + x1 = Mul(x1, workingKey[keyOff++]); + x2 += x1; + x2 &= MASK; + x0 ^= x1; + x3 ^= x2; + x1 ^= t1; + x2 ^= t0; + } + WordToBytes(Mul(x0, workingKey[keyOff++]), outBytes, outOff); + WordToBytes(x2 + workingKey[keyOff++], outBytes, outOff + 2); /* NB: Order */ + WordToBytes(x1 + workingKey[keyOff++], outBytes, outOff + 4); + WordToBytes(Mul(x3, workingKey[keyOff]), outBytes, outOff + 6); + } + /** + * The following function is used to expand the user key to the encryption + * subkey. The first 16 bytes are the user key, and the rest of the subkey + * is calculated by rotating the previous 16 bytes by 25 bits to the left, + * and so on until the subkey is completed. + */ + private int[] ExpandKey( + byte[] uKey) + { + int[] key = new int[52]; + if (uKey.Length < 16) + { + byte[] tmp = new byte[16]; + Array.Copy(uKey, 0, tmp, tmp.Length - uKey.Length, uKey.Length); + uKey = tmp; + } + for (int i = 0; i < 8; i++) + { + key[i] = BytesToWord(uKey, i * 2); + } + for (int i = 8; i < 52; i++) + { + if ((i & 7) < 6) + { + key[i] = ((key[i - 7] & 127) << 9 | key[i - 6] >> 7) & MASK; + } + else if ((i & 7) == 6) + { + key[i] = ((key[i - 7] & 127) << 9 | key[i - 14] >> 7) & MASK; + } + else + { + key[i] = ((key[i - 15] & 127) << 9 | key[i - 14] >> 7) & MASK; + } + } + return key; + } + /** + * This function computes multiplicative inverse using Euclid's Greatest + * Common Divisor algorithm. Zero and one are self inverse. + *+ * i.e. x * MulInv(x) == 1 (modulo BASE) + *
+ */ + private int MulInv( + int x) + { + int t0, t1, q, y; + + if (x < 2) + { + return x; + } + t0 = 1; + t1 = BASE / x; + y = BASE % x; + while (y != 1) + { + q = x / y; + x = x % y; + t0 = (t0 + (t1 * q)) & MASK; + if (x == 1) + { + return t0; + } + q = y / x; + y = y % x; + t1 = (t1 + (t0 * q)) & MASK; + } + return (1 - t1) & MASK; + } + /** + * Return the additive inverse of x. + *+ * i.e. x + AddInv(x) == 0 + *
+ */ + int AddInv( + int x) + { + return (0 - x) & MASK; + } + + /** + * The function to invert the encryption subkey to the decryption subkey. + * It also involves the multiplicative inverse and the additive inverse functions. + */ + private int[] InvertKey( + int[] inKey) + { + int t1, t2, t3, t4; + int p = 52; /* We work backwards */ + int[] key = new int[52]; + int inOff = 0; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff++]); + key[--p] = t4; + key[--p] = t3; + key[--p] = t2; + key[--p] = t1; + + for (int round = 1; round < 8; round++) + { + t1 = inKey[inOff++]; + t2 = inKey[inOff++]; + key[--p] = t2; + key[--p] = t1; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff++]); + key[--p] = t4; + key[--p] = t2; /* NB: Order */ + key[--p] = t3; + key[--p] = t1; + } + t1 = inKey[inOff++]; + t2 = inKey[inOff++]; + key[--p] = t2; + key[--p] = t1; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff]); + key[--p] = t4; + key[--p] = t3; + key[--p] = t2; + key[--p] = t1; + return key; + } + + private int[] GenerateWorkingKey( + bool forEncryption, + byte[] userKey) + { + if (forEncryption) + { + return ExpandKey(userKey); + } + else + { + return InvertKey(ExpandKey(userKey)); + } + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/IesEngine.cs b/iTechSharp/srcbc/crypto/engines/IesEngine.cs new file mode 100644 index 0000000..0f9ec9f --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/IesEngine.cs @@ -0,0 +1,236 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * support class for constructing intergrated encryption ciphers + * for doing basic message exchanges on top of key agreement ciphers + */ + public class IesEngine + { + private readonly IBasicAgreement agree; + private readonly IDerivationFunction kdf; + private readonly IMac mac; + private readonly BufferedBlockCipher cipher; + private readonly byte[] macBuf; + + private bool forEncryption; + private ICipherParameters privParam, pubParam; + private IesParameters param; + + /** + * set up for use with stream mode, where the key derivation function + * is used to provide a stream of bytes to xor with the message. + * + * @param agree the key agreement used as the basis for the encryption + * @param kdf the key derivation function used for byte generation + * @param mac the message authentication code generator for the message + */ + public IesEngine( + IBasicAgreement agree, + IDerivationFunction kdf, + IMac mac) + { + this.agree = agree; + this.kdf = kdf; + this.mac = mac; + this.macBuf = new byte[mac.GetMacSize()]; +// this.cipher = null; + } + + /** + * set up for use in conjunction with a block cipher to handle the + * message. + * + * @param agree the key agreement used as the basis for the encryption + * @param kdf the key derivation function used for byte generation + * @param mac the message authentication code generator for the message + * @param cipher the cipher to used for encrypting the message + */ + public IesEngine( + IBasicAgreement agree, + IDerivationFunction kdf, + IMac mac, + BufferedBlockCipher cipher) + { + this.agree = agree; + this.kdf = kdf; + this.mac = mac; + this.macBuf = new byte[mac.GetMacSize()]; + this.cipher = cipher; + } + + /** + * Initialise the encryptor. + * + * @param forEncryption whether or not this is encryption/decryption. + * @param privParam our private key parameters + * @param pubParam the recipient's/sender's public key parameters + * @param param encoding and derivation parameters. + */ + public void Init( + bool forEncryption, + ICipherParameters privParameters, + ICipherParameters pubParameters, + ICipherParameters iesParameters) + { + this.forEncryption = forEncryption; + this.privParam = privParameters; + this.pubParam = pubParameters; + this.param = (IesParameters)iesParameters; + } + + private byte[] DecryptBlock( + byte[] in_enc, + int inOff, + int inLen, + byte[] z) + { + byte[] M = null; + KeyParameter macKey = null; + KdfParameters kParam = new KdfParameters(z, param.GetDerivationV()); + int macKeySize = param.MacKeySize; + + kdf.Init(kParam); + + inLen -= mac.GetMacSize(); + + if (cipher == null) // stream mode + { + byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8)); + + M = new byte[inLen]; + + for (int i = 0; i != inLen; i++) + { + M[i] = (byte)(in_enc[inOff + i] ^ Buffer[i]); + } + + macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8)); + } + else + { + int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize; + byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8)); + + cipher.Init(false, new KeyParameter(Buffer, 0, (cipherKeySize / 8))); + + M = cipher.DoFinal(in_enc, inOff, inLen); + + macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8)); + } + + byte[] macIV = param.GetEncodingV(); + + mac.Init(macKey); + mac.BlockUpdate(in_enc, inOff, inLen); + mac.BlockUpdate(macIV, 0, macIV.Length); + mac.DoFinal(macBuf, 0); + + inOff += inLen; + + for (int t = 0; t < macBuf.Length; t++) + { + if (macBuf[t] != in_enc[inOff + t]) + { + throw (new InvalidCipherTextException("IMac codes failed to equal.")); + } + } + + return M; + } + + private byte[] EncryptBlock( + byte[] input, + int inOff, + int inLen, + byte[] z) + { + byte[] C = null; + KeyParameter macKey = null; + KdfParameters kParam = new KdfParameters(z, param.GetDerivationV()); + int c_text_length = 0; + int macKeySize = param.MacKeySize; + + if (cipher == null) // stream mode + { + byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8)); + + C = new byte[inLen + mac.GetMacSize()]; + c_text_length = inLen; + + for (int i = 0; i != inLen; i++) + { + C[i] = (byte)(input[inOff + i] ^ Buffer[i]); + } + + macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8)); + } + else + { + int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize; + byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8)); + + cipher.Init(true, new KeyParameter(Buffer, 0, (cipherKeySize / 8))); + + c_text_length = cipher.GetOutputSize(inLen); + byte[] tmp = new byte[c_text_length]; + + int len = cipher.ProcessBytes(input, inOff, inLen, tmp, 0); + len += cipher.DoFinal(tmp, len); + + C = new byte[len + mac.GetMacSize()]; + c_text_length = len; + + Array.Copy(tmp, 0, C, 0, len); + + macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8)); + } + + byte[] macIV = param.GetEncodingV(); + + mac.Init(macKey); + mac.BlockUpdate(C, 0, c_text_length); + mac.BlockUpdate(macIV, 0, macIV.Length); + // + // return the message and it's MAC + // + mac.DoFinal(C, c_text_length); + return C; + } + + private byte[] GenerateKdfBytes( + KdfParameters kParam, + int length) + { + byte[] buf = new byte[length]; + + kdf.Init(kParam); + + kdf.GenerateBytes(buf, 0, buf.Length); + + return buf; + } + + public byte[] ProcessBlock( + byte[] input, + int inOff, + int inLen) + { + agree.Init(privParam); + + BigInteger z = agree.CalculateAgreement(pubParam); + + // TODO Check that this is right (...Unsigned? Check length?) + byte[] zBytes = z.ToByteArray(); + + return forEncryption + ? EncryptBlock(input, inOff, inLen, zBytes) + : DecryptBlock(input, inOff, inLen, zBytes); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/NaccacheSternEngine.cs b/iTechSharp/srcbc/crypto/engines/NaccacheSternEngine.cs new file mode 100644 index 0000000..06432b0 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/NaccacheSternEngine.cs @@ -0,0 +1,432 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * NaccacheStern Engine. For details on this cipher, please see + * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf + */ + public class NaccacheSternEngine + : IAsymmetricBlockCipher + { + private bool forEncryption; + + private NaccacheSternKeyParameters key; + + private ArrayList[] lookup = null; + + private bool debug = false; + + public string AlgorithmName + { + get { return "NaccacheStern"; } + } + + /** + * Initializes this algorithm. Must be called before all other Functions. + * + * @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool, + * org.bouncycastle.crypto.CipherParameters) + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + key = (NaccacheSternKeyParameters)parameters; + + // construct lookup table for faster decryption if necessary + if (!this.forEncryption) + { + if (debug) + { + Console.WriteLine("Constructing lookup Array"); + } + NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key; + ArrayList primes = priv.SmallPrimes; + lookup = new ArrayList[primes.Count]; + for (int i = 0; i < primes.Count; i++) + { + BigInteger actualPrime = (BigInteger) primes[i]; + int actualPrimeValue = actualPrime.IntValue; + + lookup[i] = new ArrayList(actualPrimeValue); + lookup[i].Add(BigInteger.One); + + if (debug) + { + Console.WriteLine("Constructing lookup ArrayList for " + actualPrimeValue); + } + + BigInteger accJ = BigInteger.Zero; + + for (int j = 1; j < actualPrimeValue; j++) + { +// BigInteger bigJ = BigInteger.ValueOf(j); +// accJ = priv.PhiN.Multiply(bigJ); + accJ = accJ.Add(priv.PhiN); + BigInteger comp = accJ.Divide(actualPrime); + lookup[i].Add(priv.G.ModPow(comp, priv.Modulus)); + } + } + } + } + + public bool Debug + { + set { this.debug = value; } + } + + /** + * Returns the input block size of this algorithm. + * + * @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetInputBlockSize() + */ + public int GetInputBlockSize() + { + if (forEncryption) + { + // We can only encrypt values up to lowerSigmaBound + return (key.LowerSigmaBound + 7) / 8 - 1; + } + else + { + // We pad to modulus-size bytes for easier decryption. +// return key.Modulus.ToByteArray().Length; + return key.Modulus.BitLength / 8 + 1; + } + } + + /** + * Returns the output block size of this algorithm. + * + * @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetOutputBlockSize() + */ + public int GetOutputBlockSize() + { + if (forEncryption) + { + // encrypted Data is always padded up to modulus size +// return key.Modulus.ToByteArray().Length; + return key.Modulus.BitLength / 8 + 1; + } + else + { + // decrypted Data has upper limit lowerSigmaBound + return (key.LowerSigmaBound + 7) / 8 - 1; + } + } + + /** + * Process a single Block using the Naccache-Stern algorithm. + * + * @see org.bouncycastle.crypto.AsymmetricBlockCipher#ProcessBlock(byte[], + * int, int) + */ + public byte[] ProcessBlock( + byte[] inBytes, + int inOff, + int length) + { + if (key == null) + throw new InvalidOperationException("NaccacheStern engine not initialised"); + if (length > (GetInputBlockSize() + 1)) + throw new DataLengthException("input too large for Naccache-Stern cipher.\n"); + + if (!forEncryption) + { + // At decryption make sure that we receive padded data blocks + if (length < GetInputBlockSize()) + { + throw new InvalidCipherTextException("BlockLength does not match modulus for Naccache-Stern cipher.\n"); + } + } + + // transform input into BigInteger + BigInteger input = new BigInteger(1, inBytes, inOff, length); + + if (debug) + { + Console.WriteLine("input as BigInteger: " + input); + } + + byte[] output; + if (forEncryption) + { + output = Encrypt(input); + } + else + { + ArrayList plain = new ArrayList(); + NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key; + ArrayList primes = priv.SmallPrimes; + // Get Chinese Remainders of CipherText + for (int i = 0; i < primes.Count; i++) + { + BigInteger exp = input.ModPow(priv.PhiN.Divide((BigInteger)primes[i]), priv.Modulus); + ArrayList al = lookup[i]; + if (lookup[i].Count != ((BigInteger)primes[i]).IntValue) + { + if (debug) + { + Console.WriteLine("Prime is " + primes[i] + ", lookup table has size " + al.Count); + } + throw new InvalidCipherTextException("Error in lookup Array for " + + ((BigInteger)primes[i]).IntValue + + ": Size mismatch. Expected ArrayList with length " + + ((BigInteger)primes[i]).IntValue + " but found ArrayList of length " + + lookup[i].Count); + } + int lookedup = al.IndexOf(exp); + + if (lookedup == -1) + { + if (debug) + { + Console.WriteLine("Actual prime is " + primes[i]); + Console.WriteLine("Decrypted value is " + exp); + + Console.WriteLine("LookupList for " + primes[i] + " with size " + lookup[i].Count + + " is: "); + for (int j = 0; j < lookup[i].Count; j++) + { + Console.WriteLine(lookup[i][j]); + } + } + throw new InvalidCipherTextException("Lookup failed"); + } + plain.Add(BigInteger.ValueOf(lookedup)); + } + BigInteger test = chineseRemainder(plain, primes); + + // Should not be used as an oracle, so reencrypt output to see + // if it corresponds to input + + // this breaks probabilisic encryption, so disable it. Anyway, we do + // use the first n primes for key generation, so it is pretty easy + // to guess them. But as stated in the paper, this is not a security + // breach. So we can just work with the correct sigma. + + // if (debug) { + // Console.WriteLine("Decryption is " + test); + // } + // if ((key.G.ModPow(test, key.Modulus)).Equals(input)) { + // output = test.ToByteArray(); + // } else { + // if(debug){ + // Console.WriteLine("Engine seems to be used as an oracle, + // returning null"); + // } + // output = null; + // } + + output = test.ToByteArray(); + } + + return output; + } + + /** + * Encrypts a BigInteger aka Plaintext with the public key. + * + * @param plain + * The BigInteger to encrypt + * @return The byte[] representation of the encrypted BigInteger (i.e. + * crypted.toByteArray()) + */ + public byte[] Encrypt( + BigInteger plain) + { + // Always return modulus size values 0-padded at the beginning + // 0-padding at the beginning is correctly parsed by BigInteger :) +// byte[] output = key.Modulus.ToByteArray(); +// Array.Clear(output, 0, output.Length); + byte[] output = new byte[key.Modulus.BitLength / 8 + 1]; + + byte[] tmp = key.G.ModPow(plain, key.Modulus).ToByteArray(); + Array.Copy(tmp, 0, output, output.Length - tmp.Length, tmp.Length); + if (debug) + { + Console.WriteLine("Encrypted value is: " + new BigInteger(output)); + } + return output; + } + + /** + * Adds the contents of two encrypted blocks mod sigma + * + * @param block1 + * the first encrypted block + * @param block2 + * the second encrypted block + * @return encrypt((block1 + block2) mod sigma) + * @throws InvalidCipherTextException + */ + public byte[] AddCryptedBlocks( + byte[] block1, + byte[] block2) + { + // check for correct blocksize + if (forEncryption) + { + if ((block1.Length > GetOutputBlockSize()) + || (block2.Length > GetOutputBlockSize())) + { + throw new InvalidCipherTextException( + "BlockLength too large for simple addition.\n"); + } + } + else + { + if ((block1.Length > GetInputBlockSize()) + || (block2.Length > GetInputBlockSize())) + { + throw new InvalidCipherTextException( + "BlockLength too large for simple addition.\n"); + } + } + + // calculate resulting block + BigInteger m1Crypt = new BigInteger(1, block1); + BigInteger m2Crypt = new BigInteger(1, block2); + BigInteger m1m2Crypt = m1Crypt.Multiply(m2Crypt); + m1m2Crypt = m1m2Crypt.Mod(key.Modulus); + if (debug) + { + Console.WriteLine("c(m1) as BigInteger:....... " + m1Crypt); + Console.WriteLine("c(m2) as BigInteger:....... " + m2Crypt); + Console.WriteLine("c(m1)*c(m2)%n = c(m1+m2)%n: " + m1m2Crypt); + } + + //byte[] output = key.Modulus.ToByteArray(); + //Array.Clear(output, 0, output.Length); + byte[] output = new byte[key.Modulus.BitLength / 8 + 1]; + + byte[] m1m2CryptBytes = m1m2Crypt.ToByteArray(); + Array.Copy(m1m2CryptBytes, 0, output, + output.Length - m1m2CryptBytes.Length, m1m2CryptBytes.Length); + + return output; + } + + /** + * Convenience Method for data exchange with the cipher. + * + * Determines blocksize and splits data to blocksize. + * + * @param data the data to be processed + * @return the data after it went through the NaccacheSternEngine. + * @throws InvalidCipherTextException + */ + public byte[] ProcessData( + byte[] data) + { + if (debug) + { + Console.WriteLine(); + } + if (data.Length > GetInputBlockSize()) + { + int inBlocksize = GetInputBlockSize(); + int outBlocksize = GetOutputBlockSize(); + if (debug) + { + Console.WriteLine("Input blocksize is: " + inBlocksize + " bytes"); + Console.WriteLine("Output blocksize is: " + outBlocksize + " bytes"); + Console.WriteLine("Data has length:.... " + data.Length + " bytes"); + } + int datapos = 0; + int retpos = 0; + byte[] retval = new byte[(data.Length / inBlocksize + 1) * outBlocksize]; + while (datapos < data.Length) + { + byte[] tmp; + if (datapos + inBlocksize < data.Length) + { + tmp = ProcessBlock(data, datapos, inBlocksize); + datapos += inBlocksize; + } + else + { + tmp = ProcessBlock(data, datapos, data.Length - datapos); + datapos += data.Length - datapos; + } + if (debug) + { + Console.WriteLine("new datapos is " + datapos); + } + if (tmp != null) + { + tmp.CopyTo(retval, retpos); + retpos += tmp.Length; + } + else + { + if (debug) + { + Console.WriteLine("cipher returned null"); + } + throw new InvalidCipherTextException("cipher returned null"); + } + } + byte[] ret = new byte[retpos]; + Array.Copy(retval, 0, ret, 0, retpos); + if (debug) + { + Console.WriteLine("returning " + ret.Length + " bytes"); + } + return ret; + } + else + { + if (debug) + { + Console.WriteLine("data size is less then input block size, processing directly"); + } + return ProcessBlock(data, 0, data.Length); + } + } + + /** + * Computes the integer x that is expressed through the given primes and the + * congruences with the chinese remainder theorem (CRT). + * + * @param congruences + * the congruences c_i + * @param primes + * the primes p_i + * @return an integer x for that x % p_i == c_i + */ + private static BigInteger chineseRemainder(ArrayList congruences, ArrayList primes) + { + BigInteger retval = BigInteger.Zero; + BigInteger all = BigInteger.One; + for (int i = 0; i < primes.Count; i++) + { + all = all.Multiply((BigInteger)primes[i]); + } + for (int i = 0; i < primes.Count; i++) + { + BigInteger a = (BigInteger)primes[i]; + BigInteger b = all.Divide(a); + BigInteger b_ = b.ModInverse(a); + BigInteger tmp = b.Multiply(b_); + tmp = tmp.Multiply((BigInteger)congruences[i]); + retval = retval.Add(tmp); + } + + return retval.Mod(all); + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/NoekeonEngine.cs b/iTechSharp/srcbc/crypto/engines/NoekeonEngine.cs new file mode 100644 index 0000000..acc4ec4 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/NoekeonEngine.cs @@ -0,0 +1,256 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A Noekeon engine, using direct-key mode. + */ + public class NoekeonEngine + : IBlockCipher + { + private const int GenericSize = 16; // Block and key size, as well as the amount of rounds. + + private static readonly uint[] nullVector = + { + 0x00, 0x00, 0x00, 0x00 // Used in decryption + }; + + private static readonly uint[] roundConstants = + { + 0x80, 0x1b, 0x36, 0x6c, + 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, + 0xc6, 0x97, 0x35, 0x6a, + 0xd4 + }; + + private uint[] state = new uint[4], // a + subKeys = new uint[4], // k + decryptKeys = new uint[4]; + + private bool _initialised, _forEncryption; + + /** + * Create an instance of the Noekeon encryption algorithm + * and set some defaults + */ + public NoekeonEngine() + { + _initialised = false; + } + + public string AlgorithmName + { + get { return "Noekeon"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return GenericSize; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("Invalid parameters passed to Noekeon init - " + parameters.GetType().Name, "parameters"); + + _forEncryption = forEncryption; + _initialised = true; + + KeyParameter p = (KeyParameter) parameters; + + setKey(p.GetKey()); + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + if ((inOff + GenericSize) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + GenericSize) > output.Length) + throw new DataLengthException("output buffer too short"); + + return _forEncryption + ? encryptBlock(input, inOff, output, outOff) + : decryptBlock(input, inOff, output, outOff); + } + + public void Reset() + { + // TODO This should do something in case the encryption is aborted + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void setKey(byte[] key) + { + subKeys[0] = bytesToIntBig(key, 0); + subKeys[1] = bytesToIntBig(key, 4); + subKeys[2] = bytesToIntBig(key, 8); + subKeys[3] = bytesToIntBig(key, 12); + } + + private int encryptBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + state[0] = bytesToIntBig(input, inOff); + state[1] = bytesToIntBig(input, inOff+4); + state[2] = bytesToIntBig(input, inOff+8); + state[3] = bytesToIntBig(input, inOff+12); + + int i; + for (i = 0; i < GenericSize; i++) + { + state[0] ^= roundConstants[i]; + theta(state, subKeys); + pi1(state); + gamma(state); + pi2(state); + } + + state[0] ^= roundConstants[i]; + theta(state, subKeys); + + intToBytesBig(state[0], output, outOff); + intToBytesBig(state[1], output, outOff+4); + intToBytesBig(state[2], output, outOff+8); + intToBytesBig(state[3], output, outOff+12); + + return GenericSize; + } + + private int decryptBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + state[0] = bytesToIntBig(input, inOff); + state[1] = bytesToIntBig(input, inOff+4); + state[2] = bytesToIntBig(input, inOff+8); + state[3] = bytesToIntBig(input, inOff+12); + + Array.Copy(subKeys, 0, decryptKeys, 0, subKeys.Length); + theta(decryptKeys, nullVector); + + int i; + for (i = GenericSize; i > 0; i--) + { + theta(state, decryptKeys); + state[0] ^= roundConstants[i]; + pi1(state); + gamma(state); + pi2(state); + } + + theta(state, decryptKeys); + state[0] ^= roundConstants[i]; + + intToBytesBig(state[0], output, outOff); + intToBytesBig(state[1], output, outOff+4); + intToBytesBig(state[2], output, outOff+8); + intToBytesBig(state[3], output, outOff+12); + + return GenericSize; + } + + private void gamma(uint[] a) + { + a[1] ^= ~a[3] & ~a[2]; + a[0] ^= a[2] & a[1]; + + uint tmp = a[3]; + a[3] = a[0]; + a[0] = tmp; + a[2] ^= a[0]^a[1]^a[3]; + + a[1] ^= ~a[3] & ~a[2]; + a[0] ^= a[2] & a[1]; + } + + private void theta(uint[] a, uint[] k) + { + uint tmp; + tmp = a[0]^a[2]; + tmp ^= rotl(tmp,8)^rotl(tmp,24); + a[1] ^= tmp; + a[3] ^= tmp; + + for (int i = 0; i < 4; i++) + { + a[i] ^= k[i]; + } + + tmp = a[1]^a[3]; + tmp ^= rotl(tmp,8)^rotl(tmp,24); + a[0] ^= tmp; + a[2] ^= tmp; + } + + private void pi1(uint[] a) + { + a[1] = rotl(a[1], 1); + a[2] = rotl(a[2], 5); + a[3] = rotl(a[3], 2); + } + + private void pi2(uint[] a) + { + a[1] = rotl(a[1], 31); + a[2] = rotl(a[2], 27); + a[3] = rotl(a[3], 30); + } + + // Helpers + + private uint bytesToIntBig(byte[] input, int off) + { + int result = ((input[off++]) << 24) | + ((input[off++] & 0xff) << 16) | + ((input[off++] & 0xff) << 8) | + (input[off ] & 0xff); + return (uint) result; + } + + private void intToBytesBig(uint x, byte[] output, int off) + { + output[off++] = (byte)(x >> 24); + output[off++] = (byte)(x >> 16); + output[off++] = (byte)(x >> 8); + output[off ] = (byte)x; + } + + private uint rotl(uint x, int y) + { + return (x << y) | (x >> (32-y)); + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/NullEngine.cs b/iTechSharp/srcbc/crypto/engines/NullEngine.cs new file mode 100644 index 0000000..407b8cc --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/NullEngine.cs @@ -0,0 +1,70 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * The no-op engine that just copies bytes through, irrespective of whether encrypting and decrypting. + * Provided for the sake of completeness. + */ + public class NullEngine + : IBlockCipher + { + private bool initialised; + private const int BlockSize = 1; + + public NullEngine() + { + } + + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + // we don't mind any parameters that may come in + initialised = true; + } + + public string AlgorithmName + { + get { return "Null"; } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + public int GetBlockSize() + { + return BlockSize; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException("Null engine not initialised"); + if ((inOff + BlockSize) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + BlockSize) > output.Length) + throw new DataLengthException("output buffer too short"); + + for (int i = 0; i < BlockSize; ++i) + { + output[outOff + i] = input[inOff + i]; + } + + return BlockSize; + } + + public void Reset() + { + // nothing needs to be done + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/RC2Engine.cs b/iTechSharp/srcbc/crypto/engines/RC2Engine.cs new file mode 100644 index 0000000..aaf8c71 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RC2Engine.cs @@ -0,0 +1,312 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of RC2 as described in RFC 2268 + * "A Description of the RC2(r) Encryption Algorithm" R. Rivest. + */ + public class RC2Engine + : IBlockCipher + { + // + // the values we use for key expansion (based on the digits of PI) + // + private static readonly byte[] piTable = + { + (byte)0xd9, (byte)0x78, (byte)0xf9, (byte)0xc4, (byte)0x19, (byte)0xdd, (byte)0xb5, (byte)0xed, + (byte)0x28, (byte)0xe9, (byte)0xfd, (byte)0x79, (byte)0x4a, (byte)0xa0, (byte)0xd8, (byte)0x9d, + (byte)0xc6, (byte)0x7e, (byte)0x37, (byte)0x83, (byte)0x2b, (byte)0x76, (byte)0x53, (byte)0x8e, + (byte)0x62, (byte)0x4c, (byte)0x64, (byte)0x88, (byte)0x44, (byte)0x8b, (byte)0xfb, (byte)0xa2, + (byte)0x17, (byte)0x9a, (byte)0x59, (byte)0xf5, (byte)0x87, (byte)0xb3, (byte)0x4f, (byte)0x13, + (byte)0x61, (byte)0x45, (byte)0x6d, (byte)0x8d, (byte)0x9, (byte)0x81, (byte)0x7d, (byte)0x32, + (byte)0xbd, (byte)0x8f, (byte)0x40, (byte)0xeb, (byte)0x86, (byte)0xb7, (byte)0x7b, (byte)0xb, + (byte)0xf0, (byte)0x95, (byte)0x21, (byte)0x22, (byte)0x5c, (byte)0x6b, (byte)0x4e, (byte)0x82, + (byte)0x54, (byte)0xd6, (byte)0x65, (byte)0x93, (byte)0xce, (byte)0x60, (byte)0xb2, (byte)0x1c, + (byte)0x73, (byte)0x56, (byte)0xc0, (byte)0x14, (byte)0xa7, (byte)0x8c, (byte)0xf1, (byte)0xdc, + (byte)0x12, (byte)0x75, (byte)0xca, (byte)0x1f, (byte)0x3b, (byte)0xbe, (byte)0xe4, (byte)0xd1, + (byte)0x42, (byte)0x3d, (byte)0xd4, (byte)0x30, (byte)0xa3, (byte)0x3c, (byte)0xb6, (byte)0x26, + (byte)0x6f, (byte)0xbf, (byte)0xe, (byte)0xda, (byte)0x46, (byte)0x69, (byte)0x7, (byte)0x57, + (byte)0x27, (byte)0xf2, (byte)0x1d, (byte)0x9b, (byte)0xbc, (byte)0x94, (byte)0x43, (byte)0x3, + (byte)0xf8, (byte)0x11, (byte)0xc7, (byte)0xf6, (byte)0x90, (byte)0xef, (byte)0x3e, (byte)0xe7, + (byte)0x6, (byte)0xc3, (byte)0xd5, (byte)0x2f, (byte)0xc8, (byte)0x66, (byte)0x1e, (byte)0xd7, + (byte)0x8, (byte)0xe8, (byte)0xea, (byte)0xde, (byte)0x80, (byte)0x52, (byte)0xee, (byte)0xf7, + (byte)0x84, (byte)0xaa, (byte)0x72, (byte)0xac, (byte)0x35, (byte)0x4d, (byte)0x6a, (byte)0x2a, + (byte)0x96, (byte)0x1a, (byte)0xd2, (byte)0x71, (byte)0x5a, (byte)0x15, (byte)0x49, (byte)0x74, + (byte)0x4b, (byte)0x9f, (byte)0xd0, (byte)0x5e, (byte)0x4, (byte)0x18, (byte)0xa4, (byte)0xec, + (byte)0xc2, (byte)0xe0, (byte)0x41, (byte)0x6e, (byte)0xf, (byte)0x51, (byte)0xcb, (byte)0xcc, + (byte)0x24, (byte)0x91, (byte)0xaf, (byte)0x50, (byte)0xa1, (byte)0xf4, (byte)0x70, (byte)0x39, + (byte)0x99, (byte)0x7c, (byte)0x3a, (byte)0x85, (byte)0x23, (byte)0xb8, (byte)0xb4, (byte)0x7a, + (byte)0xfc, (byte)0x2, (byte)0x36, (byte)0x5b, (byte)0x25, (byte)0x55, (byte)0x97, (byte)0x31, + (byte)0x2d, (byte)0x5d, (byte)0xfa, (byte)0x98, (byte)0xe3, (byte)0x8a, (byte)0x92, (byte)0xae, + (byte)0x5, (byte)0xdf, (byte)0x29, (byte)0x10, (byte)0x67, (byte)0x6c, (byte)0xba, (byte)0xc9, + (byte)0xd3, (byte)0x0, (byte)0xe6, (byte)0xcf, (byte)0xe1, (byte)0x9e, (byte)0xa8, (byte)0x2c, + (byte)0x63, (byte)0x16, (byte)0x1, (byte)0x3f, (byte)0x58, (byte)0xe2, (byte)0x89, (byte)0xa9, + (byte)0xd, (byte)0x38, (byte)0x34, (byte)0x1b, (byte)0xab, (byte)0x33, (byte)0xff, (byte)0xb0, + (byte)0xbb, (byte)0x48, (byte)0xc, (byte)0x5f, (byte)0xb9, (byte)0xb1, (byte)0xcd, (byte)0x2e, + (byte)0xc5, (byte)0xf3, (byte)0xdb, (byte)0x47, (byte)0xe5, (byte)0xa5, (byte)0x9c, (byte)0x77, + (byte)0xa, (byte)0xa6, (byte)0x20, (byte)0x68, (byte)0xfe, (byte)0x7f, (byte)0xc1, (byte)0xad + }; + + private const int BLOCK_SIZE = 8; + + private int[] workingKey; + private bool encrypting; + + private int[] GenerateWorkingKey( + byte[] key, + int bits) + { + int x; + int[] xKey = new int[128]; + + for (int i = 0; i != key.Length; i++) + { + xKey[i] = key[i] & 0xff; + } + + // Phase 1: Expand input key to 128 bytes + int len = key.Length; + + if (len < 128) + { + int index = 0; + + x = xKey[len - 1]; + + do + { + x = piTable[(x + xKey[index++]) & 255] & 0xff; + xKey[len++] = x; + } + while (len < 128); + } + + // Phase 2 - reduce effective key size to "bits" + len = (bits + 7) >> 3; + x = piTable[xKey[128 - len] & (255 >> (7 & -bits))] & 0xff; + xKey[128 - len] = x; + + for (int i = 128 - len - 1; i >= 0; i--) + { + x = piTable[x ^ xKey[i + len]] & 0xff; + xKey[i] = x; + } + + // Phase 3 - copy to newKey in little-endian order + int[] newKey = new int[64]; + + for (int i = 0; i != newKey.Length; i++) + { + newKey[i] = (xKey[2 * i] + (xKey[2 * i + 1] << 8)); + } + + return newKey; + } + + /** + * initialise a RC2 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.encrypting = forEncryption; + + if (parameters is RC2Parameters) + { + RC2Parameters param = (RC2Parameters) parameters; + + workingKey = GenerateWorkingKey(param.GetKey(), param.EffectiveKeyBits); + } + else if (parameters is KeyParameter) + { + KeyParameter param = (KeyParameter) parameters; + byte[] key = param.GetKey(); + + workingKey = GenerateWorkingKey(key, key.Length * 8); + } + else + { + throw new ArgumentException("invalid parameter passed to RC2 init - " + parameters.GetType().Name); + } + } + + public void Reset() + { + } + + public string AlgorithmName + { + get { return "RC2"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("RC2 engine not initialised"); + if ((inOff + BLOCK_SIZE) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + BLOCK_SIZE) > output.Length) + throw new DataLengthException("output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + /** + * return the result rotating the 16 bit number in x left by y + */ + private int RotateWordLeft( + int x, + int y) + { + x &= 0xffff; + return (x << y) | (x >> (16 - y)); + } + + private void EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x76, x54, x32, x10; + + x76 = ((input[inOff + 7] & 0xff) << 8) + (input[inOff + 6] & 0xff); + x54 = ((input[inOff + 5] & 0xff) << 8) + (input[inOff + 4] & 0xff); + x32 = ((input[inOff + 3] & 0xff) << 8) + (input[inOff + 2] & 0xff); + x10 = ((input[inOff + 1] & 0xff) << 8) + (input[inOff + 0] & 0xff); + + for (int i = 0; i <= 16; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + x10 += workingKey[x76 & 63]; + x32 += workingKey[x10 & 63]; + x54 += workingKey[x32 & 63]; + x76 += workingKey[x54 & 63]; + + for (int i = 20; i <= 40; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + x10 += workingKey[x76 & 63]; + x32 += workingKey[x10 & 63]; + x54 += workingKey[x32 & 63]; + x76 += workingKey[x54 & 63]; + + for (int i = 44; i < 64; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + outBytes[outOff + 0] = (byte)x10; + outBytes[outOff + 1] = (byte)(x10 >> 8); + outBytes[outOff + 2] = (byte)x32; + outBytes[outOff + 3] = (byte)(x32 >> 8); + outBytes[outOff + 4] = (byte)x54; + outBytes[outOff + 5] = (byte)(x54 >> 8); + outBytes[outOff + 6] = (byte)x76; + outBytes[outOff + 7] = (byte)(x76 >> 8); + } + + private void DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x76, x54, x32, x10; + + x76 = ((input[inOff + 7] & 0xff) << 8) + (input[inOff + 6] & 0xff); + x54 = ((input[inOff + 5] & 0xff) << 8) + (input[inOff + 4] & 0xff); + x32 = ((input[inOff + 3] & 0xff) << 8) + (input[inOff + 2] & 0xff); + x10 = ((input[inOff + 1] & 0xff) << 8) + (input[inOff + 0] & 0xff); + + for (int i = 60; i >= 44; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + x76 -= workingKey[x54 & 63]; + x54 -= workingKey[x32 & 63]; + x32 -= workingKey[x10 & 63]; + x10 -= workingKey[x76 & 63]; + + for (int i = 40; i >= 20; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + x76 -= workingKey[x54 & 63]; + x54 -= workingKey[x32 & 63]; + x32 -= workingKey[x10 & 63]; + x10 -= workingKey[x76 & 63]; + + for (int i = 16; i >= 0; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + outBytes[outOff + 0] = (byte)x10; + outBytes[outOff + 1] = (byte)(x10 >> 8); + outBytes[outOff + 2] = (byte)x32; + outBytes[outOff + 3] = (byte)(x32 >> 8); + outBytes[outOff + 4] = (byte)x54; + outBytes[outOff + 5] = (byte)(x54 >> 8); + outBytes[outOff + 6] = (byte)x76; + outBytes[outOff + 7] = (byte)(x76 >> 8); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/RC2WrapEngine.cs b/iTechSharp/srcbc/crypto/engines/RC2WrapEngine.cs new file mode 100644 index 0000000..b89a761 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RC2WrapEngine.cs @@ -0,0 +1,372 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Wrap keys according to RFC 3217 - RC2 mechanism + */ + public class RC2WrapEngine + : IWrapper + { + /** Field engine */ + private CbcBlockCipher engine; + + /** Field param */ + private ICipherParameters parameters; + + /** Field paramPlusIV */ + private ParametersWithIV paramPlusIV; + + /** Field iv */ + private byte[] iv; + + /** Field forWrapping */ + private bool forWrapping; + + private SecureRandom sr; + + /** Field IV2 */ + private static readonly byte[] IV2 = + { + (byte) 0x4a, (byte) 0xdd, (byte) 0xa2, + (byte) 0x2c, (byte) 0x79, (byte) 0xe8, + (byte) 0x21, (byte) 0x05 + }; + + // + // checksum digest + // + IDigest sha1 = new Sha1Digest(); + byte[] digest = new byte[20]; + + /** + * Method init + * + * @param forWrapping + * @param param + */ + public void Init( + bool forWrapping, + ICipherParameters parameters) + { + this.forWrapping = forWrapping; + this.engine = new CbcBlockCipher(new RC2Engine()); + + if (parameters is ParametersWithRandom) + { + ParametersWithRandom pWithR = (ParametersWithRandom)parameters; + sr = pWithR.Random; + parameters = pWithR.Parameters; + } + else + { + sr = new SecureRandom(); + } + + if (parameters is ParametersWithIV) + { + if (!forWrapping) + throw new ArgumentException("You should not supply an IV for unwrapping"); + + this.paramPlusIV = (ParametersWithIV)parameters; + this.iv = this.paramPlusIV.GetIV(); + this.parameters = this.paramPlusIV.Parameters; + + if (this.iv.Length != 8) + throw new ArgumentException("IV is not 8 octets"); + } + else + { + this.parameters = parameters; + + if (this.forWrapping) + { + // Hm, we have no IV but we want to wrap ?!? + // well, then we have to create our own IV. + this.iv = new byte[8]; + sr.NextBytes(iv); + this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv); + } + } + } + + /** + * Method GetAlgorithmName + * + * @return + */ + public string AlgorithmName + { + get { return "RC2"; } + } + + /** + * Method wrap + * + * @param in + * @param inOff + * @param inLen + * @return + */ + public byte[] Wrap( + byte[] input, + int inOff, + int length) + { + if (!forWrapping) + { + throw new InvalidOperationException("Not initialized for wrapping"); + } + + int len = length + 1; + if ((len % 8) != 0) + { + len += 8 - (len % 8); + } + + byte [] keyToBeWrapped = new byte[len]; + + keyToBeWrapped[0] = (byte)length; + Array.Copy(input, inOff, keyToBeWrapped, 1, length); + + byte[] pad = new byte[keyToBeWrapped.Length - length - 1]; + + if (pad.Length > 0) + { + sr.NextBytes(pad); + Array.Copy(pad, 0, keyToBeWrapped, length + 1, pad.Length); + } + + // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. + byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped); + + // Let WKCKS = WK || CKS where || is concatenation. + byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length]; + + Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length); + Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length); + + // Encrypt WKCKS in CBC mode using KEK as the key and IV as the + // initialization vector. Call the results TEMP1. + byte [] TEMP1 = new byte[WKCKS.Length]; + + Array.Copy(WKCKS, 0, TEMP1, 0, WKCKS.Length); + + int noOfBlocks = WKCKS.Length / engine.GetBlockSize(); + int extraBytes = WKCKS.Length % engine.GetBlockSize(); + + if (extraBytes != 0) + { + throw new InvalidOperationException("Not multiple of block length"); + } + + engine.Init(true, paramPlusIV); + + for (int i = 0; i < noOfBlocks; i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP1, currentBytePos, TEMP1, currentBytePos); + } + + // Left TEMP2 = IV || TEMP1. + byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length]; + + Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length); + Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length); + + // Reverse the order of the octets in TEMP2 and call the result TEMP3. + byte[] TEMP3 = new byte[TEMP2.Length]; + + for (int i = 0; i < TEMP2.Length; i++) + { + TEMP3[i] = TEMP2[TEMP2.Length - (i + 1)]; + } + + // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector + // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired + // result. It is 40 octets long if a 168 bit key is being wrapped. + ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2); + + this.engine.Init(true, param2); + + for (int i = 0; i < noOfBlocks + 1; i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); + } + + return TEMP3; + } + + /** + * Method unwrap + * + * @param in + * @param inOff + * @param inLen + * @return + * @throws InvalidCipherTextException + */ + public byte[] Unwrap( + byte[] input, + int inOff, + int length) + { + if (forWrapping) + { + throw new InvalidOperationException("Not set for unwrapping"); + } + + if (input == null) + { + throw new InvalidCipherTextException("Null pointer as ciphertext"); + } + + if (length % engine.GetBlockSize() != 0) + { + throw new InvalidCipherTextException("Ciphertext not multiple of " + + engine.GetBlockSize()); + } + + /* + // Check if the length of the cipher text is reasonable given the key + // type. It must be 40 bytes for a 168 bit key and either 32, 40, or + // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported + // or inconsistent with the algorithm for which the key is intended, + // return error. + // + // we do not accept 168 bit keys. it has to be 192 bit. + int lengthA = (estimatedKeyLengthInBit / 8) + 16; + int lengthB = estimatedKeyLengthInBit % 8; + + if ((lengthA != keyToBeUnwrapped.Length) || (lengthB != 0)) { + throw new XMLSecurityException("empty"); + } + */ + + // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK + // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3. + ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2); + + this.engine.Init(false, param2); + + byte [] TEMP3 = new byte[length]; + + Array.Copy(input, inOff, TEMP3, 0, length); + + for (int i = 0; i < (TEMP3.Length / engine.GetBlockSize()); i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); + } + + // Reverse the order of the octets in TEMP3 and call the result TEMP2. + byte[] TEMP2 = new byte[TEMP3.Length]; + + for (int i = 0; i < TEMP3.Length; i++) + { + TEMP2[i] = TEMP3[TEMP3.Length - (i + 1)]; + } + + // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets. + this.iv = new byte[8]; + + byte[] TEMP1 = new byte[TEMP2.Length - 8]; + + Array.Copy(TEMP2, 0, this.iv, 0, 8); + Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8); + + // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV + // found in the previous step. Call the result WKCKS. + this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv); + + this.engine.Init(false, this.paramPlusIV); + + byte[] LCEKPADICV = new byte[TEMP1.Length]; + + Array.Copy(TEMP1, 0, LCEKPADICV, 0, TEMP1.Length); + + for (int i = 0; i < (LCEKPADICV.Length / engine.GetBlockSize()); i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(LCEKPADICV, currentBytePos, LCEKPADICV, currentBytePos); + } + + // Decompose LCEKPADICV. CKS is the last 8 octets and WK, the wrapped key, are + // those octets before the CKS. + byte[] result = new byte[LCEKPADICV.Length - 8]; + byte[] CKStoBeVerified = new byte[8]; + + Array.Copy(LCEKPADICV, 0, result, 0, LCEKPADICV.Length - 8); + Array.Copy(LCEKPADICV, LCEKPADICV.Length - 8, CKStoBeVerified, 0, 8); + + // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare + // with the CKS extracted in the above step. If they are not equal, return error. + if (!CheckCmsKeyChecksum(result, CKStoBeVerified)) + { + throw new InvalidCipherTextException( + "Checksum inside ciphertext is corrupted"); + } + + if ((result.Length - ((result[0] & 0xff) + 1)) > 7) + { + throw new InvalidCipherTextException( + "too many pad bytes (" + (result.Length - ((result[0] & 0xff) + 1)) + ")"); + } + + // CEK is the wrapped key, now extracted for use in data decryption. + byte[] CEK = new byte[result[0]]; + Array.Copy(result, 1, CEK, 0, CEK.Length); + return CEK; + } + + /** + * Some key wrap algorithms make use of the Key Checksum defined + * in CMS [CMS-Algorithms]. This is used to provide an integrity + * check value for the key being wrapped. The algorithm is + * + * - Compute the 20 octet SHA-1 hash on the key being wrapped. + * - Use the first 8 octets of this hash as the checksum value. + * + * @param key + * @return + * @throws Exception + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private byte[] CalculateCmsKeyChecksum( + byte[] key) + { + byte[] result = new byte[8]; + + sha1.BlockUpdate(key, 0, key.Length); + sha1.DoFinal(digest, 0); + + Array.Copy(digest, 0, result, 0, 8); + + return result; + } + + /** + * @param key + * @param checksum + * @return + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private bool CheckCmsKeyChecksum( + byte[] key, + byte[] checksum) + { + return Arrays.AreEqual(CalculateCmsKeyChecksum(key), checksum); + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/RC4Engine.cs b/iTechSharp/srcbc/crypto/engines/RC4Engine.cs new file mode 100644 index 0000000..c65468d --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RC4Engine.cs @@ -0,0 +1,147 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class RC4Engine + : IStreamCipher + { + private readonly static int STATE_LENGTH = 256; + + /* + * variables to hold the state of the RC4 engine + * during encryption and decryption + */ + + private byte[] engineState; + private int x; + private int y; + private byte[] workingKey; + + /** + * initialise a RC4 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is KeyParameter) + { + /* + * RC4 encryption and decryption is completely + * symmetrical, so the 'forEncryption' is + * irrelevant. + */ + workingKey = ((KeyParameter)parameters).GetKey(); + SetKey(workingKey); + + return; + } + + throw new ArgumentException("invalid parameter passed to RC4 init - " + parameters.GetType().ToString()); + } + + public string AlgorithmName + { + get { return "RC4"; } + } + + public byte ReturnByte( + byte input) + { + x = (x + 1) & 0xff; + y = (engineState[x] + y) & 0xff; + + // swap + byte tmp = engineState[x]; + engineState[x] = engineState[y]; + engineState[y] = tmp; + + // xor + return (byte)(input ^ engineState[(engineState[x] + engineState[y]) & 0xff]); + } + + public void ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff + ) + { + if ((inOff + length) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + length) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + for (int i = 0; i < length ; i++) + { + x = (x + 1) & 0xff; + y = (engineState[x] + y) & 0xff; + + // swap + byte tmp = engineState[x]; + engineState[x] = engineState[y]; + engineState[y] = tmp; + + // xor + output[i+outOff] = (byte)(input[i + inOff] + ^ engineState[(engineState[x] + engineState[y]) & 0xff]); + } + } + + public void Reset() + { + SetKey(workingKey); + } + + // Private implementation + + private void SetKey( + byte[] keyBytes) + { + workingKey = keyBytes; + + // System.out.println("the key length is ; "+ workingKey.Length); + + x = 0; + y = 0; + + if (engineState == null) + { + engineState = new byte[STATE_LENGTH]; + } + + // reset the state of the engine + for (int i=0; i < STATE_LENGTH; i++) + { + engineState[i] = (byte)i; + } + + int i1 = 0; + int i2 = 0; + + for (int i=0; i < STATE_LENGTH; i++) + { + i2 = ((keyBytes[i1] & 0xff) + engineState[i] + i2) & 0xff; + // do the byte-swap inline + byte tmp = engineState[i]; + engineState[i] = engineState[i2]; + engineState[i2] = tmp; + i1 = (i1+1) % keyBytes.Length; + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/RC532Engine.cs b/iTechSharp/srcbc/crypto/engines/RC532Engine.cs new file mode 100644 index 0000000..1661707 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RC532Engine.cs @@ -0,0 +1,294 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * The specification for RC5 came from theRC5 Encryption Algorithm
+ * publication in RSA CryptoBytes, Spring of 1995.
+ * http://www.rsasecurity.com/rsalabs/cryptobytes.
+ * + * This implementation has a word size of 32 bits.
+ */ + public class RC532Engine + : IBlockCipher + { + /* + * the number of rounds to perform + */ + private int _noRounds; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private int [] _S; + + /* + * our "magic constants" for 32 32 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly int P32 = unchecked((int) 0xb7e15163); + private static readonly int Q32 = unchecked((int) 0x9e3779b9); + + private bool forEncryption; + + /** + * Create an instance of the RC5 encryption algorithm + * and set some defaults + */ + public RC532Engine() + { + _noRounds = 12; // the default +// _S = null; + } + + public string AlgorithmName + { + get { return "RC5-32"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return 2 * 4; + } + + /** + * initialise a RC5-32 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (typeof(RC5Parameters).IsInstanceOfType(parameters)) + { + RC5Parameters p = (RC5Parameters)parameters; + + _noRounds = p.Rounds; + + SetKey(p.GetKey()); + } + else if (typeof(KeyParameter).IsInstanceOfType(parameters)) + { + KeyParameter p = (KeyParameter)parameters; + + SetKey(p.GetKey()); + } + else + { + throw new ArgumentException("invalid parameter passed to RC532 init - " + parameters.GetType().ToString()); + } + + this.forEncryption = forEncryption; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = 32/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + int[] L = new int[(key.Length + (4 - 1)) / 4]; + + for (int i = 0; i != key.Length; i++) + { + L[i / 4] += (key[i] & 0xff) << (8 * (i % 4)); + } + + // + // Phase 2: + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new int[2*(_noRounds + 1)]; + + _S[0] = P32; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q32); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + int A = 0, B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + /** + * Encrypt the given block starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param in in byte buffer containing data to encrypt + * @param inOff offset into src buffer + * @param out out buffer where encrypted data is written + * @param outOff offset into out buffer + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int A = BytesToWord(input, inOff) + _S[0]; + int B = BytesToWord(input, inOff + 4) + _S[1]; + + for (int i = 1; i <= _noRounds; i++) + { + A = RotateLeft(A ^ B, B) + _S[2*i]; + B = RotateLeft(B ^ A, A) + _S[2*i+1]; + } + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + 4); + + return 2 * 4; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + 4); + + for (int i = _noRounds; i >= 1; i--) + { + B = RotateRight(B - _S[2*i+1], A) ^ A; + A = RotateRight(A - _S[2*i], B) ^ B; + } + + WordToBytes(A - _S[0], outBytes, outOff); + WordToBytes(B - _S[1], outBytes, outOff + 4); + + return 2 * 4; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(32) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % 32 + */ + private int RotateLeft(int x, int y) { + return ((int) ( (uint) (x << (y & (32-1))) | + ((uint) x >> (32 - (y & (32-1)))) ) + ); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(32) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % 32 + */ + private int RotateRight(int x, int y) { + return ((int) ( ((uint) x >> (y & (32-1))) | + (uint) (x << (32 - (y & (32-1)))) ) + ); + } + + private int BytesToWord( + byte[] src, + int srcOff) + { + return (src[srcOff] & 0xff) | ((src[srcOff + 1] & 0xff) << 8) + | ((src[srcOff + 2] & 0xff) << 16) | ((src[srcOff + 3] & 0xff) << 24); + } + + private void WordToBytes( + int word, + byte[] dst, + int dstOff) + { + dst[dstOff] = (byte)word; + dst[dstOff + 1] = (byte)(word >> 8); + dst[dstOff + 2] = (byte)(word >> 16); + dst[dstOff + 3] = (byte)(word >> 24); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/RC564Engine.cs b/iTechSharp/srcbc/crypto/engines/RC564Engine.cs new file mode 100644 index 0000000..5c69d40 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RC564Engine.cs @@ -0,0 +1,295 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * The specification for RC5 came from theRC5 Encryption Algorithm
+ * publication in RSA CryptoBytes, Spring of 1995.
+ * http://www.rsasecurity.com/rsalabs/cryptobytes.
+ * + * This implementation is set to work with a 64 bit word size.
+ */ + public class RC564Engine + : IBlockCipher + { + private static readonly int wordSize = 64; + private static readonly int bytesPerWord = wordSize / 8; + + /* + * the number of rounds to perform + */ + private int _noRounds; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private long [] _S; + + /* + * our "magic constants" for wordSize 62 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly long P64 = unchecked( (long) 0xb7e151628aed2a6bL); + private static readonly long Q64 = unchecked( (long) 0x9e3779b97f4a7c15L); + + private bool forEncryption; + + /** + * Create an instance of the RC5 encryption algorithm + * and set some defaults + */ + public RC564Engine() + { + _noRounds = 12; +// _S = null; + } + + public string AlgorithmName + { + get { return "RC5-64"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return 2 * bytesPerWord; + } + + /** + * initialise a RC5-64 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(typeof(RC5Parameters).IsInstanceOfType(parameters))) + { + throw new ArgumentException("invalid parameter passed to RC564 init - " + parameters.GetType().ToString()); + } + + RC5Parameters p = (RC5Parameters)parameters; + + this.forEncryption = forEncryption; + + _noRounds = p.Rounds; + + SetKey(p.GetKey()); + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = wordSize/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + long[] L = new long[(key.Length + (bytesPerWord - 1)) / bytesPerWord]; + + for (int i = 0; i != key.Length; i++) + { + L[i / bytesPerWord] += (long)(key[i] & 0xff) << (8 * (i % bytesPerWord)); + } + + // + // Phase 2: + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new long[2*(_noRounds + 1)]; + + _S[0] = P64; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q64); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + long A = 0, B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + /** + * Encrypt the given block starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param in in byte buffer containing data to encrypt + * @param inOff offset into src buffer + * @param out out buffer where encrypted data is written + * @param outOff offset into out buffer + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + long A = BytesToWord(input, inOff) + _S[0]; + long B = BytesToWord(input, inOff + bytesPerWord) + _S[1]; + + for (int i = 1; i <= _noRounds; i++) + { + A = RotateLeft(A ^ B, B) + _S[2*i]; + B = RotateLeft(B ^ A, A) + _S[2*i+1]; + } + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + + return 2 * bytesPerWord; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + long A = BytesToWord(input, inOff); + long B = BytesToWord(input, inOff + bytesPerWord); + + for (int i = _noRounds; i >= 1; i--) + { + B = RotateRight(B - _S[2*i+1], A) ^ A; + A = RotateRight(A - _S[2*i], B) ^ B; + } + + WordToBytes(A - _S[0], outBytes, outOff); + WordToBytes(B - _S[1], outBytes, outOff + bytesPerWord); + + return 2 * bytesPerWord; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private long RotateLeft(long x, long y) { + return ((long) ( (ulong) (x << (int) (y & (wordSize-1))) | + ((ulong) x >> (int) (wordSize - (y & (wordSize-1))))) + ); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private long RotateRight(long x, long y) { + return ((long) ( ((ulong) x >> (int) (y & (wordSize-1))) | + (ulong) (x << (int) (wordSize - (y & (wordSize-1))))) + ); + } + + private long BytesToWord( + byte[] src, + int srcOff) + { + long word = 0; + + for (int i = bytesPerWord - 1; i >= 0; i--) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void WordToBytes( + long word, + byte[] dst, + int dstOff) + { + for (int i = 0; i < bytesPerWord; i++) + { + dst[i + dstOff] = (byte)word; + word = (long) ((ulong) word >> 8); + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/RC6Engine.cs b/iTechSharp/srcbc/crypto/engines/RC6Engine.cs new file mode 100644 index 0000000..d72cc2f --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RC6Engine.cs @@ -0,0 +1,362 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An RC6 engine. + */ + public class RC6Engine + : IBlockCipher + { + private static readonly int wordSize = 32; + private static readonly int bytesPerWord = wordSize / 8; + + /* + * the number of rounds to perform + */ + private static readonly int _noRounds = 20; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private int [] _S; + + /* + * our "magic constants" for wordSize 32 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly int P32 = unchecked((int) 0xb7e15163); + private static readonly int Q32 = unchecked((int) 0x9e3779b9); + + private static readonly int LGW = 5; // log2(32) + + private bool forEncryption; + + /** + * Create an instance of the RC6 encryption algorithm + * and set some defaults + */ + public RC6Engine() + { +// _S = null; + } + + public string AlgorithmName + { + get { return "RC6"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return 4 * bytesPerWord; + } + + /** + * initialise a RC5-32 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to RC6 init - " + parameters.GetType().ToString()); + + this.forEncryption = forEncryption; + + KeyParameter p = (KeyParameter)parameters; + SetKey(p.GetKey()); + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + int blockSize = GetBlockSize(); + if (_S == null) + throw new InvalidOperationException("RC6 engine not initialised"); + if ((inOff + blockSize) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + blockSize) > output.Length) + throw new DataLengthException("output buffer too short"); + + return (forEncryption) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param inKey the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = wordSize/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + // compute number of dwords + int c = (key.Length + (bytesPerWord - 1)) / bytesPerWord; + if (c == 0) + { + c = 1; + } + int[] L = new int[(key.Length + bytesPerWord - 1) / bytesPerWord]; + + // load all key bytes into array of key dwords + for (int i = key.Length - 1; i >= 0; i--) + { + L[i / bytesPerWord] = (L[i / bytesPerWord] << 8) + (key[i] & 0xff); + } + + // + // Phase 2: + // Key schedule is placed in a array of 2+2*ROUNDS+2 = 44 dwords. + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new int[2+2*_noRounds+2]; + + _S[0] = P32; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q32); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + int A = 0; + int B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + // load A,B,C and D registers from in. + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + bytesPerWord); + int C = BytesToWord(input, inOff + bytesPerWord*2); + int D = BytesToWord(input, inOff + bytesPerWord*3); + + // Do pseudo-round #0: pre-whitening of B and D + B += _S[0]; + D += _S[1]; + + // perform round #1,#2 ... #ROUNDS of encryption + for (int i = 1; i <= _noRounds; i++) + { + int t = 0,u = 0; + + t = B*(2*B+1); + t = RotateLeft(t,5); + + u = D*(2*D+1); + u = RotateLeft(u,5); + + A ^= t; + A = RotateLeft(A,u); + A += _S[2*i]; + + C ^= u; + C = RotateLeft(C,t); + C += _S[2*i+1]; + + int temp = A; + A = B; + B = C; + C = D; + D = temp; + } + // do pseudo-round #(ROUNDS+1) : post-whitening of A and C + A += _S[2*_noRounds+2]; + C += _S[2*_noRounds+3]; + + // store A, B, C and D registers to out + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + WordToBytes(C, outBytes, outOff + bytesPerWord*2); + WordToBytes(D, outBytes, outOff + bytesPerWord*3); + + return 4 * bytesPerWord; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + // load A,B,C and D registers from out. + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + bytesPerWord); + int C = BytesToWord(input, inOff + bytesPerWord*2); + int D = BytesToWord(input, inOff + bytesPerWord*3); + + // Undo pseudo-round #(ROUNDS+1) : post whitening of A and C + C -= _S[2*_noRounds+3]; + A -= _S[2*_noRounds+2]; + + // Undo round #ROUNDS, .., #2,#1 of encryption + for (int i = _noRounds; i >= 1; i--) + { + int t=0,u = 0; + + int temp = D; + D = C; + C = B; + B = A; + A = temp; + + t = B*(2*B+1); + t = RotateLeft(t, LGW); + + u = D*(2*D+1); + u = RotateLeft(u, LGW); + + C -= _S[2*i+1]; + C = RotateRight(C,t); + C ^= u; + + A -= _S[2*i]; + A = RotateRight(A,u); + A ^= t; + + } + // Undo pseudo-round #0: pre-whitening of B and D + D -= _S[1]; + B -= _S[0]; + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + WordToBytes(C, outBytes, outOff + bytesPerWord*2); + WordToBytes(D, outBytes, outOff + bytesPerWord*3); + + return 4 * bytesPerWord; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private int RotateLeft(int x, int y) + { + return ((int)((uint)(x << (y & (wordSize-1))) + | ((uint) x >> (wordSize - (y & (wordSize-1)))))); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private int RotateRight(int x, int y) + { + return ((int)(((uint) x >> (y & (wordSize-1))) + | (uint)(x << (wordSize - (y & (wordSize-1)))))); + } + + private int BytesToWord( + byte[] src, + int srcOff) + { + int word = 0; + + for (int i = bytesPerWord - 1; i >= 0; i--) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void WordToBytes( + int word, + byte[] dst, + int dstOff) + { + for (int i = 0; i < bytesPerWord; i++) + { + dst[i + dstOff] = (byte)word; + word = (int) ((uint) word >> 8); + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/RFC3211WrapEngine.cs b/iTechSharp/srcbc/crypto/engines/RFC3211WrapEngine.cs new file mode 100644 index 0000000..906630a --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RFC3211WrapEngine.cs @@ -0,0 +1,166 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the RFC 3211 Key Wrap + * Specification. + */ + public class Rfc3211WrapEngine + : IWrapper + { + private CbcBlockCipher engine; + private ParametersWithIV param; + private bool forWrapping; + private SecureRandom rand; + + public Rfc3211WrapEngine( + IBlockCipher engine) + { + this.engine = new CbcBlockCipher(engine); + } + + public void Init( + bool forWrapping, + ICipherParameters param) + { + this.forWrapping = forWrapping; + + if (param is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom) param; + + this.rand = p.Random; + this.param = (ParametersWithIV) p.Parameters; + } + else + { + if (forWrapping) + { + rand = new SecureRandom(); + } + + this.param = (ParametersWithIV) param; + } + } + + public string AlgorithmName + { + get { return engine.GetUnderlyingCipher().AlgorithmName + "/RFC3211Wrap"; } + } + + public byte[] Wrap( + byte[] inBytes, + int inOff, + int inLen) + { + if (!forWrapping) + { + throw new InvalidOperationException("not set for wrapping"); + } + + engine.Init(true, param); + + int blockSize = engine.GetBlockSize(); + byte[] cekBlock; + + if (inLen + 4 < blockSize * 2) + { + cekBlock = new byte[blockSize * 2]; + } + else + { + cekBlock = new byte[(inLen + 4) % blockSize == 0 ? inLen + 4 : ((inLen + 4) / blockSize + 1) * blockSize]; + } + + cekBlock[0] = (byte)inLen; + cekBlock[1] = (byte)~inBytes[inOff]; + cekBlock[2] = (byte)~inBytes[inOff + 1]; + cekBlock[3] = (byte)~inBytes[inOff + 2]; + + Array.Copy(inBytes, inOff, cekBlock, 4, inLen); + + rand.NextBytes(cekBlock, inLen + 4, cekBlock.Length - inLen - 4); + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + return cekBlock; + } + + public byte[] Unwrap( + byte[] inBytes, + int inOff, + int inLen) + { + if (forWrapping) + { + throw new InvalidOperationException("not set for unwrapping"); + } + + int blockSize = engine.GetBlockSize(); + + if (inLen < 2 * blockSize) + { + throw new InvalidCipherTextException("input too short"); + } + + byte[] cekBlock = new byte[inLen]; + byte[] iv = new byte[blockSize]; + + Array.Copy(inBytes, inOff, cekBlock, 0, inLen); + Array.Copy(inBytes, inOff, iv, 0, iv.Length); + + engine.Init(false, new ParametersWithIV(param.Parameters, iv)); + + for (int i = blockSize; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + Array.Copy(cekBlock, cekBlock.Length - iv.Length, iv, 0, iv.Length); + + engine.Init(false, new ParametersWithIV(param.Parameters, iv)); + + engine.ProcessBlock(cekBlock, 0, cekBlock, 0); + + engine.Init(false, param); + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + if ((cekBlock[0] & 0xff) > cekBlock.Length - 4) + { + throw new InvalidCipherTextException("wrapped key corrupted"); + } + + byte[] key = new byte[cekBlock[0] & 0xff]; + + Array.Copy(cekBlock, 4, key, 0, cekBlock[0]); + + for (int i = 0; i != 3; i++) + { + byte check = (byte)~cekBlock[1 + i]; + if (check != key[i]) + { + throw new InvalidCipherTextException("wrapped key fails checksum"); + } + } + + return key; + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/RFC3394WrapEngine.cs b/iTechSharp/srcbc/crypto/engines/RFC3394WrapEngine.cs new file mode 100644 index 0000000..fc45805 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RFC3394WrapEngine.cs @@ -0,0 +1,181 @@ +using System; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + ///+ * Note: this implementation is based on information prior to readonly NIST publication. + *
+ */ + public class RijndaelEngine + : IBlockCipher + { + private static readonly int MAXROUNDS = 14; + + private static readonly int MAXKC = (256/4); + + private static readonly byte[] Logtable = { + (byte)0, (byte)0, (byte)25, (byte)1, (byte)50, (byte)2, (byte)26, (byte)198, + (byte)75, (byte)199, (byte)27, (byte)104, (byte)51, (byte)238, (byte)223, (byte)3, + (byte)100, (byte)4, (byte)224, (byte)14, (byte)52, (byte)141, (byte)129, (byte)239, + (byte)76, (byte)113, (byte)8, (byte)200, (byte)248, (byte)105, (byte)28, (byte)193, + (byte)125, (byte)194, (byte)29, (byte)181, (byte)249, (byte)185, (byte)39, (byte)106, + (byte)77, (byte)228, (byte)166, (byte)114, (byte)154, (byte)201, (byte)9, (byte)120, + (byte)101, (byte)47, (byte)138, (byte)5, (byte)33, (byte)15, (byte)225, (byte)36, + (byte)18, (byte)240, (byte)130, (byte)69, (byte)53, (byte)147, (byte)218, (byte)142, + (byte)150, (byte)143, (byte)219, (byte)189, (byte)54, (byte)208, (byte)206, (byte)148, + (byte)19, (byte)92, (byte)210, (byte)241, (byte)64, (byte)70, (byte)131, (byte)56, + (byte)102, (byte)221, (byte)253, (byte)48, (byte)191, (byte)6, (byte)139, (byte)98, + (byte)179, (byte)37, (byte)226, (byte)152, (byte)34, (byte)136, (byte)145, (byte)16, + (byte)126, (byte)110, (byte)72, (byte)195, (byte)163, (byte)182, (byte)30, (byte)66, + (byte)58, (byte)107, (byte)40, (byte)84, (byte)250, (byte)133, (byte)61, (byte)186, + (byte)43, (byte)121, (byte)10, (byte)21, (byte)155, (byte)159, (byte)94, (byte)202, + (byte)78, (byte)212, (byte)172, (byte)229, (byte)243, (byte)115, (byte)167, (byte)87, + (byte)175, (byte)88, (byte)168, (byte)80, (byte)244, (byte)234, (byte)214, (byte)116, + (byte)79, (byte)174, (byte)233, (byte)213, (byte)231, (byte)230, (byte)173, (byte)232, + (byte)44, (byte)215, (byte)117, (byte)122, (byte)235, (byte)22, (byte)11, (byte)245, + (byte)89, (byte)203, (byte)95, (byte)176, (byte)156, (byte)169, (byte)81, (byte)160, + (byte)127, (byte)12, (byte)246, (byte)111, (byte)23, (byte)196, (byte)73, (byte)236, + (byte)216, (byte)67, (byte)31, (byte)45, (byte)164, (byte)118, (byte)123, (byte)183, + (byte)204, (byte)187, (byte)62, (byte)90, (byte)251, (byte)96, (byte)177, (byte)134, + (byte)59, (byte)82, (byte)161, (byte)108, (byte)170, (byte)85, (byte)41, (byte)157, + (byte)151, (byte)178, (byte)135, (byte)144, (byte)97, (byte)190, (byte)220, (byte)252, + (byte)188, (byte)149, (byte)207, (byte)205, (byte)55, (byte)63, (byte)91, (byte)209, + (byte)83, (byte)57, (byte)132, (byte)60, (byte)65, (byte)162, (byte)109, (byte)71, + (byte)20, (byte)42, (byte)158, (byte)93, (byte)86, (byte)242, (byte)211, (byte)171, + (byte)68, (byte)17, (byte)146, (byte)217, (byte)35, (byte)32, (byte)46, (byte)137, + (byte)180, (byte)124, (byte)184, (byte)38, (byte)119, (byte)153, (byte)227, (byte)165, + (byte)103, (byte)74, (byte)237, (byte)222, (byte)197, (byte)49, (byte)254, (byte)24, + (byte)13, (byte)99, (byte)140, (byte)128, (byte)192, (byte)247, (byte)112, (byte)7 + }; + + private static readonly byte[] Alogtable = { + (byte)0, (byte)3, (byte)5, (byte)15, (byte)17, (byte)51, (byte)85, (byte)255, (byte)26, (byte)46, (byte)114, (byte)150, (byte)161, (byte)248, (byte)19, (byte)53, + (byte)95, (byte)225, (byte)56, (byte)72, (byte)216, (byte)115, (byte)149, (byte)164, (byte)247, (byte)2, (byte)6, (byte)10, (byte)30, (byte)34, (byte)102, (byte)170, + (byte)229, (byte)52, (byte)92, (byte)228, (byte)55, (byte)89, (byte)235, (byte)38, (byte)106, (byte)190, (byte)217, (byte)112, (byte)144, (byte)171, (byte)230, (byte)49, + (byte)83, (byte)245, (byte)4, (byte)12, (byte)20, (byte)60, (byte)68, (byte)204, (byte)79, (byte)209, (byte)104, (byte)184, (byte)211, (byte)110, (byte)178, (byte)205, + (byte)76, (byte)212, (byte)103, (byte)169, (byte)224, (byte)59, (byte)77, (byte)215, (byte)98, (byte)166, (byte)241, (byte)8, (byte)24, (byte)40, (byte)120, (byte)136, + (byte)131, (byte)158, (byte)185, (byte)208, (byte)107, (byte)189, (byte)220, (byte)127, (byte)129, (byte)152, (byte)179, (byte)206, (byte)73, (byte)219, (byte)118, (byte)154, + (byte)181, (byte)196, (byte)87, (byte)249, (byte)16, (byte)48, (byte)80, (byte)240, (byte)11, (byte)29, (byte)39, (byte)105, (byte)187, (byte)214, (byte)97, (byte)163, + (byte)254, (byte)25, (byte)43, (byte)125, (byte)135, (byte)146, (byte)173, (byte)236, (byte)47, (byte)113, (byte)147, (byte)174, (byte)233, (byte)32, (byte)96, (byte)160, + (byte)251, (byte)22, (byte)58, (byte)78, (byte)210, (byte)109, (byte)183, (byte)194, (byte)93, (byte)231, (byte)50, (byte)86, (byte)250, (byte)21, (byte)63, (byte)65, + (byte)195, (byte)94, (byte)226, (byte)61, (byte)71, (byte)201, (byte)64, (byte)192, (byte)91, (byte)237, (byte)44, (byte)116, (byte)156, (byte)191, (byte)218, (byte)117, + (byte)159, (byte)186, (byte)213, (byte)100, (byte)172, (byte)239, (byte)42, (byte)126, (byte)130, (byte)157, (byte)188, (byte)223, (byte)122, (byte)142, (byte)137, (byte)128, + (byte)155, (byte)182, (byte)193, (byte)88, (byte)232, (byte)35, (byte)101, (byte)175, (byte)234, (byte)37, (byte)111, (byte)177, (byte)200, (byte)67, (byte)197, (byte)84, + (byte)252, (byte)31, (byte)33, (byte)99, (byte)165, (byte)244, (byte)7, (byte)9, (byte)27, (byte)45, (byte)119, (byte)153, (byte)176, (byte)203, (byte)70, (byte)202, + (byte)69, (byte)207, (byte)74, (byte)222, (byte)121, (byte)139, (byte)134, (byte)145, (byte)168, (byte)227, (byte)62, (byte)66, (byte)198, (byte)81, (byte)243, (byte)14, + (byte)18, (byte)54, (byte)90, (byte)238, (byte)41, (byte)123, (byte)141, (byte)140, (byte)143, (byte)138, (byte)133, (byte)148, (byte)167, (byte)242, (byte)13, (byte)23, + (byte)57, (byte)75, (byte)221, (byte)124, (byte)132, (byte)151, (byte)162, (byte)253, (byte)28, (byte)36, (byte)108, (byte)180, (byte)199, (byte)82, (byte)246, (byte)1, + (byte)3, (byte)5, (byte)15, (byte)17, (byte)51, (byte)85, (byte)255, (byte)26, (byte)46, (byte)114, (byte)150, (byte)161, (byte)248, (byte)19, (byte)53, + (byte)95, (byte)225, (byte)56, (byte)72, (byte)216, (byte)115, (byte)149, (byte)164, (byte)247, (byte)2, (byte)6, (byte)10, (byte)30, (byte)34, (byte)102, (byte)170, + (byte)229, (byte)52, (byte)92, (byte)228, (byte)55, (byte)89, (byte)235, (byte)38, (byte)106, (byte)190, (byte)217, (byte)112, (byte)144, (byte)171, (byte)230, (byte)49, + (byte)83, (byte)245, (byte)4, (byte)12, (byte)20, (byte)60, (byte)68, (byte)204, (byte)79, (byte)209, (byte)104, (byte)184, (byte)211, (byte)110, (byte)178, (byte)205, + (byte)76, (byte)212, (byte)103, (byte)169, (byte)224, (byte)59, (byte)77, (byte)215, (byte)98, (byte)166, (byte)241, (byte)8, (byte)24, (byte)40, (byte)120, (byte)136, + (byte)131, (byte)158, (byte)185, (byte)208, (byte)107, (byte)189, (byte)220, (byte)127, (byte)129, (byte)152, (byte)179, (byte)206, (byte)73, (byte)219, (byte)118, (byte)154, + (byte)181, (byte)196, (byte)87, (byte)249, (byte)16, (byte)48, (byte)80, (byte)240, (byte)11, (byte)29, (byte)39, (byte)105, (byte)187, (byte)214, (byte)97, (byte)163, + (byte)254, (byte)25, (byte)43, (byte)125, (byte)135, (byte)146, (byte)173, (byte)236, (byte)47, (byte)113, (byte)147, (byte)174, (byte)233, (byte)32, (byte)96, (byte)160, + (byte)251, (byte)22, (byte)58, (byte)78, (byte)210, (byte)109, (byte)183, (byte)194, (byte)93, (byte)231, (byte)50, (byte)86, (byte)250, (byte)21, (byte)63, (byte)65, + (byte)195, (byte)94, (byte)226, (byte)61, (byte)71, (byte)201, (byte)64, (byte)192, (byte)91, (byte)237, (byte)44, (byte)116, (byte)156, (byte)191, (byte)218, (byte)117, + (byte)159, (byte)186, (byte)213, (byte)100, (byte)172, (byte)239, (byte)42, (byte)126, (byte)130, (byte)157, (byte)188, (byte)223, (byte)122, (byte)142, (byte)137, (byte)128, + (byte)155, (byte)182, (byte)193, (byte)88, (byte)232, (byte)35, (byte)101, (byte)175, (byte)234, (byte)37, (byte)111, (byte)177, (byte)200, (byte)67, (byte)197, (byte)84, + (byte)252, (byte)31, (byte)33, (byte)99, (byte)165, (byte)244, (byte)7, (byte)9, (byte)27, (byte)45, (byte)119, (byte)153, (byte)176, (byte)203, (byte)70, (byte)202, + (byte)69, (byte)207, (byte)74, (byte)222, (byte)121, (byte)139, (byte)134, (byte)145, (byte)168, (byte)227, (byte)62, (byte)66, (byte)198, (byte)81, (byte)243, (byte)14, + (byte)18, (byte)54, (byte)90, (byte)238, (byte)41, (byte)123, (byte)141, (byte)140, (byte)143, (byte)138, (byte)133, (byte)148, (byte)167, (byte)242, (byte)13, (byte)23, + (byte)57, (byte)75, (byte)221, (byte)124, (byte)132, (byte)151, (byte)162, (byte)253, (byte)28, (byte)36, (byte)108, (byte)180, (byte)199, (byte)82, (byte)246, (byte)1, + }; + + private static readonly byte[] S = { + (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, + (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, + (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, + (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, + (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, + (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, + (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, + (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, + (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, + (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, + (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, + (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, + (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, + (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, + (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, + (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, + }; + + private static readonly byte[] Si = { + (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, + (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, + (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, + (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, + (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, + (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, + (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, + (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, + (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, + (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, + (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, + (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, + (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, + (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, + (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, + (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, + }; + + private static readonly int[] rcon = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; + + static readonly byte[][] shifts0 = new byte [][] + { + new byte [] { 0, 8, 16, 24 }, + new byte [] { 0, 8, 16, 24 }, + new byte [] { 0, 8, 16, 24 }, + new byte [] { 0, 8, 16, 32 }, + new byte [] { 0, 8, 24, 32 } + }; + + static readonly byte[][] shifts1 = + { + new byte [] { 0, 24, 16, 8 }, + new byte [] { 0, 32, 24, 16 }, + new byte [] { 0, 40, 32, 24 }, + new byte [] { 0, 48, 40, 24 }, + new byte [] { 0, 56, 40, 32 } + }; + + /** + * multiply two elements of GF(2^m) + * needed for MixColumn and InvMixColumn + */ + private byte Mul0x2( + int b) + { + if (b != 0) + { + return Alogtable[25 + (Logtable[b] & 0xff)]; + } + else + { + return 0; + } + } + + private byte Mul0x3( + int b) + { + if (b != 0) + { + return Alogtable[1 + (Logtable[b] & 0xff)]; + } + else + { + return 0; + } + } + + private byte Mul0x9( + int b) + { + if (b >= 0) + { + return Alogtable[199 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xb( + int b) + { + if (b >= 0) + { + return Alogtable[104 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xd( + int b) + { + if (b >= 0) + { + return Alogtable[238 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xe( + int b) + { + if (b >= 0) + { + return Alogtable[223 + b]; + } + else + { + return 0; + } + } + + /** + * xor corresponding text input and round key input bytes + */ + private void KeyAddition( + long[] rk) + { + A0 ^= rk[0]; + A1 ^= rk[1]; + A2 ^= rk[2]; + A3 ^= rk[3]; + } + + private long Shift( + long r, + int shift) + { + //return (((long)((ulong) r >> shift) | (r << (BC - shift)))) & BC_MASK; + + ulong temp = (ulong) r >> shift; + + // NB: This corrects for Mono Bug #79087 (fixed in 1.1.17) + if (shift > 31) + { + temp &= 0xFFFFFFFFUL; + } + + return ((long) temp | (r << (BC - shift))) & BC_MASK; + } + + /** + * Row 0 remains unchanged + * The other three rows are shifted a variable amount + */ + private void ShiftRow( + byte[] shiftsSC) + { + A1 = Shift(A1, shiftsSC[1]); + A2 = Shift(A2, shiftsSC[2]); + A3 = Shift(A3, shiftsSC[3]); + } + + private long ApplyS( + long r, + byte[] box) + { + long res = 0; + + for (int j = 0; j < BC; j += 8) + { + res |= (long)(box[(int)((r >> j) & 0xff)] & 0xff) << j; + } + + return res; + } + + /** + * Replace every byte of the input by the byte at that place + * in the nonlinear S-box + */ + private void Substitution( + byte[] box) + { + A0 = ApplyS(A0, box); + A1 = ApplyS(A1, box); + A2 = ApplyS(A2, box); + A3 = ApplyS(A3, box); + } + + /** + * Mix the bytes of every column in a linear way + */ + private void MixColumn() + { + long r0, r1, r2, r3; + + r0 = r1 = r2 = r3 = 0; + + for (int j = 0; j < BC; j += 8) + { + int a0 = (int)((A0 >> j) & 0xff); + int a1 = (int)((A1 >> j) & 0xff); + int a2 = (int)((A2 >> j) & 0xff); + int a3 = (int)((A3 >> j) & 0xff); + + r0 |= (long)((Mul0x2(a0) ^ Mul0x3(a1) ^ a2 ^ a3) & 0xff) << j; + + r1 |= (long)((Mul0x2(a1) ^ Mul0x3(a2) ^ a3 ^ a0) & 0xff) << j; + + r2 |= (long)((Mul0x2(a2) ^ Mul0x3(a3) ^ a0 ^ a1) & 0xff) << j; + + r3 |= (long)((Mul0x2(a3) ^ Mul0x3(a0) ^ a1 ^ a2) & 0xff) << j; + } + + A0 = r0; + A1 = r1; + A2 = r2; + A3 = r3; + } + + /** + * Mix the bytes of every column in a linear way + * This is the opposite operation of Mixcolumn + */ + private void InvMixColumn() + { + long r0, r1, r2, r3; + + r0 = r1 = r2 = r3 = 0; + for (int j = 0; j < BC; j += 8) + { + int a0 = (int)((A0 >> j) & 0xff); + int a1 = (int)((A1 >> j) & 0xff); + int a2 = (int)((A2 >> j) & 0xff); + int a3 = (int)((A3 >> j) & 0xff); + + // + // pre-lookup the log table + // + a0 = (a0 != 0) ? (Logtable[a0 & 0xff] & 0xff) : -1; + a1 = (a1 != 0) ? (Logtable[a1 & 0xff] & 0xff) : -1; + a2 = (a2 != 0) ? (Logtable[a2 & 0xff] & 0xff) : -1; + a3 = (a3 != 0) ? (Logtable[a3 & 0xff] & 0xff) : -1; + + r0 |= (long)((Mul0xe(a0) ^ Mul0xb(a1) ^ Mul0xd(a2) ^ Mul0x9(a3)) & 0xff) << j; + + r1 |= (long)((Mul0xe(a1) ^ Mul0xb(a2) ^ Mul0xd(a3) ^ Mul0x9(a0)) & 0xff) << j; + + r2 |= (long)((Mul0xe(a2) ^ Mul0xb(a3) ^ Mul0xd(a0) ^ Mul0x9(a1)) & 0xff) << j; + + r3 |= (long)((Mul0xe(a3) ^ Mul0xb(a0) ^ Mul0xd(a1) ^ Mul0x9(a2)) & 0xff) << j; + } + + A0 = r0; + A1 = r1; + A2 = r2; + A3 = r3; + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on keyBits and blockBits + */ + private long[][] GenerateWorkingKey( + byte[] key) + { + int KC; + int t, rconpointer = 0; + int keyBits = key.Length * 8; + byte[,] tk = new byte[4,MAXKC]; + //long[,] W = new long[MAXROUNDS+1,4]; + long[][] W = new long[MAXROUNDS+1][]; + + for (int i = 0; i < MAXROUNDS+1; i++) W[i] = new long[4]; + + switch (keyBits) + { + case 128: + KC = 4; + break; + case 160: + KC = 5; + break; + case 192: + KC = 6; + break; + case 224: + KC = 7; + break; + case 256: + KC = 8; + break; + default : + throw new ArgumentException("Key length not 128/160/192/224/256 bits."); + } + + if (keyBits >= blockBits) + { + ROUNDS = KC + 6; + } + else + { + ROUNDS = (BC / 8) + 6; + } + + // + // copy the key into the processing area + // + int index = 0; + + for (int i = 0; i < key.Length; i++) + { + tk[i % 4,i / 4] = key[index++]; + } + + t = 0; + + // + // copy values into round key array + // + for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC / 8)); j++, t++) + { + for (int i = 0; i < 4; i++) + { + W[t / (BC / 8)][i] |= (long)(tk[i,j] & 0xff) << ((t * 8) % BC); + } + } + + // + // while not enough round key material calculated + // calculate new values + // + while (t < (ROUNDS+1)*(BC/8)) + { + for (int i = 0; i < 4; i++) + { + tk[i,0] ^= S[tk[(i+1)%4,KC-1] & 0xff]; + } + tk[0,0] ^= (byte) rcon[rconpointer++]; + + if (KC <= 6) + { + for (int j = 1; j < KC; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + } + else + { + for (int j = 1; j < 4; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + for (int i = 0; i < 4; i++) + { + tk[i,4] ^= S[tk[i,3] & 0xff]; + } + for (int j = 5; j < KC; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + } + + // + // copy values into round key array + // + for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC/8)); j++, t++) + { + for (int i = 0; i < 4; i++) + { + W[t / (BC/8)][i] |= (long)(tk[i,j] & 0xff) << ((t * 8) % (BC)); + } + } + } + return W; + } + + private int BC; + private long BC_MASK; + private int ROUNDS; + private int blockBits; + private long[][] workingKey; + private long A0, A1, A2, A3; + private bool forEncryption; + private byte[] shifts0SC; + private byte[] shifts1SC; + + /** + * default constructor - 128 bit block size. + */ + public RijndaelEngine() : this(128) {} + + /** + * basic constructor - set the cipher up for a given blocksize + * + * @param blocksize the blocksize in bits, must be 128, 192, or 256. + */ + public RijndaelEngine( + int blockBits) + { + switch (blockBits) + { + case 128: + BC = 32; + BC_MASK = 0xffffffffL; + shifts0SC = shifts0[0]; + shifts1SC = shifts1[0]; + break; + case 160: + BC = 40; + BC_MASK = 0xffffffffffL; + shifts0SC = shifts0[1]; + shifts1SC = shifts1[1]; + break; + case 192: + BC = 48; + BC_MASK = 0xffffffffffffL; + shifts0SC = shifts0[2]; + shifts1SC = shifts1[2]; + break; + case 224: + BC = 56; + BC_MASK = 0xffffffffffffffL; + shifts0SC = shifts0[3]; + shifts1SC = shifts1[3]; + break; + case 256: + BC = 64; + BC_MASK = unchecked( (long)0xffffffffffffffffL); + shifts0SC = shifts0[4]; + shifts1SC = shifts1[4]; + break; + default: + throw new ArgumentException("unknown blocksize to Rijndael"); + } + + this.blockBits = blockBits; + } + + /** + * initialise a Rijndael cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (typeof(KeyParameter).IsInstanceOfType(parameters)) + { + workingKey = GenerateWorkingKey(((KeyParameter)parameters).GetKey()); + this.forEncryption = forEncryption; + return; + } + + throw new ArgumentException("invalid parameter passed to Rijndael init - " + parameters.GetType().ToString()); + } + + public string AlgorithmName + { + get { return "Rijndael"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BC / 2; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + { + throw new InvalidOperationException("Rijndael engine not initialised"); + } + + if ((inOff + (BC / 2)) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + (BC / 2)) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + UnPackBlock(input, inOff); + + if (forEncryption) + { + EncryptBlock(workingKey); + } + else + { + DecryptBlock(workingKey); + } + + PackBlock(output, outOff); + + return BC / 2; + } + + public void Reset() + { + } + + private void UnPackBlock( + byte[] bytes, + int off) + { + int index = off; + + A0 = (long)(bytes[index++] & 0xff); + A1 = (long)(bytes[index++] & 0xff); + A2 = (long)(bytes[index++] & 0xff); + A3 = (long)(bytes[index++] & 0xff); + + for (int j = 8; j != BC; j += 8) + { + A0 |= (long)(bytes[index++] & 0xff) << j; + A1 |= (long)(bytes[index++] & 0xff) << j; + A2 |= (long)(bytes[index++] & 0xff) << j; + A3 |= (long)(bytes[index++] & 0xff) << j; + } + } + + private void PackBlock( + byte[] bytes, + int off) + { + int index = off; + + for (int j = 0; j != BC; j += 8) + { + bytes[index++] = (byte)(A0 >> j); + bytes[index++] = (byte)(A1 >> j); + bytes[index++] = (byte)(A2 >> j); + bytes[index++] = (byte)(A3 >> j); + } + } + + private void EncryptBlock( + long[][] rk) + { + int r; + + // + // begin with a key addition + // + KeyAddition(rk[0]); + + // + // ROUNDS-1 ordinary rounds + // + for (r = 1; r < ROUNDS; r++) + { + Substitution(S); + ShiftRow(shifts0SC); + MixColumn(); + KeyAddition(rk[r]); + } + + // + // Last round is special: there is no MixColumn + // + Substitution(S); + ShiftRow(shifts0SC); + KeyAddition(rk[ROUNDS]); + } + + private void DecryptBlock( + long[][] rk) + { + int r; + + // To decrypt: apply the inverse operations of the encrypt routine, + // in opposite order + // + // (KeyAddition is an involution: it 's equal to its inverse) + // (the inverse of Substitution with table S is Substitution with the inverse table of S) + // (the inverse of Shiftrow is Shiftrow over a suitable distance) + // + + // First the special round: + // without InvMixColumn + // with extra KeyAddition + // + KeyAddition(rk[ROUNDS]); + Substitution(Si); + ShiftRow(shifts1SC); + + // + // ROUNDS-1 ordinary rounds + // + for (r = ROUNDS-1; r > 0; r--) + { + KeyAddition(rk[r]); + InvMixColumn(); + Substitution(Si); + ShiftRow(shifts1SC); + } + + // + // End with the extra key addition + // + KeyAddition(rk[0]); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/RsaEngine.cs b/iTechSharp/srcbc/crypto/engines/RsaEngine.cs new file mode 100644 index 0000000..7e6dfb1 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/RsaEngine.cs @@ -0,0 +1,78 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * this does your basic RSA algorithm. + */ + public class RsaEngine + : IAsymmetricBlockCipher + { + private RsaCoreEngine core; + + public string AlgorithmName + { + get { return "RSA"; } + } + + /** + * initialise the RSA engine. + * + * @param forEncryption true if we are encrypting, false otherwise. + * @param param the necessary RSA key parameters. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (core == null) + core = new RsaCoreEngine(); + + core.Init(forEncryption, parameters); + } + + /** + * Return the maximum size for an input block to this engine. + * For RSA this is always one byte less than the key size on + * encryption, and the same length as the key size on decryption. + * + * @return maximum size for an input block. + */ + public int GetInputBlockSize() + { + return core.GetInputBlockSize(); + } + + /** + * Return the maximum size for an output block to this engine. + * For RSA this is always one byte less than the key size on + * decryption, and the same length as the key size on encryption. + * + * @return maximum size for an output block. + */ + public int GetOutputBlockSize() + { + return core.GetOutputBlockSize(); + } + + /** + * Process a single block using the basic RSA algorithm. + * + * @param inBuf the input array. + * @param inOff the offset into the input buffer where the data starts. + * @param inLen the length of the data to be processed. + * @return the result of the RSA process. + * @exception DataLengthException the input block is too large. + */ + public byte[] ProcessBlock( + byte[] inBuf, + int inOff, + int inLen) + { + if (core == null) + throw new InvalidOperationException("RSA engine not initialised"); + + return core.ConvertOutput(core.ProcessBlock(core.ConvertInput(inBuf, inOff, inLen))); + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/SEEDEngine.cs b/iTechSharp/srcbc/crypto/engines/SEEDEngine.cs new file mode 100644 index 0000000..efea0f1 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/SEEDEngine.cs @@ -0,0 +1,361 @@ +using System; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Implementation of the SEED algorithm as described in RFC 4009 + */ + public class SeedEngine + : IBlockCipher + { + private const int BlockSize = 16; + + private static readonly uint[] SS0 = + { + 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124, + 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, + 0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314, + 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec, + 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, + 0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100, + 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8, + 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, + 0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c, + 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4, + 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, + 0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0, + 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8, + 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, + 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064, + 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264, + 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, + 0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc, + 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038, + 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, + 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188, + 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4, + 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, + 0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4, + 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040, + 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, + 0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254, + 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8, + 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, + 0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088, + 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330, + 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298 + }; + + private static readonly uint[] SS1 = + { + 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0, + 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, + 0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3, + 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43, + 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, + 0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890, + 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3, + 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, + 0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83, + 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430, + 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, + 0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1, + 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1, + 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171, + 0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951, + 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0, + 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, + 0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41, + 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62, + 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, + 0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303, + 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901, + 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, + 0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343, + 0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971, + 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, + 0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642, + 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1, + 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, + 0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393, + 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783, + 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3 + }; + + private static readonly uint[] SS2 = + { + + 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505, + 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, + 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707, + 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece, + 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, + 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101, + 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9, + 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, + 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f, + 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5, + 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, + 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1, + 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b, + 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, + 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444, + 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646, + 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, + 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf, + 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808, + 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, + 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989, + 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4, + 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, + 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484, + 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040, + 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, + 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646, + 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca, + 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, + 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888, + 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303, + 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a + }; + + private static readonly uint[] SS3 = + { + + 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, + 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, + 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, + 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, + 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, + 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, + 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, + 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, + 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, + 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, + 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, + 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, + 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, + 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031, + 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, + 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, + 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, + 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, + 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, + 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, + 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, + 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, + 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, + 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, + 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, + 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, + 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, + 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, + 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, + 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013, + 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, + 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437 + }; + + private static readonly uint[] KC = + { + 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, + 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf, + 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, + 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b + }; + + private int[] wKey; + private bool forEncryption; + + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + wKey = createWorkingKey(((KeyParameter)parameters).GetKey()); + } + + public string AlgorithmName + { + get { return "SEED"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BlockSize; + } + + public int ProcessBlock( + byte[] inBuf, + int inOff, + byte[] outBuf, + int outOff) + { + if (wKey == null) + throw new InvalidOperationException("SEED engine not initialised"); + if (inOff + BlockSize > inBuf.Length) + throw new DataLengthException("input buffer too short"); + if (outOff + BlockSize > outBuf.Length) + throw new DataLengthException("output buffer too short"); + + long l = bytesToLong(inBuf, inOff + 0); + long r = bytesToLong(inBuf, inOff + 8); + + if (forEncryption) + { + for (int i = 0; i < 16; i++) + { + long nl = r; + + r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r); + l = nl; + } + } + else + { + for (int i = 15; i >= 0; i--) + { + long nl = r; + + r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r); + l = nl; + } + } + + longToBytes(outBuf, outOff + 0, r); + longToBytes(outBuf, outOff + 8, l); + + return BlockSize; + } + + public void Reset() + { + } + + private int[] createWorkingKey( + byte[] inKey) + { + int[] key = new int[32]; + long lower = bytesToLong(inKey, 0); + long upper = bytesToLong(inKey, 8); + + int key0 = extractW0(lower); + int key1 = extractW1(lower); + int key2 = extractW0(upper); + int key3 = extractW1(upper); + + for (int i = 0; i < 16; i++) + { + key[2 * i] = G(key0 + key2 - (int)KC[i]); + key[2 * i + 1] = G(key1 - key3 + (int)KC[i]); + + if (i % 2 == 0) + { + lower = rotateRight8(lower); + key0 = extractW0(lower); + key1 = extractW1(lower); + } + else + { + upper = rotateLeft8(upper); + key2 = extractW0(upper); + key3 = extractW1(upper); + } + } + + return key; + } + + private int extractW1( + long lVal) + { + return (int)lVal; + } + + private int extractW0( + long lVal) + { + return (int)(lVal >> 32); + } + + private long rotateLeft8( + long x) + { + return (x << 8) | ((long)((ulong) x >> 56)); + } + + private long rotateRight8( + long x) + { + return ((long)((ulong) x >> 8)) | (x << 56); + } + + private long bytesToLong( + byte[] src, + int srcOff) + { + long word = 0; + + for (int i = 0; i <= 7; i++) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void longToBytes( + byte[] dest, + int destOff, + long value) + { + for (int i = 0; i < 8; i++) + { + dest[i + destOff] = (byte)(value >> ((7 - i) * 8)); + } + } + + private int G( + int x) + { + return (int)(SS0[x & 0xff] ^ SS1[(x >> 8) & 0xff] ^ SS2[(x >> 16) & 0xff] ^ SS3[(x >> 24) & 0xff]); + } + + private long F( + int ki0, + int ki1, + long r) + { + int r0 = (int)(r >> 32); + int r1 = (int)r; + int rd1 = phaseCalc2(r0, ki0, r1, ki1); + int rd0 = rd1 + phaseCalc1(r0, ki0, r1, ki1); + + return ((long)rd0 << 32) | (rd1 & 0xffffffffL); + } + + private int phaseCalc1( + int r0, + int ki0, + int r1, + int ki1) + { + return G(G((r0 ^ ki0) ^ (r1 ^ ki1)) + (r0 ^ ki0)); + } + + private int phaseCalc2( + int r0, + int ki0, + int r1, + int ki1) + { + return G(phaseCalc1(r0, ki0, r1, ki1) + G((r0 ^ ki0) ^ (r1 ^ ki1))); + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/SEEDWrapEngine.cs b/iTechSharp/srcbc/crypto/engines/SEEDWrapEngine.cs new file mode 100644 index 0000000..6b71f94 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/SEEDWrapEngine.cs @@ -0,0 +1,16 @@ +namespace Org.BouncyCastle.Crypto.Engines +{ + ///+ * Serpent was designed by Ross Anderson, Eli Biham and Lars Knudsen as a + * candidate algorithm for the NIST AES Quest.> + *
+ *+ * For full details see the The Serpent home page + *
+ */ + public class SerpentEngine + : IBlockCipher + { + private const int BLOCK_SIZE = 16; + + static readonly int ROUNDS = 32; + static readonly int PHI = unchecked((int)0x9E3779B9); // (Sqrt(5) - 1) * 2**31 + + private bool encrypting; + private int[] wKey; + + private int X0, X1, X2, X3; // registers + + /** + * initialise a Serpent cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to Serpent init - " + parameters.GetType().ToString()); + + this.encrypting = forEncryption; + this.wKey = MakeWorkingKey(((KeyParameter)parameters).GetKey()); + } + + public string AlgorithmName + { + get { return "Serpent"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (wKey == null) + throw new InvalidOperationException("Serpent not initialised"); + if ((inOff + BLOCK_SIZE) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + BLOCK_SIZE) > output.Length) + throw new DataLengthException("output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + } + + /** + * Expand a user-supplied key material into a session key. + * + * @param key The user-key bytes (multiples of 4) to use. + * @exception ArgumentException + */ + private int[] MakeWorkingKey( + byte[] key) + { + // + // pad key to 256 bits + // + int[] kPad = new int[16]; + int off = 0; + int length = 0; + + for (off = key.Length - 4; off > 0; off -= 4) + { + kPad[length++] = BytesToWord(key, off); + } + + if (off == 0) + { + kPad[length++] = BytesToWord(key, 0); + if (length < 8) + { + kPad[length] = 1; + } + } + else + { + throw new ArgumentException("key must be a multiple of 4 bytes"); + } + + // + // expand the padded key up to 33 x 128 bits of key material + // + int amount = (ROUNDS + 1) * 4; + int[] w = new int[amount]; + + // + // compute w0 to w7 from w-8 to w-1 + // + for (int i = 8; i < 16; i++) + { + kPad[i] = RotateLeft(kPad[i - 8] ^ kPad[i - 5] ^ kPad[i - 3] ^ kPad[i - 1] ^ PHI ^ (i - 8), 11); + } + + Array.Copy(kPad, 8, w, 0, 8); + + // + // compute w8 to w136 + // + for (int i = 8; i < amount; i++) + { + w[i] = RotateLeft(w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11); + } + + // + // create the working keys by processing w with the Sbox and IP + // + Sb3(w[0], w[1], w[2], w[3]); + w[0] = X0; w[1] = X1; w[2] = X2; w[3] = X3; + Sb2(w[4], w[5], w[6], w[7]); + w[4] = X0; w[5] = X1; w[6] = X2; w[7] = X3; + Sb1(w[8], w[9], w[10], w[11]); + w[8] = X0; w[9] = X1; w[10] = X2; w[11] = X3; + Sb0(w[12], w[13], w[14], w[15]); + w[12] = X0; w[13] = X1; w[14] = X2; w[15] = X3; + Sb7(w[16], w[17], w[18], w[19]); + w[16] = X0; w[17] = X1; w[18] = X2; w[19] = X3; + Sb6(w[20], w[21], w[22], w[23]); + w[20] = X0; w[21] = X1; w[22] = X2; w[23] = X3; + Sb5(w[24], w[25], w[26], w[27]); + w[24] = X0; w[25] = X1; w[26] = X2; w[27] = X3; + Sb4(w[28], w[29], w[30], w[31]); + w[28] = X0; w[29] = X1; w[30] = X2; w[31] = X3; + Sb3(w[32], w[33], w[34], w[35]); + w[32] = X0; w[33] = X1; w[34] = X2; w[35] = X3; + Sb2(w[36], w[37], w[38], w[39]); + w[36] = X0; w[37] = X1; w[38] = X2; w[39] = X3; + Sb1(w[40], w[41], w[42], w[43]); + w[40] = X0; w[41] = X1; w[42] = X2; w[43] = X3; + Sb0(w[44], w[45], w[46], w[47]); + w[44] = X0; w[45] = X1; w[46] = X2; w[47] = X3; + Sb7(w[48], w[49], w[50], w[51]); + w[48] = X0; w[49] = X1; w[50] = X2; w[51] = X3; + Sb6(w[52], w[53], w[54], w[55]); + w[52] = X0; w[53] = X1; w[54] = X2; w[55] = X3; + Sb5(w[56], w[57], w[58], w[59]); + w[56] = X0; w[57] = X1; w[58] = X2; w[59] = X3; + Sb4(w[60], w[61], w[62], w[63]); + w[60] = X0; w[61] = X1; w[62] = X2; w[63] = X3; + Sb3(w[64], w[65], w[66], w[67]); + w[64] = X0; w[65] = X1; w[66] = X2; w[67] = X3; + Sb2(w[68], w[69], w[70], w[71]); + w[68] = X0; w[69] = X1; w[70] = X2; w[71] = X3; + Sb1(w[72], w[73], w[74], w[75]); + w[72] = X0; w[73] = X1; w[74] = X2; w[75] = X3; + Sb0(w[76], w[77], w[78], w[79]); + w[76] = X0; w[77] = X1; w[78] = X2; w[79] = X3; + Sb7(w[80], w[81], w[82], w[83]); + w[80] = X0; w[81] = X1; w[82] = X2; w[83] = X3; + Sb6(w[84], w[85], w[86], w[87]); + w[84] = X0; w[85] = X1; w[86] = X2; w[87] = X3; + Sb5(w[88], w[89], w[90], w[91]); + w[88] = X0; w[89] = X1; w[90] = X2; w[91] = X3; + Sb4(w[92], w[93], w[94], w[95]); + w[92] = X0; w[93] = X1; w[94] = X2; w[95] = X3; + Sb3(w[96], w[97], w[98], w[99]); + w[96] = X0; w[97] = X1; w[98] = X2; w[99] = X3; + Sb2(w[100], w[101], w[102], w[103]); + w[100] = X0; w[101] = X1; w[102] = X2; w[103] = X3; + Sb1(w[104], w[105], w[106], w[107]); + w[104] = X0; w[105] = X1; w[106] = X2; w[107] = X3; + Sb0(w[108], w[109], w[110], w[111]); + w[108] = X0; w[109] = X1; w[110] = X2; w[111] = X3; + Sb7(w[112], w[113], w[114], w[115]); + w[112] = X0; w[113] = X1; w[114] = X2; w[115] = X3; + Sb6(w[116], w[117], w[118], w[119]); + w[116] = X0; w[117] = X1; w[118] = X2; w[119] = X3; + Sb5(w[120], w[121], w[122], w[123]); + w[120] = X0; w[121] = X1; w[122] = X2; w[123] = X3; + Sb4(w[124], w[125], w[126], w[127]); + w[124] = X0; w[125] = X1; w[126] = X2; w[127] = X3; + Sb3(w[128], w[129], w[130], w[131]); + w[128] = X0; w[129] = X1; w[130] = X2; w[131] = X3; + + return w; + } + + private int RotateLeft( + int x, + int bits) + { + return ((x << bits) | (int) ((uint)x >> (32 - bits))); + } + + private int RotateRight( + int x, + int bits) + { + return ( (int)((uint)x >> bits) | (x << (32 - bits))); + } + + private int BytesToWord( + byte[] src, + int srcOff) + { + return (((src[srcOff] & 0xff) << 24) | ((src[srcOff + 1] & 0xff) << 16) | + ((src[srcOff + 2] & 0xff) << 8) | ((src[srcOff + 3] & 0xff))); + } + + private void WordToBytes( + int word, + byte[] dst, + int dstOff) + { + dst[dstOff + 3] = (byte)(word); + dst[dstOff + 2] = (byte)((uint)word >> 8); + dst[dstOff + 1] = (byte)((uint)word >> 16); + dst[dstOff] = (byte)((uint)word >> 24); + } + + /** + * Encrypt one block of plaintext. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + */ + private void EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + X3 = BytesToWord(input, inOff); + X2 = BytesToWord(input, inOff + 4); + X1 = BytesToWord(input, inOff + 8); + X0 = BytesToWord(input, inOff + 12); + + Sb0(wKey[0] ^ X0, wKey[1] ^ X1, wKey[2] ^ X2, wKey[3] ^ X3); LT(); + Sb1(wKey[4] ^ X0, wKey[5] ^ X1, wKey[6] ^ X2, wKey[7] ^ X3); LT(); + Sb2(wKey[8] ^ X0, wKey[9] ^ X1, wKey[10] ^ X2, wKey[11] ^ X3); LT(); + Sb3(wKey[12] ^ X0, wKey[13] ^ X1, wKey[14] ^ X2, wKey[15] ^ X3); LT(); + Sb4(wKey[16] ^ X0, wKey[17] ^ X1, wKey[18] ^ X2, wKey[19] ^ X3); LT(); + Sb5(wKey[20] ^ X0, wKey[21] ^ X1, wKey[22] ^ X2, wKey[23] ^ X3); LT(); + Sb6(wKey[24] ^ X0, wKey[25] ^ X1, wKey[26] ^ X2, wKey[27] ^ X3); LT(); + Sb7(wKey[28] ^ X0, wKey[29] ^ X1, wKey[30] ^ X2, wKey[31] ^ X3); LT(); + Sb0(wKey[32] ^ X0, wKey[33] ^ X1, wKey[34] ^ X2, wKey[35] ^ X3); LT(); + Sb1(wKey[36] ^ X0, wKey[37] ^ X1, wKey[38] ^ X2, wKey[39] ^ X3); LT(); + Sb2(wKey[40] ^ X0, wKey[41] ^ X1, wKey[42] ^ X2, wKey[43] ^ X3); LT(); + Sb3(wKey[44] ^ X0, wKey[45] ^ X1, wKey[46] ^ X2, wKey[47] ^ X3); LT(); + Sb4(wKey[48] ^ X0, wKey[49] ^ X1, wKey[50] ^ X2, wKey[51] ^ X3); LT(); + Sb5(wKey[52] ^ X0, wKey[53] ^ X1, wKey[54] ^ X2, wKey[55] ^ X3); LT(); + Sb6(wKey[56] ^ X0, wKey[57] ^ X1, wKey[58] ^ X2, wKey[59] ^ X3); LT(); + Sb7(wKey[60] ^ X0, wKey[61] ^ X1, wKey[62] ^ X2, wKey[63] ^ X3); LT(); + Sb0(wKey[64] ^ X0, wKey[65] ^ X1, wKey[66] ^ X2, wKey[67] ^ X3); LT(); + Sb1(wKey[68] ^ X0, wKey[69] ^ X1, wKey[70] ^ X2, wKey[71] ^ X3); LT(); + Sb2(wKey[72] ^ X0, wKey[73] ^ X1, wKey[74] ^ X2, wKey[75] ^ X3); LT(); + Sb3(wKey[76] ^ X0, wKey[77] ^ X1, wKey[78] ^ X2, wKey[79] ^ X3); LT(); + Sb4(wKey[80] ^ X0, wKey[81] ^ X1, wKey[82] ^ X2, wKey[83] ^ X3); LT(); + Sb5(wKey[84] ^ X0, wKey[85] ^ X1, wKey[86] ^ X2, wKey[87] ^ X3); LT(); + Sb6(wKey[88] ^ X0, wKey[89] ^ X1, wKey[90] ^ X2, wKey[91] ^ X3); LT(); + Sb7(wKey[92] ^ X0, wKey[93] ^ X1, wKey[94] ^ X2, wKey[95] ^ X3); LT(); + Sb0(wKey[96] ^ X0, wKey[97] ^ X1, wKey[98] ^ X2, wKey[99] ^ X3); LT(); + Sb1(wKey[100] ^ X0, wKey[101] ^ X1, wKey[102] ^ X2, wKey[103] ^ X3); LT(); + Sb2(wKey[104] ^ X0, wKey[105] ^ X1, wKey[106] ^ X2, wKey[107] ^ X3); LT(); + Sb3(wKey[108] ^ X0, wKey[109] ^ X1, wKey[110] ^ X2, wKey[111] ^ X3); LT(); + Sb4(wKey[112] ^ X0, wKey[113] ^ X1, wKey[114] ^ X2, wKey[115] ^ X3); LT(); + Sb5(wKey[116] ^ X0, wKey[117] ^ X1, wKey[118] ^ X2, wKey[119] ^ X3); LT(); + Sb6(wKey[120] ^ X0, wKey[121] ^ X1, wKey[122] ^ X2, wKey[123] ^ X3); LT(); + Sb7(wKey[124] ^ X0, wKey[125] ^ X1, wKey[126] ^ X2, wKey[127] ^ X3); + + WordToBytes(wKey[131] ^ X3, outBytes, outOff); + WordToBytes(wKey[130] ^ X2, outBytes, outOff + 4); + WordToBytes(wKey[129] ^ X1, outBytes, outOff + 8); + WordToBytes(wKey[128] ^ X0, outBytes, outOff + 12); + } + + /** + * Decrypt one block of ciphertext. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + */ + private void DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + X3 = wKey[131] ^ BytesToWord(input, inOff); + X2 = wKey[130] ^ BytesToWord(input, inOff + 4); + X1 = wKey[129] ^ BytesToWord(input, inOff + 8); + X0 = wKey[128] ^ BytesToWord(input, inOff + 12); + + Ib7(X0, X1, X2, X3); + X0 ^= wKey[124]; X1 ^= wKey[125]; X2 ^= wKey[126]; X3 ^= wKey[127]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[120]; X1 ^= wKey[121]; X2 ^= wKey[122]; X3 ^= wKey[123]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[116]; X1 ^= wKey[117]; X2 ^= wKey[118]; X3 ^= wKey[119]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[112]; X1 ^= wKey[113]; X2 ^= wKey[114]; X3 ^= wKey[115]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[108]; X1 ^= wKey[109]; X2 ^= wKey[110]; X3 ^= wKey[111]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[104]; X1 ^= wKey[105]; X2 ^= wKey[106]; X3 ^= wKey[107]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[100]; X1 ^= wKey[101]; X2 ^= wKey[102]; X3 ^= wKey[103]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[96]; X1 ^= wKey[97]; X2 ^= wKey[98]; X3 ^= wKey[99]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[92]; X1 ^= wKey[93]; X2 ^= wKey[94]; X3 ^= wKey[95]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[88]; X1 ^= wKey[89]; X2 ^= wKey[90]; X3 ^= wKey[91]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[84]; X1 ^= wKey[85]; X2 ^= wKey[86]; X3 ^= wKey[87]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[80]; X1 ^= wKey[81]; X2 ^= wKey[82]; X3 ^= wKey[83]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[76]; X1 ^= wKey[77]; X2 ^= wKey[78]; X3 ^= wKey[79]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[72]; X1 ^= wKey[73]; X2 ^= wKey[74]; X3 ^= wKey[75]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[68]; X1 ^= wKey[69]; X2 ^= wKey[70]; X3 ^= wKey[71]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[64]; X1 ^= wKey[65]; X2 ^= wKey[66]; X3 ^= wKey[67]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[60]; X1 ^= wKey[61]; X2 ^= wKey[62]; X3 ^= wKey[63]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[56]; X1 ^= wKey[57]; X2 ^= wKey[58]; X3 ^= wKey[59]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[52]; X1 ^= wKey[53]; X2 ^= wKey[54]; X3 ^= wKey[55]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[48]; X1 ^= wKey[49]; X2 ^= wKey[50]; X3 ^= wKey[51]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[44]; X1 ^= wKey[45]; X2 ^= wKey[46]; X3 ^= wKey[47]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[40]; X1 ^= wKey[41]; X2 ^= wKey[42]; X3 ^= wKey[43]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[36]; X1 ^= wKey[37]; X2 ^= wKey[38]; X3 ^= wKey[39]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[32]; X1 ^= wKey[33]; X2 ^= wKey[34]; X3 ^= wKey[35]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[28]; X1 ^= wKey[29]; X2 ^= wKey[30]; X3 ^= wKey[31]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[24]; X1 ^= wKey[25]; X2 ^= wKey[26]; X3 ^= wKey[27]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[20]; X1 ^= wKey[21]; X2 ^= wKey[22]; X3 ^= wKey[23]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[16]; X1 ^= wKey[17]; X2 ^= wKey[18]; X3 ^= wKey[19]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[12]; X1 ^= wKey[13]; X2 ^= wKey[14]; X3 ^= wKey[15]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[8]; X1 ^= wKey[9]; X2 ^= wKey[10]; X3 ^= wKey[11]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[4]; X1 ^= wKey[5]; X2 ^= wKey[6]; X3 ^= wKey[7]; + InverseLT(); Ib0(X0, X1, X2, X3); + + WordToBytes(X3 ^ wKey[3], outBytes, outOff); + WordToBytes(X2 ^ wKey[2], outBytes, outOff + 4); + WordToBytes(X1 ^ wKey[1], outBytes, outOff + 8); + WordToBytes(X0 ^ wKey[0], outBytes, outOff + 12); + } + + /* + * The sboxes below are based on the work of Brian Gladman and + * Sam Simpson, whose original notice appears below. + *+ * For further details see: + * http://fp.gladman.plus.com/cryptography_technology/serpent/ + *
+ */ + + /* Partially optimised Serpent S Box bool functions derived */ + /* using a recursive descent analyser but without a full search */ + /* of all subtrees. This set of S boxes is the result of work */ + /* by Sam Simpson and Brian Gladman using the spare time on a */ + /* cluster of high capacity servers to search for S boxes with */ + /* this customised search engine. There are now an average of */ + /* 15.375 terms per S box. */ + /* */ + /* Copyright: Dr B. R Gladman (gladman@seven77.demon.co.uk) */ + /* and Sam Simpson (s.simpson@mia.co.uk) */ + /* 17th December 1998 */ + /* */ + /* We hereby give permission for information in this file to be */ + /* used freely subject only to acknowledgement of its origin. */ + + /** + * S0 - { 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12 } - 15 terms. + */ + private void Sb0(int a, int b, int c, int d) + { + int t1 = a ^ d; + int t3 = c ^ t1; + int t4 = b ^ t3; + X3 = (a & d) ^ t4; + int t7 = a ^ (b & t1); + X2 = t4 ^ (c | t7); + int t12 = X3 & (t3 ^ t7); + X1 = (~t3) ^ t12; + X0 = t12 ^ (~t7); + } + + /** + * InvSO - {13, 3,11, 0,10, 6, 5,12, 1,14, 4, 7,15, 9, 8, 2 } - 15 terms. + */ + private void Ib0(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t4 = d ^ (t1 | t2); + int t5 = c ^ t4; + X2 = t2 ^ t5; + int t8 = t1 ^ (d & t2); + X1 = t4 ^ (X2 & t8); + X3 = (a & t4) ^ (t5 | X1); + X0 = X3 ^ (t5 ^ t8); + } + + /** + * S1 - {15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4 } - 14 terms. + */ + private void Sb1(int a, int b, int c, int d) + { + int t2 = b ^ (~a); + int t5 = c ^ (a | t2); + X2 = d ^ t5; + int t7 = b ^ (d | t2); + int t8 = t2 ^ X2; + X3 = t8 ^ (t5 & t7); + int t11 = t5 ^ t7; + X1 = X3 ^ t11; + X0 = t5 ^ (t8 & t11); + } + + /** + * InvS1 - { 5, 8, 2,14,15, 6,12, 3,11, 4, 7, 9, 1,13,10, 0 } - 14 steps. + */ + private void Ib1(int a, int b, int c, int d) + { + int t1 = b ^ d; + int t3 = a ^ (b & t1); + int t4 = t1 ^ t3; + X3 = c ^ t4; + int t7 = b ^ (t1 & t3); + int t8 = X3 | t7; + X1 = t3 ^ t8; + int t10 = ~X1; + int t11 = X3 ^ t7; + X0 = t10 ^ t11; + X2 = t4 ^ (t10 | t11); + } + + /** + * S2 - { 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2 } - 16 terms. + */ + private void Sb2(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = b ^ d; + int t3 = c & t1; + X0 = t2 ^ t3; + int t5 = c ^ t1; + int t6 = c ^ X0; + int t7 = b & t6; + X3 = t5 ^ t7; + X2 = a ^ ((d | t7) & (X0 | t5)); + X1 = (t2 ^ X3) ^ (X2 ^ (d | t1)); + } + + /** + * InvS2 - {12, 9,15, 4,11,14, 1, 2, 0, 3, 6,13, 5, 8,10, 7 } - 16 steps. + */ + private void Ib2(int a, int b, int c, int d) + { + int t1 = b ^ d; + int t2 = ~t1; + int t3 = a ^ c; + int t4 = c ^ t1; + int t5 = b & t4; + X0 = t3 ^ t5; + int t7 = a | t2; + int t8 = d ^ t7; + int t9 = t3 | t8; + X3 = t1 ^ t9; + int t11 = ~t4; + int t12 = X0 | X3; + X1 = t11 ^ t12; + X2 = (d & t11) ^ (t3 ^ t12); + } + + /** + * S3 - { 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14 } - 16 terms. + */ + private void Sb3(int a, int b, int c, int d) + { + int t1 = a ^ b; + int t2 = a & c; + int t3 = a | d; + int t4 = c ^ d; + int t5 = t1 & t3; + int t6 = t2 | t5; + X2 = t4 ^ t6; + int t8 = b ^ t3; + int t9 = t6 ^ t8; + int t10 = t4 & t9; + X0 = t1 ^ t10; + int t12 = X2 & X0; + X1 = t9 ^ t12; + X3 = (b | d) ^ (t4 ^ t12); + } + + /** + * InvS3 - { 0, 9,10, 7,11,14, 6,13, 3, 5,12, 2, 4, 8,15, 1 } - 15 terms + */ + private void Ib3(int a, int b, int c, int d) + { + int t1 = a | b; + int t2 = b ^ c; + int t3 = b & t2; + int t4 = a ^ t3; + int t5 = c ^ t4; + int t6 = d | t4; + X0 = t2 ^ t6; + int t8 = t2 | t6; + int t9 = d ^ t8; + X2 = t5 ^ t9; + int t11 = t1 ^ t9; + int t12 = X0 & t11; + X3 = t4 ^ t12; + X1 = X3 ^ (X0 ^ t11); + } + + /** + * S4 - { 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13 } - 15 terms. + */ + private void Sb4(int a, int b, int c, int d) + { + int t1 = a ^ d; + int t2 = d & t1; + int t3 = c ^ t2; + int t4 = b | t3; + X3 = t1 ^ t4; + int t6 = ~b; + int t7 = t1 | t6; + X0 = t3 ^ t7; + int t9 = a & X0; + int t10 = t1 ^ t6; + int t11 = t4 & t10; + X2 = t9 ^ t11; + X1 = (a ^ t3) ^ (t10 & X2); + } + + /** + * InvS4 - { 5, 0, 8, 3,10, 9, 7,14, 2,12,11, 6, 4,15,13, 1 } - 15 terms. + */ + private void Ib4(int a, int b, int c, int d) + { + int t1 = c | d; + int t2 = a & t1; + int t3 = b ^ t2; + int t4 = a & t3; + int t5 = c ^ t4; + X1 = d ^ t5; + int t7 = ~a; + int t8 = t5 & X1; + X3 = t3 ^ t8; + int t10 = X1 | t7; + int t11 = d ^ t10; + X0 = X3 ^ t11; + X2 = (t3 & t11) ^ (X1 ^ t7); + } + + /** + * S5 - {15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1 } - 16 terms. + */ + private void Sb5(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t3 = a ^ d; + int t4 = c ^ t1; + int t5 = t2 | t3; + X0 = t4 ^ t5; + int t7 = d & X0; + int t8 = t2 ^ X0; + X1 = t7 ^ t8; + int t10 = t1 | X0; + int t11 = t2 | t7; + int t12 = t3 ^ t10; + X2 = t11 ^ t12; + X3 = (b ^ t7) ^ (X1 & t12); + } + + /** + * InvS5 - { 8,15, 2, 9, 4, 1,13,14,11, 6, 5, 3, 7,12,10, 0 } - 16 terms. + */ + private void Ib5(int a, int b, int c, int d) + { + int t1 = ~c; + int t2 = b & t1; + int t3 = d ^ t2; + int t4 = a & t3; + int t5 = b ^ t1; + X3 = t4 ^ t5; + int t7 = b | X3; + int t8 = a & t7; + X1 = t3 ^ t8; + int t10 = a | d; + int t11 = t1 ^ t7; + X0 = t10 ^ t11; + X2 = (b & t10) ^ (t4 | (a ^ c)); + } + + /** + * S6 - { 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0 } - 15 terms. + */ + private void Sb6(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ d; + int t3 = b ^ t2; + int t4 = t1 | t2; + int t5 = c ^ t4; + X1 = b ^ t5; + int t7 = t2 | X1; + int t8 = d ^ t7; + int t9 = t5 & t8; + X2 = t3 ^ t9; + int t11 = t5 ^ t8; + X0 = X2 ^ t11; + X3 = (~t5) ^ (t3 & t11); + } + + /** + * InvS6 - {15,10, 1,13, 5, 3, 6, 0, 4, 9,14, 7, 2,12, 8,11 } - 15 terms. + */ + private void Ib6(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t3 = c ^ t2; + int t4 = c | t1; + int t5 = d ^ t4; + X1 = t3 ^ t5; + int t7 = t3 & t5; + int t8 = t2 ^ t7; + int t9 = b | t8; + X3 = t5 ^ t9; + int t11 = b | X3; + X0 = t8 ^ t11; + X2 = (d & t1) ^ (t3 ^ t11); + } + + /** + * S7 - { 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6 } - 16 terms. + */ + private void Sb7(int a, int b, int c, int d) + { + int t1 = b ^ c; + int t2 = c & t1; + int t3 = d ^ t2; + int t4 = a ^ t3; + int t5 = d | t1; + int t6 = t4 & t5; + X1 = b ^ t6; + int t8 = t3 | X1; + int t9 = a & t4; + X3 = t1 ^ t9; + int t11 = t4 ^ t8; + int t12 = X3 & t11; + X2 = t3 ^ t12; + X0 = (~t11) ^ (X3 & X2); + } + + /** + * InvS7 - { 3, 0, 6,13, 9,14,15, 8, 5,12,11, 7,10, 1, 4, 2 } - 17 terms. + */ + private void Ib7(int a, int b, int c, int d) + { + int t3 = c | (a & b); + int t4 = d & (a | b); + X3 = t3 ^ t4; + int t6 = ~d; + int t7 = b ^ t4; + int t9 = t7 | (X3 ^ t6); + X1 = a ^ t9; + X0 = (c ^ t7) ^ (d | X1); + X2 = (t3 ^ X1) ^ (X0 ^ (a & X3)); + } + + /** + * Apply the linear transformation to the register set. + */ + private void LT() + { + int x0 = RotateLeft(X0, 13); + int x2 = RotateLeft(X2, 3); + int x1 = X1 ^ x0 ^ x2 ; + int x3 = X3 ^ x2 ^ x0 << 3; + + X1 = RotateLeft(x1, 1); + X3 = RotateLeft(x3, 7); + X0 = RotateLeft(x0 ^ X1 ^ X3, 5); + X2 = RotateLeft(x2 ^ X3 ^ (X1 << 7), 22); + } + + /** + * Apply the inverse of the linear transformation to the register set. + */ + private void InverseLT() + { + int x2 = RotateRight(X2, 22) ^ X3 ^ (X1 << 7); + int x0 = RotateRight(X0, 5) ^ X1 ^ X3; + int x3 = RotateRight(X3, 7); + int x1 = RotateRight(X1, 1); + X3 = x3 ^ x2 ^ x0 << 3; + X1 = x1 ^ x0 ^ x2; + X2 = RotateRight(x2, 3); + X0 = RotateRight(x0, 13); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/SkipjackEngine.cs b/iTechSharp/srcbc/crypto/engines/SkipjackEngine.cs new file mode 100644 index 0000000..3d2a781 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/SkipjackEngine.cs @@ -0,0 +1,255 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * a class that provides a basic SKIPJACK engine. + */ + public class SkipjackEngine + : IBlockCipher + { + const int BLOCK_SIZE = 8; + + static readonly short [] ftable = + { + 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4, 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9, + 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e, 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28, + 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68, 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53, + 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19, 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2, + 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b, 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8, + 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0, 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90, + 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69, 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76, + 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20, 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d, + 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43, 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18, + 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa, 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4, + 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87, 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40, + 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b, 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5, + 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0, 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2, + 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1, 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8, + 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5, 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac, + 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3, 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46 + }; + + private int[] key0, key1, key2, key3; + private bool encrypting; + + /** + * initialise a SKIPJACK cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to SKIPJACK init - " + parameters.GetType().ToString()); + + byte[] keyBytes = ((KeyParameter)parameters).GetKey(); + + this.encrypting = forEncryption; + this.key0 = new int[32]; + this.key1 = new int[32]; + this.key2 = new int[32]; + this.key3 = new int[32]; + + // + // expand the key to 128 bytes in 4 parts (saving us a modulo, multiply + // and an addition). + // + for (int i = 0; i < 32; i ++) + { + key0[i] = keyBytes[(i * 4) % 10] & 0xff; + key1[i] = keyBytes[(i * 4 + 1) % 10] & 0xff; + key2[i] = keyBytes[(i * 4 + 2) % 10] & 0xff; + key3[i] = keyBytes[(i * 4 + 3) % 10] & 0xff; + } + } + + public string AlgorithmName + { + get { return "SKIPJACK"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (key1 == null) + throw new InvalidOperationException("SKIPJACK engine not initialised"); + if ((inOff + BLOCK_SIZE) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + BLOCK_SIZE) > output.Length) + throw new DataLengthException("output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + } + + /** + * The G permutation + */ + private int G( + int k, + int w) + { + int g1, g2, g3, g4, g5, g6; + + g1 = (w >> 8) & 0xff; + g2 = w & 0xff; + + g3 = ftable[g2 ^ key0[k]] ^ g1; + g4 = ftable[g3 ^ key1[k]] ^ g2; + g5 = ftable[g4 ^ key2[k]] ^ g3; + g6 = ftable[g5 ^ key3[k]] ^ g4; + + return ((g5 << 8) + g6); + } + + public int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int w1 = (input[inOff + 0] << 8) + (input[inOff + 1] & 0xff); + int w2 = (input[inOff + 2] << 8) + (input[inOff + 3] & 0xff); + int w3 = (input[inOff + 4] << 8) + (input[inOff + 5] & 0xff); + int w4 = (input[inOff + 6] << 8) + (input[inOff + 7] & 0xff); + + int k = 0; + + for (int t = 0; t < 2; t++) + { + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w2; + w2 = G(k, w1); + w1 = w2 ^ tmp ^ (k + 1); + k++; + } + + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w1 ^ w2 ^ (k + 1); + w2 = G(k, w1); + w1 = tmp; + k++; + } + } + + outBytes[outOff + 0] = (byte)((w1 >> 8)); + outBytes[outOff + 1] = (byte)(w1); + outBytes[outOff + 2] = (byte)((w2 >> 8)); + outBytes[outOff + 3] = (byte)(w2); + outBytes[outOff + 4] = (byte)((w3 >> 8)); + outBytes[outOff + 5] = (byte)(w3); + outBytes[outOff + 6] = (byte)((w4 >> 8)); + outBytes[outOff + 7] = (byte)(w4); + + return BLOCK_SIZE; + } + + /** + * the inverse of the G permutation. + */ + private int H( + int k, + int w) + { + int h1, h2, h3, h4, h5, h6; + + h1 = w & 0xff; + h2 = (w >> 8) & 0xff; + + h3 = ftable[h2 ^ key3[k]] ^ h1; + h4 = ftable[h3 ^ key2[k]] ^ h2; + h5 = ftable[h4 ^ key1[k]] ^ h3; + h6 = ftable[h5 ^ key0[k]] ^ h4; + + return ((h6 << 8) + h5); + } + + public int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int w2 = (input[inOff + 0] << 8) + (input[inOff + 1] & 0xff); + int w1 = (input[inOff + 2] << 8) + (input[inOff + 3] & 0xff); + int w4 = (input[inOff + 4] << 8) + (input[inOff + 5] & 0xff); + int w3 = (input[inOff + 6] << 8) + (input[inOff + 7] & 0xff); + + int k = 31; + + for (int t = 0; t < 2; t++) + { + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w2; + w2 = H(k, w1); + w1 = w2 ^ tmp ^ (k + 1); + k--; + } + + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w1 ^ w2 ^ (k + 1); + w2 = H(k, w1); + w1 = tmp; + k--; + } + } + + outBytes[outOff + 0] = (byte)((w2 >> 8)); + outBytes[outOff + 1] = (byte)(w2); + outBytes[outOff + 2] = (byte)((w1 >> 8)); + outBytes[outOff + 3] = (byte)(w1); + outBytes[outOff + 4] = (byte)((w4 >> 8)); + outBytes[outOff + 5] = (byte)(w4); + outBytes[outOff + 6] = (byte)((w3 >> 8)); + outBytes[outOff + 7] = (byte)(w3); + + return BLOCK_SIZE; + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/TEAEngine.cs b/iTechSharp/srcbc/crypto/engines/TEAEngine.cs new file mode 100644 index 0000000..0fbde59 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/TEAEngine.cs @@ -0,0 +1,191 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An TEA engine. + */ + public class TeaEngine + : IBlockCipher + { + private const int + rounds = 32, + block_size = 8, + key_size = 16, + delta = unchecked((int) 0x9E3779B9), + d_sum = unchecked((int) 0xC6EF3720); // sum on decrypt + + /* + * the expanded key array of 4 subkeys + */ + private int _a, _b, _c, _d; + private bool _initialised; + private bool _forEncryption; + + /** + * Create an instance of the TEA encryption algorithm + * and set some defaults + */ + public TeaEngine() + { + _initialised = false; + } + + public string AlgorithmName + { + get { return "TEA"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return block_size; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + { + throw new ArgumentException("invalid parameter passed to TEA init - " + + parameters.GetType().FullName); + } + + _forEncryption = forEncryption; + _initialised = true; + + KeyParameter p = (KeyParameter) parameters; + + setKey(p.GetKey()); + } + + public int ProcessBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + if ((inOff + block_size) > inBytes.Length) + throw new DataLengthException("input buffer too short"); + + if ((outOff + block_size) > outBytes.Length) + throw new DataLengthException("output buffer too short"); + + return _forEncryption + ? encryptBlock(inBytes, inOff, outBytes, outOff) + : decryptBlock(inBytes, inOff, outBytes, outOff); + } + + public void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void setKey( + byte[] key) + { + _a = bytesToInt(key, 0); + _b = bytesToInt(key, 4); + _c = bytesToInt(key, 8); + _d = bytesToInt(key, 12); + } + + private int encryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + int v0 = bytesToInt(inBytes, inOff); + int v1 = bytesToInt(inBytes, inOff + 4); + + int sum = 0; + + for (int i = 0; i != rounds; i++) + { + sum += delta; +// v0 += ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >>> 5) + _b); + v0 += ((v1 << 4) + _a) ^ (v1 + sum) ^ ((int)((uint)v1 >> 5) + _b); +// v1 += ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >>> 5) + _d); + v1 += ((v0 << 4) + _c) ^ (v0 + sum) ^ ((int)((uint)v0 >> 5) + _d); + } + + unpackInt(v0, outBytes, outOff); + unpackInt(v1, outBytes, outOff + 4); + + return block_size; + } + + private int decryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + int v0 = bytesToInt(inBytes, inOff); + int v1 = bytesToInt(inBytes, inOff + 4); + + int sum = d_sum; + + for (int i = 0; i != rounds; i++) + { +// v1 -= ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >>> 5) + _d); + v1 -= ((v0 << 4) + _c) ^ (v0 + sum) ^ ((int)((uint)v0 >> 5) + _d); +// v0 -= ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >>> 5) + _b); + v0 -= ((v1 << 4) + _a) ^ (v1 + sum) ^ ((int)((uint)v1 >> 5) + _b); + sum -= delta; + } + + unpackInt(v0, outBytes, outOff); + unpackInt(v1, outBytes, outOff + 4); + + return block_size; + } + + private int bytesToInt( + byte[] b, + int inOff) + { + return ((b[inOff++]) << 24) + | ((b[inOff++] & 255) << 16) + | ((b[inOff++] & 255) << 8) + | ((b[inOff] & 255)); + } + + private void unpackInt( + int v, + byte[] b, + int outOff) + { + uint uv = (uint) v; + b[outOff++] = (byte)(uv >> 24); + b[outOff++] = (byte)(uv >> 16); + b[outOff++] = (byte)(uv >> 8); + b[outOff ] = (byte)uv; + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/TwofishEngine.cs b/iTechSharp/srcbc/crypto/engines/TwofishEngine.cs new file mode 100644 index 0000000..3895ccf --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/TwofishEngine.cs @@ -0,0 +1,673 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides Twofish encryption operations. + * + * This Java implementation is based on the Java reference + * implementation provided by Bruce Schneier and developed + * by Raif S. Naffah. + */ + public sealed class TwofishEngine + : IBlockCipher + { + private static readonly byte[,] P = { + { // p0 + (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8, + (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76, + (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78, + (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38, + (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98, + (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C, + (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26, + (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48, + (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30, + (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23, + (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59, + (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82, + (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E, + (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C, + (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE, + (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61, + (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5, + (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B, + (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B, + (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1, + (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45, + (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66, + (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56, + (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7, + (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5, + (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA, + (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF, + (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71, + (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD, + (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8, + (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D, + (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7, + (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED, + (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2, + (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11, + (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90, + (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF, + (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB, + (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B, + (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF, + (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE, + (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B, + (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46, + (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64, + (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F, + (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A, + (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A, + (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A, + (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29, + (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02, + (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17, + (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D, + (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74, + (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72, + (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12, + (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34, + (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68, + (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8, + (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40, + (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4, + (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0, + (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00, + (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42, + (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 }, + { // p1 + (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4, + (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8, + (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B, + (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B, + (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD, + (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1, + (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B, + (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F, + (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B, + (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D, + (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E, + (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5, + (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14, + (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3, + (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54, + (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51, + (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A, + (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96, + (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10, + (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C, + (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7, + (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70, + (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB, + (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8, + (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF, + (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC, + (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF, + (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2, + (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82, + (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9, + (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97, + (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17, + (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D, + (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3, + (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C, + (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E, + (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F, + (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49, + (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21, + (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9, + (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD, + (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01, + (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F, + (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48, + (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E, + (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19, + (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57, + (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64, + (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE, + (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5, + (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44, + (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69, + (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15, + (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E, + (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34, + (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC, + (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B, + (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB, + (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52, + (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9, + (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4, + (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2, + (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56, + (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91 } + }; + + /** + * Define the fixed p0/p1 permutations used in keyed S-box lookup. + * By changing the following constant definitions, the S-boxes will + * automatically Get changed in the Twofish engine. + */ + private const int P_00 = 1; + private const int P_01 = 0; + private const int P_02 = 0; + private const int P_03 = P_01 ^ 1; + private const int P_04 = 1; + + private const int P_10 = 0; + private const int P_11 = 0; + private const int P_12 = 1; + private const int P_13 = P_11 ^ 1; + private const int P_14 = 0; + + private const int P_20 = 1; + private const int P_21 = 1; + private const int P_22 = 0; + private const int P_23 = P_21 ^ 1; + private const int P_24 = 0; + + private const int P_30 = 0; + private const int P_31 = 1; + private const int P_32 = 1; + private const int P_33 = P_31 ^ 1; + private const int P_34 = 1; + + /* Primitive polynomial for GF(256) */ + private const int GF256_FDBK = 0x169; + private const int GF256_FDBK_2 = GF256_FDBK / 2; + private const int GF256_FDBK_4 = GF256_FDBK / 4; + + private const int RS_GF_FDBK = 0x14D; // field generator + + //==================================== + // Useful constants + //==================================== + + private const int ROUNDS = 16; + private const int MAX_ROUNDS = 16; // bytes = 128 bits + private const int BLOCK_SIZE = 16; // bytes = 128 bits + private const int MAX_KEY_BITS = 256; + + private const int INPUT_WHITEN=0; + private const int OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4 + private const int ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8 + + private const int TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40 + + private const int SK_STEP = 0x02020202; + private const int SK_BUMP = 0x01010101; + private const int SK_ROTL = 9; + + private bool encrypting; + + private int[] gMDS0 = new int[MAX_KEY_BITS]; + private int[] gMDS1 = new int[MAX_KEY_BITS]; + private int[] gMDS2 = new int[MAX_KEY_BITS]; + private int[] gMDS3 = new int[MAX_KEY_BITS]; + + /** + * gSubKeys[] and gSBox[] are eventually used in the + * encryption and decryption methods. + */ + private int[] gSubKeys; + private int[] gSBox; + + private int k64Cnt; + + private byte[] workingKey; + + public TwofishEngine() + { + // calculate the MDS matrix + int[] m1 = new int[2]; + int[] mX = new int[2]; + int[] mY = new int[2]; + int j; + + for (int i=0; i< MAX_KEY_BITS ; i++) + { + j = P[0,i] & 0xff; + m1[0] = j; + mX[0] = Mx_X(j) & 0xff; + mY[0] = Mx_Y(j) & 0xff; + + j = P[1,i] & 0xff; + m1[1] = j; + mX[1] = Mx_X(j) & 0xff; + mY[1] = Mx_Y(j) & 0xff; + + gMDS0[i] = m1[P_00] | mX[P_00] << 8 | + mY[P_00] << 16 | mY[P_00] << 24; + + gMDS1[i] = mY[P_10] | mY[P_10] << 8 | + mX[P_10] << 16 | m1[P_10] << 24; + + gMDS2[i] = mX[P_20] | mY[P_20] << 8 | + m1[P_20] << 16 | mY[P_20] << 24; + + gMDS3[i] = mX[P_30] | m1[P_30] << 8 | + mY[P_30] << 16 | mX[P_30] << 24; + } + } + + /** + * initialise a Twofish cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to Twofish init - " + parameters.GetType().ToString()); + + this.encrypting = forEncryption; + this.workingKey = ((KeyParameter)parameters).GetKey(); + this.k64Cnt = (this.workingKey.Length / 8); // pre-padded ? + SetKey(this.workingKey); + } + + public string AlgorithmName + { + get { return "Twofish"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Twofish not initialised"); + if ((inOff + BLOCK_SIZE) > input.Length) + throw new DataLengthException("input buffer too short"); + if ((outOff + BLOCK_SIZE) > output.Length) + throw new DataLengthException("output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + if (this.workingKey != null) + { + SetKey(this.workingKey); + } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + + private void SetKey(byte[] key) + { + int[] k32e = new int[MAX_KEY_BITS/64]; // 4 + int[] k32o = new int[MAX_KEY_BITS/64]; // 4 + + int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4 + gSubKeys = new int[TOTAL_SUBKEYS]; + + if (k64Cnt < 1) + { + throw new ArgumentException("Key size less than 64 bits"); + } + + if (k64Cnt > 4) + { + throw new ArgumentException("Key size larger than 256 bits"); + } + + /* + * k64Cnt is the number of 8 byte blocks (64 chunks) + * that are in the input key. The input key is a + * maximum of 32 bytes ( 256 bits ), so the range + * for k64Cnt is 1..4 + */ + for (int i=0,p=0; i+ *
+ * G(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1 + *+ * where a = primitive root of field generator 0x14D + * + */ + private int RS_rem(int x) + { + int b = (int) (((uint)x >> 24) & 0xff); + int g2 = ((b << 1) ^ + ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff; + int g3 = ( (int)((uint)b >> 1) ^ + ((b & 0x01) != 0 ? (int)((uint)RS_GF_FDBK >> 1) : 0)) ^ g2 ; + return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b); + } + + private int LFSR1(int x) + { + return (x >> 1) ^ + (((x & 0x01) != 0) ? GF256_FDBK_2 : 0); + } + + private int LFSR2(int x) + { + return (x >> 2) ^ + (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^ + (((x & 0x01) != 0) ? GF256_FDBK_4 : 0); + } + + private int Mx_X(int x) + { + return x ^ LFSR2(x); + } // 5B + + private int Mx_Y(int x) + { + return x ^ LFSR1(x) ^ LFSR2(x); + } // EF + + private int M_b0(int x) + { + return x & 0xff; + } + + private int M_b1(int x) + { + return (int)((uint)x >> 8) & 0xff; + } + + private int M_b2(int x) + { + return (int)((uint)x >> 16) & 0xff; + } + + private int M_b3(int x) + { + return (int)((uint)x >> 24) & 0xff; + } + + private int Fe32_0(int x) + { + return gSBox[ 0x000 + 2*(x & 0xff) ] ^ + gSBox[ 0x001 + 2*((int)((uint)x >> 8) & 0xff) ] ^ + gSBox[ 0x200 + 2*((int)((uint)x >> 16) & 0xff) ] ^ + gSBox[ 0x201 + 2*((int)((uint)x >> 24) & 0xff) ]; + } + + private int Fe32_3(int x) + { + return gSBox[ 0x000 + 2*((int)((uint)x >> 24) & 0xff) ] ^ + gSBox[ 0x001 + 2*(x & 0xff) ] ^ + gSBox[ 0x200 + 2*((int)((uint)x >> 8) & 0xff) ] ^ + gSBox[ 0x201 + 2*((int)((uint)x >> 16) & 0xff) ]; + } + + private int BytesTo32Bits(byte[] b, int p) + { + return ((b[p] & 0xff) ) | + ((b[p+1] & 0xff) << 8) | + ((b[p+2] & 0xff) << 16) | + ((b[p+3] & 0xff) << 24); + } + + private void Bits32ToBytes(int inData, byte[] b, int offset) + { + b[offset] = (byte)inData; + b[offset + 1] = (byte)(inData >> 8); + b[offset + 2] = (byte)(inData >> 16); + b[offset + 3] = (byte)(inData >> 24); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/engines/VMPCEngine.cs b/iTechSharp/srcbc/crypto/engines/VMPCEngine.cs new file mode 100644 index 0000000..d467fbb --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/VMPCEngine.cs @@ -0,0 +1,139 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class VmpcEngine + : IStreamCipher + { + /* + * variables to hold the state of the VMPC engine during encryption and + * decryption + */ + protected byte n = 0; + protected byte[] P = null; + protected byte s = 0; + + protected byte[] workingIV; + protected byte[] workingKey; + + public virtual string AlgorithmName + { + get { return "VMPC"; } + } + + /** + * initialise a VMPC cipher. + * + * @param forEncryption + * whether or not we are for encryption. + * @param params + * the parameters required to set up the cipher. + * @exception ArgumentException + * if the params argument is inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is ParametersWithIV)) + throw new ArgumentException("VMPC Init parameters must include an IV"); + + ParametersWithIV ivParams = (ParametersWithIV) parameters; + KeyParameter key = (KeyParameter) ivParams.Parameters; + + if (!(ivParams.Parameters is KeyParameter)) + throw new ArgumentException("VMPC Init parameters must include a key"); + + this.workingIV = ivParams.GetIV(); + + if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768) + throw new ArgumentException("VMPC requires 1 to 768 bytes of IV"); + + this.workingKey = key.GetKey(); + + InitKey(this.workingKey, this.workingIV); + } + + protected virtual void InitKey( + byte[] keyBytes, + byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + n = 0; + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if ((inOff + len) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + len) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + for (int i = 0; i < len; i++) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + // encryption + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + + // xor + output[i + outOff] = (byte) (input[i + inOff] ^ z); + } + } + + public virtual void Reset() + { + InitKey(this.workingKey, this.workingIV); + } + + public virtual byte ReturnByte( + byte input) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + // encryption + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + + // xor + return (byte) (input ^ z); + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/VMPCKSA3Engine.cs b/iTechSharp/srcbc/crypto/engines/VMPCKSA3Engine.cs new file mode 100644 index 0000000..95b6813 --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/VMPCKSA3Engine.cs @@ -0,0 +1,51 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class VmpcKsa3Engine + : VmpcEngine + { + public override string AlgorithmName + { + get { return "VMPC-KSA3"; } + } + + protected override void InitKey( + byte[] keyBytes, + byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + n = 0; + } + } +} diff --git a/iTechSharp/srcbc/crypto/engines/XTEAEngine.cs b/iTechSharp/srcbc/crypto/engines/XTEAEngine.cs new file mode 100644 index 0000000..04318ee --- /dev/null +++ b/iTechSharp/srcbc/crypto/engines/XTEAEngine.cs @@ -0,0 +1,185 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An XTEA engine. + */ + public class XteaEngine + : IBlockCipher + { + private const int + rounds = 32, + block_size = 8, + key_size = 16, + delta = unchecked((int) 0x9E3779B9), + d_sum = unchecked((int) 0xC6EF3720); // sum on decrypt + + /* + * the expanded key array of 4 subkeys + */ + private int[] _S = new int[4]; + private bool _initialised; + private bool _forEncryption; + + /** + * Create an instance of the TEA encryption algorithm + * and set some defaults + */ + public XteaEngine() + { + _initialised = false; + } + + public string AlgorithmName + { + get { return "XTEA"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int GetBlockSize() + { + return block_size; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + { + throw new ArgumentException("invalid parameter passed to TEA init - " + + parameters.GetType().FullName); + } + + _forEncryption = forEncryption; + _initialised = true; + + KeyParameter p = (KeyParameter) parameters; + + setKey(p.GetKey()); + } + + public int ProcessBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + if ((inOff + block_size) > inBytes.Length) + throw new DataLengthException("input buffer too short"); + + if ((outOff + block_size) > outBytes.Length) + throw new DataLengthException("output buffer too short"); + + return _forEncryption + ? encryptBlock(inBytes, inOff, outBytes, outOff) + : decryptBlock(inBytes, inOff, outBytes, outOff); + } + + public void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void setKey( + byte[] key) + { + _S[0] = bytesToInt(key, 0); + _S[1] = bytesToInt(key, 4); + _S[2] = bytesToInt(key, 8); + _S[3] = bytesToInt(key, 12); + } + + private int encryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + int v0 = bytesToInt(inBytes, inOff); + int v1 = bytesToInt(inBytes, inOff + 4); + + int sum = 0; + + for (int i = 0; i != rounds; i++) + { + v0 += ((v1 << 4 ^ (int)((uint)v1 >> 5)) + v1) ^ (sum + _S[sum & 3]); + sum += delta; + v1 += ((v0 << 4 ^ (int)((uint)v0 >> 5)) + v0) ^ (sum + _S[(int)((uint)sum >> 11) & 3]); + } + + unpackInt(v0, outBytes, outOff); + unpackInt(v1, outBytes, outOff + 4); + + return block_size; + } + + private int decryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + int v0 = bytesToInt(inBytes, inOff); + int v1 = bytesToInt(inBytes, inOff + 4); + + int sum = d_sum; + + for (int i = 0; i != rounds; i++) + { + v1 -= ((v0 << 4 ^ (int)((uint)v0 >> 5)) + v0) ^ (sum + _S[(int)((uint)sum >> 11) & 3]); + sum -= delta; + v0 -= ((v1 << 4 ^ (int)((uint)v1 >> 5)) + v1) ^ (sum + _S[sum & 3]); + } + + unpackInt(v0, outBytes, outOff); + unpackInt(v1, outBytes, outOff + 4); + + return block_size; + } + + private int bytesToInt(byte[] b, int inOff) + { + return ((b[inOff++]) << 24) | + ((b[inOff++] & 255) << 16) | + ((b[inOff++] & 255) << 8) | + ((b[inOff] & 255)); + } + + private void unpackInt( + int v, + byte[] b, + int outOff) + { + uint uv = (uint) v; + b[outOff++] = (byte)(uv >> 24); + b[outOff++] = (byte)(uv >> 16); + b[outOff++] = (byte)(uv >> 8); + b[outOff ] = (byte)uv; + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/BaseKdfBytesGenerator.cs b/iTechSharp/srcbc/crypto/generators/BaseKdfBytesGenerator.cs new file mode 100644 index 0000000..0366401 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/BaseKdfBytesGenerator.cs @@ -0,0 +1,141 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033 + *
+ * Note: can take a while...
+ */ + public virtual DHParameters GenerateParameters() + { + // + // find a safe prime p where p = 2*q + 1, where p and q are prime. + // + BigInteger[] safePrimes = DHParametersHelper.GenerateSafePrimes(size, certainty, random); + + BigInteger p = safePrimes[0]; + BigInteger q = safePrimes[1]; + BigInteger g = DHParametersHelper.SelectGenerator(p, q, random); + + return new DHParameters(p, g, q, BigInteger.Two, null); + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/DHParametersHelper.cs b/iTechSharp/srcbc/crypto/generators/DHParametersHelper.cs new file mode 100644 index 0000000..1856e88 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/DHParametersHelper.cs @@ -0,0 +1,244 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + internal class DHParametersHelper + { + // The primes b/w 2 and ~2^10 + /* + 3 5 7 11 13 17 19 23 29 + 31 37 41 43 47 53 59 61 67 71 + 73 79 83 89 97 101 103 107 109 113 + 127 131 137 139 149 151 157 163 167 173 + 179 181 191 193 197 199 211 223 227 229 + 233 239 241 251 257 263 269 271 277 281 + 283 293 307 311 313 317 331 337 347 349 + 353 359 367 373 379 383 389 397 401 409 + 419 421 431 433 439 443 449 457 461 463 + 467 479 487 491 499 503 509 521 523 541 + 547 557 563 569 571 577 587 593 599 601 + 607 613 617 619 631 641 643 647 653 659 + 661 673 677 683 691 701 709 719 727 733 + 739 743 751 757 761 769 773 787 797 809 + 811 821 823 827 829 839 853 857 859 863 + 877 881 883 887 907 911 919 929 937 941 + 947 953 967 971 977 983 991 997 + 1009 1013 1019 1021 1031 + */ + + // Each list has a product < 2^31 + private static readonly int[][] primeLists = new int[][] + { + new int[]{ 3, 5, 7, 11, 13, 17, 19, 23 }, + new int[]{ 29, 31, 37, 41, 43 }, + new int[]{ 47, 53, 59, 61, 67 }, + new int[]{ 71, 73, 79, 83 }, + new int[]{ 89, 97, 101, 103 }, + + new int[]{ 107, 109, 113, 127 }, + new int[]{ 131, 137, 139, 149 }, + new int[]{ 151, 157, 163, 167 }, + new int[]{ 173, 179, 181, 191 }, + new int[]{ 193, 197, 199, 211 }, + + new int[]{ 223, 227, 229 }, + new int[]{ 233, 239, 241 }, + new int[]{ 251, 257, 263 }, + new int[]{ 269, 271, 277 }, + new int[]{ 281, 283, 293 }, + + new int[]{ 307, 311, 313 }, + new int[]{ 317, 331, 337 }, + new int[]{ 347, 349, 353 }, + new int[]{ 359, 367, 373 }, + new int[]{ 379, 383, 389 }, + + new int[]{ 397, 401, 409 }, + new int[]{ 419, 421, 431 }, + new int[]{ 433, 439, 443 }, + new int[]{ 449, 457, 461 }, + new int[]{ 463, 467, 479 }, + + new int[]{ 487, 491, 499 }, + new int[]{ 503, 509, 521 }, + new int[]{ 523, 541, 547 }, + new int[]{ 557, 563, 569 }, + new int[]{ 571, 577, 587 }, + + new int[]{ 593, 599, 601 }, + new int[]{ 607, 613, 617 }, + new int[]{ 619, 631, 641 }, + new int[]{ 643, 647, 653 }, + new int[]{ 659, 661, 673 }, + + new int[]{ 677, 683, 691 }, + new int[]{ 701, 709, 719 }, + new int[]{ 727, 733, 739 }, + new int[]{ 743, 751, 757 }, + new int[]{ 761, 769, 773 }, + + new int[]{ 787, 797, 809 }, + new int[]{ 811, 821, 823 }, + new int[]{ 827, 829, 839 }, + new int[]{ 853, 857, 859 }, + new int[]{ 863, 877, 881 }, + + new int[]{ 883, 887, 907 }, + new int[]{ 911, 919, 929 }, + new int[]{ 937, 941, 947 }, + new int[]{ 953, 967, 971 }, + new int[]{ 977, 983, 991 }, + + new int[]{ 997, 1009, 1013 }, + new int[]{ 1019, 1021, 1031 }, + }; + + private static readonly BigInteger Six = BigInteger.ValueOf(6); + + private static readonly int[] primeProducts; + private static readonly BigInteger[] PrimeProducts; + + static DHParametersHelper() + { + primeProducts = new int[primeLists.Length]; + PrimeProducts = new BigInteger[primeLists.Length]; + + for (int i = 0; i < primeLists.Length; ++i) + { + int[] primeList = primeLists[i]; + int product = 1; + for (int j = 0; j < primeList.Length; ++j) + { + product *= primeList[j]; + } + primeProducts[i] = product; + PrimeProducts[i] = BigInteger.ValueOf(product); + } + } + + // Finds a pair of prime BigInteger's {p, q: p = 2q + 1} + internal static BigInteger[] GenerateSafePrimes( + int size, + int certainty, + SecureRandom random) + { + BigInteger p, q; + int qLength = size - 1; + + if (size <= 32) + { + for (;;) + { + q = new BigInteger(qLength, 2, random); + + p = q.ShiftLeft(1).Add(BigInteger.One); + + if (p.IsProbablePrime(certainty) + && (certainty <= 2 || q.IsProbablePrime(certainty))) + break; + } + } + else + { + // Note: Modified from Java version for speed + for (;;) + { + q = new BigInteger(qLength, 0, random); + + retry: + for (int i = 0; i < primeLists.Length; ++i) + { + int test = q.Remainder(PrimeProducts[i]).IntValue; + + if (i == 0) + { + int rem3 = test % 3; + if (rem3 != 2) + { + int diff = 2 * rem3 + 2; + q = q.Add(BigInteger.ValueOf(diff)); + test = (test + diff) % primeProducts[i]; + } + } + + int[] primeList = primeLists[i]; + for (int j = 0; j < primeList.Length; ++j) + { + int prime = primeList[j]; + int qRem = test % prime; + if (qRem == 0 || qRem == (prime >> 1)) + { + q = q.Add(Six); + goto retry; + } + } + } + + + if (q.BitLength != qLength) + continue; + + if (!q.RabinMillerTest(2, random)) + continue; + + p = q.ShiftLeft(1).Add(BigInteger.One); + + if (p.RabinMillerTest(certainty, random) + && (certainty <= 2 || q.RabinMillerTest(certainty - 2, random))) + break; + } + } + + return new BigInteger[] { p, q }; + } + + // Select a high order element of the multiplicative group Zp* + // p and q must be s.t. p = 2*q + 1, where p and q are prime + internal static BigInteger SelectGenerator( + BigInteger p, + BigInteger q, + SecureRandom random) + { + BigInteger pMinusTwo = p.Subtract(BigInteger.Two); + BigInteger g; + + // Handbook of Applied Cryptography 4.86 + do + { + g = CreateInRange(BigInteger.Two, pMinusTwo, random); + } + while (g.ModPow(BigInteger.Two, p).Equals(BigInteger.One) + || g.ModPow(q, p).Equals(BigInteger.One)); + +/* + // RFC 2631 2.1.1 (and see Handbook of Applied Cryptography 4.81) + do + { + BigInteger h = CreateInRange(BigInteger.Two, pMinusTwo, random); + + g = h.ModPow(BigInteger.Two, p); + } + while (g.Equals(BigInteger.One)); +*/ + + return g; + } + + private static BigInteger CreateInRange( + BigInteger min, + BigInteger max, + SecureRandom random) + { + BigInteger x; + do + { + x = new BigInteger(max.BitLength, random); + } + while (x.CompareTo(min) < 0 || x.CompareTo(max) > 0); + return x; + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/DesEdeKeyGenerator.cs b/iTechSharp/srcbc/crypto/generators/DesEdeKeyGenerator.cs new file mode 100644 index 0000000..62b71ca --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/DesEdeKeyGenerator.cs @@ -0,0 +1,66 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class DesEdeKeyGenerator + : DesKeyGenerator + { + public DesEdeKeyGenerator() + { + } + + internal DesEdeKeyGenerator( + int defaultStrength) + : base(defaultStrength) + { + } + + /** + * initialise the key generator - if strength is set to zero + * the key Generated will be 192 bits in size, otherwise + * strength can be 128 or 192 (or 112 or 168 if you don't count + * parity bits), depending on whether you wish to do 2-key or 3-key + * triple DES. + * + * @param param the parameters to be used for key generation + */ + protected override void engineInit( + KeyGenerationParameters parameters) + { + base.engineInit(parameters); + + if (strength == 0 || strength == (168 / 8)) + { + strength = DesEdeParameters.DesEdeKeyLength; + } + else if (strength == (112 / 8)) + { + strength = 2 * DesEdeParameters.DesKeyLength; + } + else if (strength != DesEdeParameters.DesEdeKeyLength + && strength != (2 * DesEdeParameters.DesKeyLength)) + { + throw new ArgumentException("DESede key must be " + + (DesEdeParameters.DesEdeKeyLength * 8) + " or " + + (2 * 8 * DesEdeParameters.DesKeyLength) + + " bits long."); + } + } + + protected override byte[] engineGenerateKey() + { + byte[] newKey; + + do + { + newKey = random.GenerateSeed(strength); + DesEdeParameters.SetOddParity(newKey); + } + while (DesEdeParameters.IsWeakKey(newKey, 0, newKey.Length)); + + return newKey; + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/DesKeyGenerator.cs b/iTechSharp/srcbc/crypto/generators/DesKeyGenerator.cs new file mode 100644 index 0000000..c412005 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/DesKeyGenerator.cs @@ -0,0 +1,34 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class DesKeyGenerator + : CipherKeyGenerator + { + public DesKeyGenerator() + { + } + + internal DesKeyGenerator( + int defaultStrength) + : base(defaultStrength) + { + } + + protected override byte[] engineGenerateKey() + { + byte[] newKey; + + do + { + newKey = random.GenerateSeed(DesParameters.DesKeyLength); + DesParameters.SetOddParity(newKey); + } + while (DesParameters.IsWeakKey(newKey, 0)); + + return newKey; + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/DsaKeyPairGenerator.cs b/iTechSharp/srcbc/crypto/generators/DsaKeyPairGenerator.cs new file mode 100644 index 0000000..fee3057 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/DsaKeyPairGenerator.cs @@ -0,0 +1,56 @@ +using System; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a DSA key pair generator. + * + * This Generates DSA keys in line with the method described + * in FIPS 186-2. + */ + public class DsaKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private DsaKeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + + // Note: If we start accepting instances of KeyGenerationParameters, + // must apply constraint checking on strength (see DsaParametersGenerator.Init) + + this.param = (DsaKeyGenerationParameters) parameters; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + DsaParameters dsaParams = param.Parameters; + SecureRandom random = param.Random; + + BigInteger q = dsaParams.Q; + BigInteger x; + + do + { + x = new BigInteger(160, random); + } + while (x.SignValue == 0 || x.CompareTo(q) >= 0); + + // + // calculate the public key. + // + BigInteger y = dsaParams.G.ModPow(x, dsaParams.P); + + return new AsymmetricCipherKeyPair( + new DsaPublicKeyParameters(y, dsaParams), + new DsaPrivateKeyParameters(x, dsaParams)); + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/DsaParametersGenerator.cs b/iTechSharp/srcbc/crypto/generators/DsaParametersGenerator.cs new file mode 100644 index 0000000..a23b43b --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/DsaParametersGenerator.cs @@ -0,0 +1,184 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generate suitable parameters for DSA, in line with FIPS 186-2. + */ + public class DsaParametersGenerator + { + private int size; + private int certainty; + private SecureRandom random; + + /** + * initialise the key generator. + * + * @param size size of the key (range 2^512 -> 2^1024 - 64 bit increments) + * @param certainty measure of robustness of prime (for FIPS 186-2 compliance this should be at least 80). + * @param random random byte source. + */ + public void Init( + int size, + int certainty, + SecureRandom random) + { + if (!IsValidDsaStrength(size)) + throw new ArgumentException("size must be from 512 - 1024 and a multiple of 64", "size"); + + this.size = size; + this.certainty = certainty; + this.random = random; + } + + /** + * add value to b, returning the result in a. The a value is treated + * as a BigInteger of length (a.Length * 8) bits. The result is + * modulo 2^a.Length in case of overflow. + */ + private static void Add( + byte[] a, + byte[] b, + int value) + { + int x = (b[b.Length - 1] & 0xff) + value; + + a[b.Length - 1] = (byte)x; + x = (int) ((uint) x >>8); + + for (int i = b.Length - 2; i >= 0; i--) + { + x += (b[i] & 0xff); + a[i] = (byte)x; + x = (int) ((uint) x >>8); + } + } + + /** + * which Generates the p and g values from the given parameters, + * returning the DsaParameters object. + *+ * Note: can take a while...
+ */ + public DsaParameters GenerateParameters() + { + byte[] seed = new byte[20]; + byte[] part1 = new byte[20]; + byte[] part2 = new byte[20]; + byte[] u = new byte[20]; + Sha1Digest sha1 = new Sha1Digest(); + int n = (size - 1) / 160; + byte[] w = new byte[size / 8]; + + BigInteger q = null, p = null, g = null; + int counter = 0; + bool primesFound = false; + + while (!primesFound) + { + do + { + random.NextBytes(seed); + + sha1.BlockUpdate(seed, 0, seed.Length); + + sha1.DoFinal(part1, 0); + + Array.Copy(seed, 0, part2, 0, seed.Length); + + Add(part2, seed, 1); + + sha1.BlockUpdate(part2, 0, part2.Length); + + sha1.DoFinal(part2, 0); + + for (int i = 0; i != u.Length; i++) + { + u[i] = (byte)(part1[i] ^ part2[i]); + } + + u[0] |= (byte)0x80; + u[19] |= (byte)0x01; + + q = new BigInteger(1, u); + } + while (!q.IsProbablePrime(certainty)); + + counter = 0; + + int offset = 2; + + while (counter < 4096) + { + for (int k = 0; k < n; k++) + { + Add(part1, seed, offset + k); + sha1.BlockUpdate(part1, 0, part1.Length); + sha1.DoFinal(part1, 0); + Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length); + } + + Add(part1, seed, offset + n); + sha1.BlockUpdate(part1, 0, part1.Length); + sha1.DoFinal(part1, 0); + Array.Copy(part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length); + + w[0] |= (byte)0x80; + + BigInteger x = new BigInteger(1, w); + + BigInteger c = x.Mod(q.ShiftLeft(1)); + + p = x.Subtract(c.Subtract(BigInteger.One)); + + if (p.TestBit(size - 1)) + { + if (p.IsProbablePrime(certainty)) + { + primesFound = true; + break; + } + } + + counter += 1; + offset += n + 1; + } + } + + // + // calculate the generator g + // + BigInteger pMinusOneOverQ = p.Subtract(BigInteger.One).Divide(q); + + for (;;) + { + BigInteger h = new BigInteger(size, random); + if (h.CompareTo(BigInteger.One) <= 0 || h.CompareTo(p.Subtract(BigInteger.One)) >= 0) + { + continue; + } + + g = h.ModPow(pMinusOneOverQ, p); + if (g.CompareTo(BigInteger.One) <= 0) + { + continue; + } + + break; + } + + return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter)); + } + + private static bool IsValidDsaStrength( + int strength) + { + return strength >= 512 && strength <= 1024 && strength % 64 == 0; + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/ECKeyPairGenerator.cs b/iTechSharp/srcbc/crypto/generators/ECKeyPairGenerator.cs new file mode 100644 index 0000000..1ecc471 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/ECKeyPairGenerator.cs @@ -0,0 +1,130 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class ECKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private readonly string algorithm; + + private ECDomainParameters parameters; + private DerObjectIdentifier publicKeyParamSet; + private SecureRandom random; + + public ECKeyPairGenerator() + : this("EC") + { + } + + public ECKeyPairGenerator( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + this.algorithm = VerifyAlgorithmName(algorithm); + } + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters is ECKeyGenerationParameters) + { + ECKeyGenerationParameters ecP = (ECKeyGenerationParameters) parameters; + + if (ecP.PublicKeyParamSet != null) + { + if (algorithm != "ECGOST3410") + throw new ArgumentException("parameters invalid for algorithm: " + algorithm, "parameters"); + + this.publicKeyParamSet = ecP.PublicKeyParamSet; + } + + this.parameters = ecP.DomainParameters; + } + else + { + DerObjectIdentifier oid; + switch (parameters.Strength) + { + case 192: + oid = X9ObjectIdentifiers.Prime192v1; + break; + case 239: + oid = X9ObjectIdentifiers.Prime239v1; + break; + case 256: + oid = X9ObjectIdentifiers.Prime256v1; + break; + default: + throw new InvalidParameterException("unknown key size."); + } + + X9ECParameters ecps = X962NamedCurves.GetByOid(oid); + + this.parameters = new ECDomainParameters( + ecps.Curve, ecps.G, ecps.N, ecps.H, ecps.GetSeed()); + } + + this.random = parameters.Random; + } + + /** + * Given the domain parameters this routine Generates an EC key + * pair in accordance with X9.62 section 5.2.1 pages 26, 27. + */ + public AsymmetricCipherKeyPair GenerateKeyPair() + { + BigInteger n = parameters.N; + BigInteger d; + + do + { + d = new BigInteger(n.BitLength, random); + } + while (d.SignValue == 0 || (d.CompareTo(n) >= 0)); + + ECPoint q = parameters.G.Multiply(d); + + if (publicKeyParamSet != null) + { + return new AsymmetricCipherKeyPair( + new ECPublicKeyParameters(q, publicKeyParamSet), + new ECPrivateKeyParameters(d, publicKeyParamSet)); + } + + return new AsymmetricCipherKeyPair( + new ECPublicKeyParameters(algorithm, q, parameters), + new ECPrivateKeyParameters(algorithm, d, parameters)); + } + + private string VerifyAlgorithmName( + string algorithm) + { + string upper = algorithm.ToUpper(CultureInfo.InvariantCulture); + + switch (upper) + { + case "EC": + case "ECDSA": + case "ECGOST3410": + case "ECDH": + case "ECDHC": + break; + default: + throw new ArgumentException("unrecognised algorithm: " + algorithm, "algorithm"); + } + + return upper; + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/ElGamalKeyPairGenerator.cs b/iTechSharp/srcbc/crypto/generators/ElGamalKeyPairGenerator.cs new file mode 100644 index 0000000..13e8d62 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/ElGamalKeyPairGenerator.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a ElGamal key pair generator. + *+ * This Generates keys consistent for use with ElGamal as described in + * page 164 of "Handbook of Applied Cryptography".
+ */ + public class ElGamalKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private ElGamalKeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + this.param = (ElGamalKeyGenerationParameters) parameters; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance; + ElGamalParameters elParams = param.Parameters; + + BigInteger p = elParams.P; + BigInteger x = helper.CalculatePrivate(p, param.Random, elParams.L); + BigInteger y = helper.CalculatePublic(p, elParams.G, x); + + return new AsymmetricCipherKeyPair( + new ElGamalPublicKeyParameters(y, elParams), + new ElGamalPrivateKeyParameters(x, elParams)); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/generators/ElGamalParametersGenerator.cs b/iTechSharp/srcbc/crypto/generators/ElGamalParametersGenerator.cs new file mode 100644 index 0000000..8443bb0 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/ElGamalParametersGenerator.cs @@ -0,0 +1,46 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class ElGamalParametersGenerator + { + private int size; + private int certainty; + private SecureRandom random; + + public void Init( + int size, + int certainty, + SecureRandom random) + { + this.size = size; + this.certainty = certainty; + this.random = random; + } + + /** + * which Generates the p and g values from the given parameters, + * returning the ElGamalParameters object. + *+ * Note: can take a while... + *
+ */ + public ElGamalParameters GenerateParameters() + { + // + // find a safe prime p where p = 2*q + 1, where p and q are prime. + // + BigInteger[] safePrimes = DHParametersHelper.GenerateSafePrimes(size, certainty, random); + + BigInteger p = safePrimes[0]; + BigInteger q = safePrimes[1]; + BigInteger g = DHParametersHelper.SelectGenerator(p, q, random); + + return new ElGamalParameters(p, g); + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/GOST3410KeyPairGenerator.cs b/iTechSharp/srcbc/crypto/generators/GOST3410KeyPairGenerator.cs new file mode 100644 index 0000000..5878da6 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/GOST3410KeyPairGenerator.cs @@ -0,0 +1,73 @@ +using System; + +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a GOST3410 key pair generator. + * This generates GOST3410 keys in line with the method described + * in GOST R 34.10-94. + */ + public class Gost3410KeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private Gost3410KeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters is Gost3410KeyGenerationParameters) + { + this.param = (Gost3410KeyGenerationParameters) parameters; + } + else + { + Gost3410KeyGenerationParameters kgp = new Gost3410KeyGenerationParameters( + parameters.Random, + CryptoProObjectIdentifiers.GostR3410x94CryptoProA); + + if (parameters.Strength != kgp.Parameters.P.BitLength - 1) + { + // TODO Should we complain? + } + + this.param = kgp; + } + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + SecureRandom random = param.Random; + Gost3410Parameters gost3410Params = param.Parameters; + + BigInteger q = gost3410Params.Q; + BigInteger x; + do + { + x = new BigInteger(256, random); + } + while (x.SignValue < 1 || x.CompareTo(q) >= 0); + + BigInteger p = gost3410Params.P; + BigInteger a = gost3410Params.A; + + // calculate the public key. + BigInteger y = a.ModPow(x, p); + + if (param.PublicKeyParamSet != null) + { + return new AsymmetricCipherKeyPair( + new Gost3410PublicKeyParameters(y, param.PublicKeyParamSet), + new Gost3410PrivateKeyParameters(x, param.PublicKeyParamSet)); + } + + return new AsymmetricCipherKeyPair( + new Gost3410PublicKeyParameters(y, gost3410Params), + new Gost3410PrivateKeyParameters(x, gost3410Params)); + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/GOST3410ParametersGenerator.cs b/iTechSharp/srcbc/crypto/generators/GOST3410ParametersGenerator.cs new file mode 100644 index 0000000..52a9f5a --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/GOST3410ParametersGenerator.cs @@ -0,0 +1,530 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * generate suitable parameters for GOST3410. + */ + public class Gost3410ParametersGenerator + { + private int size; + private int typeproc; + private SecureRandom init_random; + + /** + * initialise the key generator. + * + * @param size size of the key + * @param typeProcedure type procedure A,B = 1; A',B' - else + * @param random random byte source. + */ + public void Init( + int size, + int typeProcedure, + SecureRandom random) + { + this.size = size; + this.typeproc = typeProcedure; + this.init_random = random; + } + + //Procedure A + private int procedure_A(int x0, int c, BigInteger[] pq, int size) + { + //Verify and perform condition: 0+ * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an + * iteration count of 1. + *
+ */ + public class OpenSslPbeParametersGenerator + : PbeParametersGenerator + { + private readonly IDigest digest = new MD5Digest(); + + /** + * Construct a OpenSSL Parameters generator. + */ + public OpenSslPbeParametersGenerator() + { + } + + public override void Init( + byte[] password, + byte[] salt, + int iterationCount) + { + // Ignore the provided iterationCount + base.Init(password, salt, 1); + } + + /** + * Initialise - note the iteration count for this algorithm is fixed at 1. + * + * @param password password to use. + * @param salt salt to use. + */ + public virtual void Init( + byte[] password, + byte[] salt) + { + base.Init(password, salt, 1); + } + + /** + * the derived key function, the ith hash of the password and the salt. + */ + private byte[] GenerateDerivedKey( + int bytesNeeded) + { + byte[] buf = new byte[digest.GetDigestSize()]; + byte[] key = new byte[bytesNeeded]; + int offset = 0; + + for (;;) + { + digest.BlockUpdate(mPassword, 0, mPassword.Length); + digest.BlockUpdate(mSalt, 0, mSalt.Length); + + digest.DoFinal(buf, 0); + + int len = (bytesNeeded > buf.Length) ? buf.Length : bytesNeeded; + Array.Copy(buf, 0, key, offset, len); + offset += len; + + // check if we need any more + bytesNeeded -= len; + if (bytesNeeded == 0) + { + break; + } + + // do another round + digest.Reset(); + digest.BlockUpdate(buf, 0, buf.Length); + } + + return key; + } + + /** + * Generate a key parameter derived from the password, salt, and iteration + * count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + * @exception ArgumentException if the key length larger than the base hash size. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize) + { + return GenerateDerivedMacParameters(keySize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize); + + return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + } + + /** + * Generate a key with initialisation vector parameter derived from + * the password, salt, and iteration count we are currently initialised + * with. + * + * @param keySize the size of the key we want (in bits) + * @param ivSize the size of the iv we want (in bits) + * @return a ParametersWithIV object. + * @exception ArgumentException if keySize + ivSize is larger than the base hash size. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize, + int ivSize) + { + keySize = keySize / 8; + ivSize = ivSize / 8; + + byte[] dKey = GenerateDerivedKey(keySize + ivSize); + + return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize + ivSize); + KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + + return new ParametersWithIV(key, dKey, keySize, ivSize); + } + + /** + * Generate a key parameter for use with a MAC derived from the password, + * salt, and iteration count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + * @exception ArgumentException if the key length larger than the base hash size. + */ + public override ICipherParameters GenerateDerivedMacParameters( + int keySize) + { + keySize = keySize / 8; + + byte[] dKey = GenerateDerivedKey(keySize); + + return new KeyParameter(dKey, 0, keySize); + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/Pkcs12ParametersGenerator.cs b/iTechSharp/srcbc/crypto/generators/Pkcs12ParametersGenerator.cs new file mode 100644 index 0000000..d2da3f6 --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/Pkcs12ParametersGenerator.cs @@ -0,0 +1,245 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generator for Pbe derived keys and ivs as defined by Pkcs 12 V1.0. + *+ * The document this implementation is based on can be found at + * + * RSA's Pkcs12 Page + *
+ */ + public class Pkcs12ParametersGenerator + : PbeParametersGenerator + { + public const int KeyMaterial = 1; + public const int IVMaterial = 2; + public const int MacMaterial = 3; + + private readonly IDigest digest; + + private readonly int u; + private readonly int v; + + /** + * Construct a Pkcs 12 Parameters generator. + * + * @param digest the digest to be used as the source of derived keys. + * @exception ArgumentException if an unknown digest is passed in. + */ + public Pkcs12ParametersGenerator( + IDigest digest) + { + this.digest = digest; + + u = digest.GetDigestSize(); + v = digest.GetByteLength(); + } + + /** + * add a + b + 1, returning the result in a. The a value is treated + * as a BigInteger of length (b.Length * 8) bits. The result is + * modulo 2^b.Length in case of overflow. + */ + private void Adjust( + byte[] a, + int aOff, + byte[] b) + { + int x = (b[b.Length - 1] & 0xff) + (a[aOff + b.Length - 1] & 0xff) + 1; + + a[aOff + b.Length - 1] = (byte)x; + x = (int) ((uint) x >> 8); + + for (int i = b.Length - 2; i >= 0; i--) + { + x += (b[i] & 0xff) + (a[aOff + i] & 0xff); + a[aOff + i] = (byte)x; + x = (int) ((uint) x >> 8); + } + } + + /** + * generation of a derived key ala Pkcs12 V1.0. + */ + private byte[] GenerateDerivedKey( + int idByte, + int n) + { + byte[] D = new byte[v]; + byte[] dKey = new byte[n]; + + for (int i = 0; i != D.Length; i++) + { + D[i] = (byte)idByte; + } + + byte[] S; + + if ((mSalt != null) && (mSalt.Length != 0)) + { + S = new byte[v * ((mSalt.Length + v - 1) / v)]; + + for (int i = 0; i != S.Length; i++) + { + S[i] = mSalt[i % mSalt.Length]; + } + } + else + { + S = new byte[0]; + } + + byte[] P; + + if ((mPassword != null) && (mPassword.Length != 0)) + { + P = new byte[v * ((mPassword.Length + v - 1) / v)]; + + for (int i = 0; i != P.Length; i++) + { + P[i] = mPassword[i % mPassword.Length]; + } + } + else + { + P = new byte[0]; + } + + byte[] I = new byte[S.Length + P.Length]; + + Array.Copy(S, 0, I, 0, S.Length); + Array.Copy(P, 0, I, S.Length, P.Length); + + byte[] B = new byte[v]; + int c = (n + u - 1) / u; + + for (int i = 1; i <= c; i++) + { + byte[] A = new byte[u]; + + digest.BlockUpdate(D, 0, D.Length); + digest.BlockUpdate(I, 0, I.Length); + digest.DoFinal(A, 0); + for (int j = 1; j != mIterationCount; j++) + { + digest.BlockUpdate(A, 0, A.Length); + digest.DoFinal(A, 0); + } + + for (int j = 0; j != B.Length; j++) + { + B[j] = A[j % A.Length]; + } + + for (int j = 0; j != I.Length / v; j++) + { + Adjust(I, j * v, B); + } + + if (i == c) + { + Array.Copy(A, 0, dKey, (i - 1) * u, dKey.Length - ((i - 1) * u)); + } + else + { + Array.Copy(A, 0, dKey, (i - 1) * u, A.Length); + } + } + + return dKey; + } + + /** + * Generate a key parameter derived from the password, salt, and iteration + * count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize); + + return new KeyParameter(dKey, 0, keySize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize); + + return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + } + + /** + * Generate a key with initialisation vector parameter derived from + * the password, salt, and iteration count we are currently initialised + * with. + * + * @param keySize the size of the key we want (in bits) + * @param ivSize the size of the iv we want (in bits) + * @return a ParametersWithIV object. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize); + + byte[] iv = GenerateDerivedKey(IVMaterial, ivSize); + + return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), iv, 0, ivSize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize); + KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + + byte[] iv = GenerateDerivedKey(IVMaterial, ivSize); + + return new ParametersWithIV(key, iv, 0, ivSize); + } + + /** + * Generate a key parameter for use with a MAC derived from the password, + * salt, and iteration count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + */ + public override ICipherParameters GenerateDerivedMacParameters( + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(MacMaterial, keySize); + + return new KeyParameter(dKey, 0, keySize); + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/Pkcs5S1ParametersGenerator.cs b/iTechSharp/srcbc/crypto/generators/Pkcs5S1ParametersGenerator.cs new file mode 100644 index 0000000..8586e1c --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/Pkcs5S1ParametersGenerator.cs @@ -0,0 +1,162 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generator for Pbe derived keys and ivs as defined by Pkcs 5 V2.0 Scheme 1. + * Note this generator is limited to the size of the hash produced by the + * digest used to drive it. + *+ * The document this implementation is based on can be found at + * + * RSA's Pkcs5 Page + *
+ */ + public class Pkcs5S1ParametersGenerator + : PbeParametersGenerator + { + private readonly IDigest digest; + + /** + * Construct a Pkcs 5 Scheme 1 Parameters generator. + * + * @param digest the digest to be used as the source of derived keys. + */ + public Pkcs5S1ParametersGenerator( + IDigest digest) + { + this.digest = digest; + } + + /** + * the derived key function, the ith hash of the mPassword and the mSalt. + */ + private byte[] GenerateDerivedKey() + { + byte[] digestBytes = new byte[digest.GetDigestSize()]; + + digest.BlockUpdate(mPassword, 0, mPassword.Length); + digest.BlockUpdate(mSalt, 0, mSalt.Length); + + digest.DoFinal(digestBytes, 0); + for (int i = 1; i < mIterationCount; i++) + { + digest.BlockUpdate(digestBytes, 0, digestBytes.Length); + digest.DoFinal(digestBytes, 0); + } + + return digestBytes; + } + + /** + * Generate a key parameter derived from the mPassword, mSalt, and iteration + * count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + * @exception ArgumentException if the key length larger than the base hash size. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize) + { + return GenerateDerivedMacParameters(keySize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize) + { + keySize /= 8; + + if (keySize > digest.GetDigestSize()) + { + throw new ArgumentException( + "Can't Generate a derived key " + keySize + " bytes long."); + } + + byte[] dKey = GenerateDerivedKey(); + + return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + } + + /** + * Generate a key with initialisation vector parameter derived from + * the mPassword, mSalt, and iteration count we are currently initialised + * with. + * + * @param keySize the size of the key we want (in bits) + * @param ivSize the size of the iv we want (in bits) + * @return a ParametersWithIV object. + * @exception ArgumentException if keySize + ivSize is larger than the base hash size. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + if ((keySize + ivSize) > digest.GetDigestSize()) + { + throw new ArgumentException( + "Can't Generate a derived key " + (keySize + ivSize) + " bytes long."); + } + + byte[] dKey = GenerateDerivedKey(); + + return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + if ((keySize + ivSize) > digest.GetDigestSize()) + { + throw new ArgumentException( + "Can't Generate a derived key " + (keySize + ivSize) + " bytes long."); + } + + byte[] dKey = GenerateDerivedKey(); + KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + + return new ParametersWithIV(key, dKey, keySize, ivSize); + } + + /** + * Generate a key parameter for use with a MAC derived from the mPassword, + * mSalt, and iteration count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + * @exception ArgumentException if the key length larger than the base hash size. + */ + public override ICipherParameters GenerateDerivedMacParameters( + int keySize) + { + keySize /= 8; + + if (keySize > digest.GetDigestSize()) + { + throw new ArgumentException( + "Can't Generate a derived key " + keySize + " bytes long."); + } + + byte[] dKey = GenerateDerivedKey(); + + return new KeyParameter(dKey, 0, keySize); + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/Pkcs5S2ParametersGenerator.cs b/iTechSharp/srcbc/crypto/generators/Pkcs5S2ParametersGenerator.cs new file mode 100644 index 0000000..223595d --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/Pkcs5S2ParametersGenerator.cs @@ -0,0 +1,175 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generator for Pbe derived keys and ivs as defined by Pkcs 5 V2.0 Scheme 2. + * This generator uses a SHA-1 HMac as the calculation function. + *+ * The document this implementation is based on can be found at + * + * RSA's Pkcs5 Page
+ */ + public class Pkcs5S2ParametersGenerator + : PbeParametersGenerator + { + private readonly IMac hMac = new HMac(new Sha1Digest()); + + /** + * construct a Pkcs5 Scheme 2 Parameters generator. + */ + public Pkcs5S2ParametersGenerator() + { + } + + private void F( + byte[] P, + byte[] S, + int c, + byte[] iBuf, + byte[] outBytes, + int outOff) + { + byte[] state = new byte[hMac.GetMacSize()]; + ICipherParameters param = new KeyParameter(P); + + hMac.Init(param); + + if (S != null) + { + hMac.BlockUpdate(S, 0, S.Length); + } + + hMac.BlockUpdate(iBuf, 0, iBuf.Length); + + hMac.DoFinal(state, 0); + + Array.Copy(state, 0, outBytes, outOff, state.Length); + + for (int count = 1; count != c; count++) + { + hMac.Init(param); + hMac.BlockUpdate(state, 0, state.Length); + hMac.DoFinal(state, 0); + + for (int j = 0; j != state.Length; j++) + { + outBytes[outOff + j] ^= state[j]; + } + } + } + + private void IntToOctet( + byte[] Buffer, + int i) + { + Buffer[0] = (byte)((uint) i >> 24); + Buffer[1] = (byte)((uint) i >> 16); + Buffer[2] = (byte)((uint) i >> 8); + Buffer[3] = (byte)i; + } + + private byte[] GenerateDerivedKey( + int dkLen) + { + int hLen = hMac.GetMacSize(); + int l = (dkLen + hLen - 1) / hLen; + byte[] iBuf = new byte[4]; + byte[] outBytes = new byte[l * hLen]; + + for (int i = 1; i <= l; i++) + { + IntToOctet(iBuf, i); + + F(mPassword, mSalt, mIterationCount, iBuf, outBytes, (i - 1) * hLen); + } + + return outBytes; + } + + /** + * Generate a key parameter derived from the password, salt, and iteration + * count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize) + { + return GenerateDerivedMacParameters(keySize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize); + + return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + } + + /** + * Generate a key with initialisation vector parameter derived from + * the password, salt, and iteration count we are currently initialised + * with. + * + * @param keySize the size of the key we want (in bits) + * @param ivSize the size of the iv we want (in bits) + * @return a ParametersWithIV object. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize + ivSize); + + return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize + ivSize); + KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + + return new ParametersWithIV(key, dKey, keySize, ivSize); + } + + /** + * Generate a key parameter for use with a MAC derived from the password, + * salt, and iteration count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + */ + public override ICipherParameters GenerateDerivedMacParameters( + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize); + + return new KeyParameter(dKey, 0, keySize); + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/RSABlindingFactorGenerator.cs b/iTechSharp/srcbc/crypto/generators/RSABlindingFactorGenerator.cs new file mode 100644 index 0000000..e2f63fa --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/RSABlindingFactorGenerator.cs @@ -0,0 +1,69 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generate a random factor suitable for use with RSA blind signatures + * as outlined in Chaum's blinding and unblinding as outlined in + * "Handbook of Applied Cryptography", page 475. + */ + public class RsaBlindingFactorGenerator + { + private RsaKeyParameters key; + private SecureRandom random; + + /** + * Initialise the factor generator + * + * @param param the necessary RSA key parameters. + */ + public void Init( + ICipherParameters param) + { + if (param is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + + key = (RsaKeyParameters)rParam.Parameters; + random = rParam.Random; + } + else + { + key = (RsaKeyParameters)param; + random = new SecureRandom(); + } + + if (key.IsPrivate) + throw new ArgumentException("generator requires RSA public key"); + } + + /** + * Generate a suitable blind factor for the public key the generator was initialised with. + * + * @return a random blind factor + */ + public BigInteger GenerateBlindingFactor() + { + if (key == null) + throw new InvalidOperationException("generator not initialised"); + + BigInteger m = key.Modulus; + int length = m.BitLength - 1; // must be less than m.BitLength + BigInteger factor; + BigInteger gcd; + + do + { + factor = new BigInteger(length, random); + gcd = factor.Gcd(m); + } + while (factor.SignValue == 0 || factor.Equals(BigInteger.One) || !gcd.Equals(BigInteger.One)); + + return factor; + } + } +} diff --git a/iTechSharp/srcbc/crypto/generators/RsaKeyPairGenerator.cs b/iTechSharp/srcbc/crypto/generators/RsaKeyPairGenerator.cs new file mode 100644 index 0000000..3074aed --- /dev/null +++ b/iTechSharp/srcbc/crypto/generators/RsaKeyPairGenerator.cs @@ -0,0 +1,139 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * an RSA key pair generator. + */ + public class RsaKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001); + private const int DefaultTests = 12; + + private RsaKeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters is RsaKeyGenerationParameters) + { + this.param = (RsaKeyGenerationParameters)parameters; + } + else + { + this.param = new RsaKeyGenerationParameters( + DefaultPublicExponent, parameters.Random, parameters.Strength, DefaultTests); + } + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + BigInteger p, q, n, d, e, pSub1, qSub1, phi; + + // + // p and q values should have a length of half the strength in bits + // + int strength = param.Strength; + int pbitlength = (strength + 1) / 2; + int qbitlength = (strength - pbitlength); + int mindiffbits = strength / 3; + + e = param.PublicExponent; + + // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) + // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") + + // + // Generate p, prime and (p-1) relatively prime to e + // + for (;;) + { + p = new BigInteger(pbitlength, 1, param.Random); + + if (p.Mod(e).Equals(BigInteger.One)) + continue; + + if (!p.IsProbablePrime(param.Certainty)) + continue; + + if (e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One)) + break; + } + + // + // Generate a modulus of the required length + // + for (;;) + { + // Generate q, prime and (q-1) relatively prime to e, + // and not equal to p + // + for (;;) + { + q = new BigInteger(qbitlength, 1, param.Random); + + if (q.Subtract(p).Abs().BitLength < mindiffbits) + continue; + + if (q.Mod(e).Equals(BigInteger.One)) + continue; + + if (!q.IsProbablePrime(param.Certainty)) + continue; + + if (e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One)) + break; + } + + // + // calculate the modulus + // + n = p.Multiply(q); + + if (n.BitLength == param.Strength) + break; + + // + // if we Get here our primes aren't big enough, make the largest + // of the two p and try again + // + p = p.Max(q); + } + + if (p.CompareTo(q) < 0) + { + phi = p; + p = q; + q = phi; + } + + pSub1 = p.Subtract(BigInteger.One); + qSub1 = q.Subtract(BigInteger.One); + phi = pSub1.Multiply(qSub1); + + // + // calculate the private exponent + // + d = e.ModInverse(phi); + + // + // calculate the CRT factors + // + BigInteger dP, dQ, qInv; + + dP = d.Remainder(pSub1); + dQ = d.Remainder(qSub1); + qInv = q.ModInverse(p); + + return new AsymmetricCipherKeyPair( + new RsaKeyParameters(false, n, e), + new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/io/CipherStream.cs b/iTechSharp/srcbc/crypto/io/CipherStream.cs new file mode 100644 index 0000000..459aa35 --- /dev/null +++ b/iTechSharp/srcbc/crypto/io/CipherStream.cs @@ -0,0 +1,224 @@ +using System; +using System.Diagnostics; +using System.IO; +using Org.BouncyCastle.Crypto; +namespace Org.BouncyCastle.Crypto.IO +{ + public class CipherStream : Stream + { + internal Stream stream; + internal IBufferedCipher inCipher, outCipher; + private byte[] mInBuf; + private int mInPos; + private bool inStreamEnded; + + public CipherStream( + Stream stream, + IBufferedCipher readCipher, + IBufferedCipher writeCipher) + { + this.stream = stream; + + if (readCipher != null) + { + this.inCipher = readCipher; + mInBuf = null; + } + + if (writeCipher != null) + { + this.outCipher = writeCipher; + } + } + + public IBufferedCipher ReadCipher + { + get { return inCipher; } + } + + public IBufferedCipher WriteCipher + { + get { return outCipher; } + } + + public override int ReadByte() + { + if (inCipher == null) + { + return stream.ReadByte(); + } + + if (mInBuf == null || mInPos >= mInBuf.Length) + { + if (!FillInBuf()) + { + return -1; + } + } + + return mInBuf[mInPos++]; + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (inCipher == null) + { + return stream.Read(buffer, offset, count); + } + +// int pos = offset; +// int end = offset + count; +// try +// { +// while (pos < end) +// { +// if (mInPos >= mInBufEnd && !FillInBuf()) break; +// +// int len = System.Math.Min(end - pos, mInBufEnd - mInPos); +// Array.Copy(mInBuf, mInPos, buffer, pos, len); +// mInPos += len; +// pos += len; +// } +// } +// catch (IOException) +// { +// if (pos == offset) throw; +// } +// return pos - offset; + + // TODO Optimise + int i = 0; + while (i < count) + { + int c = ReadByte(); + + if (c < 0) break; + + buffer[offset + i++] = (byte) c; + } + + return i; + } + private bool FillInBuf() + { + if (inStreamEnded) + { + return false; + } + + mInPos = 0; + + do + { + mInBuf = readAndProcessBlock(); + } + while (!inStreamEnded && mInBuf == null); + + return mInBuf != null; + } + private byte[] readAndProcessBlock() + { + int blockSize = inCipher.GetBlockSize(); + int readSize = (blockSize == 0) ? 256 : blockSize; + + byte[] block = new byte[readSize]; + int numRead = 0; + do + { + int count = stream.Read(block, numRead, block.Length - numRead); + if (count < 1) + { + inStreamEnded = true; + break; + } + numRead += count; + } + while (numRead < block.Length); + + Debug.Assert(inStreamEnded || numRead == block.Length); + + byte[] bytes = inStreamEnded + ? inCipher.DoFinal(block, 0, numRead) + : inCipher.ProcessBytes(block); + + if (bytes != null && bytes.Length == 0) + { + bytes = null; + } + + return bytes; + } + public override void Write(byte[] buffer, int offset, int count) + { + Debug.Assert(buffer != null); + Debug.Assert(0 <= offset && offset <= buffer.Length); + Debug.Assert(count >= 0); + + int end = offset + count; + + Debug.Assert(0 <= end && end <= buffer.Length); + + if (outCipher == null) + { + stream.Write(buffer, offset, count); + return; + } + + byte[] data = outCipher.ProcessBytes(buffer, offset, count); + if (data != null) + { + stream.Write(data, 0, data.Length); + } + } + public override void WriteByte( + byte value) + { + if (outCipher == null) + { + stream.WriteByte(value); + return; + } + + byte[] data = outCipher.ProcessByte(value); + if (data != null) + { + stream.Write(data, 0, data.Length); + } + } + public override bool CanRead + { + get { return stream.CanRead && (inCipher != null); } + } + public override bool CanWrite + { + get { return stream.CanWrite && (outCipher != null); } + } + public override bool CanSeek + { + get { return false; } + } + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + public override void Close() + { + if (outCipher != null) + { + byte[] data = outCipher.DoFinal(); + stream.Write(data, 0, data.Length); + stream.Flush(); + } + stream.Close(); + } + public override void Flush() + { + // Note: outCipher.DoFinal is only called during Close() + stream.Flush(); + } + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + } +} diff --git a/iTechSharp/srcbc/crypto/io/DigestStream.cs b/iTechSharp/srcbc/crypto/io/DigestStream.cs new file mode 100644 index 0000000..04409c4 --- /dev/null +++ b/iTechSharp/srcbc/crypto/io/DigestStream.cs @@ -0,0 +1,116 @@ +using System; +using System.IO; +using Org.BouncyCastle.Crypto; +namespace Org.BouncyCastle.Crypto.IO +{ + public class DigestStream : Stream + { + internal Stream stream; + internal IDigest inDigest; + internal IDigest outDigest; + + public DigestStream( + Stream stream, + IDigest readDigest, + IDigest writeDigest) + { + this.stream = stream; + this.inDigest = readDigest; + this.outDigest = writeDigest; + } + public IDigest ReadDigest() + { + return inDigest; + } + public IDigest WriteDigest() + { + return outDigest; + } + public override int ReadByte() + { + int b = stream.ReadByte(); + if (inDigest != null) + { + if (b >= 0) + { + inDigest.Update((byte)b); + } + } + return b; + } + + public override int Read(byte[] buffer, int offset, int count) + { + int n = stream.Read(buffer, offset, count); + if (inDigest != null) + { + if (n > 0) + { + inDigest.BlockUpdate(buffer, offset, n); + } + } + return n; + } + public override void Write( + byte[] buffer, + int offset, + int count) + { + if (outDigest != null) + { + if (count > 0) + { + outDigest.BlockUpdate(buffer, offset, count); + } + } + stream.Write(buffer, offset, count); + } + public override void WriteByte(byte value) + { + if (outDigest != null) + { + outDigest.Update(value); + } + stream.WriteByte(value); + } + public override bool CanRead + { + get { return stream.CanRead && (inDigest != null); } + } + public override bool CanWrite + { + get { return stream.CanWrite && (outDigest != null); } + } + public override bool CanSeek + { + get { return stream.CanSeek; } + } + public override long Length + { + get { return stream.Length; } + } + public override long Position + { + get { return stream.Position; } + set { stream.Position = value; } + } + public override void Close() + { + stream.Close(); + } + public override void Flush() + { + stream.Flush(); + } + public override long Seek( + long offset, + SeekOrigin origin) + { + return stream.Seek(offset,origin); + } + public override void SetLength(long value) + { + stream.SetLength(value); + } + } +} diff --git a/iTechSharp/srcbc/crypto/io/MacStream.cs b/iTechSharp/srcbc/crypto/io/MacStream.cs new file mode 100644 index 0000000..622e528 --- /dev/null +++ b/iTechSharp/srcbc/crypto/io/MacStream.cs @@ -0,0 +1,116 @@ +using System; +using System.IO; +using Org.BouncyCastle.Crypto; +namespace Org.BouncyCastle.Crypto.IO +{ + public class MacStream : Stream + { + internal Stream stream; + internal IMac inMac; + internal IMac outMac; + + public MacStream( + Stream stream, + IMac readMac, + IMac writeMac) + { + this.stream = stream; + this.inMac = readMac; + this.outMac = writeMac; + } + public IMac ReadMac() + { + return inMac; + } + public IMac WriteMac() + { + return outMac; + } + public override int ReadByte() + { + int b = stream.ReadByte(); + if (inMac != null) + { + if (b >= 0) + { + inMac.Update((byte)b); + } + } + return b; + } + + public override int Read(byte[] buffer, int offset, int count) + { + int n = stream.Read(buffer, offset, count); + if (inMac != null) + { + if (n > 0) + { + inMac.BlockUpdate(buffer, offset, count); + } + } + return n; + } + public override void Write( + byte[] buffer, + int offset, + int count) + { + if (outMac != null) + { + if (count > 0) + { + outMac.BlockUpdate(buffer, offset, count); + } + } + stream.Write(buffer, offset, count); + } + public override void WriteByte(byte value) + { + if (outMac != null) + { + outMac.Update(value); + } + stream.WriteByte(value); + } + public override bool CanRead + { + get { return stream.CanRead && (inMac != null); } + } + public override bool CanWrite + { + get { return stream.CanWrite && (outMac != null); } + } + public override bool CanSeek + { + get { return stream.CanSeek; } + } + public override long Length + { + get { return stream.Length; } + } + public override long Position + { + get { return stream.Position; } + set { stream.Position = value; } + } + public override void Close() + { + stream.Close(); + } + public override void Flush() + { + stream.Flush(); + } + public override long Seek( + long offset, + SeekOrigin origin) + { + return stream.Seek(offset,origin); + } + public override void SetLength(long value) + { + stream.SetLength(value); + } + } +} diff --git a/iTechSharp/srcbc/crypto/macs/CMac.cs b/iTechSharp/srcbc/crypto/macs/CMac.cs new file mode 100644 index 0000000..ea1ce88 --- /dev/null +++ b/iTechSharp/srcbc/crypto/macs/CMac.cs @@ -0,0 +1,240 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * CMAC - as specified at www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html + *+ * CMAC is analogous to OMAC1 - see also en.wikipedia.org/wiki/CMAC + *
+ * CMAC is a NIST recomendation - see + * csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf + *
+ * CMAC/OMAC1 is a blockcipher-based message authentication code designed and + * analyzed by Tetsu Iwata and Kaoru Kurosawa. + *
+ * CMAC/OMAC1 is a simple variant of the CBC MAC (Cipher Block Chaining Message + * Authentication Code). OMAC stands for One-Key CBC MAC. + *
+ * It supports 128- or 64-bits block ciphers, with any key size, and returns + * a MAC with dimension less or equal to the block size of the underlying + * cipher. + *
+ */ + public class CMac + : IMac + { + private const byte CONSTANT_128 = (byte)0x87; + private const byte CONSTANT_64 = (byte)0x1b; + + private byte[] ZEROES; + + private byte[] mac; + + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + + private int macSize; + + private byte[] L, Lu, Lu2; + + /** + * create a standard MAC based on a CBC block cipher (64 or 128 bit block). + * This will produce an authentication code the length of the block size + * of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CMac( + IBlockCipher cipher) + : this(cipher, cipher.GetBlockSize() * 8) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. + * + * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8 and @lt;= 128. + */ + public CMac( + IBlockCipher cipher, + int macSizeInBits) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + if (macSizeInBits > (cipher.GetBlockSize() * 8)) + { + throw new ArgumentException( + "MAC size must be less or equal to " + + (cipher.GetBlockSize() * 8)); + } + + if (cipher.GetBlockSize() != 8 && cipher.GetBlockSize() != 16) + { + throw new ArgumentException( + "Block size must be either 64 or 128 bits"); + } + + this.cipher = new CbcBlockCipher(cipher); + this.macSize = macSizeInBits / 8; + + mac = new byte[cipher.GetBlockSize()]; + + buf = new byte[cipher.GetBlockSize()]; + + ZEROES = new byte[cipher.GetBlockSize()]; + + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + private byte[] doubleLu( + byte[] inBytes) + { + int FirstBit = (inBytes[0] & 0xFF) >> 7; + byte[] ret = new byte[inBytes.Length]; + for (int i = 0; i < inBytes.Length - 1; i++) + { + ret[i] = (byte)((inBytes[i] << 1) + ((inBytes[i + 1] & 0xFF) >> 7)); + } + ret[inBytes.Length - 1] = (byte)(inBytes[inBytes.Length - 1] << 1); + if (FirstBit == 1) + { + ret[inBytes.Length - 1] ^= inBytes.Length == 16 ? CONSTANT_128 : CONSTANT_64; + } + return ret; + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + cipher.Init(true, parameters); + + //initializes the L, Lu, Lu2 numbers + L = new byte[ZEROES.Length]; + cipher.ProcessBlock(ZEROES, 0, L, 0); + Lu = doubleLu(L); + Lu2 = doubleLu(Lu); + + cipher.Init(true, parameters); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] inBytes, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(inBytes, inOff, buf, bufOff, gapLen); + + cipher.ProcessBlock(buf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + cipher.ProcessBlock(inBytes, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(inBytes, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] outBytes, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + byte[] lu; + if (bufOff == blockSize) + { + lu = Lu; + } + else + { + new ISO7816d4Padding().AddPadding(buf, bufOff); + lu = Lu2; + } + + for (int i = 0; i < mac.Length; i++) + { + buf[i] ^= lu[i]; + } + + cipher.ProcessBlock(buf, 0, mac, 0); + + Array.Copy(mac, 0, outBytes, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + /* + * clean the buffer. + */ + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + /* + * Reset the underlying cipher. + */ + cipher.Reset(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/macs/CbcBlockCipherMac.cs b/iTechSharp/srcbc/crypto/macs/CbcBlockCipherMac.cs new file mode 100644 index 0000000..11ed834 --- /dev/null +++ b/iTechSharp/srcbc/crypto/macs/CbcBlockCipherMac.cs @@ -0,0 +1,213 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * standard CBC Block Cipher MAC - if no padding is specified the default of + * pad of zeroes is used. + */ + public class CbcBlockCipherMac + : IMac + { + private byte[] mac; + private byte[] Buffer; + private int bufOff; + private IBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + + /** + * create a standard MAC based on a CBC block cipher. This will produce an + * authentication code half the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CbcBlockCipherMac( + IBlockCipher cipher) + : this(cipher, (cipher.GetBlockSize() * 8) / 2, null) + { + } + + /** + * create a standard MAC based on a CBC block cipher. This will produce an + * authentication code half the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used to complete the last block. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, (cipher.GetBlockSize() * 8) / 2, padding) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CBC mode as the basis for the + * MAC generation. + *+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *
+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + int macSizeInBits) + : this(cipher, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CBC mode as the basis for the + * MAC generation. + *+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *
+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding the padding to be used to complete the last block. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + this.cipher = new CbcBlockCipher(cipher); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + mac = new byte[cipher.GetBlockSize()]; + + Buffer = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + cipher.Init(true, parameters); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == Buffer.Length) + { + cipher.ProcessBlock(Buffer, 0, mac, 0); + bufOff = 0; + } + + Buffer[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, Buffer, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(Buffer, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + resultLen += cipher.ProcessBlock(input, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, Buffer, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + if (padding == null) + { + // pad with zeroes + while (bufOff < blockSize) + { + Buffer[bufOff++] = 0; + } + } + else + { + if (bufOff == blockSize) + { + cipher.ProcessBlock(Buffer, 0, mac, 0); + bufOff = 0; + } + + padding.AddPadding(Buffer, bufOff); + } + + cipher.ProcessBlock(Buffer, 0, mac, 0); + + Array.Copy(mac, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + // Clear the buffer. + Array.Clear(Buffer, 0, Buffer.Length); + bufOff = 0; + + // Reset the underlying cipher. + cipher.Reset(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/macs/CfbBlockCipherMac.cs b/iTechSharp/srcbc/crypto/macs/CfbBlockCipherMac.cs new file mode 100644 index 0000000..364cf84 --- /dev/null +++ b/iTechSharp/srcbc/crypto/macs/CfbBlockCipherMac.cs @@ -0,0 +1,368 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. + */ + class MacCFBBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] cfbV; + private byte[] cfbOutV; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + * @param blockSize the block size in bits (note: a multiple of 8) + */ + public MacCFBBlockCipher( + IBlockCipher cipher, + int bitBlockSize) + { + this.cipher = cipher; + this.blockSize = bitBlockSize / 8; + + this.IV = new byte[cipher.GetBlockSize()]; + this.cfbV = new byte[cipher.GetBlockSize()]; + this.cfbOutV = new byte[cipher.GetBlockSize()]; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + cipher.Init(true, parameters); + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CFB" + (blockSize * 8); } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + throw new DataLengthException("input buffer too short"); + + if ((outOff + blockSize) > outBytes.Length) + throw new DataLengthException("output buffer too short"); + + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + + // + // XOR the cfbV with the plaintext producing the cipher text + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(outBytes, outOff, cfbV, cfbV.Length - blockSize, blockSize); + + return blockSize; + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + IV.CopyTo(cfbV, 0); + + cipher.Reset(); + } + + public void GetMacBlock( + byte[] mac) + { + cipher.ProcessBlock(cfbV, 0, mac, 0); + } + } + + public class CfbBlockCipherMac + : IMac + { + private byte[] mac; + private byte[] Buffer; + private int bufOff; + private MacCFBBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + + /** + * create a standard MAC based on a CFB block cipher. This will produce an + * authentication code half the length of the block size of the cipher, with + * the CFB mode set to 8 bits. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CfbBlockCipherMac( + IBlockCipher cipher) + : this(cipher, 8, (cipher.GetBlockSize() * 8) / 2, null) + { + } + + /** + * create a standard MAC based on a CFB block cipher. This will produce an + * authentication code half the length of the block size of the cipher, with + * the CFB mode set to 8 bits. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, 8, (cipher.GetBlockSize() * 8) / 2, padding) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CFB mode as the basis for the + * MAC generation. + *+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *
+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param cfbBitSize the size of an output block produced by the CFB mode. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + int cfbBitSize, + int macSizeInBits) + : this(cipher, cfbBitSize, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CFB mode as the basis for the + * MAC generation. + *+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *
+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param cfbBitSize the size of an output block produced by the CFB mode. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding a padding to be used. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + int cfbBitSize, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + mac = new byte[cipher.GetBlockSize()]; + + this.cipher = new MacCFBBlockCipher(cipher, cfbBitSize); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + Buffer = new byte[this.cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + cipher.Init(true, parameters); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == Buffer.Length) + { + cipher.ProcessBlock(Buffer, 0, mac, 0); + bufOff = 0; + } + + Buffer[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, Buffer, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(Buffer, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + resultLen += cipher.ProcessBlock(input, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, Buffer, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + // pad with zeroes + if (this.padding == null) + { + while (bufOff < blockSize) + { + Buffer[bufOff++] = 0; + } + } + else + { + padding.AddPadding(Buffer, bufOff); + } + + cipher.ProcessBlock(Buffer, 0, mac, 0); + + cipher.GetMacBlock(mac); + + Array.Copy(mac, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + // Clear the buffer. + Array.Clear(Buffer, 0, Buffer.Length); + bufOff = 0; + + // Reset the underlying cipher. + cipher.Reset(); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/macs/GOST28147Mac.cs b/iTechSharp/srcbc/crypto/macs/GOST28147Mac.cs new file mode 100644 index 0000000..9a8f1b7 --- /dev/null +++ b/iTechSharp/srcbc/crypto/macs/GOST28147Mac.cs @@ -0,0 +1,296 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * implementation of GOST 28147-89 MAC + */ + public class Gost28147Mac : IMac + { + private const int blockSize = 8; + private const int macSize = 4; + private int bufOff; + private byte[] buf; + private byte[] mac; + private bool firstStep = true; + private int[] workingKey; + + // + // This is default S-box - E_A. + private byte[] S = + { + 0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5, + 0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1, + 0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9, + 0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6, + 0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6, + 0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6, + 0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE, + 0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4 + }; + + public Gost28147Mac() + { + mac = new byte[blockSize]; + buf = new byte[blockSize]; + bufOff = 0; + } + + private static int[] generateWorkingKey( + byte[] userKey) + { + if (userKey.Length != 32) + throw new ArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!"); + + int[] key = new int[8]; + for(int i=0; i!=8; i++) + { + key[i] = bytesToint(userKey,i*4); + } + + return key; + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + buf = new byte[blockSize]; + if (parameters is ParametersWithSBox) + { + ParametersWithSBox param = (ParametersWithSBox)parameters; + + // + // Set the S-Box + // + param.GetSBox().CopyTo(this.S, 0); + + // + // set key if there is one + // + if (param.Parameters != null) + { + workingKey = generateWorkingKey(((KeyParameter)param.Parameters).GetKey()); + } + } + else if (parameters is KeyParameter) + { + workingKey = generateWorkingKey(((KeyParameter)parameters).GetKey()); + } + else + { + throw new ArgumentException("invalid parameter passed to Gost28147 init - " + + parameters.GetType().Name); + } + } + + public string AlgorithmName + { + get { return "Gost28147Mac"; } + } + + public int GetMacSize() + { + return macSize; + } + + private int gost28147_mainStep(int n1, int key) + { + int cm = (key + n1); // CM1 + + // S-box replacing + + int om = S[ 0 + ((cm >> (0 * 4)) & 0xF)] << (0 * 4); + om += S[ 16 + ((cm >> (1 * 4)) & 0xF)] << (1 * 4); + om += S[ 32 + ((cm >> (2 * 4)) & 0xF)] << (2 * 4); + om += S[ 48 + ((cm >> (3 * 4)) & 0xF)] << (3 * 4); + om += S[ 64 + ((cm >> (4 * 4)) & 0xF)] << (4 * 4); + om += S[ 80 + ((cm >> (5 * 4)) & 0xF)] << (5 * 4); + om += S[ 96 + ((cm >> (6 * 4)) & 0xF)] << (6 * 4); + om += S[112 + ((cm >> (7 * 4)) & 0xF)] << (7 * 4); + +// return om << 11 | om >>> (32-11); // 11-leftshift + int omLeft = om << 11; + int omRight = (int)(((uint) om) >> (32 - 11)); // Note: Casts required to get unsigned bit rotation + + return omLeft | omRight; + } + + private void gost28147MacFunc( + int[] workingKey, + byte[] input, + int inOff, + byte[] output, + int outOff) + { + int N1, N2, tmp; //tmp -> for saving N1 + N1 = bytesToint(input, inOff); + N2 = bytesToint(input, inOff + 4); + + for (int k = 0; k < 2; k++) // 1-16 steps + { + for (int j = 0; j < 8; j++) + { + tmp = N1; + N1 = N2 ^ gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + } + + intTobytes(N1, output, outOff); + intTobytes(N2, output, outOff + 4); + } + + //array of bytes to type int + private static int bytesToint( + byte[] input, + int inOff) + { + return (int)((input[inOff + 3] << 24) & 0xff000000) + ((input[inOff + 2] << 16) & 0xff0000) + + ((input[inOff + 1] << 8) & 0xff00) + (input[inOff] & 0xff); + } + + //int to array of bytes + private static void intTobytes( + int num, + byte[] output, + int outOff) + { + output[outOff + 3] = (byte)(num >> 24); + output[outOff + 2] = (byte)(num >> 16); + output[outOff + 1] = (byte)(num >> 8); + output[outOff] = (byte)num; + } + + private static byte[] CM5func( + byte[] buf, + int bufOff, + byte[] mac) + { + byte[] sum = new byte[buf.Length - bufOff]; + + Array.Copy(buf, bufOff, sum, 0, mac.Length); + + for (int i = 0; i != mac.Length; i++) + { + sum[i] = (byte)(sum[i] ^ mac[i]); + } + + return sum; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + sumbuf = CM5func(input, inOff, mac); + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + //padding with zero + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + Array.Copy(mac, (mac.Length/2)-macSize, output, outOff, macSize); + + Reset(); + + return macSize; + } + + public void Reset() + { + // Clear the buffer. + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + firstStep = true; + } + } +} diff --git a/iTechSharp/srcbc/crypto/macs/HMac.cs b/iTechSharp/srcbc/crypto/macs/HMac.cs new file mode 100644 index 0000000..e1a5628 --- /dev/null +++ b/iTechSharp/srcbc/crypto/macs/HMac.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * HMAC implementation based on RFC2104 + * + * H(K XOR opad, H(K XOR ipad, text)) + */ + public class HMac : IMac + { + private const byte IPAD = (byte)0x36; + private const byte OPAD = (byte)0x5C; + + private readonly IDigest digest; + private readonly int digestSize; + private readonly int blockLength; + + private byte[] inputPad; + private byte[] outputPad; + + public HMac( + IDigest digest) + { + this.digest = digest; + digestSize = digest.GetDigestSize(); + + blockLength = digest.GetByteLength(); + + inputPad = new byte[blockLength]; + outputPad = new byte[blockLength]; + } + + public string AlgorithmName + { + get { return digest.AlgorithmName + "/HMAC"; } + } + + public IDigest GetUnderlyingDigest() + { + return digest; + } + + public void Init( + ICipherParameters parameters) + { + digest.Reset(); + + byte[] key = ((KeyParameter)parameters).GetKey(); + + if (key.Length > blockLength) + { + digest.BlockUpdate(key, 0, key.Length); + digest.DoFinal(inputPad, 0); + for (int i = digestSize; i < inputPad.Length; i++) + { + inputPad[i] = 0; + } + } + else + { + Array.Copy(key, 0, inputPad, 0, key.Length); + for (int i = key.Length; i < inputPad.Length; i++) + { + inputPad[i] = 0; + } + } + + outputPad = new byte[inputPad.Length]; + Array.Copy(inputPad, 0, outputPad, 0, inputPad.Length); + + for (int i = 0; i < inputPad.Length; i++) + { + inputPad[i] ^= IPAD; + } + + for (int i = 0; i < outputPad.Length; i++) + { + outputPad[i] ^= OPAD; + } + + digest.BlockUpdate(inputPad, 0, inputPad.Length); + } + + public int GetMacSize() + { + return digestSize; + } + + public void Update( + byte input) + { + digest.Update(input); + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + digest.BlockUpdate(input, inOff, len); + } + + public int DoFinal( + byte[] output, + int outOff) + { + byte[] tmp = new byte[digestSize]; + digest.DoFinal(tmp, 0); + + digest.BlockUpdate(outputPad, 0, outputPad.Length); + digest.BlockUpdate(tmp, 0, tmp.Length); + + int len = digest.DoFinal(output, outOff); + + Reset(); + + return len; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + /* + * reset the underlying digest. + */ + digest.Reset(); + + /* + * reinitialize the digest. + */ + digest.BlockUpdate(inputPad, 0, inputPad.Length); + } + } +} diff --git a/iTechSharp/srcbc/crypto/macs/ISO9797Alg3Mac.cs b/iTechSharp/srcbc/crypto/macs/ISO9797Alg3Mac.cs new file mode 100644 index 0000000..40e67b5 --- /dev/null +++ b/iTechSharp/srcbc/crypto/macs/ISO9797Alg3Mac.cs @@ -0,0 +1,259 @@ +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * DES based CBC Block Cipher MAC according to ISO9797, algorithm 3 (ANSI X9.19 Retail MAC) + * + * This could as well be derived from CBCBlockCipherMac, but then the property mac in the base + * class must be changed to protected + */ + public class ISO9797Alg3Mac : IMac + { + private byte[] mac; + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + private KeyParameter lastKey2; + private KeyParameter lastKey3; + + /** + * create a Retail-MAC based on a CBC block cipher. This will produce an + * authentication code of the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. This must + * be DESEngine. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher) + : this(cipher, cipher.GetBlockSize() * 8, null) + { + } + + /** + * create a Retail-MAC based on a CBC block cipher. This will produce an + * authentication code of the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used to complete the last block. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, cipher.GetBlockSize() * 8, padding) + { + } + + /** + * create a Retail-MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses single DES CBC mode as the basis for the + * MAC generation. + *+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *
+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + int macSizeInBits) + : this(cipher, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses single DES CBC mode as the basis for the + * MAC generation. The final block is decrypted and then encrypted using the + * middle and right part of the key. + *+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *
+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding the padding to be used to complete the last block. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + if (!(cipher is DesEngine)) + throw new ArgumentException("cipher must be instance of DesEngine"); + + this.cipher = new CbcBlockCipher(cipher); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + mac = new byte[cipher.GetBlockSize()]; + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return "ISO9797Alg3"; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + if (!(parameters is KeyParameter)) + throw new ArgumentException("parameters must be an instance of KeyParameter"); + + // KeyParameter must contain a double or triple length DES key, + // however the underlying cipher is a single DES. The middle and + // right key are used only in the final step. + + KeyParameter kp = (KeyParameter)parameters; + KeyParameter key1; + byte[] keyvalue = kp.GetKey(); + + if (keyvalue.Length == 16) + { // Double length DES key + key1 = new KeyParameter(keyvalue, 0, 8); + this.lastKey2 = new KeyParameter(keyvalue, 8, 8); + this.lastKey3 = key1; + } + else if (keyvalue.Length == 24) + { // Triple length DES key + key1 = new KeyParameter(keyvalue, 0, 8); + this.lastKey2 = new KeyParameter(keyvalue, 8, 8); + this.lastKey3 = new KeyParameter(keyvalue, 16, 8); + } + else + { + throw new ArgumentException("Key must be either 112 or 168 bit long"); + } + + cipher.Init(true, key1); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + resultLen += cipher.ProcessBlock(input, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + if (padding == null) + { + // pad with zeroes + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + } + else + { + if (bufOff == blockSize) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + padding.AddPadding(buf, bufOff); + } + + cipher.ProcessBlock(buf, 0, mac, 0); + + // Added to code from base class + DesEngine deseng = new DesEngine(); + + deseng.Init(false, this.lastKey2); + deseng.ProcessBlock(mac, 0, mac, 0); + + deseng.Init(true, this.lastKey3); + deseng.ProcessBlock(mac, 0, mac, 0); + // **** + + Array.Copy(mac, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + // reset the underlying cipher. + cipher.Reset(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/macs/VMPCMac.cs b/iTechSharp/srcbc/crypto/macs/VMPCMac.cs new file mode 100644 index 0000000..8991635 --- /dev/null +++ b/iTechSharp/srcbc/crypto/macs/VMPCMac.cs @@ -0,0 +1,173 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + public class VmpcMac + : IMac + { + private byte g; + + private byte n = 0; + private byte[] P = null; + private byte s = 0; + + private byte[] T; + private byte[] workingIV; + + private byte[] workingKey; + + private byte x1, x2, x3, x4; + + public virtual int DoFinal(byte[] output, int outOff) + { + // Execute the Post-Processing Phase + for (int r = 1; r < 25; r++) + { + s = P[(s + P[n & 0xff]) & 0xff]; + + x4 = P[(x4 + x3 + r) & 0xff]; + x3 = P[(x3 + x2 + r) & 0xff]; + x2 = P[(x2 + x1 + r) & 0xff]; + x1 = P[(x1 + s + r) & 0xff]; + T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1); + T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2); + T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3); + T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4); + g = (byte) ((g + 4) & 0x1f); + + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + } + + // Input T to the IV-phase of the VMPC KSA + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + T[m & 0x1f]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + // Store 20 new outputs of the VMPC Stream Cipher input table M + byte[] M = new byte[20]; + for (int i = 0; i < 20; i++) + { + s = P[(s + P[i & 0xff]) & 0xff]; + M[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + + byte temp = P[i & 0xff]; + P[i & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + Array.Copy(M, 0, output, outOff, M.Length); + Reset(); + + return M.Length; + } + + public virtual string AlgorithmName + { + get { return "VMPC-MAC"; } + } + + public virtual int GetMacSize() + { + return 20; + } + + public virtual void Init(ICipherParameters parameters) + { + if (!(parameters is ParametersWithIV)) + throw new ArgumentException("VMPC-MAC Init parameters must include an IV", "parameters"); + + ParametersWithIV ivParams = (ParametersWithIV) parameters; + KeyParameter key = (KeyParameter) ivParams.Parameters; + + if (!(ivParams.Parameters is KeyParameter)) + throw new ArgumentException("VMPC-MAC Init parameters must include a key", "parameters"); + + this.workingIV = ivParams.GetIV(); + + if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768) + throw new ArgumentException("VMPC-MAC requires 1 to 768 bytes of IV", "parameters"); + + this.workingKey = key.GetKey(); + + Reset(); + + } + + private void initKey(byte[] keyBytes, byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + n = 0; + } + + public virtual void Reset() + { + initKey(this.workingKey, this.workingIV); + g = x1 = x2 = x3 = x4 = n = 0; + T = new byte[32]; + for (int i = 0; i < 32; i++) + { + T[i] = 0; + } + } + + public virtual void Update(byte input) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte c = (byte) (input ^ P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]); + + x4 = P[(x4 + x3) & 0xff]; + x3 = P[(x3 + x2) & 0xff]; + x2 = P[(x2 + x1) & 0xff]; + x1 = P[(x1 + s + c) & 0xff]; + T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1); + T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2); + T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3); + T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4); + g = (byte) ((g + 4) & 0x1f); + + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + if ((inOff + len) > input.Length) + throw new DataLengthException("input buffer too short"); + + for (int i = 0; i < len; i++) + { + Update(input[i]); + } + } + } +} diff --git a/iTechSharp/srcbc/crypto/modes/CbcBlockCipher.cs b/iTechSharp/srcbc/crypto/modes/CbcBlockCipher.cs new file mode 100644 index 0000000..c183025 --- /dev/null +++ b/iTechSharp/srcbc/crypto/modes/CbcBlockCipher.cs @@ -0,0 +1,230 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher. + */ + public class CbcBlockCipher + : IBlockCipher + { + private byte[] IV, cbcV, cbcNextV; + private int blockSize; + private IBlockCipher cipher; + private bool encrypting; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of chaining. + */ + public CbcBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + this.blockSize = cipher.GetBlockSize(); + + this.IV = new byte[blockSize]; + this.cbcV = new byte[blockSize]; + this.cbcNextV = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.encrypting = forEncryption; + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length != blockSize) + { + throw new ArgumentException("initialisation vector must be the same length as block size"); + } + + Array.Copy(iv, 0, IV, 0, iv.Length); + + parameters = ivParam.Parameters; + } + + Reset(); + + cipher.Init(encrypting, parameters); + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CBC". + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CBC"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + /** + * return the block size of the underlying cipher. + * + * @return the block size of the underlying cipher. + */ + public int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (encrypting) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, cbcV, 0, IV.Length); + + cipher.Reset(); + } + + /** + * Do the appropriate chaining step for CBC mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + /* + * XOR the cbcV and the input, + * then encrypt the cbcV + */ + for (int i = 0; i < blockSize; i++) + { + cbcV[i] ^= input[inOff + i]; + } + + int length = cipher.ProcessBlock(cbcV, 0, outBytes, outOff); + + /* + * copy ciphertext to cbcV + */ + Array.Copy(outBytes, outOff, cbcV, 0, cbcV.Length); + + return length; + } + + /** + * Do the appropriate chaining step for CBC mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the decrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + Array.Copy(input, inOff, cbcNextV, 0, blockSize); + + int length = cipher.ProcessBlock(input, inOff, outBytes, outOff); + + /* + * XOR the cbcV and the output + */ + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] ^= cbcV[i]; + } + + /* + * swap the back up buffer into next position + */ + byte[] tmp; + + tmp = cbcV; + cbcV = cbcNextV; + cbcNextV = tmp; + + return length; + } + } + +} diff --git a/iTechSharp/srcbc/crypto/modes/CcmBlockCipher.cs b/iTechSharp/srcbc/crypto/modes/CcmBlockCipher.cs new file mode 100644 index 0000000..21b049f --- /dev/null +++ b/iTechSharp/srcbc/crypto/modes/CcmBlockCipher.cs @@ -0,0 +1,345 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements the Counter with Cipher Block Chaining mode (CCM) detailed in + * NIST Special Publication 800-38C. + *+ * Note: this mode is a packet mode - it needs all the data up front. + *
+ */ + public class CcmBlockCipher + : IAeadBlockCipher + { + private static readonly int BlockSize = 16; + + private readonly IBlockCipher cipher; + private readonly byte[] macBlock; + private bool forEncryption; + private byte[] nonce; + private byte[] associatedText; + private int macSize; + private ICipherParameters keyParam; + private readonly MemoryStream data = new MemoryStream(); + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used. + */ + public CcmBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + this.macBlock = new byte[BlockSize]; + + if (cipher.GetBlockSize() != BlockSize) + throw new ArgumentException("cipher required with a block size of " + BlockSize + "."); + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public virtual IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + if (parameters is AeadParameters) + { + AeadParameters param = (AeadParameters) parameters; + + nonce = param.GetNonce(); + associatedText = param.GetAssociatedText(); + macSize = param.MacSize / 8; + keyParam = param.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV) parameters; + + nonce = param.GetIV(); + associatedText = null; + macSize = macBlock.Length / 2; + keyParam = param.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to CCM"); + } + } + + public virtual string AlgorithmName + { + get { return cipher.AlgorithmName + "/CCM"; } + } + + public virtual int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public virtual int ProcessByte( + byte input, + byte[] outBytes, + int outOff) + { + data.WriteByte(input); + + return 0; + } + + public virtual int ProcessBytes( + byte[] inBytes, + int inOff, + int inLen, + byte[] outBytes, + int outOff) + { + data.Write(inBytes, inOff, inLen); + + return 0; + } + + public virtual int DoFinal( + byte[] outBytes, + int outOff) + { + byte[] text = data.ToArray(); + byte[] enc = ProcessPacket(text, 0, text.Length); + + Array.Copy(enc, 0, outBytes, outOff, enc.Length); + + Reset(); + + return enc.Length; + } + + public virtual void Reset() + { + cipher.Reset(); + data.SetLength(0); + } + + /** + * Returns a byte array containing the mac calculated as part of the + * last encrypt or decrypt operation. + * + * @return the last mac calculated. + */ + public virtual byte[] GetMac() + { + byte[] mac = new byte[macSize]; + + Array.Copy(macBlock, 0, mac, 0, mac.Length); + + return mac; + } + + public virtual int GetUpdateOutputSize( + int len) + { + return 0; + } + + public int GetOutputSize( + int len) + { + if (forEncryption) + { + return (int) data.Length + len + macSize; + } + + return (int) data.Length + len - macSize; + } + + public byte[] ProcessPacket( + byte[] input, + int inOff, + int inLen) + { + if (keyParam == null) + throw new InvalidOperationException("CCM cipher unitialized."); + + IBlockCipher ctrCipher = new SicBlockCipher(cipher); + byte[] iv = new byte[BlockSize]; + byte[] output; + + iv[0] = (byte)(((15 - nonce.Length) - 1) & 0x7); + + Array.Copy(nonce, 0, iv, 1, nonce.Length); + + ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv)); + + if (forEncryption) + { + int index = inOff; + int outOff = 0; + + output = new byte[inLen + macSize]; + + calculateMac(input, inOff, inLen, macBlock); + + ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0); // S0 + + while (index < inLen - BlockSize) // S1... + { + ctrCipher.ProcessBlock(input, index, output, outOff); + outOff += BlockSize; + index += BlockSize; + } + + byte[] block = new byte[BlockSize]; + + Array.Copy(input, index, block, 0, inLen - index); + + ctrCipher.ProcessBlock(block, 0, block, 0); + + Array.Copy(block, 0, output, outOff, inLen - index); + + outOff += inLen - index; + + Array.Copy(macBlock, 0, output, outOff, output.Length - outOff); + } + else + { + int index = inOff; + int outOff = 0; + + output = new byte[inLen - macSize]; + + Array.Copy(input, inOff + inLen - macSize, macBlock, 0, macSize); + + ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0); + + for (int i = macSize; i != macBlock.Length; i++) + { + macBlock[i] = 0; + } + + while (outOff < output.Length - BlockSize) + { + ctrCipher.ProcessBlock(input, index, output, outOff); + outOff += BlockSize; + index += BlockSize; + } + + byte[] block = new byte[BlockSize]; + + Array.Copy(input, index, block, 0, output.Length - outOff); + + ctrCipher.ProcessBlock(block, 0, block, 0); + + Array.Copy(block, 0, output, outOff, output.Length - outOff); + + byte[] calculatedMacBlock = new byte[BlockSize]; + + calculateMac(output, 0, output.Length, calculatedMacBlock); + + if (!Arrays.AreEqual(macBlock, calculatedMacBlock)) + throw new InvalidCipherTextException("mac check in CCM failed"); + } + + return output; + } + + private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock) + { + IMac cMac = new CbcBlockCipherMac(cipher, macSize * 8); + + cMac.Init(keyParam); + + // + // build b0 + // + byte[] b0 = new byte[16]; + + if (hasAssociatedText()) + { + b0[0] |= 0x40; + } + + b0[0] |= (byte)((((cMac.GetMacSize() - 2) / 2) & 0x7) << 3); + + b0[0] |= (byte)(((15 - nonce.Length) - 1) & 0x7); + + Array.Copy(nonce, 0, b0, 1, nonce.Length); + + int q = dataLen; + int count = 1; + while (q > 0) + { + b0[b0.Length - count] = (byte)(q & 0xff); + q >>= 8; + count++; + } + + cMac.BlockUpdate(b0, 0, b0.Length); + + // + // process associated text + // + if (hasAssociatedText()) + { + int extra; + + if (associatedText.Length < ((1 << 16) - (1 << 8))) + { + cMac.Update((byte)(associatedText.Length >> 8)); + cMac.Update((byte)associatedText.Length); + + extra = 2; + } + else // can't go any higher than 2^32 + { + cMac.Update((byte)0xff); + cMac.Update((byte)0xfe); + cMac.Update((byte)(associatedText.Length >> 24)); + cMac.Update((byte)(associatedText.Length >> 16)); + cMac.Update((byte)(associatedText.Length >> 8)); + cMac.Update((byte)associatedText.Length); + + extra = 6; + } + + cMac.BlockUpdate(associatedText, 0, associatedText.Length); + + extra = (extra + associatedText.Length) % 16; + if (extra != 0) + { + for (int i = 0; i != 16 - extra; i++) + { + cMac.Update((byte)0x00); + } + } + } + + // + // add the text + // + cMac.BlockUpdate(data, dataOff, dataLen); + + return cMac.DoFinal(macBlock, 0); + } + + private bool hasAssociatedText() + { + return associatedText != null && associatedText.Length != 0; + } + } +} diff --git a/iTechSharp/srcbc/crypto/modes/CfbBlockCipher.cs b/iTechSharp/srcbc/crypto/modes/CfbBlockCipher.cs new file mode 100644 index 0000000..5340bc7 --- /dev/null +++ b/iTechSharp/srcbc/crypto/modes/CfbBlockCipher.cs @@ -0,0 +1,218 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. + */ + public class CfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] cfbV; + private byte[] cfbOutV; + private bool encrypting; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + * @param blockSize the block size in bits (note: a multiple of 8) + */ + public CfbBlockCipher( + IBlockCipher cipher, + int bitBlockSize) + { + this.cipher = cipher; + this.blockSize = bitBlockSize / 8; + this.IV = new byte[cipher.GetBlockSize()]; + this.cfbV = new byte[cipher.GetBlockSize()]; + this.cfbOutV = new byte[cipher.GetBlockSize()]; + } + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.encrypting = forEncryption; + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV) parameters; + byte[] iv = ivParam.GetIV(); + int diff = IV.Length - iv.Length; + Array.Copy(iv, 0, IV, diff, iv.Length); + Array.Clear(IV, 0, diff); + + parameters = ivParam.Parameters; + } + Reset(); + cipher.Init(true, parameters); + } + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CFB" + (blockSize * 8); } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (encrypting) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + /** + * Do the appropriate processing for CFB mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + // + // XOR the cfbV with the plaintext producing the cipher text + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(outBytes, outOff, cfbV, cfbV.Length - blockSize, blockSize); + return blockSize; + } + /** + * Do the appropriate processing for CFB mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(input, inOff, cfbV, cfbV.Length - blockSize, blockSize); + // + // XOR the cfbV with the plaintext producing the plain text + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + return blockSize; + } + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, cfbV, 0, IV.Length); + cipher.Reset(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/modes/CtsBlockCipher.cs b/iTechSharp/srcbc/crypto/modes/CtsBlockCipher.cs new file mode 100644 index 0000000..a32b496 --- /dev/null +++ b/iTechSharp/srcbc/crypto/modes/CtsBlockCipher.cs @@ -0,0 +1,253 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to + * be used to produce cipher text which is the same outLength as the plain text. + */ + public class CtsBlockCipher + : BufferedBlockCipher + { + private readonly int blockSize; + + /** + * Create a buffered block cipher that uses Cipher Text Stealing + * + * @param cipher the underlying block cipher this buffering object wraps. + */ + public CtsBlockCipher( + IBlockCipher cipher) + { + // TODO Should this test for acceptable ones instead? + if (cipher is OfbBlockCipher || cipher is CfbBlockCipher) + throw new ArgumentException("CtsBlockCipher can only accept ECB, or CBC ciphers"); + + this.cipher = cipher; + + blockSize = cipher.GetBlockSize(); + + buf = new byte[blockSize * 2]; + bufOff = 0; + } + + /** + * return the size of the output buffer required for an update of 'length' bytes. + * + * @param length the outLength of the input. + * @return the space required to accommodate a call to update + * with length bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + return total - buf.Length; + } + + return total - leftOver; + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of length bytes. + * + * @param length the outLength of the input. + * @return the space required to accommodate a call to update and doFinal + * with length bytes of input. + */ + public override int GetOutputSize( + int length) + { + return length + bufOff; + } + + /** + * process a single byte, producing an output block if neccessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + int resultLen = 0; + + if (bufOff == buf.Length) + { + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + Debug.Assert(resultLen == blockSize); + + Array.Copy(buf, blockSize, buf, 0, blockSize); + bufOff = blockSize; + } + + buf[bufOff++] = input; + + return resultLen; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param length the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 0) + { + throw new ArgumentException("Can't have a negative input outLength!"); + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + if ((outOff + outLength) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + Array.Copy(buf, blockSize, buf, 0, blockSize); + + bufOff = blockSize; + + length -= gapLen; + inOff += gapLen; + + while (length > blockSize) + { + Array.Copy(input, inOff, buf, bufOff, blockSize); + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + Array.Copy(buf, blockSize, buf, 0, blockSize); + + length -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, length); + + bufOff += length; + + return resultLen; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if cipher text decrypts wrongly (in + * case the exception will never Get thrown). + */ + public override int DoFinal( + byte[] output, + int outOff) + { + if (bufOff + outOff > output.Length) + { + throw new DataLengthException("output buffer too small in doFinal"); + } + + int blockSize = cipher.GetBlockSize(); + int length = bufOff - blockSize; + byte[] block = new byte[blockSize]; + + if (forEncryption) + { + cipher.ProcessBlock(buf, 0, block, 0); + + if (bufOff < blockSize) + { + throw new DataLengthException("need at least one block of input for CTS"); + } + + for (int i = bufOff; i != buf.Length; i++) + { + buf[i] = block[i - blockSize]; + } + + for (int i = blockSize; i != bufOff; i++) + { + buf[i] ^= block[i - blockSize]; + } + + IBlockCipher c = (cipher is CbcBlockCipher) + ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() + : cipher; + + c.ProcessBlock(buf, blockSize, output, outOff); + + Array.Copy(block, 0, output, outOff + blockSize, length); + } + else + { + byte[] lastBlock = new byte[blockSize]; + + IBlockCipher c = (cipher is CbcBlockCipher) + ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() + : cipher; + + c.ProcessBlock(buf, 0, block, 0); + + for (int i = blockSize; i != bufOff; i++) + { + lastBlock[i - blockSize] = (byte)(block[i - blockSize] ^ buf[i]); + } + + Array.Copy(buf, blockSize, block, 0, length); + + cipher.ProcessBlock(block, 0, output, outOff); + Array.Copy(lastBlock, 0, output, outOff + blockSize, length); + } + + int offset = bufOff; + + Reset(); + + return offset; + } + } +} diff --git a/iTechSharp/srcbc/crypto/modes/EAXBlockCipher.cs b/iTechSharp/srcbc/crypto/modes/EAXBlockCipher.cs new file mode 100644 index 0000000..b3016d7 --- /dev/null +++ b/iTechSharp/srcbc/crypto/modes/EAXBlockCipher.cs @@ -0,0 +1,302 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * A Two-Pass Authenticated-Encryption Scheme Optimized for Simplicity and + * Efficiency - by M. Bellare, P. Rogaway, D. Wagner. + * + * http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf + * + * EAX is an AEAD scheme based on CTR and OMAC1/CMAC, that uses a single block + * cipher to encrypt and authenticate data. It's on-line (the length of a + * message isn't needed to begin processing it), has good performances, it's + * simple and provably secure (provided the underlying block cipher is secure). + * + * Of course, this implementations is NOT thread-safe. + */ + public class EaxBlockCipher + : IAeadBlockCipher + { + private enum Tag : byte { N, H, C }; + + private SicBlockCipher cipher; + + private bool forEncryption; + + private int blockSize; + + private IMac mac; + + private byte[] nonceMac; + private byte[] associatedTextMac; + private byte[] macBlock; + + private int macSize; + private byte[] bufBlock; + private int bufOff; + + /** + * Constructor that accepts an instance of a block cipher engine. + * + * @param cipher the engine to use + */ + public EaxBlockCipher( + IBlockCipher cipher) + { + blockSize = cipher.GetBlockSize(); + mac = new CMac(cipher); + macBlock = new byte[blockSize]; + bufBlock = new byte[blockSize * 2]; + associatedTextMac = new byte[mac.GetMacSize()]; + nonceMac = new byte[mac.GetMacSize()]; + this.cipher = new SicBlockCipher(cipher); + } + + public virtual string AlgorithmName + { + get { return cipher.GetUnderlyingCipher().AlgorithmName + "/EAX"; } + } + + public virtual int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + byte[] nonce, associatedText; + ICipherParameters keyParam; + + if (parameters is AeadParameters) + { + AeadParameters param = (AeadParameters) parameters; + + nonce = param.GetNonce(); + associatedText = param.GetAssociatedText(); + macSize = param.MacSize / 8; + keyParam = param.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV) parameters; + + nonce = param.GetIV(); + associatedText = new byte[0]; + macSize = mac.GetMacSize() / 2; + keyParam = param.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to EAX"); + } + + byte[] tag = new byte[blockSize]; + + mac.Init(keyParam); + tag[blockSize - 1] = (byte) Tag.H; + mac.BlockUpdate(tag, 0, blockSize); + mac.BlockUpdate(associatedText, 0, associatedText.Length); + mac.DoFinal(associatedTextMac, 0); + + tag[blockSize - 1] = (byte) Tag.N; + mac.BlockUpdate(tag, 0, blockSize); + mac.BlockUpdate(nonce, 0, nonce.Length); + mac.DoFinal(nonceMac, 0); + + tag[blockSize - 1] = (byte) Tag.C; + mac.BlockUpdate(tag, 0, blockSize); + + cipher.Init(true, new ParametersWithIV(keyParam, nonceMac)); + } + + private void calculateMac() + { + byte[] outC = new byte[blockSize]; + mac.DoFinal(outC, 0); + + for (int i = 0; i < macBlock.Length; i++) + { + macBlock[i] = (byte)(nonceMac[i] ^ associatedTextMac[i] ^ outC[i]); + } + } + + public virtual void Reset() + { + Reset(true); + } + + private void Reset( + bool clearMac) + { + cipher.Reset(); + mac.Reset(); + + bufOff = 0; + Array.Clear(bufBlock, 0, bufBlock.Length); + + if (clearMac) + { + Array.Clear(macBlock, 0, macBlock.Length); + } + + byte[] tag = new byte[blockSize]; + tag[blockSize - 1] = (byte) Tag.C; + mac.BlockUpdate(tag, 0, blockSize); + } + + public virtual int ProcessByte( + byte input, + byte[] outBytes, + int outOff) + { + return process(input, outBytes, outOff); + } + + public virtual int ProcessBytes( + byte[] inBytes, + int inOff, + int len, + byte[] outBytes, + int outOff) + { + int resultLen = 0; + + for (int i = 0; i != len; i++) + { + resultLen += process(inBytes[inOff + i], outBytes, outOff + resultLen); + } + + return resultLen; + } + + public virtual int DoFinal( + byte[] outBytes, + int outOff) + { + int extra = bufOff; + byte[] tmp = new byte[bufBlock.Length]; + + bufOff = 0; + + if (forEncryption) + { + cipher.ProcessBlock(bufBlock, 0, tmp, 0); + cipher.ProcessBlock(bufBlock, blockSize, tmp, blockSize); + + Array.Copy(tmp, 0, outBytes, outOff, extra); + + mac.BlockUpdate(tmp, 0, extra); + + calculateMac(); + + Array.Copy(macBlock, 0, outBytes, outOff + extra, macSize); + + Reset(false); + + return extra + macSize; + } + else + { + if (extra > macSize) + { + mac.BlockUpdate(bufBlock, 0, extra - macSize); + + cipher.ProcessBlock(bufBlock, 0, tmp, 0); + cipher.ProcessBlock(bufBlock, blockSize, tmp, blockSize); + + Array.Copy(tmp, 0, outBytes, outOff, extra - macSize); + } + + calculateMac(); + + if (!verifyMac(bufBlock, extra - macSize)) + throw new InvalidCipherTextException("mac check in EAX failed"); + + Reset(false); + + return extra - macSize; + } + } + + public virtual byte[] GetMac() + { + byte[] mac = new byte[macSize]; + + Array.Copy(macBlock, 0, mac, 0, macSize); + + return mac; + } + + public virtual int GetUpdateOutputSize( + int len) + { + return ((len + bufOff) / blockSize) * blockSize; + } + + public virtual int GetOutputSize( + int len) + { + if (forEncryption) + { + return len + bufOff + macSize; + } + + return len + bufOff - macSize; + } + + private int process( + byte b, + byte[] outBytes, + int outOff) + { + bufBlock[bufOff++] = b; + + if (bufOff == bufBlock.Length) + { + int size; + + if (forEncryption) + { + size = cipher.ProcessBlock(bufBlock, 0, outBytes, outOff); + + mac.BlockUpdate(outBytes, outOff, blockSize); + } + else + { + mac.BlockUpdate(bufBlock, 0, blockSize); + + size = cipher.ProcessBlock(bufBlock, 0, outBytes, outOff); + } + + bufOff = blockSize; + Array.Copy(bufBlock, blockSize, bufBlock, 0, blockSize); + + return size; + } + + return 0; + } + + private bool verifyMac(byte[] mac, int off) + { + for (int i = 0; i < macSize; i++) + { + if (macBlock[i] != mac[off + i]) + { + return false; + } + } + + return true; + } + } +} diff --git a/iTechSharp/srcbc/crypto/modes/GCMBlockCipher.cs b/iTechSharp/srcbc/crypto/modes/GCMBlockCipher.cs new file mode 100644 index 0000000..98c0543 --- /dev/null +++ b/iTechSharp/srcbc/crypto/modes/GCMBlockCipher.cs @@ -0,0 +1,447 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + ///+ * For further info see RFC 2440. + *
+ */ + public class OpenPgpCfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] FR; + private byte[] FRE; + private byte[] tmp; + + private readonly IBlockCipher cipher; + private readonly int blockSize; + + private int count; + private bool forEncryption; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + */ + public OpenPgpCfbBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + + this.blockSize = cipher.GetBlockSize(); + this.IV = new byte[blockSize]; + this.FR = new byte[blockSize]; + this.FRE = new byte[blockSize]; + this.tmp = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/PGPCFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/OpenPGPCFB"; } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) ? EncryptBlock(input, inOff, output, outOff) : DecryptBlock(input, inOff, output, outOff); + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + count = 0; + + Array.Copy(IV, 0, FR, 0, FR.Length); + + cipher.Reset(); + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param parameters the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + for (int i = 0; i < IV.Length - iv.Length; i++) + { + IV[i] = 0; + } + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + cipher.Init(true, parameters); + } + + /** + * Encrypt one byte of data according to CFB mode. + * @param data the byte to encrypt + * @param blockOff offset in the current block + * @returns the encrypted byte + */ + private byte EncryptByte(byte data, int blockOff) + { + return (byte)(FRE[blockOff] ^ data); + } + + /** + * Do the appropriate processing for CFB IV mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (count > blockSize) + { + FR[blockSize - 2] = outBytes[outOff] = EncryptByte(input[inOff], blockSize - 2); + FR[blockSize - 1] = outBytes[outOff + 1] = EncryptByte(input[inOff + 1], blockSize - 1); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2); + } + + Array.Copy(outBytes, outOff + 2, FR, 0, blockSize - 2); + } + else if (count == 0) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 0; n < blockSize; n++) + { + outBytes[outOff + n] = EncryptByte(input[inOff + n], n); + } + + Array.Copy(outBytes, outOff, FR, 0, blockSize); + + count += blockSize; + } + else if (count == blockSize) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + outBytes[outOff] = EncryptByte(input[inOff], 0); + outBytes[outOff + 1] = EncryptByte(input[inOff + 1], 1); + + // + // do reset + // + Array.Copy(FR, 2, FR, 0, blockSize - 2); + Array.Copy(outBytes, outOff, FR, blockSize - 2, 2); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2); + } + + Array.Copy(outBytes, outOff + 2, FR, 0, blockSize - 2); + + count += blockSize; + } + + return blockSize; + } + + /** + * Do the appropriate processing for CFB IV mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (count > blockSize) + { + // copy in buffer so that this mode works if in and out are the same + Array.Copy(input, inOff, tmp, 0, blockSize); + + outBytes[outOff] = EncryptByte(tmp[0], blockSize - 2); + outBytes[outOff + 1] = EncryptByte(tmp[1], blockSize - 1); + + Array.Copy(tmp, 0, FR, blockSize - 2, 2); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + outBytes[outOff + n] = EncryptByte(tmp[n], n - 2); + } + + Array.Copy(tmp, 2, FR, 0, blockSize - 2); + } + else if (count == 0) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 0; n < blockSize; n++) + { + FR[n] = input[inOff + n]; + outBytes[n] = EncryptByte(input[inOff + n], n); + } + + count += blockSize; + } + else if (count == blockSize) + { + Array.Copy(input, inOff, tmp, 0, blockSize); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + outBytes[outOff] = EncryptByte(tmp[0], 0); + outBytes[outOff + 1] = EncryptByte(tmp[1], 1); + + Array.Copy(FR, 2, FR, 0, blockSize - 2); + + FR[blockSize - 2] = tmp[0]; + FR[blockSize - 1] = tmp[1]; + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + FR[n - 2] = input[inOff + n]; + outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2); + } + + count += blockSize; + } + + return blockSize; + } + } +} diff --git a/iTechSharp/srcbc/crypto/modes/SicBlockCipher.cs b/iTechSharp/srcbc/crypto/modes/SicBlockCipher.cs new file mode 100644 index 0000000..fe7fb10 --- /dev/null +++ b/iTechSharp/srcbc/crypto/modes/SicBlockCipher.cs @@ -0,0 +1,106 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements the Segmented Integer Counter (SIC) mode on top of a simple + * block cipher. + */ + public class SicBlockCipher + : IBlockCipher + { + private readonly IBlockCipher cipher; + private readonly int blockSize; + private readonly byte[] IV; + private readonly byte[] counter; + private readonly byte[] counterOut; + + /** + * Basic constructor. + * + * @param c the block cipher to be used. + */ + public SicBlockCipher(IBlockCipher cipher) + { + this.cipher = cipher; + this.blockSize = cipher.GetBlockSize(); + this.IV = new byte[blockSize]; + this.counter = new byte[blockSize]; + this.counterOut = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public void Init( + bool forEncryption, //ignored by this CTR mode + ICipherParameters parameters) + { + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV) parameters; + byte[] iv = ivParam.GetIV(); + Array.Copy(iv, 0, IV, 0, IV.Length); + + Reset(); + cipher.Init(true, ivParam.Parameters); + } + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/SIC"; } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + public int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + cipher.ProcessBlock(counter, 0, counterOut, 0); + + // + // XOR the counterOut with the plaintext producing the cipher text + // + for (int i = 0; i < counterOut.Length; i++) + { + output[outOff + i] = (byte)(counterOut[i] ^ input[inOff + i]); + } + + // Increment the counter + int j = counter.Length; + while (--j >= 0 && ++counter[j] == 0) + { + } + + return counter.Length; + } + + public void Reset() + { + Array.Copy(IV, 0, counter, 0, counter.Length); + cipher.Reset(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/paddings/BlockCipherPadding.cs b/iTechSharp/srcbc/crypto/paddings/BlockCipherPadding.cs new file mode 100644 index 0000000..33a5f9f --- /dev/null +++ b/iTechSharp/srcbc/crypto/paddings/BlockCipherPadding.cs @@ -0,0 +1,43 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * Block cipher padders are expected to conform to this interface + */ + public interface IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param param parameters, if any required. + */ + void Init(SecureRandom random); + //throws ArgumentException; + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + string PaddingName { get; } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + int AddPadding(byte[] input, int inOff); + + /** + * return the number of pad bytes present in the block. + * @exception InvalidCipherTextException if the padding is badly formed + * or invalid. + */ + int PadCount(byte[] input); + //throws InvalidCipherTextException; + } + +} diff --git a/iTechSharp/srcbc/crypto/paddings/ISO10126d2Padding.cs b/iTechSharp/srcbc/crypto/paddings/ISO10126d2Padding.cs new file mode 100644 index 0000000..e132a62 --- /dev/null +++ b/iTechSharp/srcbc/crypto/paddings/ISO10126d2Padding.cs @@ -0,0 +1,76 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + + +namespace Org.BouncyCastle.Crypto.Paddings +{ + + /** + * A padder that adds ISO10126-2 padding to a block. + */ + public class ISO10126d2Padding: IBlockCipherPadding + { + private SecureRandom random; + + /** + * Initialise the padder. + * + * @param random a SecureRandom if available. + */ + public void Init( + SecureRandom random) + //throws ArgumentException + { + this.random = (random != null) ? random : new SecureRandom(); + } + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public string PaddingName + { + get { return "ISO10126-2"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + byte code = (byte)(input.Length - inOff); + + while (inOff < (input.Length - 1)) + { + input[inOff] = (byte)random.NextInt(); + inOff++; + } + + input[inOff] = code; + + return code; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount(byte[] input) + //throws InvalidCipherTextException + { + int count = input[input.Length - 1] & 0xff; + + if (count > input.Length) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + return count; + } + } + +} diff --git a/iTechSharp/srcbc/crypto/paddings/ISO7816d4Padding.cs b/iTechSharp/srcbc/crypto/paddings/ISO7816d4Padding.cs new file mode 100644 index 0000000..016b25a --- /dev/null +++ b/iTechSharp/srcbc/crypto/paddings/ISO7816d4Padding.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A padder that adds the padding according to the scheme referenced in + * ISO 7814-4 - scheme 2 from ISO 9797-1. The first byte is 0x80, rest is 0x00 + */ + public class ISO7816d4Padding + : IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param random - a SecureRandom if available. + */ + public void Init( + SecureRandom random) + { + // nothing to do. + } + + /** + * Return the name of the algorithm the padder implements. + * + * @return the name of the algorithm the padder implements. + */ + public string PaddingName + { + get { return "ISO7816-4"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + int added = (input.Length - inOff); + + input[inOff]= (byte) 0x80; + inOff ++; + + while (inOff < input.Length) + { + input[inOff] = (byte) 0; + inOff++; + } + + return added; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount( + byte[] input) + { + int count = input.Length - 1; + + while (count > 0 && input[count] == 0) + { + count--; + } + + if (input[count] != (byte)0x80) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + return input.Length - count; + } + } +} diff --git a/iTechSharp/srcbc/crypto/paddings/PaddedBufferedBlockCipher.cs b/iTechSharp/srcbc/crypto/paddings/PaddedBufferedBlockCipher.cs new file mode 100644 index 0000000..dd5cba8 --- /dev/null +++ b/iTechSharp/srcbc/crypto/paddings/PaddedBufferedBlockCipher.cs @@ -0,0 +1,287 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A wrapper class that allows block ciphers to be used to process data in + * a piecemeal fashion with padding. The PaddedBufferedBlockCipher + * outputs a block only when the buffer is full and more data is being added, + * or on a doFinal (unless the current block in the buffer is a pad block). + * The default padding mechanism used is the one outlined in Pkcs5/Pkcs7. + */ + public class PaddedBufferedBlockCipher + : BufferedBlockCipher + { + private readonly IBlockCipherPadding padding; + + /** + * Create a buffered block cipher with the desired padding. + * + * @param cipher the underlying block cipher this buffering object wraps. + * @param padding the padding type. + */ + public PaddedBufferedBlockCipher( + IBlockCipher cipher, + IBlockCipherPadding padding) + { + this.cipher = cipher; + this.padding = padding; + + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + /** + * Create a buffered block cipher Pkcs7 padding + * + * @param cipher the underlying block cipher this buffering object wraps. + */ + public PaddedBufferedBlockCipher(IBlockCipher cipher) + : this(cipher, new Pkcs7Padding()) { } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + SecureRandom initRandom = null; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom)parameters; + initRandom = p.Random; + parameters = p.Parameters; + } + + Reset(); + padding.Init(initRandom); + cipher.Init(forEncryption, parameters); + } + + /** + * return the minimum size of the output buffer required for an update + * plus a doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + if (forEncryption) + { + return total + buf.Length; + } + + return total; + } + + return total - leftOver + buf.Length; + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + return total - buf.Length; + } + + return total - leftOver; + } + + /** + * process a single byte, producing an output block if neccessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + int resultLen = 0; + + if (bufOff == buf.Length) + { + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + } + + buf[bufOff++] = input; + + return resultLen; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 0) + { + throw new ArgumentException("Can't have a negative input length!"); + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + if ((outOff + outLength) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + + bufOff = 0; + length -= gapLen; + inOff += gapLen; + + while (length > buf.Length) + { + resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); + + length -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, length); + + bufOff += length; + + return resultLen; + } + + /** + * Process the last block in the buffer. If the buffer is currently + * full and padding needs to be added a call to doFinal will produce + * 2 * GetBlockSize() bytes. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output or we are decrypting and the input is not block size aligned. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + + if (forEncryption) + { + if (bufOff == blockSize) + { + if ((outOff + 2 * blockSize) > output.Length) + { + Reset(); + + throw new DataLengthException("output buffer too short"); + } + + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + } + + padding.AddPadding(buf, bufOff); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + + Reset(); + } + else + { + if (bufOff == blockSize) + { + resultLen = cipher.ProcessBlock(buf, 0, buf, 0); + bufOff = 0; + } + else + { + Reset(); + + throw new DataLengthException("last block incomplete in decryption"); + } + + try + { + resultLen -= padding.PadCount(buf); + + Array.Copy(buf, 0, output, outOff, resultLen); + } + finally + { + Reset(); + } + } + + return resultLen; + } + } + +} diff --git a/iTechSharp/srcbc/crypto/paddings/Pkcs7Padding.cs b/iTechSharp/srcbc/crypto/paddings/Pkcs7Padding.cs new file mode 100644 index 0000000..e873940 --- /dev/null +++ b/iTechSharp/srcbc/crypto/paddings/Pkcs7Padding.cs @@ -0,0 +1,77 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A padder that adds Pkcs7/Pkcs5 padding to a block. + */ + public class Pkcs7Padding: IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param random - a SecureRandom if available. + */ + public void Init(SecureRandom random) + { + // nothing to do. + } + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public string PaddingName + { + get { return "PKCS7"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + byte code = (byte)(input.Length - inOff); + + while (inOff < input.Length) + { + input[inOff] = code; + inOff++; + } + + return code; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount( + byte[] input) + { + int count = (int) input[input.Length - 1]; + + if (count < 1 || count > input.Length) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + for (int i = 1; i <= count; i++) + { + if (input[input.Length - i] != count) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + } + + return count; + } + } + +} diff --git a/iTechSharp/srcbc/crypto/paddings/TbcPadding.cs b/iTechSharp/srcbc/crypto/paddings/TbcPadding.cs new file mode 100644 index 0000000..74b64e8 --- /dev/null +++ b/iTechSharp/srcbc/crypto/paddings/TbcPadding.cs @@ -0,0 +1,79 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + + ///+ /// This padding pads the block out compliment of the last bit + /// of the plain text. + ///
+ ///+ /// Note: this assumes that the last block of plain text is always + /// passed to it inside in. i.e. if inOff is zero, indicating the + /// entire block is to be overwritten with padding the value of in + /// should be the same as the last block of plain text. + ///
+ ///+ * See "Applied + * Cryptography" by Bruce Schneier for more information. + *
+ * @return true if the given DES key material is weak or semi-weak, + * false otherwise. + */ + public static bool IsWeakKey( + byte[] key, + int offset) + { + if (key.Length - offset < DesKeyLength) + throw new ArgumentException("key material too short."); + + //nextkey: + for (int i = 0; i < N_DES_WEAK_KEYS; i++) + { + bool unmatch = false; + for (int j = 0; j < DesKeyLength; j++) + { + if (key[j + offset] != DES_weak_keys[i * DesKeyLength + j]) + { + //continue nextkey; + unmatch = true; + break; + } + } + + if (!unmatch) + { + return true; + } + } + + return false; + } + + public static bool IsWeakKey( + byte[] key) + { + return IsWeakKey(key, 0); + } + + /** + * DES Keys use the LSB as the odd parity bit. This can + * be used to check for corrupt keys. + * + * @param bytes the byte array to set the parity on. + */ + public static void SetOddParity( + byte[] bytes) + { + for (int i = 0; i < bytes.Length; i++) + { + int b = bytes[i]; + bytes[i] = (byte)((b & 0xfe) | + ((((b >> 1) ^ + (b >> 2) ^ + (b >> 3) ^ + (b >> 4) ^ + (b >> 5) ^ + (b >> 6) ^ + (b >> 7)) ^ 0x01) & 0x01)); + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/parameters/DsaKeyGenerationParameters.cs b/iTechSharp/srcbc/crypto/parameters/DsaKeyGenerationParameters.cs new file mode 100644 index 0000000..86d6f5b --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/DsaKeyGenerationParameters.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaKeyGenerationParameters + : KeyGenerationParameters + { + private readonly DsaParameters parameters; + + public DsaKeyGenerationParameters( + SecureRandom random, + DsaParameters parameters) + : base(random, parameters.P.BitLength - 1) + { + this.parameters = parameters; + } + + public DsaParameters Parameters + { + get { return parameters; } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/parameters/DsaKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/DsaKeyParameters.cs new file mode 100644 index 0000000..a51cbfb --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/DsaKeyParameters.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaKeyParameters + : AsymmetricKeyParameter + { + private readonly DsaParameters parameters; + + public DsaKeyParameters( + bool isPrivate, + DsaParameters parameters) + : base(isPrivate) + { + // Note: parameters may be null + this.parameters = parameters; + } + + public DsaParameters Parameters + { + get { return parameters; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaKeyParameters other = obj as DsaKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaKeyParameters other) + { + return Platform.Equals(parameters, other.parameters) + && base.Equals(other); + } + + public override int GetHashCode() + { + int hc = base.GetHashCode(); + + if (parameters != null) + { + hc ^= parameters.GetHashCode(); + } + + return hc; + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/DsaParameters.cs b/iTechSharp/srcbc/crypto/parameters/DsaParameters.cs new file mode 100644 index 0000000..50d080e --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/DsaParameters.cs @@ -0,0 +1,85 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaParameters + : ICipherParameters + { + private readonly BigInteger p, q , g; + private readonly DsaValidationParameters validation; + + public DsaParameters( + BigInteger p, + BigInteger q, + BigInteger g) + : this(p, q, g, null) + { + } + + public DsaParameters( + BigInteger p, + BigInteger q, + BigInteger g, + DsaValidationParameters parameters) + { + if (p == null) + throw new ArgumentNullException("p"); + if (q == null) + throw new ArgumentNullException("q"); + if (g == null) + throw new ArgumentNullException("g"); + + this.p = p; + this.q = q; + this.g = g; + this.validation = parameters; + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger G + { + get { return g; } + } + + public DsaValidationParameters ValidationParameters + { + get { return validation; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaParameters other = obj as DsaParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaParameters other) + { + return p.Equals(other.p) && q.Equals(other.q) && g.Equals(other.g); + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ q.GetHashCode() ^ g.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/DsaPrivateKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/DsaPrivateKeyParameters.cs new file mode 100644 index 0000000..2abdd0e --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/DsaPrivateKeyParameters.cs @@ -0,0 +1,53 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaPrivateKeyParameters + : DsaKeyParameters + { + private readonly BigInteger x; + + public DsaPrivateKeyParameters( + BigInteger x, + DsaParameters parameters) + : base(true, parameters) + { + if (x == null) + throw new ArgumentNullException("x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaPrivateKeyParameters other = obj as DsaPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaPrivateKeyParameters other) + { + return x.Equals(other.x) && base.Equals(other); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/DsaPublicKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/DsaPublicKeyParameters.cs new file mode 100644 index 0000000..f11f858 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/DsaPublicKeyParameters.cs @@ -0,0 +1,52 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaPublicKeyParameters + : DsaKeyParameters + { + private readonly BigInteger y; + + public DsaPublicKeyParameters( + BigInteger y, + DsaParameters parameters) + : base(false, parameters) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + DsaPublicKeyParameters other = obj as DsaPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaPublicKeyParameters other) + { + return y.Equals(other.y) && base.Equals(other); + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/DsaValidationParameters.cs b/iTechSharp/srcbc/crypto/parameters/DsaValidationParameters.cs new file mode 100644 index 0000000..b9cdc4a --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/DsaValidationParameters.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaValidationParameters + { + private readonly byte[] seed; + private readonly int counter; + + public DsaValidationParameters( + byte[] seed, + int counter) + { + if (seed == null) + throw new ArgumentNullException("seed"); + + this.seed = (byte[]) seed.Clone(); + this.counter = counter; + } + + public byte[] GetSeed() + { + return (byte[]) seed.Clone(); + } + + public int Counter + { + get { return counter; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaValidationParameters other = obj as DsaValidationParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaValidationParameters other) + { + return counter == other.counter + && Arrays.AreEqual(seed, other.seed); + } + + public override int GetHashCode() + { + return counter.GetHashCode() ^ Arrays.GetHashCode(seed); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ECDomainParameters.cs b/iTechSharp/srcbc/crypto/parameters/ECDomainParameters.cs new file mode 100644 index 0000000..c6a3e4e --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ECDomainParameters.cs @@ -0,0 +1,116 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECDomainParameters + { + internal ECCurve curve; + internal byte[] seed; + internal ECPoint g; + internal BigInteger n; + internal BigInteger h; + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n) + : this(curve, g, n, BigInteger.One) + { + } + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + { + if (curve == null) + throw new ArgumentNullException("curve"); + if (g == null) + throw new ArgumentNullException("g"); + if (n == null) + throw new ArgumentNullException("n"); + if (h == null) + throw new ArgumentNullException("h"); + + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + this.seed = Arrays.Clone(seed); + } + + public ECCurve Curve + { + get { return curve; } + } + + public ECPoint G + { + get { return g; } + } + + public BigInteger N + { + get { return n; } + } + + public BigInteger H + { + get { return h; } + } + + public byte[] GetSeed() + { + return Arrays.Clone(seed); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECDomainParameters other = obj as ECDomainParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECDomainParameters other) + { + return curve.Equals(other.curve) + && g.Equals(other.g) + && n.Equals(other.n) + && h.Equals(other.h) + && Arrays.AreEqual(seed, other.seed); + } + + public override int GetHashCode() + { + return curve.GetHashCode() + ^ g.GetHashCode() + ^ n.GetHashCode() + ^ h.GetHashCode() + ^ Arrays.GetHashCode(seed); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/parameters/ECKeyGenerationParameters.cs b/iTechSharp/srcbc/crypto/parameters/ECKeyGenerationParameters.cs new file mode 100644 index 0000000..4bed302 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ECKeyGenerationParameters.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECKeyGenerationParameters + : KeyGenerationParameters + { + private readonly ECDomainParameters domainParams; + private readonly DerObjectIdentifier publicKeyParamSet; + + public ECKeyGenerationParameters( + ECDomainParameters domainParameters, + SecureRandom random) + : base(random, domainParameters.N.BitLength) + { + this.domainParams = domainParameters; + } + + public ECKeyGenerationParameters( + DerObjectIdentifier publicKeyParamSet, + SecureRandom random) + : this(LookupParameters(publicKeyParamSet), random) + { + this.publicKeyParamSet = publicKeyParamSet; + } + + public ECDomainParameters DomainParameters + { + get { return domainParams; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + private static ECDomainParameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + ECDomainParameters p = ECGost3410NamedCurves.GetByOid(publicKeyParamSet); + + if (p == null) + throw new ArgumentException("OID is not a valid CryptoPro public key parameter set", "publicKeyParamSet"); + + return p; + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ECKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/ECKeyParameters.cs new file mode 100644 index 0000000..6c848c1 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ECKeyParameters.cs @@ -0,0 +1,121 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public abstract class ECKeyParameters + : AsymmetricKeyParameter + { + private readonly string algorithm; + private readonly ECDomainParameters parameters; + private readonly DerObjectIdentifier publicKeyParamSet; + + protected ECKeyParameters( + string algorithm, + bool isPrivate, + ECDomainParameters parameters) + : base(isPrivate) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (parameters == null) + throw new ArgumentNullException("parameters"); + + this.algorithm = VerifyAlgorithmName(algorithm); + this.parameters = parameters; + } + + protected ECKeyParameters( + string algorithm, + bool isPrivate, + DerObjectIdentifier publicKeyParamSet) + : base(isPrivate) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + this.algorithm = VerifyAlgorithmName(algorithm); + this.parameters = LookupParameters(publicKeyParamSet); + this.publicKeyParamSet = publicKeyParamSet; + } + + public string AlgorithmName + { + get { return algorithm; } + } + + public ECDomainParameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECDomainParameters other = obj as ECDomainParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECKeyParameters other) + { + return parameters.Equals(other.parameters) && base.Equals(other); + } + + public override int GetHashCode() + { + return parameters.GetHashCode() ^ base.GetHashCode(); + } + + private string VerifyAlgorithmName( + string algorithm) + { + string upper = algorithm.ToUpper(CultureInfo.InvariantCulture); + + switch (upper) + { + case "EC": + case "ECDSA": + case "ECGOST3410": + case "ECDH": + case "ECDHC": + break; + default: + throw new ArgumentException("unrecognised algorithm: " + algorithm, "algorithm"); + } + + return upper; + } + + private static ECDomainParameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + ECDomainParameters p = ECGost3410NamedCurves.GetByOid(publicKeyParamSet); + + if (p == null) + throw new ArgumentException("OID is not a valid CryptoPro public key parameter set", "publicKeyParamSet"); + + return p; + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ECPrivateKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/ECPrivateKeyParameters.cs new file mode 100644 index 0000000..f003fb6 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ECPrivateKeyParameters.cs @@ -0,0 +1,74 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECPrivateKeyParameters + : ECKeyParameters + { + private readonly BigInteger d; + + public ECPrivateKeyParameters( + BigInteger d, + ECDomainParameters parameters) + : this("EC", d, parameters) + { + } + + public ECPrivateKeyParameters( + BigInteger d, + DerObjectIdentifier publicKeyParamSet) + : base("ECGOST3410", true, publicKeyParamSet) + { + if (d == null) + throw new ArgumentNullException("d"); + + this.d = d; + } + + public ECPrivateKeyParameters( + string algorithm, + BigInteger d, + ECDomainParameters parameters) + : base(algorithm, true, parameters) + { + if (d == null) + throw new ArgumentNullException("d"); + + this.d = d; + } + + public BigInteger D + { + get { return d; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECPrivateKeyParameters other = obj as ECPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECPrivateKeyParameters other) + { + return d.Equals(other.d) && base.Equals(other); + } + + public override int GetHashCode() + { + return d.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ECPublicKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/ECPublicKeyParameters.cs new file mode 100644 index 0000000..39919c1 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ECPublicKeyParameters.cs @@ -0,0 +1,73 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECPublicKeyParameters + : ECKeyParameters + { + private readonly ECPoint q; + + public ECPublicKeyParameters( + ECPoint q, + ECDomainParameters parameters) + : this("EC", q, parameters) + { + } + + public ECPublicKeyParameters( + ECPoint q, + DerObjectIdentifier publicKeyParamSet) + : base("ECGOST3410", false, publicKeyParamSet) + { + if (q == null) + throw new ArgumentNullException("q"); + + this.q = q; + } + + public ECPublicKeyParameters( + string algorithm, + ECPoint q, + ECDomainParameters parameters) + : base(algorithm, false, parameters) + { + if (q == null) + throw new ArgumentNullException("q"); + + this.q = q; + } + + public ECPoint Q + { + get { return q; } + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + ECPublicKeyParameters other = obj as ECPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECPublicKeyParameters other) + { + return q.Equals(other.q) && base.Equals(other); + } + + public override int GetHashCode() + { + return q.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ElGamalKeyGenerationParameters.cs b/iTechSharp/srcbc/crypto/parameters/ElGamalKeyGenerationParameters.cs new file mode 100644 index 0000000..3454362 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ElGamalKeyGenerationParameters.cs @@ -0,0 +1,25 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalKeyGenerationParameters + : KeyGenerationParameters + { + private readonly ElGamalParameters parameters; + + public ElGamalKeyGenerationParameters( + SecureRandom random, + ElGamalParameters parameters) + : base(random, parameters.P.BitLength) + { + this.parameters = parameters; + } + + public ElGamalParameters Parameters + { + get { return parameters; } + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ElGamalKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/ElGamalKeyParameters.cs new file mode 100644 index 0000000..8b6e279 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ElGamalKeyParameters.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalKeyParameters + : AsymmetricKeyParameter + { + private readonly ElGamalParameters parameters; + + protected ElGamalKeyParameters( + bool isPrivate, + ElGamalParameters parameters) + : base(isPrivate) + { + // TODO Should we allow 'parameters' to be null? + this.parameters = parameters; + } + + public ElGamalParameters Parameters + { + get { return parameters; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalKeyParameters other = obj as ElGamalKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalKeyParameters other) + { + return Platform.Equals(parameters, other.parameters) + && base.Equals(other); + } + + public override int GetHashCode() + { + int hc = base.GetHashCode(); + + if (parameters != null) + { + hc ^= parameters.GetHashCode(); + } + + return hc; + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ElGamalParameters.cs b/iTechSharp/srcbc/crypto/parameters/ElGamalParameters.cs new file mode 100644 index 0000000..ab6d3e7 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ElGamalParameters.cs @@ -0,0 +1,81 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalParameters + : ICipherParameters + { + private readonly BigInteger p, g; + private readonly int l; + + public ElGamalParameters( + BigInteger p, + BigInteger g) + : this(p, g, 0) + { + } + + public ElGamalParameters( + BigInteger p, + BigInteger g, + int l) + { + if (p == null) + throw new ArgumentNullException("p"); + if (g == null) + throw new ArgumentNullException("g"); + + this.p = p; + this.g = g; + this.l = l; + } + + public BigInteger P + { + get { return p; } + } + + /** + * return the generator - g + */ + public BigInteger G + { + get { return g; } + } + + /** + * return private value limit - l + */ + public int L + { + get { return l; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalParameters other = obj as ElGamalParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalParameters other) + { + return p.Equals(other.p) && g.Equals(other.g) && l == other.l; + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ g.GetHashCode() ^ l; + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ElGamalPrivateKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/ElGamalPrivateKeyParameters.cs new file mode 100644 index 0000000..6363f2b --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ElGamalPrivateKeyParameters.cs @@ -0,0 +1,53 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalPrivateKeyParameters + : ElGamalKeyParameters + { + private readonly BigInteger x; + + public ElGamalPrivateKeyParameters( + BigInteger x, + ElGamalParameters parameters) + : base(true, parameters) + { + if (x == null) + throw new ArgumentNullException("x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalPrivateKeyParameters other = obj as ElGamalPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalPrivateKeyParameters other) + { + return other.x.Equals(x) && base.Equals(other); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ElGamalPublicKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/ElGamalPublicKeyParameters.cs new file mode 100644 index 0000000..25ac625 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ElGamalPublicKeyParameters.cs @@ -0,0 +1,53 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalPublicKeyParameters + : ElGamalKeyParameters + { + private readonly BigInteger y; + + public ElGamalPublicKeyParameters( + BigInteger y, + ElGamalParameters parameters) + : base(false, parameters) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalPublicKeyParameters other = obj as ElGamalPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalPublicKeyParameters other) + { + return y.Equals(other.y) && base.Equals(other); + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/GOST3410KeyGenerationParameters.cs b/iTechSharp/srcbc/crypto/parameters/GOST3410KeyGenerationParameters.cs new file mode 100644 index 0000000..b06a5d8 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/GOST3410KeyGenerationParameters.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410KeyGenerationParameters + : KeyGenerationParameters + { + private readonly Gost3410Parameters parameters; + private readonly DerObjectIdentifier publicKeyParamSet; + + public Gost3410KeyGenerationParameters( + SecureRandom random, + Gost3410Parameters parameters) + : base(random, parameters.P.BitLength - 1) + { + this.parameters = parameters; + } + + public Gost3410KeyGenerationParameters( + SecureRandom random, + DerObjectIdentifier publicKeyParamSet) + : this(random, LookupParameters(publicKeyParamSet)) + { + this.publicKeyParamSet = publicKeyParamSet; + } + + public Gost3410Parameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + private static Gost3410Parameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + Gost3410ParamSetParameters p = Gost3410NamedParameters.GetByOid(publicKeyParamSet); + + if (p == null) + throw new ArgumentException("OID is not a valid CryptoPro public key parameter set", "publicKeyParamSet"); + + return new Gost3410Parameters(p.P, p.Q, p.A); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/GOST3410KeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/GOST3410KeyParameters.cs new file mode 100644 index 0000000..f771c4d --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/GOST3410KeyParameters.cs @@ -0,0 +1,58 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public abstract class Gost3410KeyParameters + : AsymmetricKeyParameter + { + private readonly Gost3410Parameters parameters; + private readonly DerObjectIdentifier publicKeyParamSet; + + protected Gost3410KeyParameters( + bool isPrivate, + Gost3410Parameters parameters) + : base(isPrivate) + { + this.parameters = parameters; + } + + protected Gost3410KeyParameters( + bool isPrivate, + DerObjectIdentifier publicKeyParamSet) + : base(isPrivate) + { + this.parameters = LookupParameters(publicKeyParamSet); + this.publicKeyParamSet = publicKeyParamSet; + } + + public Gost3410Parameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + // TODO Implement Equals/GetHashCode + + private static Gost3410Parameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + Gost3410ParamSetParameters p = Gost3410NamedParameters.GetByOid(publicKeyParamSet); + + if (p == null) + throw new ArgumentException("OID is not a valid CryptoPro public key parameter set", "publicKeyParamSet"); + + return new Gost3410Parameters(p.P, p.Q, p.A); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/GOST3410Parameters.cs b/iTechSharp/srcbc/crypto/parameters/GOST3410Parameters.cs new file mode 100644 index 0000000..2ec167e --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/GOST3410Parameters.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410Parameters + : ICipherParameters + { + private readonly BigInteger p, q, a; + private readonly Gost3410ValidationParameters validation; + + public Gost3410Parameters( + BigInteger p, + BigInteger q, + BigInteger a) + : this(p, q, a, null) + { + } + + public Gost3410Parameters( + BigInteger p, + BigInteger q, + BigInteger a, + Gost3410ValidationParameters validation) + { + if (p == null) + throw new ArgumentNullException("p"); + if (q == null) + throw new ArgumentNullException("q"); + if (a == null) + throw new ArgumentNullException("a"); + + this.p = p; + this.q = q; + this.a = a; + this.validation = validation; + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger A + { + get { return a; } + } + + public Gost3410ValidationParameters ValidationParameters + { + get { return validation; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + Gost3410Parameters other = obj as Gost3410Parameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + Gost3410Parameters other) + { + return p.Equals(other.p) && q.Equals(other.q) && a.Equals(other.a); + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ q.GetHashCode() ^ a.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/GOST3410PrivateKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/GOST3410PrivateKeyParameters.cs new file mode 100644 index 0000000..e3a613d --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/GOST3410PrivateKeyParameters.cs @@ -0,0 +1,41 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410PrivateKeyParameters + : Gost3410KeyParameters + { + private readonly BigInteger x; + + public Gost3410PrivateKeyParameters( + BigInteger x, + Gost3410Parameters parameters) + : base(true, parameters) + { + if (x.SignValue < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0) + throw new ArgumentException("Invalid x for GOST3410 private key", "x"); + + this.x = x; + } + + public Gost3410PrivateKeyParameters( + BigInteger x, + DerObjectIdentifier publicKeyParamSet) + : base(true, publicKeyParamSet) + { + if (x.SignValue < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0) + throw new ArgumentException("Invalid x for GOST3410 private key", "x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/GOST3410PublicKeyParameters.cs b/iTechSharp/srcbc/crypto/parameters/GOST3410PublicKeyParameters.cs new file mode 100644 index 0000000..96b7e91 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/GOST3410PublicKeyParameters.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410PublicKeyParameters + : Gost3410KeyParameters + { + private readonly BigInteger y; + + public Gost3410PublicKeyParameters( + BigInteger y, + Gost3410Parameters parameters) + : base(false, parameters) + { + if (y.SignValue < 1 || y.CompareTo(Parameters.P) >= 0) + throw new ArgumentException("Invalid y for GOST3410 public key", "y"); + + this.y = y; + } + + public Gost3410PublicKeyParameters( + BigInteger y, + DerObjectIdentifier publicKeyParamSet) + : base(false, publicKeyParamSet) + { + if (y.SignValue < 1 || y.CompareTo(Parameters.P) >= 0) + throw new ArgumentException("Invalid y for GOST3410 public key", "y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/GOST3410ValidationParameters.cs b/iTechSharp/srcbc/crypto/parameters/GOST3410ValidationParameters.cs new file mode 100644 index 0000000..21e5af8 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/GOST3410ValidationParameters.cs @@ -0,0 +1,51 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410ValidationParameters + { + private int x0; + private int c; + private long x0L; + private long cL; + + public Gost3410ValidationParameters( + int x0, + int c) + { + this.x0 = x0; + this.c = c; + } + + public Gost3410ValidationParameters( + long x0L, + long cL) + { + this.x0L = x0L; + this.cL = cL; + } + + public int C { get { return c; } } + public int X0 { get { return x0; } } + public long CL { get { return cL; } } + public long X0L { get { return x0L; } } + + public override bool Equals( + object obj) + { + Gost3410ValidationParameters other = obj as Gost3410ValidationParameters; + + return other != null + && other.c == this.c + && other.x0 == this.x0 + && other.cL == this.cL + && other.x0L == this.x0L; + } + + public override int GetHashCode() + { + return c.GetHashCode() ^ x0.GetHashCode() ^ cL.GetHashCode() ^ x0L.GetHashCode(); + } + + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/ISO18033KDFParameters.cs b/iTechSharp/srcbc/crypto/parameters/ISO18033KDFParameters.cs new file mode 100644 index 0000000..2d8fff8 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/ISO18033KDFParameters.cs @@ -0,0 +1,25 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for Key derivation functions for ISO-18033 + */ + public class Iso18033KdfParameters + : IDerivationParameters + { + byte[] seed; + + public Iso18033KdfParameters( + byte[] seed) + { + this.seed = seed; + } + + public byte[] GetSeed() + { + return seed; + } + } +} diff --git a/iTechSharp/srcbc/crypto/parameters/IesParameters.cs b/iTechSharp/srcbc/crypto/parameters/IesParameters.cs new file mode 100644 index 0000000..d306b2c --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/IesParameters.cs @@ -0,0 +1,49 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for using an integrated cipher in stream mode. + */ + public class IesParameters : ICipherParameters + { + private byte[] derivation; + private byte[] encoding; + private int macKeySize; + + /** + * @param derivation the derivation parameter for the KDF function. + * @param encoding the encoding parameter for the KDF function. + * @param macKeySize the size of the MAC key (in bits). + */ + public IesParameters( + byte[] derivation, + byte[] encoding, + int macKeySize) + { + this.derivation = derivation; + this.encoding = encoding; + this.macKeySize = macKeySize; + } + + public byte[] GetDerivationV() + { + return derivation; + } + + public byte[] GetEncodingV() + { + return encoding; + } + + public int MacKeySize + { + get + { + return macKeySize; + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/parameters/IesWithCipherParameters.cs b/iTechSharp/srcbc/crypto/parameters/IesWithCipherParameters.cs new file mode 100644 index 0000000..70ef55d --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/IesWithCipherParameters.cs @@ -0,0 +1,33 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class IesWithCipherParameters : IesParameters + { + private int cipherKeySize; + + /** + * @param derivation the derivation parameter for the KDF function. + * @param encoding the encoding parameter for the KDF function. + * @param macKeySize the size of the MAC key (in bits). + * @param cipherKeySize the size of the associated Cipher key (in bits). + */ + public IesWithCipherParameters( + byte[] derivation, + byte[] encoding, + int macKeySize, + int cipherKeySize) : base(derivation, encoding, macKeySize) + { + this.cipherKeySize = cipherKeySize; + } + + public int CipherKeySize + { + get + { + return cipherKeySize; + } + } + } + +} diff --git a/iTechSharp/srcbc/crypto/parameters/KdfParameters.cs b/iTechSharp/srcbc/crypto/parameters/KdfParameters.cs new file mode 100644 index 0000000..bc5c905 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/KdfParameters.cs @@ -0,0 +1,33 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for Key derivation functions for IEEE P1363a + */ + public class KdfParameters : IDerivationParameters + { + byte[] iv; + byte[] shared; + + public KdfParameters( + byte[] shared, + byte[] iv) + { + this.shared = shared; + this.iv = iv; + } + + public byte[] GetSharedSecret() + { + return shared; + } + + public byte[] GetIV() + { + return iv; + } + } + +} diff --git a/iTechSharp/srcbc/crypto/parameters/KeyParameter.cs b/iTechSharp/srcbc/crypto/parameters/KeyParameter.cs new file mode 100644 index 0000000..33dff96 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/KeyParameter.cs @@ -0,0 +1,43 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KeyParameter + : ICipherParameters + { + private readonly byte[] key; + + public KeyParameter( + byte[] key) + { + if (key == null) + throw new ArgumentNullException("key"); + + this.key = (byte[]) key.Clone(); + } + + public KeyParameter( + byte[] key, + int keyOff, + int keyLen) + { + if (key == null) + throw new ArgumentNullException("key"); + if (keyOff < 0 || keyOff > key.Length) + throw new ArgumentOutOfRangeException("keyOff"); + if (keyLen < 0 || (keyOff + keyLen) > key.Length) + throw new ArgumentOutOfRangeException("keyLen"); + + this.key = new byte[keyLen]; + Array.Copy(key, keyOff, this.key, 0, keyLen); + } + + public byte[] GetKey() + { + return (byte[]) key.Clone(); + } + } + +} diff --git a/iTechSharp/srcbc/crypto/parameters/MgfParameters.cs b/iTechSharp/srcbc/crypto/parameters/MgfParameters.cs new file mode 100644 index 0000000..11983b8 --- /dev/null +++ b/iTechSharp/srcbc/crypto/parameters/MgfParameters.cs @@ -0,0 +1,31 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + ///+ * Internal access to the digest is syncrhonized so a single one of these can be shared. + *
+ */ + public class DigestRandomGenerator + : IRandomGenerator + { + private long counter; + private IDigest digest; + private byte[] state; + + public DigestRandomGenerator( + IDigest digest) + { + this.digest = digest; + this.state = new byte[digest.GetDigestSize()]; + this.counter = 1; + } + + public void AddSeedMaterial( + byte[] inSeed) + { + lock (this) + { + DigestUpdate(inSeed); + } + } + + public void AddSeedMaterial( + long rSeed) + { + lock (this) + { + for (int i = 0; i != 8; i++) + { + DigestUpdate((byte)rSeed); +// rSeed >>>= 8; + rSeed >>= 8; + } + } + } + + public void NextBytes( + byte[] bytes) + { + NextBytes(bytes, 0, bytes.Length); + } + + public void NextBytes( + byte[] bytes, + int start, + int len) + { + lock (this) + { + int stateOff = 0; + + DigestDoFinal(state); + + int end = start + len; + for (int i = start; i < end; ++i) + { + if (stateOff == state.Length) + { + DigestUpdate(counter++); + DigestUpdate(state); + DigestDoFinal(state); + stateOff = 0; + } + bytes[i] = state[stateOff++]; + } + + DigestUpdate(counter++); + DigestUpdate(state); + } + } + + private void DigestUpdate(long seed) + { + for (int i = 0; i != 8; i++) + { + digest.Update((byte)seed); +// seed >>>= 8; + seed >>= 8; + } + } + + private void DigestUpdate(byte[] inSeed) + { + digest.BlockUpdate(inSeed, 0, inSeed.Length); + } + + private void DigestDoFinal(byte[] result) + { + digest.DoFinal(result, 0); + } + } +} diff --git a/iTechSharp/srcbc/crypto/prng/IRandomGenerator.cs b/iTechSharp/srcbc/crypto/prng/IRandomGenerator.cs new file mode 100644 index 0000000..8dbe406 --- /dev/null +++ b/iTechSharp/srcbc/crypto/prng/IRandomGenerator.cs @@ -0,0 +1,26 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Prng +{ + ///+ /// Access to internals is synchronized so a single one of these can be shared. + ///
+ ///+ * Based on an idea from Marcus Lippert. + *
+ */ + public class ThreadedSeedGenerator + { + private class SeedGenerator + { +#if NETCF_1_0 + // No volatile keyword, but all fields implicitly volatile anyway + private int counter = 0; + private bool stop = false; +#else + private volatile int counter = 0; + private volatile bool stop = false; +#endif + + private void Run(object ignored) + { + while (!this.stop) + { + this.counter++; + } + } + + public byte[] GenerateSeed( + int numBytes, + bool fast) + { + this.counter = 0; + this.stop = false; + + byte[] result = new byte[numBytes]; + int last = 0; + int end = fast ? numBytes : numBytes * 8; + + ThreadPool.QueueUserWorkItem(new WaitCallback(Run)); + + for (int i = 0; i < end; i++) + { + while (this.counter == last) + { + try + { + Thread.Sleep(1); + } + catch (Exception) + { + // ignore + } + } + + last = this.counter; + + if (fast) + { + result[i] = (byte) last; + } + else + { + int bytepos = i / 8; + result[bytepos] = (byte) ((result[bytepos] << 1) | (last & 1)); + } + } + + this.stop = true; + + return result; + } + } + + /** + * Generate seed bytes. Set fast to false for best quality. + *+ * If fast is set to true, the code should be round about 8 times faster when + * generating a long sequence of random bytes. 20 bytes of random values using + * the fast mode take less than half a second on a Nokia e70. If fast is set to false, + * it takes round about 2500 ms. + *
+ * @param numBytes the number of bytes to generate + * @param fast true if fast mode should be used + */ + public byte[] GenerateSeed( + int numBytes, + bool fast) + { + return new SeedGenerator().GenerateSeed(numBytes, fast); + } + } +} diff --git a/iTechSharp/srcbc/crypto/prng/VMPCRandomGenerator.cs b/iTechSharp/srcbc/crypto/prng/VMPCRandomGenerator.cs new file mode 100644 index 0000000..2ab0799 --- /dev/null +++ b/iTechSharp/srcbc/crypto/prng/VMPCRandomGenerator.cs @@ -0,0 +1,115 @@ +namespace Org.BouncyCastle.Crypto.Prng +{ + public class VmpcRandomGenerator + : IRandomGenerator + { + private byte n = 0; + + ///
+ /// // First 1850 fractional digit of Pi number.
+ /// byte[] key = new BigInteger("14159265358979323846...5068006422512520511").ToByteArray();
+ /// s = 0;
+ /// P = new byte[256];
+ /// for (int i = 0; i < 256; i++)
+ /// {
+ /// P[i] = (byte) i;
+ /// }
+ /// for (int m = 0; m < 768; m++)
+ /// {
+ /// s = P[(s + P[m & 0xff] + key[m % key.length]) & 0xff];
+ /// byte temp = P[m & 0xff];
+ /// P[m & 0xff] = P[s & 0xff];
+ /// P[s & 0xff] = temp;
+ /// }
+ /// + /// Note: the usual length for the salt is the length of the hash + /// function used in bytes.
+ ///+ /// Note: the usual value for the salt length is the number of + /// bytes in the hash function.
+ ///+ /// DO NOT USE THIS FILE UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING. + ///+ ///
+ /// This file could be more optimized. + ///
+ ///From Knuth Vol 2, pg 395.
+ */ + public bool IsProbablePrime( + int certainty) + { + if (certainty <= 0) + return true; + + BigInteger n = Abs(); + + if (!n.TestBit(0)) + return n.Equals(Two); + + if (n.Equals(One)) + return false; + + return n.CheckProbablePrime(certainty, RandomSource); + } + + private bool CheckProbablePrime( + int certainty, + Random random) + { + Debug.Assert(certainty > 0); + Debug.Assert(CompareTo(Two) > 0); + Debug.Assert(TestBit(0)); + + + // Try to reduce the penalty for really small numbers + int numLists = System.Math.Min(BitLength - 1, primeLists.Length); + + for (int i = 0; i < numLists; ++i) + { + int test = Remainder(primeProducts[i]); + + int[] primeList = primeLists[i]; + for (int j = 0; j < primeList.Length; ++j) + { + int prime = primeList[j]; + int qRem = test % prime; + if (qRem == 0) + { + // We may find small numbers in the list + return BitLength < 16 && IntValue == prime; + } + } + } + + + // TODO Special case for < 10^16 (RabinMiller fixed list) +// if (BitLength < 30) +// { +// RabinMiller against 2, 3, 5, 7, 11, 13, 23 is sufficient +// } + + + // TODO Is it worth trying to create a hybrid of these two? + return RabinMillerTest(certainty, random); +// return SolovayStrassenTest(certainty, random); + +// bool rbTest = RabinMillerTest(certainty, random); +// bool ssTest = SolovayStrassenTest(certainty, random); +// +// Debug.Assert(rbTest == ssTest); +// +// return rbTest; + } + + internal bool RabinMillerTest( + int certainty, + Random random) + { + Debug.Assert(certainty > 0); + Debug.Assert(BitLength > 2); + Debug.Assert(TestBit(0)); + + // let n = 1 + d . 2^s + BigInteger n = this; + BigInteger nMinusOne = n.Subtract(One); + int s = nMinusOne.GetLowestSetBit(); + BigInteger r = nMinusOne.ShiftRight(s); + + Debug.Assert(s >= 1); + + do + { + // TODO Make a method for random BigIntegers in range 0 < x < n) + // - Method can be optimized by only replacing examined bits at each trial + BigInteger a; + do + { + a = new BigInteger(n.BitLength, random); + } + while (a.CompareTo(One) <= 0 || a.CompareTo(nMinusOne) >= 0); + + BigInteger y = a.ModPow(r, n); + + if (!y.Equals(One)) + { + int j = 0; + while (!y.Equals(nMinusOne)) + { + if (++j == s) + return false; + + y = y.ModPow(Two, n); + + if (y.Equals(One)) + return false; + } + } + + certainty -= 2; // composites pass for only 1/4 possible 'a' + } + while (certainty > 0); + + return true; + } + +// private bool SolovayStrassenTest( +// int certainty, +// Random random) +// { +// Debug.Assert(certainty > 0); +// Debug.Assert(CompareTo(Two) > 0); +// Debug.Assert(TestBit(0)); +// +// BigInteger n = this; +// BigInteger nMinusOne = n.Subtract(One); +// BigInteger e = nMinusOne.ShiftRight(1); +// +// do +// { +// BigInteger a; +// do +// { +// a = new BigInteger(nBitLength, random); +// } +// // NB: Spec says 0 < x < n, but 1 is trivial +// while (a.CompareTo(One) <= 0 || a.CompareTo(n) >= 0); +// +// +// // TODO Check this is redundant given the way Jacobi() works? +//// if (!a.Gcd(n).Equals(One)) +//// return false; +// +// int x = Jacobi(a, n); +// +// if (x == 0) +// return false; +// +// BigInteger check = a.ModPow(e, n); +// +// if (x == 1 && !check.Equals(One)) +// return false; +// +// if (x == -1 && !check.Equals(nMinusOne)) +// return false; +// +// --certainty; +// } +// while (certainty > 0); +// +// return true; +// } +// +// private static int Jacobi( +// BigInteger a, +// BigInteger b) +// { +// Debug.Assert(a.sign >= 0); +// Debug.Assert(b.sign > 0); +// Debug.Assert(b.TestBit(0)); +// Debug.Assert(a.CompareTo(b) < 0); +// +// int totalS = 1; +// for (;;) +// { +// if (a.sign == 0) +// return 0; +// +// if (a.Equals(One)) +// break; +// +// int e = a.GetLowestSetBit(); +// +// int bLsw = b.magnitude[b.magnitude.Length - 1]; +// if ((e & 1) != 0 && ((bLsw & 7) == 3 || (bLsw & 7) == 5)) +// totalS = -totalS; +// +// // TODO Confirm this is faster than later a1.Equals(One) test +// if (a.BitLength == e + 1) +// break; +// BigInteger a1 = a.ShiftRight(e); +//// if (a1.Equals(One)) +//// break; +// +// int a1Lsw = a1.magnitude[a1.magnitude.Length - 1]; +// if ((bLsw & 3) == 3 && (a1Lsw & 3) == 3) +// totalS = -totalS; +// +//// a = b.Mod(a1); +// a = b.Remainder(a1); +// b = a1; +// } +// return totalS; +// } + + public long LongValue + { + get + { + if (sign == 0) + return 0; + + long v; + if (magnitude.Length > 1) + { + v = ((long)magnitude[magnitude.Length - 2] << 32) + | (magnitude[magnitude.Length - 1] & IMASK); + } + else + { + v = (magnitude[magnitude.Length - 1] & IMASK); + } + + return sign < 0 ? -v : v; + } + } + + public BigInteger Max( + BigInteger value) + { + return CompareTo(value) > 0 ? this : value; + } + + public BigInteger Min( + BigInteger value) + { + return CompareTo(value) < 0 ? this : value; + } + + public BigInteger Mod( + BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + BigInteger biggie = Remainder(m); + + return (biggie.sign >= 0 ? biggie : biggie.Add(m)); + } + + public BigInteger ModInverse( + BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + // TODO Too slow at the moment +// // "Fast Key Exchange with Elliptic Curve Systems" R.Schoeppel +// if (m.TestBit(0)) +// { +// //The Almost Inverse Algorithm +// int k = 0; +// BigInteger B = One, C = Zero, F = this, G = m, tmp; +// +// for (;;) +// { +// // While F is even, do F=F/u, C=C*u, k=k+1. +// int zeroes = F.GetLowestSetBit(); +// if (zeroes > 0) +// { +// F = F.ShiftRight(zeroes); +// C = C.ShiftLeft(zeroes); +// k += zeroes; +// } +// +// // If F = 1, then return B,k. +// if (F.Equals(One)) +// { +// BigInteger half = m.Add(One).ShiftRight(1); +// BigInteger halfK = half.ModPow(BigInteger.ValueOf(k), m); +// return B.Multiply(halfK).Mod(m); +// } +// +// if (F.CompareTo(G) < 0) +// { +// tmp = G; G = F; F = tmp; +// tmp = B; B = C; C = tmp; +// } +// +// F = F.Add(G); +// B = B.Add(C); +// } +// } + + BigInteger x = new BigInteger(); + BigInteger gcd = ExtEuclid(this.Mod(m), m, x, null); + + if (!gcd.Equals(One)) + throw new ArithmeticException("Numbers not relatively prime."); + + if (x.sign < 0) + { + x.sign = 1; + //x = m.Subtract(x); + x.magnitude = doSubBigLil(m.magnitude, x.magnitude); + } + + return x; + } + + /** + * Calculate the numbers u1, u2, and u3 such that: + * + * u1 * a + u2 * b = u3 + * + * where u3 is the greatest common divider of a and b. + * a and b using the extended Euclid algorithm (refer p. 323 + * of The Art of Computer Programming vol 2, 2nd ed). + * This also seems to have the side effect of calculating + * some form of multiplicative inverse. + * + * @param a First number to calculate gcd for + * @param b Second number to calculate gcd for + * @param u1Out the return object for the u1 value + * @param u2Out the return object for the u2 value + * @return The greatest common divisor of a and b + */ + private static BigInteger ExtEuclid( + BigInteger a, + BigInteger b, + BigInteger u1Out, + BigInteger u2Out) + { + BigInteger u1 = One; + BigInteger u3 = a; + BigInteger v1 = Zero; + BigInteger v3 = b; + + while (v3.sign > 0) + { + BigInteger[] q = u3.DivideAndRemainder(v3); + + BigInteger tmp = v1.Multiply(q[0]); + BigInteger tn = u1.Subtract(tmp); + u1 = v1; + v1 = tn; + + u3 = v3; + v3 = q[1]; + } + + if (u1Out != null) + { + u1Out.sign = u1.sign; + u1Out.magnitude = u1.magnitude; + } + + if (u2Out != null) + { + BigInteger tmp = u1.Multiply(a); + tmp = u3.Subtract(tmp); + BigInteger res = tmp.Divide(b); + u2Out.sign = res.sign; + u2Out.magnitude = res.magnitude; + } + + return u3; + } + + private static void ZeroOut( + int[] x) + { + Array.Clear(x, 0, x.Length); + } + + public BigInteger ModPow( + BigInteger exponent, + BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + if (m.Equals(One)) + return Zero; + + if (exponent.sign == 0) + return One; + + if (sign == 0) + return Zero; + + int[] zVal = null; + int[] yAccum = null; + int[] yVal; + + // Montgomery exponentiation is only possible if the modulus is odd, + // but AFAIK, this is always the case for crypto algo's + bool useMonty = ((m.magnitude[m.magnitude.Length - 1] & 1) == 1); + long mQ = 0; + if (useMonty) + { + mQ = m.GetMQuote(); + + // tmp = this * R mod m + BigInteger tmp = ShiftLeft(32 * m.magnitude.Length).Mod(m); + zVal = tmp.magnitude; + + useMonty = (zVal.Length <= m.magnitude.Length); + + if (useMonty) + { + yAccum = new int[m.magnitude.Length + 1]; + if (zVal.Length < m.magnitude.Length) + { + int[] longZ = new int[m.magnitude.Length]; + zVal.CopyTo(longZ, longZ.Length - zVal.Length); + zVal = longZ; + } + } + } + + if (!useMonty) + { + if (magnitude.Length <= m.magnitude.Length) + { + //zAccum = new int[m.magnitude.Length * 2]; + zVal = new int[m.magnitude.Length]; + magnitude.CopyTo(zVal, zVal.Length - magnitude.Length); + } + else + { + // + // in normal practice we'll never see this... + // + BigInteger tmp = Remainder(m); + + //zAccum = new int[m.magnitude.Length * 2]; + zVal = new int[m.magnitude.Length]; + tmp.magnitude.CopyTo(zVal, zVal.Length - tmp.magnitude.Length); + } + + yAccum = new int[m.magnitude.Length * 2]; + } + + yVal = new int[m.magnitude.Length]; + + // + // from LSW to MSW + // + for (int i = 0; i < exponent.magnitude.Length; i++) + { + int v = exponent.magnitude[i]; + int bits = 0; + + if (i == 0) + { + while (v > 0) + { + v <<= 1; + bits++; + } + + // + // first time in initialise y + // + zVal.CopyTo(yVal, 0); + + v <<= 1; + bits++; + } + + while (v != 0) + { + if (useMonty) + { + // Montgomery square algo doesn't exist, and a normal + // square followed by a Montgomery reduction proved to + // be almost as heavy as a Montgomery mulitply. + MultiplyMonty(yAccum, yVal, yVal, m.magnitude, mQ); + } + else + { + Square(yAccum, yVal); + Remainder(yAccum, m.magnitude); + Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length); + ZeroOut(yAccum); + } + bits++; + + if (v < 0) + { + if (useMonty) + { + MultiplyMonty(yAccum, yVal, zVal, m.magnitude, mQ); + } + else + { + Multiply(yAccum, yVal, zVal); + Remainder(yAccum, m.magnitude); + Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, + yVal.Length); + ZeroOut(yAccum); + } + } + + v <<= 1; + } + + while (bits < 32) + { + if (useMonty) + { + MultiplyMonty(yAccum, yVal, yVal, m.magnitude, mQ); + } + else + { + Square(yAccum, yVal); + Remainder(yAccum, m.magnitude); + Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length); + ZeroOut(yAccum); + } + bits++; + } + } + + if (useMonty) + { + // Return y * R^(-1) mod m by doing y * 1 * R^(-1) mod m + ZeroOut(zVal); + zVal[zVal.Length - 1] = 1; + MultiplyMonty(yAccum, yVal, zVal, m.magnitude, mQ); + } + + BigInteger result = new BigInteger(1, yVal, true); + + return exponent.sign > 0 + ? result + : result.ModInverse(m); + } + + /** + * return w with w = x * x - w is assumed to have enough space. + */ + private static int[] Square( + int[] w, + int[] x) + { + // Note: this method allows w to be only (2 * x.Length - 1) words if result will fit +// if (w.Length != 2 * x.Length) +// throw new ArgumentException("no I don't think so..."); + + ulong u1, u2, c; + + int wBase = w.Length - 1; + + for (int i = x.Length - 1; i != 0; i--) + { + ulong v = (ulong)(uint) x[i]; + + u1 = v * v; + u2 = u1 >> 32; + u1 = (uint) u1; + + u1 += (ulong)(uint) w[wBase]; + + w[wBase] = (int)(uint) u1; + c = u2 + (u1 >> 32); + + for (int j = i - 1; j >= 0; j--) + { + --wBase; + u1 = v * (ulong)(uint) x[j]; + u2 = u1 >> 31; // multiply by 2! + u1 = (uint)(u1 << 1); // multiply by 2! + u1 += c + (ulong)(uint) w[wBase]; + + w[wBase] = (int)(uint) u1; + c = u2 + (u1 >> 32); + } + + c += (ulong)(uint) w[--wBase]; + w[wBase] = (int)(uint) c; + + if (--wBase >= 0) + { + w[wBase] = (int)(uint)(c >> 32); + } + else + { + Debug.Assert((uint)(c >> 32) == 0); + } + wBase += i; + } + + u1 = (ulong)(uint) x[0]; + u1 = u1 * u1; + u2 = u1 >> 32; + u1 = u1 & IMASK; + + u1 += (ulong)(uint) w[wBase]; + + w[wBase] = (int)(uint) u1; + if (--wBase >= 0) + { + w[wBase] = (int)(uint)(u2 + (u1 >> 32) + (ulong)(uint) w[wBase]); + } + else + { + Debug.Assert((uint)(u2 + (u1 >> 32)) == 0); + } + + return w; + } + + /** + * return x with x = y * z - x is assumed to have enough space. + */ + private static int[] Multiply( + int[] x, + int[] y, + int[] z) + { + int i = z.Length; + + if (i < 1) + return x; + + int xBase = x.Length - y.Length; + + for (;;) + { + long a = z[--i] & IMASK; + long val = 0; + + for (int j = y.Length - 1; j >= 0; j--) + { + val += a * (y[j] & IMASK) + (x[xBase + j] & IMASK); + + x[xBase + j] = (int)val; + + val = (long)((ulong)val >> 32); + } + + --xBase; + + if (i < 1) + { + if (xBase >= 0) + { + x[xBase] = (int)val; + } + else + { + Debug.Assert(val == 0); + } + break; + } + + x[xBase] = (int)val; + } + + return x; + } + + private static long FastExtEuclid( + long a, + long b, + long[] uOut) + { + long u1 = 1; + long u3 = a; + long v1 = 0; + long v3 = b; + + while (v3 > 0) + { + long q, tn; + + q = u3 / v3; + + tn = u1 - (v1 * q); + u1 = v1; + v1 = tn; + + tn = u3 - (v3 * q); + u3 = v3; + v3 = tn; + } + + uOut[0] = u1; + uOut[1] = (u3 - (u1 * a)) / b; + + return u3; + } + + private static long FastModInverse( + long v, + long m) + { + if (m < 1) + throw new ArithmeticException("Modulus must be positive"); + + long[] x = new long[2]; + long gcd = FastExtEuclid(v, m, x); + + if (gcd != 1) + throw new ArithmeticException("Numbers not relatively prime."); + + if (x[0] < 0) + { + x[0] += m; + } + + return x[0]; + } + +// private static BigInteger MQuoteB = One.ShiftLeft(32); +// private static BigInteger MQuoteBSub1 = MQuoteB.Subtract(One); + + /** + * Calculate mQuote = -m^(-1) mod b with b = 2^32 (32 = word size) + */ + private long GetMQuote() + { + Debug.Assert(this.sign > 0); + + if (mQuote != -1) + { + return mQuote; // already calculated + } + + if (magnitude.Length == 0 || (magnitude[magnitude.Length - 1] & 1) == 0) + { + return -1; // not for even numbers + } + + long v = (((~this.magnitude[this.magnitude.Length - 1]) | 1) & 0xffffffffL); + mQuote = FastModInverse(v, 0x100000000L); + + return mQuote; + } + + /** + * Montgomery multiplication: a = x * y * R^(-1) mod m + *Fp
(X9.62 s 4.2.1 pg 17).
+ * @return The decoded point.
+ */
+ public override ECPoint DecodePoint(
+ byte[] encoded)
+ {
+ ECPoint p = null;
+ int expectedLength = (FieldSize + 7) / 8;
+
+ switch (encoded[0])
+ {
+ case 0x00: // infinity
+ {
+ if (encoded.Length != 1)
+ throw new ArgumentException("Incorrect length for infinity encoding", "encoded");
+
+ p = Infinity;
+ break;
+ }
+
+ case 0x02: // compressed
+ case 0x03: // compressed
+ {
+ if (encoded.Length != (expectedLength + 1))
+ throw new ArgumentException("Incorrect length for compressed encoding", "encoded");
+
+ int yTilde = encoded[0] & 1;
+ BigInteger X1 = new BigInteger(1, encoded, 1, encoded.Length - 1);
+
+ p = DecompressPoint(yTilde, X1);
+ break;
+ }
+
+ case 0x04: // uncompressed
+ case 0x06: // hybrid
+ case 0x07: // hybrid
+ {
+ if (encoded.Length != (2 * expectedLength + 1))
+ throw new ArgumentException("Incorrect length for uncompressed/hybrid encoding", "encoded");
+
+ BigInteger X1 = new BigInteger(1, encoded, 1, expectedLength);
+ BigInteger Y1 = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);
+
+ p = CreatePoint(X1, Y1, false);
+ break;
+ }
+
+ default:
+ throw new FormatException("Invalid point encoding " + encoded[0]);
+ }
+
+ return p;
+ }
+ }
+
+ /**
+ * Elliptic curve over Fp
+ */
+ public class FpCurve : ECCurveBase
+ {
+ private readonly BigInteger q;
+ private readonly FpPoint infinity;
+
+ public FpCurve(BigInteger q, BigInteger a, BigInteger b)
+ {
+ this.q = q;
+ this.a = FromBigInteger(a);
+ this.b = FromBigInteger(b);
+ this.infinity = new FpPoint(this, null, null);
+ }
+
+ public BigInteger Q
+ {
+ get { return q; }
+ }
+
+ public override ECPoint Infinity
+ {
+ get { return infinity; }
+ }
+
+ public override int FieldSize
+ {
+ get { return q.BitLength; }
+ }
+
+ public override ECFieldElement FromBigInteger(BigInteger x)
+ {
+ return new FpFieldElement(this.q, x);
+ }
+
+ public override ECPoint CreatePoint(
+ BigInteger X1,
+ BigInteger Y1,
+ bool withCompression)
+ {
+ // TODO Validation of X1, Y1?
+ return new FpPoint(
+ this,
+ FromBigInteger(X1),
+ FromBigInteger(Y1),
+ withCompression);
+ }
+
+ protected internal override ECPoint DecompressPoint(
+ int yTilde,
+ BigInteger X1)
+ {
+ ECFieldElement x = FromBigInteger(X1);
+ ECFieldElement alpha = x.Multiply(x.Square().Add(a)).Add(b);
+ ECFieldElement beta = alpha.Sqrt();
+
+ //
+ // if we can't find a sqrt we haven't got a point on the
+ // curve - run!
+ //
+ if (beta == null)
+ throw new ArithmeticException("Invalid point compression");
+
+ BigInteger betaValue = beta.ToBigInteger();
+ int bit0 = betaValue.TestBit(0) ? 1 : 0;
+
+ if (bit0 != yTilde)
+ {
+ // Use the other root
+ beta = FromBigInteger(q.Subtract(betaValue));
+ }
+
+ return new FpPoint(this, x, beta, true);
+ }
+
+ public override bool Equals(
+ object obj)
+ {
+ if (obj == this)
+ return true;
+
+ FpCurve other = obj as FpCurve;
+
+ if (other == null)
+ return false;
+
+ return Equals(other);
+ }
+
+ protected bool Equals(
+ FpCurve other)
+ {
+ return base.Equals(other) && q.Equals(other.q);
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode() ^ q.GetHashCode();
+ }
+ }
+
+ /**
+ * Elliptic curves over F2m. The Weierstrass equation is given by
+ * y2 + xy = x3 + ax2 + b
.
+ */
+ public class F2mCurve : ECCurveBase
+ {
+ /**
+ * The exponent m
of F2m
.
+ */
+ private readonly int m;
+
+ /**
+ * TPB: The integer k
where xm +
+ * xk + 1
represents the reduction polynomial
+ * f(z)
.k1
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.0
k2
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.0
k3
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.μ
of the elliptic curve if this is
+ * a Koblitz curve.
+ */
+ private sbyte mu = 0;
+
+ /**
+ * The auxiliary values s0
and
+ * s1
used for partial modular reduction for
+ * Koblitz curves.
+ */
+ private BigInteger[] si = null;
+
+ /**
+ * Constructor for Trinomial Polynomial Basis (TPB).
+ * @param m The exponent m
of
+ * F2m
.
+ * @param k The integer k
where xm +
+ * xk + 1
represents the reduction
+ * polynomial f(z)
.
+ * @param a The coefficient a
in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * F2m
.
+ * @param b The coefficient b
in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * F2m
.
+ */
+ public F2mCurve(
+ int m,
+ int k,
+ BigInteger a,
+ BigInteger b)
+ : this(m, k, 0, 0, a, b, null, null)
+ {
+ }
+
+ /**
+ * Constructor for Trinomial Polynomial Basis (TPB).
+ * @param m The exponent m
of
+ * F2m
.
+ * @param k The integer k
where xm +
+ * xk + 1
represents the reduction
+ * polynomial f(z)
.
+ * @param a The coefficient a
in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * F2m
.
+ * @param b The coefficient b
in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * F2m
.
+ * @param n The order of the main subgroup of the elliptic curve.
+ * @param h The cofactor of the elliptic curve, i.e.
+ * #Ea(F2m) = h * n
.
+ */
+ public F2mCurve(
+ int m,
+ int k,
+ BigInteger a,
+ BigInteger b,
+ BigInteger n,
+ BigInteger h)
+ : this(m, k, 0, 0, a, b, n, h)
+ {
+ }
+
+ /**
+ * Constructor for Pentanomial Polynomial Basis (PPB).
+ * @param m The exponent m
of
+ * F2m
.
+ * @param k1 The integer k1
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param k2 The integer k2
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param k3 The integer k3
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param a The coefficient a
in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * F2m
.
+ * @param b The coefficient b
in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * F2m
.
+ */
+ public F2mCurve(
+ int m,
+ int k1,
+ int k2,
+ int k3,
+ BigInteger a,
+ BigInteger b)
+ : this(m, k1, k2, k3, a, b, null, null)
+ {
+ }
+
+ /**
+ * Constructor for Pentanomial Polynomial Basis (PPB).
+ * @param m The exponent m
of
+ * F2m
.
+ * @param k1 The integer k1
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param k2 The integer k2
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param k3 The integer k3
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param a The coefficient a
in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * F2m
.
+ * @param b The coefficient b
in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * F2m
.
+ * @param n The order of the main subgroup of the elliptic curve.
+ * @param h The cofactor of the elliptic curve, i.e.
+ * #Ea(F2m) = h * n
.
+ */
+ public F2mCurve(
+ int m,
+ int k1,
+ int k2,
+ int k3,
+ BigInteger a,
+ BigInteger b,
+ BigInteger n,
+ BigInteger h)
+ {
+ this.m = m;
+ this.k1 = k1;
+ this.k2 = k2;
+ this.k3 = k3;
+ this.n = n;
+ this.h = h;
+ this.infinity = new F2mPoint(this, null, null);
+
+ if (k1 == 0)
+ throw new ArgumentException("k1 must be > 0");
+
+ if (k2 == 0)
+ {
+ if (k3 != 0)
+ throw new ArgumentException("k3 must be 0 if k2 == 0");
+ }
+ else
+ {
+ if (k2 <= k1)
+ throw new ArgumentException("k2 must be > k1");
+
+ if (k3 <= k2)
+ throw new ArgumentException("k3 must be > k2");
+ }
+
+ this.a = FromBigInteger(a);
+ this.b = FromBigInteger(b);
+ }
+
+ public override ECPoint Infinity
+ {
+ get { return infinity; }
+ }
+
+ public override int FieldSize
+ {
+ get { return m; }
+ }
+
+ public override ECFieldElement FromBigInteger(BigInteger x)
+ {
+ return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, x);
+ }
+
+ /**
+ * Returns true if this is a Koblitz curve (ABC curve).
+ * @return true if this is a Koblitz curve (ABC curve), false otherwise
+ */
+ public bool IsKoblitz
+ {
+ get
+ {
+ return n != null && h != null
+ && (a.ToBigInteger().Equals(BigInteger.Zero)
+ || a.ToBigInteger().Equals(BigInteger.One))
+ && b.ToBigInteger().Equals(BigInteger.One);
+ }
+ }
+
+ /**
+ * Returns the parameter μ
of the elliptic curve.
+ * @return μ
of the elliptic curve.
+ * @throws ArgumentException if the given ECCurve is not a
+ * Koblitz curve.
+ */
+ internal sbyte GetMu()
+ {
+ if (mu == 0)
+ {
+ lock (this)
+ {
+ if (mu == 0)
+ {
+ mu = Tnaf.GetMu(this);
+ }
+ }
+ }
+
+ return mu;
+ }
+
+ /**
+ * @return the auxiliary values s0
and
+ * s1
used for partial modular reduction for
+ * Koblitz curves.
+ */
+ internal BigInteger[] GetSi()
+ {
+ if (si == null)
+ {
+ lock (this)
+ {
+ if (si == null)
+ {
+ si = Tnaf.GetSi(this);
+ }
+ }
+ }
+ return si;
+ }
+
+ public override ECPoint CreatePoint(
+ BigInteger X1,
+ BigInteger Y1,
+ bool withCompression)
+ {
+ // TODO Validation of X1, Y1?
+ return new F2mPoint(
+ this,
+ FromBigInteger(X1),
+ FromBigInteger(Y1),
+ withCompression);
+ }
+
+ protected internal override ECPoint DecompressPoint(
+ int yTilde,
+ BigInteger X1)
+ {
+ ECFieldElement xp = FromBigInteger(X1);
+ ECFieldElement yp = null;
+ if (xp.ToBigInteger().SignValue == 0)
+ {
+ yp = (F2mFieldElement)b;
+ for (int i = 0; i < m - 1; i++)
+ {
+ yp = yp.Square();
+ }
+ }
+ else
+ {
+ ECFieldElement beta = xp.Add(a).Add(
+ b.Multiply(xp.Square().Invert()));
+ ECFieldElement z = solveQuadradicEquation(beta);
+
+ if (z == null)
+ throw new ArithmeticException("Invalid point compression");
+
+ int zBit = z.ToBigInteger().TestBit(0) ? 1 : 0;
+ if (zBit != yTilde)
+ {
+ z = z.Add(FromBigInteger(BigInteger.One));
+ }
+
+ yp = xp.Multiply(z);
+ }
+
+ return new F2mPoint(this, xp, yp, true);
+ }
+
+ /**
+ * Solves a quadratic equation z2 + z = beta
(X9.62
+ * D.1.6) The other solution is z + 1
.
+ *
+ * @param beta
+ * The value to solve the qradratic equation for.
+ * @return the solution for z2 + z = beta
or
+ * null
if no solution exists.
+ */
+ private ECFieldElement solveQuadradicEquation(ECFieldElement beta)
+ {
+ if (beta.ToBigInteger().SignValue == 0)
+ {
+ return FromBigInteger(BigInteger.Zero);
+ }
+
+ ECFieldElement z = null;
+ ECFieldElement gamma = FromBigInteger(BigInteger.Zero);
+
+ while (gamma.ToBigInteger().SignValue == 0)
+ {
+ ECFieldElement t = FromBigInteger(new BigInteger(m, new Random()));
+ z = FromBigInteger(BigInteger.Zero);
+
+ ECFieldElement w = beta;
+ for (int i = 1; i <= m - 1; i++)
+ {
+ ECFieldElement w2 = w.Square();
+ z = z.Square().Add(w2.Multiply(t));
+ w = w2.Add(beta);
+ }
+ if (w.ToBigInteger().SignValue != 0)
+ {
+ return null;
+ }
+ gamma = z.Square().Add(z);
+ }
+ return z;
+ }
+
+ public override bool Equals(
+ object obj)
+ {
+ if (obj == this)
+ return true;
+
+ F2mCurve other = obj as F2mCurve;
+
+ if (other == null)
+ return false;
+
+ return Equals(other);
+ }
+
+ protected bool Equals(
+ F2mCurve other)
+ {
+ return m == other.m
+ && k1 == other.k1
+ && k2 == other.k2
+ && k3 == other.k3
+ && base.Equals(other);
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode() ^ m ^ k1 ^ k2 ^ k3;
+ }
+
+ public int M
+ {
+ get { return m; }
+ }
+
+ /**
+ * Return true if curve uses a Trinomial basis.
+ *
+ * @return true if curve Trinomial, false otherwise.
+ */
+ public bool IsTrinomial()
+ {
+ return k2 == 0 && k3 == 0;
+ }
+
+ public int K1
+ {
+ get { return k1; }
+ }
+
+ public int K2
+ {
+ get { return k2; }
+ }
+
+ public int K3
+ {
+ get { return k3; }
+ }
+
+ public BigInteger N
+ {
+ get { return n; }
+ }
+
+ public BigInteger H
+ {
+ get { return h; }
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/ECFieldElement.cs b/iTechSharp/srcbc/math/ec/ECFieldElement.cs
new file mode 100644
index 0000000..63a0d2f
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/ECFieldElement.cs
@@ -0,0 +1,1253 @@
+using System;
+using System.Diagnostics;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Math.EC
+{
+ public abstract class ECFieldElement
+ {
+ public abstract BigInteger ToBigInteger();
+ public abstract string FieldName { get; }
+ public abstract int FieldSize { get; }
+ public abstract ECFieldElement Add(ECFieldElement b);
+ public abstract ECFieldElement Subtract(ECFieldElement b);
+ public abstract ECFieldElement Multiply(ECFieldElement b);
+ public abstract ECFieldElement Divide(ECFieldElement b);
+ public abstract ECFieldElement Negate();
+ public abstract ECFieldElement Square();
+ public abstract ECFieldElement Invert();
+ public abstract ECFieldElement Sqrt();
+
+ public override bool Equals(
+ object obj)
+ {
+ if (obj == this)
+ return true;
+
+ ECFieldElement other = obj as ECFieldElement;
+
+ if (other == null)
+ return false;
+
+ return Equals(other);
+ }
+
+ protected bool Equals(
+ ECFieldElement other)
+ {
+ return ToBigInteger().Equals(other.ToBigInteger());
+ }
+
+ public override int GetHashCode()
+ {
+ return ToBigInteger().GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return this.ToBigInteger().ToString(2);
+ }
+ }
+
+ public class FpFieldElement
+ : ECFieldElement
+ {
+ private readonly BigInteger q, x;
+
+ public FpFieldElement(
+ BigInteger q,
+ BigInteger x)
+ {
+ if (x.CompareTo(q) >= 0)
+ throw new ArgumentException("x value too large in field element");
+
+ this.q = q;
+ this.x = x;
+ }
+
+ public override BigInteger ToBigInteger()
+ {
+ return x;
+ }
+
+ /**
+ * return the field name for this field.
+ *
+ * @return the string "Fp".
+ */
+ public override string FieldName
+ {
+ get { return "Fp"; }
+ }
+
+ public override int FieldSize
+ {
+ get { return q.BitLength; }
+ }
+
+ public BigInteger Q
+ {
+ get { return q; }
+ }
+
+ public override ECFieldElement Add(
+ ECFieldElement b)
+ {
+ return new FpFieldElement(q, x.Add(b.ToBigInteger()).Mod(q));
+ }
+
+ public override ECFieldElement Subtract(
+ ECFieldElement b)
+ {
+ return new FpFieldElement(q, x.Subtract(b.ToBigInteger()).Mod(q));
+ }
+
+ public override ECFieldElement Multiply(
+ ECFieldElement b)
+ {
+ return new FpFieldElement(q, x.Multiply(b.ToBigInteger()).Mod(q));
+ }
+
+ public override ECFieldElement Divide(
+ ECFieldElement b)
+ {
+ return new FpFieldElement(q, x.Multiply(b.ToBigInteger().ModInverse(q)).Mod(q));
+ }
+
+ public override ECFieldElement Negate()
+ {
+ return new FpFieldElement(q, x.Negate().Mod(q));
+ }
+
+ public override ECFieldElement Square()
+ {
+ return new FpFieldElement(q, x.Multiply(x).Mod(q));
+ }
+
+ public override ECFieldElement Invert()
+ {
+ return new FpFieldElement(q, x.ModInverse(q));
+ }
+
+ // D.1.4 91
+ /**
+ * return a sqrt root - the routine verifies that the calculation
+ * returns the right value - if none exists it returns null.
+ */
+ public override ECFieldElement Sqrt()
+ {
+ if (!q.TestBit(0))
+ throw Platform.CreateNotImplementedException("even value of q");
+
+ // p mod 4 == 3
+ if (q.TestBit(1))
+ {
+ // TODO Can this be optimised (inline the Square?)
+ // z = g^(u+1) + p, p = 4u + 3
+ ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q));
+
+ return z.Square().Equals(this) ? z : null;
+ }
+
+ // p mod 4 == 1
+ BigInteger qMinusOne = q.Subtract(BigInteger.One);
+
+ BigInteger legendreExponent = qMinusOne.ShiftRight(1);
+ if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
+ return null;
+
+ BigInteger u = qMinusOne.ShiftRight(2);
+ BigInteger k = u.ShiftLeft(1).Add(BigInteger.One);
+
+ BigInteger Q = this.x;
+ BigInteger fourQ = Q.ShiftLeft(2).Mod(q);
+
+ BigInteger U, V;
+ do
+ {
+ Random rand = new Random();
+ BigInteger P;
+ do
+ {
+ P = new BigInteger(q.BitLength, rand);
+ }
+ while (P.CompareTo(q) >= 0
+ || !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne)));
+
+ BigInteger[] result = fastLucasSequence(q, P, Q, k);
+ U = result[0];
+ V = result[1];
+
+ if (V.Multiply(V).Mod(q).Equals(fourQ))
+ {
+ // Integer division by 2, mod q
+ if (V.TestBit(0))
+ {
+ V = V.Add(q);
+ }
+
+ V = V.ShiftRight(1);
+
+ Debug.Assert(V.Multiply(V).Mod(q).Equals(x));
+
+ return new FpFieldElement(q, V);
+ }
+ }
+ while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));
+
+ return null;
+
+
+// BigInteger qMinusOne = q.Subtract(BigInteger.One);
+//
+// BigInteger legendreExponent = qMinusOne.ShiftRight(1);
+// if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
+// return null;
+//
+// Random rand = new Random();
+// BigInteger fourX = x.ShiftLeft(2);
+//
+// BigInteger r;
+// do
+// {
+// r = new BigInteger(q.BitLength, rand);
+// }
+// while (r.CompareTo(q) >= 0
+// || !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne)));
+//
+// BigInteger n1 = qMinusOne.ShiftRight(2);
+// BigInteger n2 = n1.Add(BigInteger.One);
+//
+// BigInteger wOne = WOne(r, x, q);
+// BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q);
+// BigInteger twoR = r.ShiftLeft(1);
+//
+// BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q)
+// .Multiply(x).Mod(q)
+// .Multiply(wSum).Mod(q);
+//
+// return new FpFieldElement(q, root);
+ }
+
+// private static BigInteger W(BigInteger n, BigInteger wOne, BigInteger p)
+// {
+// if (n.Equals(BigInteger.One))
+// return wOne;
+//
+// bool isEven = !n.TestBit(0);
+// n = n.ShiftRight(1);
+// if (isEven)
+// {
+// BigInteger w = W(n, wOne, p);
+// return w.Multiply(w).Subtract(BigInteger.Two).Mod(p);
+// }
+// BigInteger w1 = W(n.Add(BigInteger.One), wOne, p);
+// BigInteger w2 = W(n, wOne, p);
+// return w1.Multiply(w2).Subtract(wOne).Mod(p);
+// }
+//
+// private BigInteger WOne(BigInteger r, BigInteger x, BigInteger p)
+// {
+// return r.Multiply(r).Multiply(x.ModPow(q.Subtract(BigInteger.Two), q)).Subtract(BigInteger.Two).Mod(p);
+// }
+
+ private static BigInteger[] fastLucasSequence(
+ BigInteger p,
+ BigInteger P,
+ BigInteger Q,
+ BigInteger k)
+ {
+ // TODO Research and apply "common-multiplicand multiplication here"
+
+ int n = k.BitLength;
+ int s = k.GetLowestSetBit();
+
+ Debug.Assert(k.TestBit(s));
+
+ BigInteger Uh = BigInteger.One;
+ BigInteger Vl = BigInteger.Two;
+ BigInteger Vh = P;
+ BigInteger Ql = BigInteger.One;
+ BigInteger Qh = BigInteger.One;
+
+ for (int j = n - 1; j >= s + 1; --j)
+ {
+ Ql = Ql.Multiply(Qh).Mod(p);
+
+ if (k.TestBit(j))
+ {
+ Qh = Ql.Multiply(Q).Mod(p);
+ Uh = Uh.Multiply(Vh).Mod(p);
+ Vl = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
+ Vh = Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1)).Mod(p);
+ }
+ else
+ {
+ Qh = Ql;
+ Uh = Uh.Multiply(Vl).Subtract(Ql).Mod(p);
+ Vh = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
+ Vl = Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)).Mod(p);
+ }
+ }
+
+ Ql = Ql.Multiply(Qh).Mod(p);
+ Qh = Ql.Multiply(Q).Mod(p);
+ Uh = Uh.Multiply(Vl).Subtract(Ql).Mod(p);
+ Vl = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
+ Ql = Ql.Multiply(Qh).Mod(p);
+
+ for (int j = 1; j <= s; ++j)
+ {
+ Uh = Uh.Multiply(Vl).Mod(p);
+ Vl = Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)).Mod(p);
+ Ql = Ql.Multiply(Ql).Mod(p);
+ }
+
+ return new BigInteger[]{ Uh, Vl };
+ }
+
+// private static BigInteger[] verifyLucasSequence(
+// BigInteger p,
+// BigInteger P,
+// BigInteger Q,
+// BigInteger k)
+// {
+// BigInteger[] actual = fastLucasSequence(p, P, Q, k);
+// BigInteger[] plus1 = fastLucasSequence(p, P, Q, k.Add(BigInteger.One));
+// BigInteger[] plus2 = fastLucasSequence(p, P, Q, k.Add(BigInteger.Two));
+//
+// BigInteger[] check = stepLucasSequence(p, P, Q, actual, plus1);
+//
+// Debug.Assert(check[0].Equals(plus2[0]));
+// Debug.Assert(check[1].Equals(plus2[1]));
+//
+// return actual;
+// }
+//
+// private static BigInteger[] stepLucasSequence(
+// BigInteger p,
+// BigInteger P,
+// BigInteger Q,
+// BigInteger[] backTwo,
+// BigInteger[] backOne)
+// {
+// return new BigInteger[]
+// {
+// P.Multiply(backOne[0]).Subtract(Q.Multiply(backTwo[0])).Mod(p),
+// P.Multiply(backOne[1]).Subtract(Q.Multiply(backTwo[1])).Mod(p)
+// };
+// }
+
+ public override bool Equals(
+ object obj)
+ {
+ if (obj == this)
+ return true;
+
+ FpFieldElement other = obj as FpFieldElement;
+
+ if (other == null)
+ return false;
+
+ return Equals(other);
+ }
+
+ protected bool Equals(
+ FpFieldElement other)
+ {
+ return q.Equals(other.q) && base.Equals(other);
+ }
+
+ public override int GetHashCode()
+ {
+ return q.GetHashCode() ^ base.GetHashCode();
+ }
+ }
+
+// /**
+// * Class representing the Elements of the finite field
+// * F2m
in polynomial basis (PB)
+// * representation. Both trinomial (Tpb) and pentanomial (Ppb) polynomial
+// * basis representations are supported. Gaussian normal basis (GNB)
+// * representation is not supported.
+// */
+// public class F2mFieldElement
+// : ECFieldElement
+// {
+// /**
+// * Indicates gaussian normal basis representation (GNB). Number chosen
+// * according to X9.62. GNB is not implemented at present.
+// */
+// public const int Gnb = 1;
+//
+// /**
+// * Indicates trinomial basis representation (Tpb). Number chosen
+// * according to X9.62.
+// */
+// public const int Tpb = 2;
+//
+// /**
+// * Indicates pentanomial basis representation (Ppb). Number chosen
+// * according to X9.62.
+// */
+// public const int Ppb = 3;
+//
+// /**
+// * Tpb or Ppb.
+// */
+// private int representation;
+//
+// /**
+// * The exponent m
of F2m
.
+// */
+// private int m;
+//
+// /**
+// * Tpb: The integer k
where xm +
+// * xk + 1
represents the reduction polynomial
+// * f(z)
.k1
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.0
k2
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.0
k3
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.m
of
+// * F2m
.
+// * @param k1 The integer k1
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.
+// * @param k2 The integer k2
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.
+// * @param k3 The integer k3
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.
+// * @param x The BigInteger representing the value of the field element.
+// */
+// public F2mFieldElement(
+// int m,
+// int k1,
+// int k2,
+// int k3,
+// BigInteger x)
+// : base(x)
+// {
+// if ((k2 == 0) && (k3 == 0))
+// {
+// this.representation = Tpb;
+// }
+// else
+// {
+// if (k2 >= k3)
+// throw new ArgumentException("k2 must be smaller than k3");
+// if (k2 <= 0)
+// throw new ArgumentException("k2 must be larger than 0");
+//
+// this.representation = Ppb;
+// }
+//
+// if (x.SignValue < 0)
+// throw new ArgumentException("x value cannot be negative");
+//
+// this.m = m;
+// this.k1 = k1;
+// this.k2 = k2;
+// this.k3 = k3;
+// }
+//
+// /**
+// * Constructor for Tpb.
+// * @param m The exponent m
of
+// * F2m
.
+// * @param k The integer k
where xm +
+// * xk + 1
represents the reduction
+// * polynomial f(z)
.
+// * @param x The BigInteger representing the value of the field element.
+// */
+// public F2mFieldElement(
+// int m,
+// int k,
+// BigInteger x)
+// : this(m, k, 0, 0, x)
+// {
+// // Set k1 to k, and set k2 and k3 to 0
+// }
+//
+// public override string FieldName
+// {
+// get { return "F2m"; }
+// }
+//
+// /**
+// * Checks, if the ECFieldElements a
and b
+// * are elements of the same field F2m
+// * (having the same representation).
+// * @param a field element.
+// * @param b field element to be compared.
+// * @throws ArgumentException if a
and b
+// * are not elements of the same field
+// * F2m
(having the same
+// * representation).
+// */
+// public static void CheckFieldElements(
+// ECFieldElement a,
+// ECFieldElement b)
+// {
+// if (!(a is F2mFieldElement) || !(b is F2mFieldElement))
+// {
+// throw new ArgumentException("Field elements are not "
+// + "both instances of F2mFieldElement");
+// }
+//
+// if ((a.x.SignValue < 0) || (b.x.SignValue < 0))
+// {
+// throw new ArgumentException(
+// "x value may not be negative");
+// }
+//
+// F2mFieldElement aF2m = (F2mFieldElement)a;
+// F2mFieldElement bF2m = (F2mFieldElement)b;
+//
+// if ((aF2m.m != bF2m.m) || (aF2m.k1 != bF2m.k1)
+// || (aF2m.k2 != bF2m.k2) || (aF2m.k3 != bF2m.k3))
+// {
+// throw new ArgumentException("Field elements are not "
+// + "elements of the same field F2m");
+// }
+//
+// if (aF2m.representation != bF2m.representation)
+// {
+// // Should never occur
+// throw new ArgumentException(
+// "One of the field "
+// + "elements are not elements has incorrect representation");
+// }
+// }
+//
+// /**
+// * Computes z * a(z) mod f(z)
, where f(z)
is
+// * the reduction polynomial of this
.
+// * @param a The polynomial a(z)
to be multiplied by
+// * z mod f(z)
.
+// * @return z * a(z) mod f(z)
+// */
+// private BigInteger multZModF(
+// BigInteger a)
+// {
+// // Left-shift of a(z)
+// BigInteger az = a.ShiftLeft(1);
+// if (az.TestBit(this.m))
+// {
+// // If the coefficient of z^m in a(z) Equals 1, reduction
+// // modulo f(z) is performed: Add f(z) to to a(z):
+// // Step 1: Unset mth coeffient of a(z)
+// az = az.ClearBit(this.m);
+//
+// // Step 2: Add r(z) to a(z), where r(z) is defined as
+// // f(z) = z^m + r(z), and k1, k2, k3 are the positions of
+// // the non-zero coefficients in r(z)
+// az = az.FlipBit(0);
+// az = az.FlipBit(this.k1);
+// if (this.representation == Ppb)
+// {
+// az = az.FlipBit(this.k2);
+// az = az.FlipBit(this.k3);
+// }
+// }
+// return az;
+// }
+//
+// public override ECFieldElement Add(
+// ECFieldElement b)
+// {
+// // No check performed here for performance reasons. Instead the
+// // elements involved are checked in ECPoint.F2m
+// // checkFieldElements(this, b);
+// if (b.x.SignValue == 0)
+// return this;
+//
+// return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, this.x.Xor(b.x));
+// }
+//
+// public override ECFieldElement Subtract(
+// ECFieldElement b)
+// {
+// // Addition and subtraction are the same in F2m
+// return Add(b);
+// }
+//
+// public override ECFieldElement Multiply(
+// ECFieldElement b)
+// {
+// // Left-to-right shift-and-add field multiplication in F2m
+// // Input: Binary polynomials a(z) and b(z) of degree at most m-1
+// // Output: c(z) = a(z) * b(z) mod f(z)
+//
+// // No check performed here for performance reasons. Instead the
+// // elements involved are checked in ECPoint.F2m
+// // checkFieldElements(this, b);
+// BigInteger az = this.x;
+// BigInteger bz = b.x;
+// BigInteger cz;
+//
+// // Compute c(z) = a(z) * b(z) mod f(z)
+// if (az.TestBit(0))
+// {
+// cz = bz;
+// }
+// else
+// {
+// cz = BigInteger.Zero;
+// }
+//
+// for (int i = 1; i < this.m; i++)
+// {
+// // b(z) := z * b(z) mod f(z)
+// bz = multZModF(bz);
+//
+// if (az.TestBit(i))
+// {
+// // If the coefficient of x^i in a(z) Equals 1, b(z) is added
+// // to c(z)
+// cz = cz.Xor(bz);
+// }
+// }
+// return new F2mFieldElement(m, this.k1, this.k2, this.k3, cz);
+// }
+//
+//
+// public override ECFieldElement Divide(
+// ECFieldElement b)
+// {
+// // There may be more efficient implementations
+// ECFieldElement bInv = b.Invert();
+// return Multiply(bInv);
+// }
+//
+// public override ECFieldElement Negate()
+// {
+// // -x == x holds for all x in F2m
+// return this;
+// }
+//
+// public override ECFieldElement Square()
+// {
+// // Naive implementation, can probably be speeded up using modular
+// // reduction
+// return Multiply(this);
+// }
+//
+// public override ECFieldElement Invert()
+// {
+// // Inversion in F2m using the extended Euclidean algorithm
+// // Input: A nonzero polynomial a(z) of degree at most m-1
+// // Output: a(z)^(-1) mod f(z)
+//
+// // u(z) := a(z)
+// BigInteger uz = this.x;
+// if (uz.SignValue <= 0)
+// {
+// throw new ArithmeticException("x is zero or negative, " +
+// "inversion is impossible");
+// }
+//
+// // v(z) := f(z)
+// BigInteger vz = BigInteger.One.ShiftLeft(m);
+// vz = vz.SetBit(0);
+// vz = vz.SetBit(this.k1);
+// if (this.representation == Ppb)
+// {
+// vz = vz.SetBit(this.k2);
+// vz = vz.SetBit(this.k3);
+// }
+//
+// // g1(z) := 1, g2(z) := 0
+// BigInteger g1z = BigInteger.One;
+// BigInteger g2z = BigInteger.Zero;
+//
+// // while u != 1
+// while (uz.SignValue != 0)
+// {
+// // j := deg(u(z)) - deg(v(z))
+// int j = uz.BitLength - vz.BitLength;
+//
+// // If j < 0 then: u(z) <-> v(z), g1(z) <-> g2(z), j := -j
+// if (j < 0)
+// {
+// BigInteger uzCopy = uz;
+// uz = vz;
+// vz = uzCopy;
+//
+// BigInteger g1zCopy = g1z;
+// g1z = g2z;
+// g2z = g1zCopy;
+//
+// j = -j;
+// }
+//
+// // u(z) := u(z) + z^j * v(z)
+// // Note, that no reduction modulo f(z) is required, because
+// // deg(u(z) + z^j * v(z)) <= max(deg(u(z)), j + deg(v(z)))
+// // = max(deg(u(z)), deg(u(z)) - deg(v(z)) + deg(v(z))
+// // = deg(u(z))
+// uz = uz.Xor(vz.ShiftLeft(j));
+//
+// // g1(z) := g1(z) + z^j * g2(z)
+// g1z = g1z.Xor(g2z.ShiftLeft(j));
+// // if (g1z.BitLength() > this.m) {
+// // throw new ArithmeticException(
+// // "deg(g1z) >= m, g1z = " + g1z.ToString(2));
+// // }
+// }
+// return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, g2z);
+// }
+//
+// public override ECFieldElement Sqrt()
+// {
+// throw new ArithmeticException("Not implemented");
+// }
+//
+// /**
+// * @return the representation of the field
+// * F2m
, either of
+// * {@link F2mFieldElement.Tpb} (trinomial
+// * basis representation) or
+// * {@link F2mFieldElement.Ppb} (pentanomial
+// * basis representation).
+// */
+// public int Representation
+// {
+// get { return this.representation; }
+// }
+//
+// /**
+// * @return the degree m
of the reduction polynomial
+// * f(z)
.
+// */
+// public int M
+// {
+// get { return this.m; }
+// }
+//
+// /**
+// * @return Tpb: The integer k
where xm +
+// * xk + 1
represents the reduction polynomial
+// * f(z)
.k1
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.0
k2
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.0
k3
where xm +
+// * xk3 + xk2 + xk1 + 1
+// * represents the reduction polynomial f(z)
.F2m
in polynomial basis (PB)
+ * representation. Both trinomial (Tpb) and pentanomial (Ppb) polynomial
+ * basis representations are supported. Gaussian normal basis (GNB)
+ * representation is not supported.
+ */
+ public class F2mFieldElement
+ : ECFieldElement
+ {
+ /**
+ * Indicates gaussian normal basis representation (GNB). Number chosen
+ * according to X9.62. GNB is not implemented at present.
+ */
+ public const int Gnb = 1;
+
+ /**
+ * Indicates trinomial basis representation (Tpb). Number chosen
+ * according to X9.62.
+ */
+ public const int Tpb = 2;
+
+ /**
+ * Indicates pentanomial basis representation (Ppb). Number chosen
+ * according to X9.62.
+ */
+ public const int Ppb = 3;
+
+ /**
+ * Tpb or Ppb.
+ */
+ private int representation;
+
+ /**
+ * The exponent m
of F2m
.
+ */
+ private int m;
+
+ /**
+ * Tpb: The integer k
where xm +
+ * xk + 1
represents the reduction polynomial
+ * f(z)
.k1
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.0
k2
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.0
k3
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.IntArray
holding the bits.
+ */
+ private IntArray x;
+
+ /**
+ * The number of int
s required to hold m
bits.
+ */
+ private readonly int t;
+
+ /**
+ * Constructor for Ppb.
+ * @param m The exponent m
of
+ * F2m
.
+ * @param k1 The integer k1
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param k2 The integer k2
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param k3 The integer k3
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.
+ * @param x The BigInteger representing the value of the field element.
+ */
+ public F2mFieldElement(
+ int m,
+ int k1,
+ int k2,
+ int k3,
+ BigInteger x)
+ {
+ // t = m / 32 rounded up to the next integer
+ this.t = (m + 31) >> 5;
+ this.x = new IntArray(x, t);
+
+ if ((k2 == 0) && (k3 == 0))
+ {
+ this.representation = Tpb;
+ }
+ else
+ {
+ if (k2 >= k3)
+ throw new ArgumentException("k2 must be smaller than k3");
+ if (k2 <= 0)
+ throw new ArgumentException("k2 must be larger than 0");
+
+ this.representation = Ppb;
+ }
+
+ if (x.SignValue < 0)
+ throw new ArgumentException("x value cannot be negative");
+
+ this.m = m;
+ this.k1 = k1;
+ this.k2 = k2;
+ this.k3 = k3;
+ }
+
+ /**
+ * Constructor for Tpb.
+ * @param m The exponent m
of
+ * F2m
.
+ * @param k The integer k
where xm +
+ * xk + 1
represents the reduction
+ * polynomial f(z)
.
+ * @param x The BigInteger representing the value of the field element.
+ */
+ public F2mFieldElement(
+ int m,
+ int k,
+ BigInteger x)
+ : this(m, k, 0, 0, x)
+ {
+ // Set k1 to k, and set k2 and k3 to 0
+ }
+
+ private F2mFieldElement(int m, int k1, int k2, int k3, IntArray x)
+ {
+ t = (m + 31) >> 5;
+ this.x = x;
+ this.m = m;
+ this.k1 = k1;
+ this.k2 = k2;
+ this.k3 = k3;
+
+ if ((k2 == 0) && (k3 == 0))
+ {
+ this.representation = Tpb;
+ }
+ else
+ {
+ this.representation = Ppb;
+ }
+ }
+
+ public override BigInteger ToBigInteger()
+ {
+ return x.ToBigInteger();
+ }
+
+ public override string FieldName
+ {
+ get { return "F2m"; }
+ }
+
+ public override int FieldSize
+ {
+ get { return m; }
+ }
+
+ /**
+ * Checks, if the ECFieldElements a
and b
+ * are elements of the same field F2m
+ * (having the same representation).
+ * @param a field element.
+ * @param b field element to be compared.
+ * @throws ArgumentException if a
and b
+ * are not elements of the same field
+ * F2m
(having the same
+ * representation).
+ */
+ public static void CheckFieldElements(
+ ECFieldElement a,
+ ECFieldElement b)
+ {
+ if (!(a is F2mFieldElement) || !(b is F2mFieldElement))
+ {
+ throw new ArgumentException("Field elements are not "
+ + "both instances of F2mFieldElement");
+ }
+
+ F2mFieldElement aF2m = (F2mFieldElement)a;
+ F2mFieldElement bF2m = (F2mFieldElement)b;
+
+ if ((aF2m.m != bF2m.m) || (aF2m.k1 != bF2m.k1)
+ || (aF2m.k2 != bF2m.k2) || (aF2m.k3 != bF2m.k3))
+ {
+ throw new ArgumentException("Field elements are not "
+ + "elements of the same field F2m");
+ }
+
+ if (aF2m.representation != bF2m.representation)
+ {
+ // Should never occur
+ throw new ArgumentException(
+ "One of the field "
+ + "elements are not elements has incorrect representation");
+ }
+ }
+
+ public override ECFieldElement Add(
+ ECFieldElement b)
+ {
+ // No check performed here for performance reasons. Instead the
+ // elements involved are checked in ECPoint.F2m
+ // checkFieldElements(this, b);
+ IntArray iarrClone = (IntArray) this.x.Clone();
+ F2mFieldElement bF2m = (F2mFieldElement) b;
+ iarrClone.AddShifted(bF2m.x, 0);
+ return new F2mFieldElement(m, k1, k2, k3, iarrClone);
+ }
+
+ public override ECFieldElement Subtract(
+ ECFieldElement b)
+ {
+ // Addition and subtraction are the same in F2m
+ return Add(b);
+ }
+
+ public override ECFieldElement Multiply(
+ ECFieldElement b)
+ {
+ // Right-to-left comb multiplication in the IntArray
+ // Input: Binary polynomials a(z) and b(z) of degree at most m-1
+ // Output: c(z) = a(z) * b(z) mod f(z)
+
+ // No check performed here for performance reasons. Instead the
+ // elements involved are checked in ECPoint.F2m
+ // checkFieldElements(this, b);
+ F2mFieldElement bF2m = (F2mFieldElement) b;
+ IntArray mult = x.Multiply(bF2m.x, m);
+ mult.Reduce(m, new int[]{k1, k2, k3});
+ return new F2mFieldElement(m, k1, k2, k3, mult);
+ }
+
+ public override ECFieldElement Divide(
+ ECFieldElement b)
+ {
+ // There may be more efficient implementations
+ ECFieldElement bInv = b.Invert();
+ return Multiply(bInv);
+ }
+
+ public override ECFieldElement Negate()
+ {
+ // -x == x holds for all x in F2m
+ return this;
+ }
+
+ public override ECFieldElement Square()
+ {
+ IntArray squared = x.Square(m);
+ squared.Reduce(m, new int[]{k1, k2, k3});
+ return new F2mFieldElement(m, k1, k2, k3, squared);
+ }
+
+ public override ECFieldElement Invert()
+ {
+ // Inversion in F2m using the extended Euclidean algorithm
+ // Input: A nonzero polynomial a(z) of degree at most m-1
+ // Output: a(z)^(-1) mod f(z)
+
+ // u(z) := a(z)
+ IntArray uz = (IntArray)this.x.Clone();
+
+ // v(z) := f(z)
+ IntArray vz = new IntArray(t);
+ vz.SetBit(m);
+ vz.SetBit(0);
+ vz.SetBit(this.k1);
+ if (this.representation == Ppb)
+ {
+ vz.SetBit(this.k2);
+ vz.SetBit(this.k3);
+ }
+
+ // g1(z) := 1, g2(z) := 0
+ IntArray g1z = new IntArray(t);
+ g1z.SetBit(0);
+ IntArray g2z = new IntArray(t);
+
+ // while u != 0
+ while (uz.GetUsedLength() > 0)
+// while (uz.bitLength() > 1)
+ {
+ // j := deg(u(z)) - deg(v(z))
+ int j = uz.BitLength - vz.BitLength;
+
+ // If j < 0 then: u(z) <-> v(z), g1(z) <-> g2(z), j := -j
+ if (j < 0)
+ {
+ IntArray uzCopy = uz;
+ uz = vz;
+ vz = uzCopy;
+
+ IntArray g1zCopy = g1z;
+ g1z = g2z;
+ g2z = g1zCopy;
+
+ j = -j;
+ }
+
+ // u(z) := u(z) + z^j * v(z)
+ // Note, that no reduction modulo f(z) is required, because
+ // deg(u(z) + z^j * v(z)) <= max(deg(u(z)), j + deg(v(z)))
+ // = max(deg(u(z)), deg(u(z)) - deg(v(z)) + deg(v(z))
+ // = deg(u(z))
+ // uz = uz.xor(vz.ShiftLeft(j));
+ // jInt = n / 32
+ int jInt = j >> 5;
+ // jInt = n % 32
+ int jBit = j & 0x1F;
+ IntArray vzShift = vz.ShiftLeft(jBit);
+ uz.AddShifted(vzShift, jInt);
+
+ // g1(z) := g1(z) + z^j * g2(z)
+// g1z = g1z.xor(g2z.ShiftLeft(j));
+ IntArray g2zShift = g2z.ShiftLeft(jBit);
+ g1z.AddShifted(g2zShift, jInt);
+ }
+ return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, g2z);
+ }
+
+ public override ECFieldElement Sqrt()
+ {
+ throw new ArithmeticException("Not implemented");
+ }
+
+ /**
+ * @return the representation of the field
+ * F2m
, either of
+ * {@link F2mFieldElement.Tpb} (trinomial
+ * basis representation) or
+ * {@link F2mFieldElement.Ppb} (pentanomial
+ * basis representation).
+ */
+ public int Representation
+ {
+ get { return this.representation; }
+ }
+
+ /**
+ * @return the degree m
of the reduction polynomial
+ * f(z)
.
+ */
+ public int M
+ {
+ get { return this.m; }
+ }
+
+ /**
+ * @return Tpb: The integer k
where xm +
+ * xk + 1
represents the reduction polynomial
+ * f(z)
.k1
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.0
k2
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.0
k3
where xm +
+ * xk3 + xk2 + xk1 + 1
+ * represents the reduction polynomial f(z)
.ECMultiplier
.
+// * @param multiplier The ECMultiplier
to be used to multiply
+// * this ECPoint
.
+// */
+// internal void SetECMultiplier(
+// ECMultiplier multiplier)
+// {
+// this.multiplier = multiplier;
+// }
+
+ /**
+ * Sets the PreCompInfo
. Used by ECMultiplier
s
+ * to save the precomputation for this ECPoint
to store the
+ * precomputation result for use by subsequent multiplication.
+ * @param preCompInfo The values precomputed by the
+ * ECMultiplier
.
+ */
+ internal void SetPreCompInfo(
+ PreCompInfo preCompInfo)
+ {
+ this.preCompInfo = preCompInfo;
+ }
+
+ public abstract byte[] GetEncoded();
+
+ public abstract ECPoint Add(ECPoint b);
+ public abstract ECPoint Subtract(ECPoint b);
+ public abstract ECPoint Negate();
+ public abstract ECPoint Twice();
+ public abstract ECPoint Multiply(BigInteger b);
+
+ /**
+ * Sets the appropriate ECMultiplier
, unless already set.
+ */
+ internal virtual void AssertECMultiplier()
+ {
+ if (this.multiplier == null)
+ {
+ lock (this)
+ {
+ if (this.multiplier == null)
+ {
+ this.multiplier = new FpNafMultiplier();
+ }
+ }
+ }
+ }
+ }
+
+ public abstract class ECPointBase
+ : ECPoint
+ {
+ protected internal ECPointBase(
+ ECCurve curve,
+ ECFieldElement x,
+ ECFieldElement y,
+ bool withCompression)
+ : base(curve, x, y, withCompression)
+ {
+ }
+
+ protected internal abstract bool YTilde { get; }
+
+ /**
+ * return the field element encoded with point compression. (S 4.3.6)
+ */
+ public override byte[] GetEncoded()
+ {
+ if (this.IsInfinity)
+ return new byte[1];
+
+ // Note: some of the tests rely on calculating byte length from the field element
+ // (since the test cases use mismatching fields for curve/elements)
+ int byteLength = X9IntegerConverter.GetByteLength(x);
+ byte[] X = X9IntegerConverter.IntegerToBytes(this.X.ToBigInteger(), byteLength);
+ byte[] PO;
+
+ if (withCompression)
+ {
+ PO = new byte[1 + X.Length];
+
+ PO[0] = (byte)(YTilde ? 0x03 : 0x02);
+ }
+ else
+ {
+ byte[] Y = X9IntegerConverter.IntegerToBytes(this.Y.ToBigInteger(), byteLength);
+ PO = new byte[1 + X.Length + Y.Length];
+
+ PO[0] = 0x04;
+
+ Y.CopyTo(PO, 1 + X.Length);
+ }
+
+ X.CopyTo(PO, 1);
+
+ return PO;
+ }
+
+ /**
+ * Multiplies this ECPoint
by the given number.
+ * @param k The multiplicator.
+ * @return k * this
.
+ */
+ public override ECPoint Multiply(
+ BigInteger k)
+ {
+ if (this.IsInfinity)
+ return this;
+
+ if (k.SignValue == 0)
+ return this.curve.Infinity;
+
+ AssertECMultiplier();
+ return this.multiplier.Multiply(this, k, preCompInfo);
+ }
+ }
+
+ /**
+ * Elliptic curve points over Fp
+ */
+ public class FpPoint
+ : ECPointBase
+ {
+ /**
+ * Create a point which encodes with point compression.
+ *
+ * @param curve the curve to use
+ * @param x affine x co-ordinate
+ * @param y affine y co-ordinate
+ */
+ public FpPoint(
+ ECCurve curve,
+ ECFieldElement x,
+ ECFieldElement y)
+ : this(curve, x, y, false)
+ {
+ }
+
+ /**
+ * Create a point that encodes with or without point compresion.
+ *
+ * @param curve the curve to use
+ * @param x affine x co-ordinate
+ * @param y affine y co-ordinate
+ * @param withCompression if true encode with point compression
+ */
+ public FpPoint(
+ ECCurve curve,
+ ECFieldElement x,
+ ECFieldElement y,
+ bool withCompression)
+ : base(curve, x, y, withCompression)
+ {
+ if ((x != null && y == null) || (x == null && y != null))
+ throw new ArgumentException("Exactly one of the field elements is null");
+ }
+
+ protected internal override bool YTilde
+ {
+ get
+ {
+ return this.Y.ToBigInteger().TestBit(0);
+ }
+ }
+
+ // B.3 pg 62
+ public override ECPoint Add(
+ ECPoint b)
+ {
+ if (this.IsInfinity)
+ return b;
+
+ if (b.IsInfinity)
+ return this;
+
+ // Check if b = this or b = -this
+ if (this.x.Equals(b.x))
+ {
+ if (this.y.Equals(b.y))
+ {
+ // this = b, i.e. this must be doubled
+ return this.Twice();
+ }
+
+ Debug.Assert(this.y.Equals(b.y.Negate()));
+
+ // this = -b, i.e. the result is the point at infinity
+ return this.curve.Infinity;
+ }
+
+ ECFieldElement gamma = b.y.Subtract(this.y).Divide(b.x.Subtract(this.x));
+
+ ECFieldElement x3 = gamma.Square().Subtract(this.x).Subtract(b.x);
+ ECFieldElement y3 = gamma.Multiply(this.x.Subtract(x3)).Subtract(this.y);
+
+ return new FpPoint(curve, x3, y3);
+ }
+
+ // B.3 pg 62
+ public override ECPoint Twice()
+ {
+ // Twice identity element (point at infinity) is identity
+ if (this.IsInfinity)
+ return this;
+
+ // if y1 == 0, then (x1, y1) == (x1, -y1)
+ // and hence this = -this and thus 2(x1, y1) == infinity
+ if (this.y.ToBigInteger().SignValue == 0)
+ return this.curve.Infinity;
+
+ ECFieldElement TWO = this.curve.FromBigInteger(BigInteger.Two);
+ ECFieldElement THREE = this.curve.FromBigInteger(BigInteger.Three);
+ ECFieldElement gamma = this.x.Square().Multiply(THREE).Add(curve.a).Divide(y.Multiply(TWO));
+
+ ECFieldElement x3 = gamma.Square().Subtract(this.x.Multiply(TWO));
+ ECFieldElement y3 = gamma.Multiply(this.x.Subtract(x3)).Subtract(this.y);
+
+ return new FpPoint(curve, x3, y3, this.withCompression);
+ }
+
+ // D.3.2 pg 102 (see Note:)
+ public override ECPoint Subtract(
+ ECPoint b)
+ {
+ if (b.IsInfinity)
+ return this;
+
+ // Add -b
+ return Add(b.Negate());
+ }
+
+ public override ECPoint Negate()
+ {
+ return new FpPoint(this.curve, this.x, this.y.Negate(), this.withCompression);
+ }
+
+ // TODO Uncomment this to enable WNAF Fp point multiplication
+// /**
+// * Sets the default ECMultiplier
, unless already set.
+// */
+// internal override void AssertECMultiplier()
+// {
+// if (this.multiplier == null)
+// {
+// lock (this)
+// {
+// if (this.multiplier == null)
+// {
+// this.multiplier = new WNafMultiplier();
+// }
+// }
+// }
+// }
+ }
+
+ /**
+ * Elliptic curve points over F2m
+ */
+ public class F2mPoint
+ : ECPointBase
+ {
+ /**
+ * @param curve base curve
+ * @param x x point
+ * @param y y point
+ */
+ public F2mPoint(
+ ECCurve curve,
+ ECFieldElement x,
+ ECFieldElement y)
+ : this(curve, x, y, false)
+ {
+ }
+
+ /**
+ * @param curve base curve
+ * @param x x point
+ * @param y y point
+ * @param withCompression true if encode with point compression.
+ */
+ public F2mPoint(
+ ECCurve curve,
+ ECFieldElement x,
+ ECFieldElement y,
+ bool withCompression)
+ : base(curve, x, y, withCompression)
+ {
+ if ((x != null && y == null) || (x == null && y != null))
+ {
+ throw new ArgumentException("Exactly one of the field elements is null");
+ }
+
+ if (x != null)
+ {
+ // Check if x and y are elements of the same field
+ F2mFieldElement.CheckFieldElements(this.x, this.y);
+
+ // Check if x and a are elements of the same field
+ F2mFieldElement.CheckFieldElements(this.x, this.curve.A);
+ }
+ }
+
+ /**
+ * Constructor for point at infinity
+ */
+ [Obsolete("Use ECCurve.Infinity property")]
+ public F2mPoint(
+ ECCurve curve)
+ : this(curve, null, null)
+ {
+ }
+
+ protected internal override bool YTilde
+ {
+ get
+ {
+ // X9.62 4.2.2 and 4.3.6:
+ // if x = 0 then ypTilde := 0, else ypTilde is the rightmost
+ // bit of y * x^(-1)
+ return this.X.ToBigInteger().SignValue != 0
+ && this.Y.Multiply(this.X.Invert()).ToBigInteger().TestBit(0);
+ }
+ }
+
+ /**
+ * Check, if two ECPoint
s can be added or subtracted.
+ * @param a The first ECPoint
to check.
+ * @param b The second ECPoint
to check.
+ * @throws IllegalArgumentException if a
and b
+ * cannot be added.
+ */
+ private static void CheckPoints(
+ ECPoint a,
+ ECPoint b)
+ {
+ // Check, if points are on the same curve
+ if (!a.curve.Equals(b.curve))
+ throw new ArgumentException("Only points on the same curve can be added or subtracted");
+
+// F2mFieldElement.CheckFieldElements(a.x, b.x);
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.math.ec.ECPoint#add(org.bouncycastle.math.ec.ECPoint)
+ */
+ public override ECPoint Add(ECPoint b)
+ {
+ CheckPoints(this, b);
+ return AddSimple((F2mPoint) b);
+ }
+
+ /**
+ * Adds another ECPoints.F2m
to this
without
+ * checking if both points are on the same curve. Used by multiplication
+ * algorithms, because there all points are a multiple of the same point
+ * and hence the checks can be omitted.
+ * @param b The other ECPoints.F2m
to add to
+ * this
.
+ * @return this + b
+ */
+ internal F2mPoint AddSimple(F2mPoint b)
+ {
+ if (this.IsInfinity)
+ return b;
+
+ if (b.IsInfinity)
+ return this;
+
+ F2mFieldElement x2 = (F2mFieldElement) b.X;
+ F2mFieldElement y2 = (F2mFieldElement) b.Y;
+
+ // Check if b == this or b == -this
+ if (this.x.Equals(x2))
+ {
+ // this == b, i.e. this must be doubled
+ if (this.y.Equals(y2))
+ return (F2mPoint) this.Twice();
+
+ // this = -other, i.e. the result is the point at infinity
+ return (F2mPoint) this.curve.Infinity;
+ }
+
+ ECFieldElement xSum = this.x.Add(x2);
+
+ F2mFieldElement lambda
+ = (F2mFieldElement)(this.y.Add(y2)).Divide(xSum);
+
+ F2mFieldElement x3
+ = (F2mFieldElement)lambda.Square().Add(lambda).Add(xSum).Add(this.curve.A);
+
+ F2mFieldElement y3
+ = (F2mFieldElement)lambda.Multiply(this.x.Add(x3)).Add(x3).Add(this.y);
+
+ return new F2mPoint(curve, x3, y3, withCompression);
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.math.ec.ECPoint#subtract(org.bouncycastle.math.ec.ECPoint)
+ */
+ public override ECPoint Subtract(
+ ECPoint b)
+ {
+ CheckPoints(this, b);
+ return SubtractSimple((F2mPoint) b);
+ }
+
+ /**
+ * Subtracts another ECPoints.F2m
from this
+ * without checking if both points are on the same curve. Used by
+ * multiplication algorithms, because there all points are a multiple
+ * of the same point and hence the checks can be omitted.
+ * @param b The other ECPoints.F2m
to subtract from
+ * this
.
+ * @return this - b
+ */
+ internal F2mPoint SubtractSimple(
+ F2mPoint b)
+ {
+ if (b.IsInfinity)
+ return this;
+
+ // Add -b
+ return AddSimple((F2mPoint) b.Negate());
+ }
+
+ /* (non-Javadoc)
+ * @see Org.BouncyCastle.Math.EC.ECPoint#twice()
+ */
+ public override ECPoint Twice()
+ {
+ // Twice identity element (point at infinity) is identity
+ if (this.IsInfinity)
+ return this;
+
+ // if x1 == 0, then (x1, y1) == (x1, x1 + y1)
+ // and hence this = -this and thus 2(x1, y1) == infinity
+ if (this.x.ToBigInteger().SignValue == 0)
+ return this.curve.Infinity;
+
+ F2mFieldElement lambda = (F2mFieldElement) this.x.Add(this.y.Divide(this.x));
+ F2mFieldElement x2 = (F2mFieldElement)lambda.Square().Add(lambda).Add(this.curve.A);
+ ECFieldElement ONE = this.curve.FromBigInteger(BigInteger.One);
+ F2mFieldElement y2 = (F2mFieldElement)this.x.Square().Add(
+ x2.Multiply(lambda.Add(ONE)));
+
+ return new F2mPoint(this.curve, x2, y2, withCompression);
+ }
+
+ public override ECPoint Negate()
+ {
+ return new F2mPoint(curve, this.x, this.x.Add(this.y), withCompression);
+ }
+
+ // TODO Uncomment this to enable WNAF/WTNAF F2m point multiplication
+// /**
+// * Sets the appropriate ECMultiplier
, unless already set.
+// */
+// internal override void AssertECMultiplier()
+// {
+// if (this.multiplier == null)
+// {
+// lock (this)
+// {
+// if (this.multiplier == null)
+// {
+// if (((F2mCurve) this.curve).IsKoblitz)
+// {
+// this.multiplier = new WTauNafMultiplier();
+// }
+// else
+// {
+// this.multiplier = new WNafMultiplier();
+// }
+// }
+// }
+// }
+// }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/IntArray.cs b/iTechSharp/srcbc/math/ec/IntArray.cs
new file mode 100644
index 0000000..b6b5828
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/IntArray.cs
@@ -0,0 +1,486 @@
+using System;
+using System.Text;
+
+namespace Org.BouncyCastle.Math.EC
+{
+ internal class IntArray
+ : ICloneable
+ {
+ // TODO make m fixed for the IntArray, and hence compute T once and for all
+
+ // TODO Use uint's internally?
+ private int[] m_ints;
+
+ public IntArray(int intLen)
+ {
+ m_ints = new int[intLen];
+ }
+
+ private IntArray(int[] ints)
+ {
+ m_ints = ints;
+ }
+
+ public IntArray(BigInteger bigInt)
+ : this(bigInt, 0)
+ {
+ }
+
+ public IntArray(BigInteger bigInt, int minIntLen)
+ {
+ if (bigInt.SignValue == -1)
+ throw new ArgumentException("Only positive Integers allowed", "bigint");
+
+ if (bigInt.SignValue == 0)
+ {
+ m_ints = new int[] { 0 };
+ return;
+ }
+
+ byte[] barr = bigInt.ToByteArrayUnsigned();
+ int barrLen = barr.Length;
+
+ int intLen = (barrLen + 3) / 4;
+ m_ints = new int[System.Math.Max(intLen, minIntLen)];
+
+ int rem = barrLen % 4;
+ int barrI = 0;
+
+ if (0 < rem)
+ {
+ int temp = (int) barr[barrI++];
+ while (barrI < rem)
+ {
+ temp = temp << 8 | (int) barr[barrI++];
+ }
+ m_ints[--intLen] = temp;
+ }
+
+ while (intLen > 0)
+ {
+ int temp = (int) barr[barrI++];
+ for (int i = 1; i < 4; i++)
+ {
+ temp = temp << 8 | (int) barr[barrI++];
+ }
+ m_ints[--intLen] = temp;
+ }
+ }
+
+ public int GetUsedLength()
+ {
+ int highestIntPos = m_ints.Length;
+
+ if (highestIntPos < 1)
+ return 0;
+
+ // Check if first element will act as sentinel
+ if (m_ints[0] != 0)
+ {
+ while (m_ints[--highestIntPos] == 0)
+ {
+ }
+ return highestIntPos + 1;
+ }
+
+ do
+ {
+ if (m_ints[--highestIntPos] != 0)
+ {
+ return highestIntPos + 1;
+ }
+ }
+ while (highestIntPos > 0);
+
+ return 0;
+ }
+
+ public int BitLength
+ {
+ get
+ {
+ // JDK 1.5: see Integer.numberOfLeadingZeros()
+ int intLen = GetUsedLength();
+ if (intLen == 0)
+ return 0;
+
+ int last = intLen - 1;
+ uint highest = (uint) m_ints[last];
+ int bits = (last << 5) + 1;
+
+ // A couple of binary search steps
+ if (highest > 0x0000ffff)
+ {
+ if (highest > 0x00ffffff)
+ {
+ bits += 24;
+ highest >>= 24;
+ }
+ else
+ {
+ bits += 16;
+ highest >>= 16;
+ }
+ }
+ else if (highest > 0x000000ff)
+ {
+ bits += 8;
+ highest >>= 8;
+ }
+
+ while (highest > 1)
+ {
+ ++bits;
+ highest >>= 1;
+ }
+
+ return bits;
+ }
+ }
+
+ private int[] resizedInts(int newLen)
+ {
+ int[] newInts = new int[newLen];
+ int oldLen = m_ints.Length;
+ int copyLen = oldLen < newLen ? oldLen : newLen;
+ Array.Copy(m_ints, 0, newInts, 0, copyLen);
+ return newInts;
+ }
+
+ public BigInteger ToBigInteger()
+ {
+ int usedLen = GetUsedLength();
+ if (usedLen == 0)
+ {
+ return BigInteger.Zero;
+ }
+
+ int highestInt = m_ints[usedLen - 1];
+ byte[] temp = new byte[4];
+ int barrI = 0;
+ bool trailingZeroBytesDone = false;
+ for (int j = 3; j >= 0; j--)
+ {
+ byte thisByte = (byte)((int)((uint) highestInt >> (8 * j)));
+ if (trailingZeroBytesDone || (thisByte != 0))
+ {
+ trailingZeroBytesDone = true;
+ temp[barrI++] = thisByte;
+ }
+ }
+
+ int barrLen = 4 * (usedLen - 1) + barrI;
+ byte[] barr = new byte[barrLen];
+ for (int j = 0; j < barrI; j++)
+ {
+ barr[j] = temp[j];
+ }
+ // Highest value int is done now
+
+ for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--)
+ {
+ for (int j = 3; j >= 0; j--)
+ {
+ barr[barrI++] = (byte)((int)((uint)m_ints[iarrJ] >> (8 * j)));
+ }
+ }
+ return new BigInteger(1, barr);
+ }
+
+ public void ShiftLeft()
+ {
+ int usedLen = GetUsedLength();
+ if (usedLen == 0)
+ {
+ return;
+ }
+ if (m_ints[usedLen - 1] < 0)
+ {
+ // highest bit of highest used byte is set, so shifting left will
+ // make the IntArray one byte longer
+ usedLen++;
+ if (usedLen > m_ints.Length)
+ {
+ // make the m_ints one byte longer, because we need one more
+ // byte which is not available in m_ints
+ m_ints = resizedInts(m_ints.Length + 1);
+ }
+ }
+
+ bool carry = false;
+ for (int i = 0; i < usedLen; i++)
+ {
+ // nextCarry is true if highest bit is set
+ bool nextCarry = m_ints[i] < 0;
+ m_ints[i] <<= 1;
+ if (carry)
+ {
+ // set lowest bit
+ m_ints[i] |= 1;
+ }
+ carry = nextCarry;
+ }
+ }
+
+ public IntArray ShiftLeft(int n)
+ {
+ int usedLen = GetUsedLength();
+ if (usedLen == 0)
+ {
+ return this;
+ }
+
+ if (n == 0)
+ {
+ return this;
+ }
+
+ if (n > 31)
+ {
+ throw new ArgumentException("shiftLeft() for max 31 bits "
+ + ", " + n + "bit shift is not possible", "n");
+ }
+
+ int[] newInts = new int[usedLen + 1];
+
+ int nm32 = 32 - n;
+ newInts[0] = m_ints[0] << n;
+ for (int i = 1; i < usedLen; i++)
+ {
+ newInts[i] = (m_ints[i] << n) | (int)((uint)m_ints[i - 1] >> nm32);
+ }
+ newInts[usedLen] = (int)((uint)m_ints[usedLen - 1] >> nm32);
+
+ return new IntArray(newInts);
+ }
+
+ public void AddShifted(IntArray other, int shift)
+ {
+ int usedLenOther = other.GetUsedLength();
+ int newMinUsedLen = usedLenOther + shift;
+ if (newMinUsedLen > m_ints.Length)
+ {
+ m_ints = resizedInts(newMinUsedLen);
+ //Console.WriteLine("Resize required");
+ }
+
+ for (int i = 0; i < usedLenOther; i++)
+ {
+ m_ints[i + shift] ^= other.m_ints[i];
+ }
+ }
+
+ public int Length
+ {
+ get { return m_ints.Length; }
+ }
+
+ public bool TestBit(int n)
+ {
+ // theInt = n / 32
+ int theInt = n >> 5;
+ // theBit = n % 32
+ int theBit = n & 0x1F;
+ int tester = 1 << theBit;
+ return ((m_ints[theInt] & tester) != 0);
+ }
+
+ public void FlipBit(int n)
+ {
+ // theInt = n / 32
+ int theInt = n >> 5;
+ // theBit = n % 32
+ int theBit = n & 0x1F;
+ int flipper = 1 << theBit;
+ m_ints[theInt] ^= flipper;
+ }
+
+ public void SetBit(int n)
+ {
+ // theInt = n / 32
+ int theInt = n >> 5;
+ // theBit = n % 32
+ int theBit = n & 0x1F;
+ int setter = 1 << theBit;
+ m_ints[theInt] |= setter;
+ }
+
+ public IntArray Multiply(IntArray other, int m)
+ {
+ // Lenght of c is 2m bits rounded up to the next int (32 bit)
+ int t = (m + 31) >> 5;
+ if (m_ints.Length < t)
+ {
+ m_ints = resizedInts(t);
+ }
+
+ IntArray b = new IntArray(other.resizedInts(other.Length + 1));
+ IntArray c = new IntArray((m + m + 31) >> 5);
+ // IntArray c = new IntArray(t + t);
+ int testBit = 1;
+ for (int k = 0; k < 32; k++)
+ {
+ for (int j = 0; j < t; j++)
+ {
+ if ((m_ints[j] & testBit) != 0)
+ {
+ // The kth bit of m_ints[j] is set
+ c.AddShifted(b, j);
+ }
+ }
+ testBit <<= 1;
+ b.ShiftLeft();
+ }
+ return c;
+ }
+
+ // public IntArray multiplyLeftToRight(IntArray other, int m) {
+ // // Lenght of c is 2m bits rounded up to the next int (32 bit)
+ // int t = (m + 31) / 32;
+ // if (m_ints.Length < t) {
+ // m_ints = resizedInts(t);
+ // }
+ //
+ // IntArray b = new IntArray(other.resizedInts(other.getLength() + 1));
+ // IntArray c = new IntArray((m + m + 31) / 32);
+ // // IntArray c = new IntArray(t + t);
+ // int testBit = 1 << 31;
+ // for (int k = 31; k >= 0; k--) {
+ // for (int j = 0; j < t; j++) {
+ // if ((m_ints[j] & testBit) != 0) {
+ // // The kth bit of m_ints[j] is set
+ // c.addShifted(b, j);
+ // }
+ // }
+ // testBit >>>= 1;
+ // if (k > 0) {
+ // c.shiftLeft();
+ // }
+ // }
+ // return c;
+ // }
+
+ // TODO note, redPol.Length must be 3 for TPB and 5 for PPB
+ public void Reduce(int m, int[] redPol)
+ {
+ for (int i = m + m - 2; i >= m; i--)
+ {
+ if (TestBit(i))
+ {
+ int bit = i - m;
+ FlipBit(bit);
+ FlipBit(i);
+ int l = redPol.Length;
+ while (--l >= 0)
+ {
+ FlipBit(redPol[l] + bit);
+ }
+ }
+ }
+ m_ints = resizedInts((m + 31) >> 5);
+ }
+
+ public IntArray Square(int m)
+ {
+ // TODO make the table static readonly
+ int[] table = { 0x0, 0x1, 0x4, 0x5, 0x10, 0x11, 0x14, 0x15, 0x40,
+ 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55 };
+
+ int t = (m + 31) >> 5;
+ if (m_ints.Length < t)
+ {
+ m_ints = resizedInts(t);
+ }
+
+ IntArray c = new IntArray(t + t);
+
+ // TODO twice the same code, put in separate private method
+ for (int i = 0; i < t; i++)
+ {
+ int v0 = 0;
+ for (int j = 0; j < 4; j++)
+ {
+ v0 = (int)((uint) v0 >> 8);
+ int u = (int)((uint)m_ints[i] >> (j * 4)) & 0xF;
+ int w = table[u] << 24;
+ v0 |= w;
+ }
+ c.m_ints[i + i] = v0;
+
+ v0 = 0;
+ int upper = (int)((uint) m_ints[i] >> 16);
+ for (int j = 0; j < 4; j++)
+ {
+ v0 = (int)((uint) v0 >> 8);
+ int u = (int)((uint)upper >> (j * 4)) & 0xF;
+ int w = table[u] << 24;
+ v0 |= w;
+ }
+ c.m_ints[i + i + 1] = v0;
+ }
+ return c;
+ }
+
+ public override bool Equals(object o)
+ {
+ if (!(o is IntArray))
+ {
+ return false;
+ }
+ IntArray other = (IntArray) o;
+ int usedLen = GetUsedLength();
+ if (other.GetUsedLength() != usedLen)
+ {
+ return false;
+ }
+ for (int i = 0; i < usedLen; i++)
+ {
+ if (m_ints[i] != other.m_ints[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public override int GetHashCode()
+ {
+ int i = GetUsedLength();
+ int hc = i;
+ while (--i >= 0)
+ {
+ hc *= 17;
+ hc ^= m_ints[i];
+ }
+ return hc;
+ }
+
+ public object Clone()
+ {
+ return new IntArray((int[]) m_ints.Clone());
+ }
+
+ public override string ToString()
+ {
+ int usedLen = GetUsedLength();
+ if (usedLen == 0)
+ {
+ return "0";
+ }
+
+ StringBuilder sb = new StringBuilder(Convert.ToString(m_ints[usedLen - 1], 2));
+ for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--)
+ {
+ string hexString = Convert.ToString(m_ints[iarrJ], 2);
+
+ // Add leading zeroes, except for highest significant int
+ for (int i = hexString.Length; i < 8; i++)
+ {
+ hexString = "0" + hexString;
+ }
+ sb.Append(hexString);
+ }
+ return sb.ToString();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/abc/SimpleBigDecimal.cs b/iTechSharp/srcbc/math/ec/abc/SimpleBigDecimal.cs
new file mode 100644
index 0000000..d5664db
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/abc/SimpleBigDecimal.cs
@@ -0,0 +1,241 @@
+using System;
+using System.Text;
+
+namespace Org.BouncyCastle.Math.EC.Abc
+{
+ /**
+ * Class representing a simple version of a big decimal. A
+ * SimpleBigDecimal
is basically a
+ * {@link java.math.BigInteger BigInteger} with a few digits on the right of
+ * the decimal point. The number of (binary) digits on the right of the decimal
+ * point is called the scale
of the SimpleBigDecimal
.
+ * Unlike in {@link java.math.BigDecimal BigDecimal}, the scale is not adjusted
+ * automatically, but must be set manually. All SimpleBigDecimal
s
+ * taking part in the same arithmetic operation must have equal scale. The
+ * result of a multiplication of two SimpleBigDecimal
s returns a
+ * SimpleBigDecimal
with double scale.
+ */
+ internal class SimpleBigDecimal
+ // : Number
+ {
+ // private static final long serialVersionUID = 1L;
+
+ private readonly BigInteger bigInt;
+ private readonly int scale;
+
+ /**
+ * Returns a SimpleBigDecimal
representing the same numerical
+ * value as value
.
+ * @param value The value of the SimpleBigDecimal
to be
+ * created.
+ * @param scale The scale of the SimpleBigDecimal
to be
+ * created.
+ * @return The such created SimpleBigDecimal
.
+ */
+ public static SimpleBigDecimal GetInstance(BigInteger val, int scale)
+ {
+ return new SimpleBigDecimal(val.ShiftLeft(scale), scale);
+ }
+
+ /**
+ * Constructor for SimpleBigDecimal
. The value of the
+ * constructed SimpleBigDecimal
Equals bigInt /
+ * 2scale
.
+ * @param bigInt The bigInt
value parameter.
+ * @param scale The scale of the constructed SimpleBigDecimal
.
+ */
+ public SimpleBigDecimal(BigInteger bigInt, int scale)
+ {
+ if (scale < 0)
+ throw new ArgumentException("scale may not be negative");
+
+ this.bigInt = bigInt;
+ this.scale = scale;
+ }
+
+ private SimpleBigDecimal(SimpleBigDecimal limBigDec)
+ {
+ bigInt = limBigDec.bigInt;
+ scale = limBigDec.scale;
+ }
+
+ private void CheckScale(SimpleBigDecimal b)
+ {
+ if (scale != b.scale)
+ throw new ArgumentException("Only SimpleBigDecimal of same scale allowed in arithmetic operations");
+ }
+
+ public SimpleBigDecimal AdjustScale(int newScale)
+ {
+ if (newScale < 0)
+ throw new ArgumentException("scale may not be negative");
+
+ if (newScale == scale)
+ return this;
+
+ return new SimpleBigDecimal(bigInt.ShiftLeft(newScale - scale), newScale);
+ }
+
+ public SimpleBigDecimal Add(SimpleBigDecimal b)
+ {
+ CheckScale(b);
+ return new SimpleBigDecimal(bigInt.Add(b.bigInt), scale);
+ }
+
+ public SimpleBigDecimal Add(BigInteger b)
+ {
+ return new SimpleBigDecimal(bigInt.Add(b.ShiftLeft(scale)), scale);
+ }
+
+ public SimpleBigDecimal Negate()
+ {
+ return new SimpleBigDecimal(bigInt.Negate(), scale);
+ }
+
+ public SimpleBigDecimal Subtract(SimpleBigDecimal b)
+ {
+ return Add(b.Negate());
+ }
+
+ public SimpleBigDecimal Subtract(BigInteger b)
+ {
+ return new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale);
+ }
+
+ public SimpleBigDecimal Multiply(SimpleBigDecimal b)
+ {
+ CheckScale(b);
+ return new SimpleBigDecimal(bigInt.Multiply(b.bigInt), scale + scale);
+ }
+
+ public SimpleBigDecimal Multiply(BigInteger b)
+ {
+ return new SimpleBigDecimal(bigInt.Multiply(b), scale);
+ }
+
+ public SimpleBigDecimal Divide(SimpleBigDecimal b)
+ {
+ CheckScale(b);
+ BigInteger dividend = bigInt.ShiftLeft(scale);
+ return new SimpleBigDecimal(dividend.Divide(b.bigInt), scale);
+ }
+
+ public SimpleBigDecimal Divide(BigInteger b)
+ {
+ return new SimpleBigDecimal(bigInt.Divide(b), scale);
+ }
+
+ public SimpleBigDecimal ShiftLeft(int n)
+ {
+ return new SimpleBigDecimal(bigInt.ShiftLeft(n), scale);
+ }
+
+ public int CompareTo(SimpleBigDecimal val)
+ {
+ CheckScale(val);
+ return bigInt.CompareTo(val.bigInt);
+ }
+
+ public int CompareTo(BigInteger val)
+ {
+ return bigInt.CompareTo(val.ShiftLeft(scale));
+ }
+
+ public BigInteger Floor()
+ {
+ return bigInt.ShiftRight(scale);
+ }
+
+ public BigInteger Round()
+ {
+ SimpleBigDecimal oneHalf = new SimpleBigDecimal(BigInteger.One, 1);
+ return Add(oneHalf.AdjustScale(scale)).Floor();
+ }
+
+ public int IntValue
+ {
+ get { return Floor().IntValue; }
+ }
+
+ public long LongValue
+ {
+ get { return Floor().LongValue; }
+ }
+
+// public double doubleValue()
+// {
+// return new Double(ToString()).doubleValue();
+// }
+//
+// public float floatValue()
+// {
+// return new Float(ToString()).floatValue();
+// }
+
+ public int Scale
+ {
+ get { return scale; }
+ }
+
+ public override string ToString()
+ {
+ if (scale == 0)
+ return bigInt.ToString();
+
+ BigInteger floorBigInt = Floor();
+
+ BigInteger fract = bigInt.Subtract(floorBigInt.ShiftLeft(scale));
+ if (bigInt.SignValue < 0)
+ {
+ fract = BigInteger.One.ShiftLeft(scale).Subtract(fract);
+ }
+
+ if ((floorBigInt.SignValue == -1) && (!(fract.Equals(BigInteger.Zero))))
+ {
+ floorBigInt = floorBigInt.Add(BigInteger.One);
+ }
+ string leftOfPoint = floorBigInt.ToString();
+
+ char[] fractCharArr = new char[scale];
+ string fractStr = fract.ToString(2);
+ int fractLen = fractStr.Length;
+ int zeroes = scale - fractLen;
+ for (int i = 0; i < zeroes; i++)
+ {
+ fractCharArr[i] = '0';
+ }
+ for (int j = 0; j < fractLen; j++)
+ {
+ fractCharArr[zeroes + j] = fractStr[j];
+ }
+ string rightOfPoint = new string(fractCharArr);
+
+ StringBuilder sb = new StringBuilder(leftOfPoint);
+ sb.Append(".");
+ sb.Append(rightOfPoint);
+
+ return sb.ToString();
+ }
+
+ public override bool Equals(
+ object obj)
+ {
+ if (this == obj)
+ return true;
+
+ SimpleBigDecimal other = obj as SimpleBigDecimal;
+
+ if (other == null)
+ return false;
+
+ return bigInt.Equals(other.bigInt)
+ && scale == other.scale;
+ }
+
+ public override int GetHashCode()
+ {
+ return bigInt.GetHashCode() ^ scale;
+ }
+
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/abc/Tnaf.cs b/iTechSharp/srcbc/math/ec/abc/Tnaf.cs
new file mode 100644
index 0000000..225fc30
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/abc/Tnaf.cs
@@ -0,0 +1,834 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC.Abc
+{
+ /**
+ * Class holding methods for point multiplication based on the window
+ * τ-adic nonadjacent form (WTNAF). The algorithms are based on the
+ * paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves"
+ * by Jerome A. Solinas. The paper first appeared in the Proceedings of
+ * Crypto 1997.
+ */
+ internal class Tnaf
+ {
+ private static readonly BigInteger MinusOne = BigInteger.One.Negate();
+ private static readonly BigInteger MinusTwo = BigInteger.Two.Negate();
+ private static readonly BigInteger MinusThree = BigInteger.Three.Negate();
+ private static readonly BigInteger Four = BigInteger.ValueOf(4);
+
+ /**
+ * The window width of WTNAF. The standard value of 4 is slightly less
+ * than optimal for running time, but keeps space requirements for
+ * precomputation low. For typical curves, a value of 5 or 6 results in
+ * a better running time. When changing this value, the
+ * αu
's must be computed differently, see
+ * e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson,
+ * Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004,
+ * p. 121-122
+ */
+ public const sbyte Width = 4;
+
+ /**
+ * 24
+ */
+ public const sbyte Pow2Width = 16;
+
+ /**
+ * The αu
's for a=0
as an array
+ * of ZTauElement
s.
+ */
+ public static readonly ZTauElement[] Alpha0 =
+ {
+ null,
+ new ZTauElement(BigInteger.One, BigInteger.Zero), null,
+ new ZTauElement(MinusThree, MinusOne), null,
+ new ZTauElement(MinusOne, MinusOne), null,
+ new ZTauElement(BigInteger.One, MinusOne), null
+ };
+
+ /**
+ * The αu
's for a=0
as an array
+ * of TNAFs.
+ */
+ public static readonly sbyte[][] Alpha0Tnaf =
+ {
+ null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, 1}
+ };
+
+ /**
+ * The αu
's for a=1
as an array
+ * of ZTauElement
s.
+ */
+ public static readonly ZTauElement[] Alpha1 =
+ {
+ null,
+ new ZTauElement(BigInteger.One, BigInteger.Zero), null,
+ new ZTauElement(MinusThree, BigInteger.One), null,
+ new ZTauElement(MinusOne, BigInteger.One), null,
+ new ZTauElement(BigInteger.One, BigInteger.One), null
+ };
+
+ /**
+ * The αu
's for a=1
as an array
+ * of TNAFs.
+ */
+ public static readonly sbyte[][] Alpha1Tnaf =
+ {
+ null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, -1}
+ };
+
+ /**
+ * Computes the norm of an element λ
of
+ * Z[τ]
.
+ * @param mu The parameter μ
of the elliptic curve.
+ * @param lambda The element λ
of
+ * Z[τ]
.
+ * @return The norm of λ
.
+ */
+ public static BigInteger Norm(sbyte mu, ZTauElement lambda)
+ {
+ BigInteger norm;
+
+ // s1 = u^2
+ BigInteger s1 = lambda.u.Multiply(lambda.u);
+
+ // s2 = u * v
+ BigInteger s2 = lambda.u.Multiply(lambda.v);
+
+ // s3 = 2 * v^2
+ BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1);
+
+ if (mu == 1)
+ {
+ norm = s1.Add(s2).Add(s3);
+ }
+ else if (mu == -1)
+ {
+ norm = s1.Subtract(s2).Add(s3);
+ }
+ else
+ {
+ throw new ArgumentException("mu must be 1 or -1");
+ }
+
+ return norm;
+ }
+
+ /**
+ * Computes the norm of an element λ
of
+ * R[τ]
, where λ = u + vτ
+ * and u
and u
are real numbers (elements of
+ * R
).
+ * @param mu The parameter μ
of the elliptic curve.
+ * @param u The real part of the element λ
of
+ * R[τ]
.
+ * @param v The τ
-adic part of the element
+ * λ
of R[τ]
.
+ * @return The norm of λ
.
+ */
+ public static SimpleBigDecimal Norm(sbyte mu, SimpleBigDecimal u, SimpleBigDecimal v)
+ {
+ SimpleBigDecimal norm;
+
+ // s1 = u^2
+ SimpleBigDecimal s1 = u.Multiply(u);
+
+ // s2 = u * v
+ SimpleBigDecimal s2 = u.Multiply(v);
+
+ // s3 = 2 * v^2
+ SimpleBigDecimal s3 = v.Multiply(v).ShiftLeft(1);
+
+ if (mu == 1)
+ {
+ norm = s1.Add(s2).Add(s3);
+ }
+ else if (mu == -1)
+ {
+ norm = s1.Subtract(s2).Add(s3);
+ }
+ else
+ {
+ throw new ArgumentException("mu must be 1 or -1");
+ }
+
+ return norm;
+ }
+
+ /**
+ * Rounds an element λ
of R[τ]
+ * to an element of Z[τ]
, such that their difference
+ * has minimal norm. λ
is given as
+ * λ = λ0 + λ1τ
.
+ * @param lambda0 The component λ0
.
+ * @param lambda1 The component λ1
.
+ * @param mu The parameter μ
of the elliptic curve. Must
+ * equal 1 or -1.
+ * @return The rounded element of Z[τ]
.
+ * @throws ArgumentException if lambda0
and
+ * lambda1
do not have same scale.
+ */
+ public static ZTauElement Round(SimpleBigDecimal lambda0,
+ SimpleBigDecimal lambda1, sbyte mu)
+ {
+ int scale = lambda0.Scale;
+ if (lambda1.Scale != scale)
+ throw new ArgumentException("lambda0 and lambda1 do not have same scale");
+
+ if (!((mu == 1) || (mu == -1)))
+ throw new ArgumentException("mu must be 1 or -1");
+
+ BigInteger f0 = lambda0.Round();
+ BigInteger f1 = lambda1.Round();
+
+ SimpleBigDecimal eta0 = lambda0.Subtract(f0);
+ SimpleBigDecimal eta1 = lambda1.Subtract(f1);
+
+ // eta = 2*eta0 + mu*eta1
+ SimpleBigDecimal eta = eta0.Add(eta0);
+ if (mu == 1)
+ {
+ eta = eta.Add(eta1);
+ }
+ else
+ {
+ // mu == -1
+ eta = eta.Subtract(eta1);
+ }
+
+ // check1 = eta0 - 3*mu*eta1
+ // check2 = eta0 + 4*mu*eta1
+ SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1);
+ SimpleBigDecimal fourEta1 = threeEta1.Add(eta1);
+ SimpleBigDecimal check1;
+ SimpleBigDecimal check2;
+ if (mu == 1)
+ {
+ check1 = eta0.Subtract(threeEta1);
+ check2 = eta0.Add(fourEta1);
+ }
+ else
+ {
+ // mu == -1
+ check1 = eta0.Add(threeEta1);
+ check2 = eta0.Subtract(fourEta1);
+ }
+
+ sbyte h0 = 0;
+ sbyte h1 = 0;
+
+ // if eta >= 1
+ if (eta.CompareTo(BigInteger.One) >= 0)
+ {
+ if (check1.CompareTo(MinusOne) < 0)
+ {
+ h1 = mu;
+ }
+ else
+ {
+ h0 = 1;
+ }
+ }
+ else
+ {
+ // eta < 1
+ if (check2.CompareTo(BigInteger.Two) >= 0)
+ {
+ h1 = mu;
+ }
+ }
+
+ // if eta < -1
+ if (eta.CompareTo(MinusOne) < 0)
+ {
+ if (check1.CompareTo(BigInteger.One) >= 0)
+ {
+ h1 = (sbyte)-mu;
+ }
+ else
+ {
+ h0 = -1;
+ }
+ }
+ else
+ {
+ // eta >= -1
+ if (check2.CompareTo(MinusTwo) < 0)
+ {
+ h1 = (sbyte)-mu;
+ }
+ }
+
+ BigInteger q0 = f0.Add(BigInteger.ValueOf(h0));
+ BigInteger q1 = f1.Add(BigInteger.ValueOf(h1));
+ return new ZTauElement(q0, q1);
+ }
+
+ /**
+ * Approximate division by n
. For an integer
+ * k
, the value λ = s k / n
is
+ * computed to c
bits of accuracy.
+ * @param k The parameter k
.
+ * @param s The curve parameter s0
or
+ * s1
.
+ * @param vm The Lucas Sequence element Vm
.
+ * @param a The parameter a
of the elliptic curve.
+ * @param m The bit length of the finite field
+ * Fm
.
+ * @param c The number of bits of accuracy, i.e. the scale of the returned
+ * SimpleBigDecimal
.
+ * @return The value λ = s k / n
computed to
+ * c
bits of accuracy.
+ */
+ public static SimpleBigDecimal ApproximateDivisionByN(BigInteger k,
+ BigInteger s, BigInteger vm, sbyte a, int m, int c)
+ {
+ int _k = (m + 5)/2 + c;
+ BigInteger ns = k.ShiftRight(m - _k - 2 + a);
+
+ BigInteger gs = s.Multiply(ns);
+
+ BigInteger hs = gs.ShiftRight(m);
+
+ BigInteger js = vm.Multiply(hs);
+
+ BigInteger gsPlusJs = gs.Add(js);
+ BigInteger ls = gsPlusJs.ShiftRight(_k-c);
+ if (gsPlusJs.TestBit(_k-c-1))
+ {
+ // round up
+ ls = ls.Add(BigInteger.One);
+ }
+
+ return new SimpleBigDecimal(ls, c);
+ }
+
+ /**
+ * Computes the τ
-adic NAF (non-adjacent form) of an
+ * element λ
of Z[τ]
.
+ * @param mu The parameter μ
of the elliptic curve.
+ * @param lambda The element λ
of
+ * Z[τ]
.
+ * @return The τ
-adic NAF of λ
.
+ */
+ public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda)
+ {
+ if (!((mu == 1) || (mu == -1)))
+ throw new ArgumentException("mu must be 1 or -1");
+
+ BigInteger norm = Norm(mu, lambda);
+
+ // Ceiling of log2 of the norm
+ int log2Norm = norm.BitLength;
+
+ // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
+ int maxLength = log2Norm > 30 ? log2Norm + 4 : 34;
+
+ // The array holding the TNAF
+ sbyte[] u = new sbyte[maxLength];
+ int i = 0;
+
+ // The actual length of the TNAF
+ int length = 0;
+
+ BigInteger r0 = lambda.u;
+ BigInteger r1 = lambda.v;
+
+ while(!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
+ {
+ // If r0 is odd
+ if (r0.TestBit(0))
+ {
+ u[i] = (sbyte) BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue;
+
+ // r0 = r0 - u[i]
+ if (u[i] == 1)
+ {
+ r0 = r0.ClearBit(0);
+ }
+ else
+ {
+ // u[i] == -1
+ r0 = r0.Add(BigInteger.One);
+ }
+ length = i;
+ }
+ else
+ {
+ u[i] = 0;
+ }
+
+ BigInteger t = r0;
+ BigInteger s = r0.ShiftRight(1);
+ if (mu == 1)
+ {
+ r0 = r1.Add(s);
+ }
+ else
+ {
+ // mu == -1
+ r0 = r1.Subtract(s);
+ }
+
+ r1 = t.ShiftRight(1).Negate();
+ i++;
+ }
+
+ length++;
+
+ // Reduce the TNAF array to its actual length
+ sbyte[] tnaf = new sbyte[length];
+ Array.Copy(u, 0, tnaf, 0, length);
+ return tnaf;
+ }
+
+ /**
+ * Applies the operation τ()
to an
+ * F2mPoint
.
+ * @param p The F2mPoint to which τ()
is applied.
+ * @return τ(p)
+ */
+ public static F2mPoint Tau(F2mPoint p)
+ {
+ if (p.IsInfinity)
+ return p;
+
+ ECFieldElement x = p.X;
+ ECFieldElement y = p.Y;
+
+ return new F2mPoint(p.Curve, x.Square(), y.Square(), p.IsCompressed);
+ }
+
+ /**
+ * Returns the parameter μ
of the elliptic curve.
+ * @param curve The elliptic curve from which to obtain μ
.
+ * The curve must be a Koblitz curve, i.e. a
Equals
+ * 0
or 1
and b
Equals
+ * 1
.
+ * @return μ
of the elliptic curve.
+ * @throws ArgumentException if the given ECCurve is not a Koblitz
+ * curve.
+ */
+ public static sbyte GetMu(F2mCurve curve)
+ {
+ BigInteger a = curve.A.ToBigInteger();
+
+ sbyte mu;
+ if (a.SignValue == 0)
+ {
+ mu = -1;
+ }
+ else if (a.Equals(BigInteger.One))
+ {
+ mu = 1;
+ }
+ else
+ {
+ throw new ArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible");
+ }
+ return mu;
+ }
+
+ /**
+ * Calculates the Lucas Sequence elements Uk-1
and
+ * Uk
or Vk-1
and
+ * Vk
.
+ * @param mu The parameter μ
of the elliptic curve.
+ * @param k The index of the second element of the Lucas Sequence to be
+ * returned.
+ * @param doV If set to true, computes Vk-1
and
+ * Vk
, otherwise Uk-1
and
+ * Uk
.
+ * @return An array with 2 elements, containing Uk-1
+ * and Uk
or Vk-1
+ * and Vk
.
+ */
+ public static BigInteger[] GetLucas(sbyte mu, int k, bool doV)
+ {
+ if (!(mu == 1 || mu == -1))
+ throw new ArgumentException("mu must be 1 or -1");
+
+ BigInteger u0;
+ BigInteger u1;
+ BigInteger u2;
+
+ if (doV)
+ {
+ u0 = BigInteger.Two;
+ u1 = BigInteger.ValueOf(mu);
+ }
+ else
+ {
+ u0 = BigInteger.Zero;
+ u1 = BigInteger.One;
+ }
+
+ for (int i = 1; i < k; i++)
+ {
+ // u2 = mu*u1 - 2*u0;
+ BigInteger s = null;
+ if (mu == 1)
+ {
+ s = u1;
+ }
+ else
+ {
+ // mu == -1
+ s = u1.Negate();
+ }
+
+ u2 = s.Subtract(u0.ShiftLeft(1));
+ u0 = u1;
+ u1 = u2;
+ // System.out.println(i + ": " + u2);
+ // System.out.println();
+ }
+
+ BigInteger[] retVal = {u0, u1};
+ return retVal;
+ }
+
+ /**
+ * Computes the auxiliary value tw
. If the width is
+ * 4, then for mu = 1
, tw = 6
and for
+ * mu = -1
, tw = 10
+ * @param mu The parameter μ
of the elliptic curve.
+ * @param w The window width of the WTNAF.
+ * @return the auxiliary value tw
+ */
+ public static BigInteger GetTw(sbyte mu, int w)
+ {
+ if (w == 4)
+ {
+ if (mu == 1)
+ {
+ return BigInteger.ValueOf(6);
+ }
+ else
+ {
+ // mu == -1
+ return BigInteger.ValueOf(10);
+ }
+ }
+ else
+ {
+ // For w <> 4, the values must be computed
+ BigInteger[] us = GetLucas(mu, w, false);
+ BigInteger twoToW = BigInteger.Zero.SetBit(w);
+ BigInteger u1invert = us[1].ModInverse(twoToW);
+ BigInteger tw;
+ tw = BigInteger.Two.Multiply(us[0]).Multiply(u1invert).Mod(twoToW);
+ //System.out.println("mu = " + mu);
+ //System.out.println("tw = " + tw);
+ return tw;
+ }
+ }
+
+ /**
+ * Computes the auxiliary values s0
and
+ * s1
used for partial modular reduction.
+ * @param curve The elliptic curve for which to compute
+ * s0
and s1
.
+ * @throws ArgumentException if curve
is not a
+ * Koblitz curve (Anomalous Binary Curve, ABC).
+ */
+ public static BigInteger[] GetSi(F2mCurve curve)
+ {
+ if (!curve.IsKoblitz)
+ throw new ArgumentException("si is defined for Koblitz curves only");
+
+ int m = curve.M;
+ int a = curve.A.ToBigInteger().IntValue;
+ sbyte mu = curve.GetMu();
+ int h = curve.H.IntValue;
+ int index = m + 3 - a;
+ BigInteger[] ui = GetLucas(mu, index, false);
+
+ BigInteger dividend0;
+ BigInteger dividend1;
+ if (mu == 1)
+ {
+ dividend0 = BigInteger.One.Subtract(ui[1]);
+ dividend1 = BigInteger.One.Subtract(ui[0]);
+ }
+ else if (mu == -1)
+ {
+ dividend0 = BigInteger.One.Add(ui[1]);
+ dividend1 = BigInteger.One.Add(ui[0]);
+ }
+ else
+ {
+ throw new ArgumentException("mu must be 1 or -1");
+ }
+
+ BigInteger[] si = new BigInteger[2];
+
+ if (h == 2)
+ {
+ si[0] = dividend0.ShiftRight(1);
+ si[1] = dividend1.ShiftRight(1).Negate();
+ }
+ else if (h == 4)
+ {
+ si[0] = dividend0.ShiftRight(2);
+ si[1] = dividend1.ShiftRight(2).Negate();
+ }
+ else
+ {
+ throw new ArgumentException("h (Cofactor) must be 2 or 4");
+ }
+
+ return si;
+ }
+
+ /**
+ * Partial modular reduction modulo
+ * (τm - 1)/(τ - 1)
.
+ * @param k The integer to be reduced.
+ * @param m The bitlength of the underlying finite field.
+ * @param a The parameter a
of the elliptic curve.
+ * @param s The auxiliary values s0
and
+ * s1
.
+ * @param mu The parameter μ of the elliptic curve.
+ * @param c The precision (number of bits of accuracy) of the partial
+ * modular reduction.
+ * @return ρ := k partmod (τm - 1)/(τ - 1)
+ */
+ public static ZTauElement PartModReduction(BigInteger k, int m, sbyte a,
+ BigInteger[] s, sbyte mu, sbyte c)
+ {
+ // d0 = s[0] + mu*s[1]; mu is either 1 or -1
+ BigInteger d0;
+ if (mu == 1)
+ {
+ d0 = s[0].Add(s[1]);
+ }
+ else
+ {
+ d0 = s[0].Subtract(s[1]);
+ }
+
+ BigInteger[] v = GetLucas(mu, m, true);
+ BigInteger vm = v[1];
+
+ SimpleBigDecimal lambda0 = ApproximateDivisionByN(
+ k, s[0], vm, a, m, c);
+
+ SimpleBigDecimal lambda1 = ApproximateDivisionByN(
+ k, s[1], vm, a, m, c);
+
+ ZTauElement q = Round(lambda0, lambda1, mu);
+
+ // r0 = n - d0*q0 - 2*s1*q1
+ BigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract(
+ BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v));
+
+ // r1 = s1*q0 - s0*q1
+ BigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v));
+
+ return new ZTauElement(r0, r1);
+ }
+
+ /**
+ * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+ * by a BigInteger
using the reduced τ
-adic
+ * NAF (RTNAF) method.
+ * @param p The F2mPoint to Multiply.
+ * @param k The BigInteger
by which to Multiply p
.
+ * @return k * p
+ */
+ public static F2mPoint MultiplyRTnaf(F2mPoint p, BigInteger k)
+ {
+ F2mCurve curve = (F2mCurve) p.Curve;
+ int m = curve.M;
+ sbyte a = (sbyte) curve.A.ToBigInteger().IntValue;
+ sbyte mu = curve.GetMu();
+ BigInteger[] s = curve.GetSi();
+ ZTauElement rho = PartModReduction(k, m, a, s, mu, (sbyte)10);
+
+ return MultiplyTnaf(p, rho);
+ }
+
+ /**
+ * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+ * by an element λ
of Z[τ]
+ * using the τ
-adic NAF (TNAF) method.
+ * @param p The F2mPoint to Multiply.
+ * @param lambda The element λ
of
+ * Z[τ]
.
+ * @return λ * p
+ */
+ public static F2mPoint MultiplyTnaf(F2mPoint p, ZTauElement lambda)
+ {
+ F2mCurve curve = (F2mCurve)p.Curve;
+ sbyte mu = curve.GetMu();
+ sbyte[] u = TauAdicNaf(mu, lambda);
+
+ F2mPoint q = MultiplyFromTnaf(p, u);
+
+ return q;
+ }
+
+ /**
+ * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+ * by an element λ
of Z[τ]
+ * using the τ
-adic NAF (TNAF) method, given the TNAF
+ * of λ
.
+ * @param p The F2mPoint to Multiply.
+ * @param u The the TNAF of λ
..
+ * @return λ * p
+ */
+ public static F2mPoint MultiplyFromTnaf(F2mPoint p, sbyte[] u)
+ {
+ F2mCurve curve = (F2mCurve)p.Curve;
+ F2mPoint q = (F2mPoint) curve.Infinity;
+ for (int i = u.Length - 1; i >= 0; i--)
+ {
+ q = Tau(q);
+ if (u[i] == 1)
+ {
+ q = (F2mPoint)q.AddSimple(p);
+ }
+ else if (u[i] == -1)
+ {
+ q = (F2mPoint)q.SubtractSimple(p);
+ }
+ }
+ return q;
+ }
+
+ /**
+ * Computes the [τ]
-adic window NAF of an element
+ * λ
of Z[τ]
.
+ * @param mu The parameter μ of the elliptic curve.
+ * @param lambda The element λ
of
+ * Z[τ]
of which to compute the
+ * [τ]
-adic NAF.
+ * @param width The window width of the resulting WNAF.
+ * @param pow2w 2width.
+ * @param tw The auxiliary value tw
.
+ * @param alpha The αu
's for the window width.
+ * @return The [τ]
-adic window NAF of
+ * λ
.
+ */
+ public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda,
+ sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
+ {
+ if (!((mu == 1) || (mu == -1)))
+ throw new ArgumentException("mu must be 1 or -1");
+
+ BigInteger norm = Norm(mu, lambda);
+
+ // Ceiling of log2 of the norm
+ int log2Norm = norm.BitLength;
+
+ // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
+ int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width;
+
+ // The array holding the TNAF
+ sbyte[] u = new sbyte[maxLength];
+
+ // 2^(width - 1)
+ BigInteger pow2wMin1 = pow2w.ShiftRight(1);
+
+ // Split lambda into two BigIntegers to simplify calculations
+ BigInteger r0 = lambda.u;
+ BigInteger r1 = lambda.v;
+ int i = 0;
+
+ // while lambda <> (0, 0)
+ while (!((r0.Equals(BigInteger.Zero))&&(r1.Equals(BigInteger.Zero))))
+ {
+ // if r0 is odd
+ if (r0.TestBit(0))
+ {
+ // uUnMod = r0 + r1*tw Mod 2^width
+ BigInteger uUnMod
+ = r0.Add(r1.Multiply(tw)).Mod(pow2w);
+
+ sbyte uLocal;
+ // if uUnMod >= 2^(width - 1)
+ if (uUnMod.CompareTo(pow2wMin1) >= 0)
+ {
+ uLocal = (sbyte) uUnMod.Subtract(pow2w).IntValue;
+ }
+ else
+ {
+ uLocal = (sbyte) uUnMod.IntValue;
+ }
+ // uLocal is now in [-2^(width-1), 2^(width-1)-1]
+
+ u[i] = uLocal;
+ bool s = true;
+ if (uLocal < 0)
+ {
+ s = false;
+ uLocal = (sbyte)-uLocal;
+ }
+ // uLocal is now >= 0
+
+ if (s)
+ {
+ r0 = r0.Subtract(alpha[uLocal].u);
+ r1 = r1.Subtract(alpha[uLocal].v);
+ }
+ else
+ {
+ r0 = r0.Add(alpha[uLocal].u);
+ r1 = r1.Add(alpha[uLocal].v);
+ }
+ }
+ else
+ {
+ u[i] = 0;
+ }
+
+ BigInteger t = r0;
+
+ if (mu == 1)
+ {
+ r0 = r1.Add(r0.ShiftRight(1));
+ }
+ else
+ {
+ // mu == -1
+ r0 = r1.Subtract(r0.ShiftRight(1));
+ }
+ r1 = t.ShiftRight(1).Negate();
+ i++;
+ }
+ return u;
+ }
+
+ /**
+ * Does the precomputation for WTNAF multiplication.
+ * @param p The ECPoint
for which to do the precomputation.
+ * @param a The parameter a
of the elliptic curve.
+ * @return The precomputation array for p
.
+ */
+ public static F2mPoint[] GetPreComp(F2mPoint p, sbyte a)
+ {
+ F2mPoint[] pu;
+ pu = new F2mPoint[16];
+ pu[1] = p;
+ sbyte[][] alphaTnaf;
+ if (a == 0)
+ {
+ alphaTnaf = Tnaf.Alpha0Tnaf;
+ }
+ else
+ {
+ // a == 1
+ alphaTnaf = Tnaf.Alpha1Tnaf;
+ }
+
+ int precompLen = alphaTnaf.Length;
+ for (int i = 3; i < precompLen; i = i + 2)
+ {
+ pu[i] = Tnaf.MultiplyFromTnaf(p, alphaTnaf[i]);
+ }
+
+ return pu;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/abc/ZTauElement.cs b/iTechSharp/srcbc/math/ec/abc/ZTauElement.cs
new file mode 100644
index 0000000..4fcbf1b
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/abc/ZTauElement.cs
@@ -0,0 +1,36 @@
+namespace Org.BouncyCastle.Math.EC.Abc
+{
+ /**
+ * Class representing an element of Z[τ]
. Let
+ * λ
be an element of Z[τ]
. Then
+ * λ
is given as λ = u + vτ
. The
+ * components u
and v
may be used directly, there
+ * are no accessor methods.
+ * Immutable class.
+ */
+ internal class ZTauElement
+ {
+ /**
+ * The "real" part of λ
.
+ */
+ public readonly BigInteger u;
+
+ /**
+ * The "τ
-adic" part of λ
.
+ */
+ public readonly BigInteger v;
+
+ /**
+ * Constructor for an element λ
of
+ * Z[τ]
.
+ * @param u The "real" part of λ
.
+ * @param v The "τ
-adic" part of
+ * λ
.
+ */
+ public ZTauElement(BigInteger u, BigInteger v)
+ {
+ this.u = u;
+ this.v = v;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/multiplier/ECMultiplier.cs b/iTechSharp/srcbc/math/ec/multiplier/ECMultiplier.cs
new file mode 100644
index 0000000..c6d768e
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/multiplier/ECMultiplier.cs
@@ -0,0 +1,18 @@
+namespace Org.BouncyCastle.Math.EC.Multiplier
+{
+ /**
+ * Interface for classes encapsulating a point multiplication algorithm
+ * for ECPoint
s.
+ */
+ internal interface ECMultiplier
+ {
+ /**
+ * Multiplies the ECPoint p
by k
, i.e.
+ * p
is added k
times to itself.
+ * @param p The ECPoint
to be multiplied.
+ * @param k The factor by which p
i multiplied.
+ * @return p
multiplied by k
.
+ */
+ ECPoint Multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo);
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/multiplier/FpNafMultiplier.cs b/iTechSharp/srcbc/math/ec/multiplier/FpNafMultiplier.cs
new file mode 100644
index 0000000..f5a9850
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/multiplier/FpNafMultiplier.cs
@@ -0,0 +1,39 @@
+namespace Org.BouncyCastle.Math.EC.Multiplier
+{
+ /**
+ * Class implementing the NAF (Non-Adjacent Form) multiplication algorithm.
+ */
+ internal class FpNafMultiplier
+ : ECMultiplier
+ {
+ /**
+ * D.3.2 pg 101
+ * @see org.bouncycastle.math.ec.multiplier.ECMultiplier#multiply(org.bouncycastle.math.ec.ECPoint, java.math.BigInteger)
+ */
+ public ECPoint Multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo)
+ {
+ // TODO Probably should try to add this
+ // BigInteger e = k.Mod(n); // n == order of p
+ BigInteger e = k;
+ BigInteger h = e.Multiply(BigInteger.Three);
+
+ ECPoint neg = p.Negate();
+ ECPoint R = p;
+
+ for (int i = h.BitLength - 2; i > 0; --i)
+ {
+ R = R.Twice();
+
+ bool hBit = h.TestBit(i);
+ bool eBit = e.TestBit(i);
+
+ if (hBit != eBit)
+ {
+ R = R.Add(hBit ? p : neg);
+ }
+ }
+
+ return R;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/multiplier/PreCompInfo.cs b/iTechSharp/srcbc/math/ec/multiplier/PreCompInfo.cs
new file mode 100644
index 0000000..d379508
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/multiplier/PreCompInfo.cs
@@ -0,0 +1,11 @@
+namespace Org.BouncyCastle.Math.EC.Multiplier
+{
+ /**
+ * Interface for classes storing precomputation data for multiplication
+ * algorithms. Used as a Memento (see GOF patterns) for
+ * WNafMultiplier
.
+ */
+ internal interface PreCompInfo
+ {
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/multiplier/ReferenceMultiplier.cs b/iTechSharp/srcbc/math/ec/multiplier/ReferenceMultiplier.cs
new file mode 100644
index 0000000..cdccffc
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/multiplier/ReferenceMultiplier.cs
@@ -0,0 +1,30 @@
+namespace Org.BouncyCastle.Math.EC.Multiplier
+{
+ internal class ReferenceMultiplier
+ : ECMultiplier
+ {
+ /**
+ * Simple shift-and-add multiplication. Serves as reference implementation
+ * to verify (possibly faster) implementations in
+ * {@link org.bouncycastle.math.ec.ECPoint ECPoint}.
+ *
+ * @param p The point to multiply.
+ * @param k The factor by which to multiply.
+ * @return The result of the point multiplication k * p
.
+ */
+ public ECPoint Multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo)
+ {
+ ECPoint q = p.Curve.Infinity;
+ int t = k.BitLength;
+ for (int i = 0; i < t; i++)
+ {
+ if (k.TestBit(i))
+ {
+ q = q.Add(p);
+ }
+ p = p.Twice();
+ }
+ return q;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/multiplier/WNafMultiplier.cs b/iTechSharp/srcbc/math/ec/multiplier/WNafMultiplier.cs
new file mode 100644
index 0000000..b5cf34b
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/multiplier/WNafMultiplier.cs
@@ -0,0 +1,241 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC.Multiplier
+{
+ /**
+ * Class implementing the WNAF (Window Non-Adjacent Form) multiplication
+ * algorithm.
+ */
+ internal class WNafMultiplier
+ : ECMultiplier
+ {
+ /**
+ * Computes the Window NAF (non-adjacent Form) of an integer.
+ * @param width The width w
of the Window NAF. The width is
+ * defined as the minimal number w
, such that for any
+ * w
consecutive digits in the resulting representation, at
+ * most one is non-zero.
+ * @param k The integer of which the Window NAF is computed.
+ * @return The Window NAF of the given width, such that the following holds:
+ * k = −i=0l-1 ki2i
+ *
, where the ki
denote the elements of the
+ * returned sbyte[]
.
+ */
+ public sbyte[] WindowNaf(sbyte width, BigInteger k)
+ {
+ // The window NAF is at most 1 element longer than the binary
+ // representation of the integer k. sbyte can be used instead of short or
+ // int unless the window width is larger than 8. For larger width use
+ // short or int. However, a width of more than 8 is not efficient for
+ // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than
+ // 1000 Bits are currently not used in practice.
+ sbyte[] wnaf = new sbyte[k.BitLength + 1];
+
+ // 2^width as short and BigInteger
+ short pow2wB = (short)(1 << width);
+ BigInteger pow2wBI = BigInteger.ValueOf(pow2wB);
+
+ int i = 0;
+
+ // The actual length of the WNAF
+ int length = 0;
+
+ // while k >= 1
+ while (k.SignValue > 0)
+ {
+ // if k is odd
+ if (k.TestBit(0))
+ {
+ // k Mod 2^width
+ BigInteger remainder = k.Mod(pow2wBI);
+
+ // if remainder > 2^(width - 1) - 1
+ if (remainder.TestBit(width - 1))
+ {
+ wnaf[i] = (sbyte)(remainder.IntValue - pow2wB);
+ }
+ else
+ {
+ wnaf[i] = (sbyte)remainder.IntValue;
+ }
+ // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1]
+
+ k = k.Subtract(BigInteger.ValueOf(wnaf[i]));
+ length = i;
+ }
+ else
+ {
+ wnaf[i] = 0;
+ }
+
+ // k = k/2
+ k = k.ShiftRight(1);
+ i++;
+ }
+
+ length++;
+
+ // Reduce the WNAF array to its actual length
+ sbyte[] wnafShort = new sbyte[length];
+ Array.Copy(wnaf, 0, wnafShort, 0, length);
+ return wnafShort;
+ }
+
+ /**
+ * Multiplies this
by an integer k
using the
+ * Window NAF method.
+ * @param k The integer by which this
is multiplied.
+ * @return A new ECPoint
which equals this
+ * multiplied by k
.
+ */
+ public ECPoint Multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo)
+ {
+ WNafPreCompInfo wnafPreCompInfo;
+
+ if ((preCompInfo != null) && (preCompInfo is WNafPreCompInfo))
+ {
+ wnafPreCompInfo = (WNafPreCompInfo)preCompInfo;
+ }
+ else
+ {
+ // Ignore empty PreCompInfo or PreCompInfo of incorrect type
+ wnafPreCompInfo = new WNafPreCompInfo();
+ }
+
+ // floor(log2(k))
+ int m = k.BitLength;
+
+ // width of the Window NAF
+ sbyte width;
+
+ // Required length of precomputation array
+ int reqPreCompLen;
+
+ // Determine optimal width and corresponding length of precomputation
+ // array based on literature values
+ if (m < 13)
+ {
+ width = 2;
+ reqPreCompLen = 1;
+ }
+ else
+ {
+ if (m < 41)
+ {
+ width = 3;
+ reqPreCompLen = 2;
+ }
+ else
+ {
+ if (m < 121)
+ {
+ width = 4;
+ reqPreCompLen = 4;
+ }
+ else
+ {
+ if (m < 337)
+ {
+ width = 5;
+ reqPreCompLen = 8;
+ }
+ else
+ {
+ if (m < 897)
+ {
+ width = 6;
+ reqPreCompLen = 16;
+ }
+ else
+ {
+ if (m < 2305)
+ {
+ width = 7;
+ reqPreCompLen = 32;
+ }
+ else
+ {
+ width = 8;
+ reqPreCompLen = 127;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // The length of the precomputation array
+ int preCompLen = 1;
+
+ ECPoint[] preComp = wnafPreCompInfo.GetPreComp();
+ ECPoint twiceP = wnafPreCompInfo.GetTwiceP();
+
+ // Check if the precomputed ECPoints already exist
+ if (preComp == null)
+ {
+ // Precomputation must be performed from scratch, create an empty
+ // precomputation array of desired length
+ preComp = new ECPoint[]{ p };
+ }
+ else
+ {
+ // Take the already precomputed ECPoints to start with
+ preCompLen = preComp.Length;
+ }
+
+ if (twiceP == null)
+ {
+ // Compute twice(p)
+ twiceP = p.Twice();
+ }
+
+ if (preCompLen < reqPreCompLen)
+ {
+ // Precomputation array must be made bigger, copy existing preComp
+ // array into the larger new preComp array
+ ECPoint[] oldPreComp = preComp;
+ preComp = new ECPoint[reqPreCompLen];
+ Array.Copy(oldPreComp, 0, preComp, 0, preCompLen);
+
+ for (int i = preCompLen; i < reqPreCompLen; i++)
+ {
+ // Compute the new ECPoints for the precomputation array.
+ // The values 1, 3, 5, ..., 2^(width-1)-1 times p are
+ // computed
+ preComp[i] = twiceP.Add(preComp[i - 1]);
+ }
+ }
+
+ // Compute the Window NAF of the desired width
+ sbyte[] wnaf = WindowNaf(width, k);
+ int l = wnaf.Length;
+
+ // Apply the Window NAF to p using the precomputed ECPoint values.
+ ECPoint q = p.Curve.Infinity;
+ for (int i = l - 1; i >= 0; i--)
+ {
+ q = q.Twice();
+
+ if (wnaf[i] != 0)
+ {
+ if (wnaf[i] > 0)
+ {
+ q = q.Add(preComp[(wnaf[i] - 1)/2]);
+ }
+ else
+ {
+ // wnaf[i] < 0
+ q = q.Subtract(preComp[(-wnaf[i] - 1)/2]);
+ }
+ }
+ }
+
+ // Set PreCompInfo in ECPoint, such that it is available for next
+ // multiplication.
+ wnafPreCompInfo.SetPreComp(preComp);
+ wnafPreCompInfo.SetTwiceP(twiceP);
+ p.SetPreCompInfo(wnafPreCompInfo);
+ return q;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/multiplier/WNafPreCompInfo.cs b/iTechSharp/srcbc/math/ec/multiplier/WNafPreCompInfo.cs
new file mode 100644
index 0000000..d9305da
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/multiplier/WNafPreCompInfo.cs
@@ -0,0 +1,46 @@
+namespace Org.BouncyCastle.Math.EC.Multiplier
+{
+ /**
+ * Class holding precomputation data for the WNAF (Window Non-Adjacent Form)
+ * algorithm.
+ */
+ internal class WNafPreCompInfo
+ : PreCompInfo
+ {
+ /**
+ * Array holding the precomputed ECPoint
s used for the Window
+ * NAF multiplication in
+ * {@link org.bouncycastle.math.ec.multiplier.WNafMultiplier.multiply()
+ * WNafMultiplier.multiply()}
.
+ */
+ private ECPoint[] preComp = null;
+
+ /**
+ * Holds an ECPoint
representing twice(this). Used for the
+ * Window NAF multiplication in
+ * {@link org.bouncycastle.math.ec.multiplier.WNafMultiplier.multiply()
+ * WNafMultiplier.multiply()}
.
+ */
+ private ECPoint twiceP = null;
+
+ internal ECPoint[] GetPreComp()
+ {
+ return preComp;
+ }
+
+ internal void SetPreComp(ECPoint[] preComp)
+ {
+ this.preComp = preComp;
+ }
+
+ internal ECPoint GetTwiceP()
+ {
+ return twiceP;
+ }
+
+ internal void SetTwiceP(ECPoint twiceThis)
+ {
+ this.twiceP = twiceThis;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/multiplier/WTauNafMultiplier.cs b/iTechSharp/srcbc/math/ec/multiplier/WTauNafMultiplier.cs
new file mode 100644
index 0000000..f1a6057
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/multiplier/WTauNafMultiplier.cs
@@ -0,0 +1,120 @@
+using System;
+
+using Org.BouncyCastle.Math.EC.Abc;
+
+namespace Org.BouncyCastle.Math.EC.Multiplier
+{
+ /**
+ * Class implementing the WTNAF (Window
+ * τ
-adic Non-Adjacent Form) algorithm.
+ */
+ internal class WTauNafMultiplier
+ : ECMultiplier
+ {
+ /**
+ * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+ * by k
using the reduced τ
-adic NAF (RTNAF)
+ * method.
+ * @param p The F2mPoint to multiply.
+ * @param k The integer by which to multiply k
.
+ * @return p
multiplied by k
.
+ */
+ public ECPoint Multiply(ECPoint point, BigInteger k, PreCompInfo preCompInfo)
+ {
+ if (!(point is F2mPoint))
+ throw new ArgumentException("Only F2mPoint can be used in WTauNafMultiplier");
+
+ F2mPoint p = (F2mPoint)point;
+
+ F2mCurve curve = (F2mCurve) p.Curve;
+ int m = curve.M;
+ sbyte a = (sbyte) curve.A.ToBigInteger().IntValue;
+ sbyte mu = curve.GetMu();
+ BigInteger[] s = curve.GetSi();
+
+ ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10);
+
+ return MultiplyWTnaf(p, rho, preCompInfo, a, mu);
+ }
+
+ /**
+ * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+ * by an element λ
of Z[τ]
using
+ * the τ
-adic NAF (TNAF) method.
+ * @param p The F2mPoint to multiply.
+ * @param lambda The element λ
of
+ * Z[τ]
of which to compute the
+ * [τ]
-adic NAF.
+ * @return p
multiplied by λ
.
+ */
+ private F2mPoint MultiplyWTnaf(F2mPoint p, ZTauElement lambda,
+ PreCompInfo preCompInfo, sbyte a, sbyte mu)
+ {
+ ZTauElement[] alpha;
+ if (a == 0)
+ {
+ alpha = Tnaf.Alpha0;
+ }
+ else
+ {
+ // a == 1
+ alpha = Tnaf.Alpha1;
+ }
+
+ BigInteger tw = Tnaf.GetTw(mu, Tnaf.Width);
+
+ sbyte[]u = Tnaf.TauAdicWNaf(mu, lambda, Tnaf.Width,
+ BigInteger.ValueOf(Tnaf.Pow2Width), tw, alpha);
+
+ return MultiplyFromWTnaf(p, u, preCompInfo);
+ }
+
+ /**
+ * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint}
+ * by an element λ
of Z[τ]
+ * using the window τ
-adic NAF (TNAF) method, given the
+ * WTNAF of λ
.
+ * @param p The F2mPoint to multiply.
+ * @param u The the WTNAF of λ
..
+ * @return λ * p
+ */
+ private static F2mPoint MultiplyFromWTnaf(F2mPoint p, sbyte[] u,
+ PreCompInfo preCompInfo)
+ {
+ F2mCurve curve = (F2mCurve)p.Curve;
+ sbyte a = (sbyte) curve.A.ToBigInteger().IntValue;
+
+ F2mPoint[] pu;
+ if ((preCompInfo == null) || !(preCompInfo is WTauNafPreCompInfo))
+ {
+ pu = Tnaf.GetPreComp(p, a);
+ p.SetPreCompInfo(new WTauNafPreCompInfo(pu));
+ }
+ else
+ {
+ pu = ((WTauNafPreCompInfo)preCompInfo).GetPreComp();
+ }
+
+ // q = infinity
+ F2mPoint q = (F2mPoint) p.Curve.Infinity;
+ for (int i = u.Length - 1; i >= 0; i--)
+ {
+ q = Tnaf.Tau(q);
+ if (u[i] != 0)
+ {
+ if (u[i] > 0)
+ {
+ q = q.AddSimple(pu[u[i]]);
+ }
+ else
+ {
+ // u[i] < 0
+ q = q.SubtractSimple(pu[-u[i]]);
+ }
+ }
+ }
+
+ return q;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/math/ec/multiplier/WTauNafPreCompInfo.cs b/iTechSharp/srcbc/math/ec/multiplier/WTauNafPreCompInfo.cs
new file mode 100644
index 0000000..cede4a0
--- /dev/null
+++ b/iTechSharp/srcbc/math/ec/multiplier/WTauNafPreCompInfo.cs
@@ -0,0 +1,41 @@
+namespace Org.BouncyCastle.Math.EC.Multiplier
+{
+ /**
+ * Class holding precomputation data for the WTNAF (Window
+ * τ
-adic Non-Adjacent Form) algorithm.
+ */
+ internal class WTauNafPreCompInfo
+ : PreCompInfo
+ {
+ /**
+ * Array holding the precomputed F2mPoint
s used for the
+ * WTNAF multiplication in
+ * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply()
+ * WTauNafMultiplier.multiply()}
.
+ */
+ private readonly F2mPoint[] preComp;
+
+ /**
+ * Constructor for WTauNafPreCompInfo
+ * @param preComp Array holding the precomputed F2mPoint
s
+ * used for the WTNAF multiplication in
+ * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply()
+ * WTauNafMultiplier.multiply()}
.
+ */
+ internal WTauNafPreCompInfo(F2mPoint[] preComp)
+ {
+ this.preComp = preComp;
+ }
+
+ /**
+ * @return the array holding the precomputed F2mPoint
s
+ * used for the WTNAF multiplication in
+ * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply()
+ * WTauNafMultiplier.multiply()}
.
+ */
+ internal F2mPoint[] GetPreComp()
+ {
+ return preComp;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/ocsp/BasicOCSPResp.cs b/iTechSharp/srcbc/ocsp/BasicOCSPResp.cs
new file mode 100644
index 0000000..ffe45e2
--- /dev/null
+++ b/iTechSharp/srcbc/ocsp/BasicOCSPResp.cs
@@ -0,0 +1,215 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Ocsp;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Security.Certificates;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.Ocsp
+{
+ ///
+ /// BasicOcspResponse ::= SEQUENCE {
+ /// tbsResponseData ResponseData,
+ /// signatureAlgorithm AlgorithmIdentifier,
+ /// signature BIT STRING,
+ /// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
+ /// }
+ ///
+ /// + * OcspRequest ::= SEQUENCE { + * tbsRequest TBSRequest, + * optionalSignature [0] EXPLICIT Signature OPTIONAL } + * + * TBSRequest ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * requestorName [1] EXPLICIT GeneralName OPTIONAL, + * requestList SEQUENCE OF Request, + * requestExtensions [2] EXPLICIT Extensions OPTIONAL } + * + * Signature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL} + * + * Version ::= INTEGER { v1(0) } + * + * Request ::= SEQUENCE { + * reqCert CertID, + * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } + * + * CertID ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * issuerNameHash OCTET STRING, -- Hash of Issuer's DN + * issuerKeyHash OCTET STRING, -- Hash of Issuers public key + * serialNumber CertificateSerialNumber } + *+ */ + public class OcspReq + : X509ExtensionBase + { + private OcspRequest req; + + public OcspReq( + OcspRequest req) + { + this.req = req; + } + + public OcspReq( + byte[] req) + : this(new Asn1InputStream(req)) + { + } + + public OcspReq( + Stream inStr) + : this(new Asn1InputStream(inStr)) + { + } + + private OcspReq( + Asn1InputStream aIn) + { + try + { + this.req = OcspRequest.GetInstance(aIn.ReadObject()); + } + catch (ArgumentException e) + { + throw new IOException("malformed request: " + e.Message); + } + catch (InvalidCastException e) + { + throw new IOException("malformed request: " + e.Message); + } + } + + /** + * Return the DER encoding of the tbsRequest field. + * @return DER encoding of tbsRequest + * @throws OcspException in the event of an encoding error. + */ + public byte[] GetTbsRequest() + { + try + { + return req.TbsRequest.GetEncoded(); + } + catch (IOException e) + { + throw new OcspException("problem encoding tbsRequest", e); + } + } + + public int Version + { + get { return req.TbsRequest.Version.Value.IntValue + 1; } + } + + public GeneralName RequestorName + { + get { return GeneralName.GetInstance(req.TbsRequest.RequestorName); } + } + + public Req[] GetRequestList() + { + Asn1Sequence seq = req.TbsRequest.RequestList; + Req[] requests = new Req[seq.Count]; + + for (int i = 0; i != requests.Length; i++) + { + requests[i] = new Req(Request.GetInstance(seq[i])); + } + + return requests; + } + + public X509Extensions RequestExtensions + { + get { return X509Extensions.GetInstance(req.TbsRequest.RequestExtensions); } + } + + protected override X509Extensions GetX509Extensions() + { + return RequestExtensions; + } + + /** + * return the object identifier representing the signature algorithm + */ + public string SignatureAlgOid + { + get + { + if (!this.IsSigned) + return null; + + return req.OptionalSignature.SignatureAlgorithm.ObjectID.Id; + } + } + + public byte[] GetSignature() + { + if (!this.IsSigned) + return null; + + return req.OptionalSignature.SignatureValue.GetBytes(); + } + + private ArrayList GetCertList() + { + // load the certificates if we have any + + ArrayList certs = new ArrayList(); + Asn1Sequence s = req.OptionalSignature.Certs; + + if (s != null) + { + foreach (Asn1Encodable ae in s) + { + try + { + certs.Add(new X509CertificateParser().ReadCertificate(ae.GetEncoded())); + } + catch (Exception e) + { + throw new OcspException("can't re-encode certificate!", e); + } + } + } + + return certs; + } + + public X509Certificate[] GetCerts() + { + if (!this.IsSigned) + return null; + + ArrayList certs = this.GetCertList(); + + return (X509Certificate[]) certs.ToArray(typeof(X509Certificate)); + } + + /** + * If the request is signed return a possibly empty CertStore containing the certificates in the + * request. If the request is not signed the method returns null. + * + * @return null if not signed, a CertStore otherwise + * @throws OcspException + */ + public IX509Store GetCertificates( + string type) + { + if (!this.IsSigned) + return null; + + try + { + return X509StoreFactory.Create( + "Certificate/" + type, + new X509CollectionStoreParameters(this.GetCertList())); + } + catch (Exception e) + { + throw new OcspException("can't setup the CertStore", e); + } + } + + /** + * Return whether or not this request is signed. + * + * @return true if signed false otherwise. + */ + public bool IsSigned + { + get { return req.OptionalSignature != null; } + } + + /** + * Verify the signature against the TBSRequest object we contain. + */ + public bool Verify( + AsymmetricKeyParameter publicKey) + { + if (!this.IsSigned) + throw new OcspException("attempt to Verify signature on unsigned object"); + + try + { + ISigner signature = SignerUtilities.GetSigner(this.SignatureAlgOid); + + signature.Init(false, publicKey); + + byte[] encoded = req.TbsRequest.GetEncoded(); + + signature.BlockUpdate(encoded, 0, encoded.Length); + + return signature.VerifySignature(this.GetSignature()); + } + catch (Exception e) + { + throw new OcspException("exception processing sig: " + e, e); + } + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return req.GetEncoded(); + } + } +} diff --git a/iTechSharp/srcbc/ocsp/OCSPReqGenerator.cs b/iTechSharp/srcbc/ocsp/OCSPReqGenerator.cs new file mode 100644 index 0000000..5f3c0d5 --- /dev/null +++ b/iTechSharp/srcbc/ocsp/OCSPReqGenerator.cs @@ -0,0 +1,242 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class OcspReqGenerator + { + private IList list = new ArrayList(); + private GeneralName requestorName = null; + private X509Extensions requestExtensions = null; + + private class RequestObject + { + internal CertificateID certId; + internal X509Extensions extensions; + + public RequestObject( + CertificateID certId, + X509Extensions extensions) + { + this.certId = certId; + this.extensions = extensions; + } + + public Request ToRequest() + { + return new Request(certId.ToAsn1Object(), extensions); + } + } + + /** + * Add a request for the given CertificateID. + * + * @param certId certificate ID of interest + */ + public void AddRequest( + CertificateID certId) + { + list.Add(new RequestObject(certId, null)); + } + + /** + * Add a request with extensions + * + * @param certId certificate ID of interest + * @param singleRequestExtensions the extensions to attach to the request + */ + public void AddRequest( + CertificateID certId, + X509Extensions singleRequestExtensions) + { + list.Add(new RequestObject(certId, singleRequestExtensions)); + } + + /** + * Set the requestor name to the passed in X509Principal + * + * @param requestorName a X509Principal representing the requestor name. + */ + public void SetRequestorName( + X509Name requestorName) + { + try + { + this.requestorName = new GeneralName(GeneralName.DirectoryName, requestorName); + } + catch (Exception e) + { + throw new ArgumentException("cannot encode principal", e); + } + } + + public void SetRequestorName( + GeneralName requestorName) + { + this.requestorName = requestorName; + } + + public void SetRequestExtensions( + X509Extensions requestExtensions) + { + this.requestExtensions = requestExtensions; + } + + private OcspReq GenerateRequest( + DerObjectIdentifier signingAlgorithm, + AsymmetricKeyParameter privateKey, + X509Certificate[] chain, + SecureRandom random) + { + Asn1EncodableVector requests = new Asn1EncodableVector(); + + foreach (RequestObject reqObj in list) + { + try + { + requests.Add(reqObj.ToRequest()); + } + catch (Exception e) + { + throw new OcspException("exception creating Request", e); + } + } + + TbsRequest tbsReq = new TbsRequest(requestorName, new DerSequence(requests), requestExtensions); + + ISigner sig = null; + Signature signature = null; + + if (signingAlgorithm != null) + { + if (requestorName == null) + { + throw new OcspException("requestorName must be specified if request is signed."); + } + + try + { + sig = SignerUtilities.GetSigner(signingAlgorithm.Id); + if (random != null) + { + sig.Init(true, new ParametersWithRandom(privateKey, random)); + } + else + { + sig.Init(true, privateKey); + } + } + catch (Exception e) + { + throw new OcspException("exception creating signature: " + e, e); + } + + DerBitString bitSig = null; + + try + { + byte[] encoded = tbsReq.GetEncoded(); + sig.BlockUpdate(encoded, 0, encoded.Length); + + bitSig = new DerBitString(sig.GenerateSignature()); + } + catch (Exception e) + { + throw new OcspException("exception processing TBSRequest: " + e, e); + } + + AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(signingAlgorithm, DerNull.Instance); + + if (chain != null && chain.Length > 0) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + try + { + for (int i = 0; i != chain.Length; i++) + { + v.Add( + X509CertificateStructure.GetInstance( + Asn1Object.FromByteArray(chain[i].GetEncoded()))); + } + } + catch (IOException e) + { + throw new OcspException("error processing certs", e); + } + catch (CertificateEncodingException e) + { + throw new OcspException("error encoding certs", e); + } + + signature = new Signature(sigAlgId, bitSig, new DerSequence(v)); + } + else + { + signature = new Signature(sigAlgId, bitSig); + } + } + + return new OcspReq(new OcspRequest(tbsReq, signature)); + } + + /** + * Generate an unsigned request + * + * @return the OcspReq + * @throws OcspException + */ + public OcspReq Generate() + { + return GenerateRequest(null, null, null, null); + } + + public OcspReq Generate( + string signingAlgorithm, + AsymmetricKeyParameter privateKey, + X509Certificate[] chain) + { + return Generate(signingAlgorithm, privateKey, chain, null); + } + + public OcspReq Generate( + string signingAlgorithm, + AsymmetricKeyParameter privateKey, + X509Certificate[] chain, + SecureRandom random) + { + if (signingAlgorithm == null) + throw new ArgumentException("no signing algorithm specified"); + + try + { + DerObjectIdentifier oid = OcspUtilities.GetAlgorithmOid(signingAlgorithm); + + return GenerateRequest(oid, privateKey, chain, random); + } + catch (ArgumentException) + { + throw new ArgumentException("unknown signing algorithm specified: " + signingAlgorithm); + } + } + + /** + * Return an IEnumerable of the signature names supported by the generator. + * + * @return an IEnumerable containing recognised names. + */ + public IEnumerable SignatureAlgNames + { + get { return OcspUtilities.AlgNames; } + } + } +} diff --git a/iTechSharp/srcbc/ocsp/OCSPResp.cs b/iTechSharp/srcbc/ocsp/OCSPResp.cs new file mode 100644 index 0000000..dc99c6a --- /dev/null +++ b/iTechSharp/srcbc/ocsp/OCSPResp.cs @@ -0,0 +1,100 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; + +namespace Org.BouncyCastle.Ocsp +{ + public class OcspResp + { + private OcspResponse resp; + + public OcspResp( + OcspResponse resp) + { + this.resp = resp; + } + + public OcspResp( + byte[] resp) + : this(new Asn1InputStream(resp)) + { + } + + public OcspResp( + Stream inStr) + : this(new Asn1InputStream(inStr)) + { + } + + private OcspResp( + Asn1InputStream aIn) + { + try + { + this.resp = OcspResponse.GetInstance(aIn.ReadObject()); + } + catch (Exception e) + { + throw new IOException("malformed response: " + e.Message, e); + } + } + + public int Status + { + get { return this.resp.ResponseStatus.Value.IntValue; } + } + + public object GetResponseObject() + { + ResponseBytes rb = this.resp.ResponseBytes; + + if (rb == null) + return null; + + if (rb.ResponseType.Equals(OcspObjectIdentifiers.PkixOcspBasic)) + { + try + { + return new BasicOcspResp( + BasicOcspResponse.GetInstance( + Asn1Object.FromByteArray(rb.Response.GetOctets()))); + } + catch (Exception e) + { + throw new OcspException("problem decoding object: " + e, e); + } + } + + return rb.Response; + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return resp.GetEncoded(); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + OcspResp other = obj as OcspResp; + + if (other == null) + return false; + + return resp.Equals(other.resp); + } + + public override int GetHashCode() + { + return resp.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/ocsp/OCSPRespGenerator.cs b/iTechSharp/srcbc/ocsp/OCSPRespGenerator.cs new file mode 100644 index 0000000..e0eb9ae --- /dev/null +++ b/iTechSharp/srcbc/ocsp/OCSPRespGenerator.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * base generator for an OCSP response - at the moment this only supports the + * generation of responses containing BasicOCSP responses. + */ + public class OCSPRespGenerator + { + public const int Successful = 0; // Response has valid confirmations + public const int MalformedRequest = 1; // Illegal confirmation request + public const int InternalError = 2; // Internal error in issuer + public const int TryLater = 3; // Try again later + // (4) is not used + public const int SigRequired = 5; // Must sign the request + public const int Unauthorized = 6; // Request unauthorized + + public OcspResp Generate( + int status, + object response) + { + if (response == null) + { + return new OcspResp(new OcspResponse(new OcspResponseStatus(status),null)); + } + if (response is BasicOcspResp) + { + BasicOcspResp r = (BasicOcspResp)response; + Asn1OctetString octs; + + try + { + octs = new DerOctetString(r.GetEncoded()); + } + catch (Exception e) + { + throw new OcspException("can't encode object.", e); + } + + ResponseBytes rb = new ResponseBytes( + OcspObjectIdentifiers.PkixOcspBasic, octs); + + return new OcspResp(new OcspResponse( + new OcspResponseStatus(status), rb)); + } + + throw new OcspException("unknown response object"); + } + } +} diff --git a/iTechSharp/srcbc/ocsp/OCSPRespStatus.cs b/iTechSharp/srcbc/ocsp/OCSPRespStatus.cs new file mode 100644 index 0000000..9c00c70 --- /dev/null +++ b/iTechSharp/srcbc/ocsp/OCSPRespStatus.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Ocsp +{ + [Obsolete("Use version with correct spelling 'OcspRespStatus'")] + public abstract class OcscpRespStatus : OcspRespStatus + { + } + + public abstract class OcspRespStatus + { + /** + * note 4 is not used. + */ + public const int Successful = 0; // --Response has valid confirmations + public const int MalformedRequest = 1; // --Illegal confirmation request + public const int InternalError = 2; // --Internal error in issuer + public const int TryLater = 3; // --Try again later + public const int SigRequired = 5; // --Must sign the request + public const int Unauthorized = 6; // --Request unauthorized + } +} diff --git a/iTechSharp/srcbc/ocsp/OCSPUtil.cs b/iTechSharp/srcbc/ocsp/OCSPUtil.cs new file mode 100644 index 0000000..390ba0f --- /dev/null +++ b/iTechSharp/srcbc/ocsp/OCSPUtil.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Ocsp +{ + class OcspUtilities + { + private static readonly Hashtable algorithms = new Hashtable(); + private static readonly Hashtable oids = new Hashtable(); + private static readonly ISet noParams = new HashSet(); + + static OcspUtilities() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + + oids.Add(PkcsObjectIdentifiers.MD2WithRsaEncryption, "MD2WITHRSA"); + oids.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption, "MD5WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption, "SHA384WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption, "SHA512WITHRSA"); + oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160, "RIPEMD160WITHRSA"); + oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128, "RIPEMD128WITHRSA"); + oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256, "RIPEMD256WITHRSA"); + oids.Add(X9ObjectIdentifiers.IdDsaWithSha1, "SHA1WITHDSA"); + oids.Add(NistObjectIdentifiers.DsaWithSha224, "SHA224WITHDSA"); + oids.Add(NistObjectIdentifiers.DsaWithSha256, "SHA256WITHDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha1, "SHA1WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha224, "SHA224WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha256, "SHA256WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha384, "SHA384WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha512, "SHA512WITHECDSA"); + oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, "GOST3411WITHGOST3410"); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add(NistObjectIdentifiers.DsaWithSha224); + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + } + + internal static DerObjectIdentifier GetAlgorithmOid( + string algorithmName) + { + algorithmName = algorithmName.ToUpper(CultureInfo.InvariantCulture); + + if (algorithms.ContainsKey(algorithmName)) + { + return (DerObjectIdentifier)algorithms[algorithmName]; + } + + return new DerObjectIdentifier(algorithmName); + } + + + internal static string GetAlgorithmName( + DerObjectIdentifier oid) + { + if (oids.ContainsKey(oid)) + { + return (string)oids[oid]; + } + + return oid.Id; + } + + internal static AlgorithmIdentifier GetSigAlgID( + DerObjectIdentifier sigOid) + { + if (noParams.Contains(sigOid)) + { + return new AlgorithmIdentifier(sigOid); + } + + return new AlgorithmIdentifier(sigOid, DerNull.Instance); + } + + internal static IEnumerable AlgNames + { + get { return new EnumerableProxy(algorithms.Keys); } + } + } +} diff --git a/iTechSharp/srcbc/ocsp/Req.cs b/iTechSharp/srcbc/ocsp/Req.cs new file mode 100644 index 0000000..68fd9f1 --- /dev/null +++ b/iTechSharp/srcbc/ocsp/Req.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class Req + : X509ExtensionBase + { + private Request req; + + public Req( + Request req) + { + this.req = req; + } + + public CertificateID GetCertID() + { + return new CertificateID(req.ReqCert); + } + + public X509Extensions SingleRequestExtensions + { + get { return req.SingleRequestExtensions; } + } + + protected override X509Extensions GetX509Extensions() + { + return SingleRequestExtensions; + } + } +} diff --git a/iTechSharp/srcbc/ocsp/RespData.cs b/iTechSharp/srcbc/ocsp/RespData.cs new file mode 100644 index 0000000..105726c --- /dev/null +++ b/iTechSharp/srcbc/ocsp/RespData.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class RespData + : X509ExtensionBase + { + internal readonly ResponseData data; + + public RespData( + ResponseData data) + { + this.data = data; + } + + public int Version + { + get { return data.Version.Value.IntValue + 1; } + } + + public RespID GetResponderId() + { + return new RespID(data.ResponderID); + } + + public DateTime ProducedAt + { + get { return data.ProducedAt.ToDateTime(); } + } + + public SingleResp[] GetResponses() + { + Asn1Sequence s = data.Responses; + SingleResp[] rs = new SingleResp[s.Count]; + + for (int i = 0; i != rs.Length; i++) + { + rs[i] = new SingleResp(SingleResponse.GetInstance(s[i])); + } + + return rs; + } + + public X509Extensions ResponseExtensions + { + get { return data.ResponseExtensions; } + } + + protected override X509Extensions GetX509Extensions() + { + return ResponseExtensions; + } + } +} diff --git a/iTechSharp/srcbc/ocsp/RespID.cs b/iTechSharp/srcbc/ocsp/RespID.cs new file mode 100644 index 0000000..302811d --- /dev/null +++ b/iTechSharp/srcbc/ocsp/RespID.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * Carrier for a ResponderID. + */ + public class RespID + { + internal readonly ResponderID id; + + public RespID( + ResponderID id) + { + this.id = id; + } + + public RespID( + X509Name name) + { + try + { + this.id = new ResponderID(name); + } + catch (Exception e) + { + throw new ArgumentException("can't decode name.", e); + } + } + + public RespID( + AsymmetricKeyParameter publicKey) + { + try + { + IDigest digest = DigestUtilities.GetDigest("SHA1"); + + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey); + + byte[] encoded = info.PublicKeyData.GetBytes(); + digest.BlockUpdate(encoded, 0, encoded.Length); + + byte[] hash = DigestUtilities.DoFinal(digest); + + Asn1OctetString keyHash = new DerOctetString(hash); + + this.id = new ResponderID(keyHash); + } + catch (Exception e) + { + throw new OcspException("problem creating ID: " + e, e); + } + } + + public ResponderID ToAsn1Object() + { + return id; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + RespID other = obj as RespID; + + if (other == null) + return false; + + return id.Equals(other.id); + } + + public override int GetHashCode() + { + return id.GetHashCode(); + } + } +} diff --git a/iTechSharp/srcbc/ocsp/RevokedStatus.cs b/iTechSharp/srcbc/ocsp/RevokedStatus.cs new file mode 100644 index 0000000..6e5ad1b --- /dev/null +++ b/iTechSharp/srcbc/ocsp/RevokedStatus.cs @@ -0,0 +1,58 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * wrapper for the RevokedInfo object + */ + public class RevokedStatus + : CertificateStatus + { + internal readonly RevokedInfo info; + + public RevokedStatus( + RevokedInfo info) + { + this.info = info; + } + + public RevokedStatus( + DateTime revocationDate, + int reason) + { + this.info = new RevokedInfo(new DerGeneralizedTime(revocationDate), new CrlReason(reason)); + } + + public DateTime RevocationTime + { + get { return info.RevocationTime.ToDateTime(); } + } + + public bool HasRevocationReason + { + get { return (info.RevocationReason != null); } + } + + /** + * return the revocation reason. Note: this field is optional, test for it + * with hasRevocationReason() first. + * @exception InvalidOperationException if a reason is asked for and none is avaliable + */ + public int RevocationReason + { + get + { + if (info.RevocationReason == null) + { + throw new InvalidOperationException("attempt to get a reason where none is available"); + } + + return info.RevocationReason.Value.IntValue; + } + } + } +} diff --git a/iTechSharp/srcbc/ocsp/SingleResp.cs b/iTechSharp/srcbc/ocsp/SingleResp.cs new file mode 100644 index 0000000..b8979c5 --- /dev/null +++ b/iTechSharp/srcbc/ocsp/SingleResp.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class SingleResp + : X509ExtensionBase + { + internal readonly SingleResponse resp; + + public SingleResp( + SingleResponse resp) + { + this.resp = resp; + } + + public CertificateID GetCertID() + { + return new CertificateID(resp.CertId); + } + + /** + * Return the status object for the response - null indicates good. + * + * @return the status object for the response, null if it is good. + */ + public object GetCertStatus() + { + CertStatus s = resp.CertStatus; + + if (s.TagNo == 0) + { + return null; // good + } + + if (s.TagNo == 1) + { + return new RevokedStatus(RevokedInfo.GetInstance(s.Status)); + } + + return new UnknownStatus(); + } + + public DateTime ThisUpdate + { + get { return resp.ThisUpdate.ToDateTime(); } + } + + /** + * return the NextUpdate value - note: this is an optional field so may + * be returned as null. + * + * @return nextUpdate, or null if not present. + */ + public DateTimeObject NextUpdate + { + get + { + return resp.NextUpdate == null + ? null + : new DateTimeObject(resp.NextUpdate.ToDateTime()); + } + } + + public X509Extensions SingleExtensions + { + get { return resp.SingleExtensions; } + } + + protected override X509Extensions GetX509Extensions() + { + return SingleExtensions; + } + } +} diff --git a/iTechSharp/srcbc/ocsp/UnknownStatus.cs b/iTechSharp/srcbc/ocsp/UnknownStatus.cs new file mode 100644 index 0000000..c0f7a3a --- /dev/null +++ b/iTechSharp/srcbc/ocsp/UnknownStatus.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * wrapper for the UnknownInfo object + */ + public class UnknownStatus + : CertificateStatus + { + public UnknownStatus() + { + } + } +} diff --git a/iTechSharp/srcbc/openpgp/IStreamGenerator.cs b/iTechSharp/srcbc/openpgp/IStreamGenerator.cs new file mode 100644 index 0000000..379213a --- /dev/null +++ b/iTechSharp/srcbc/openpgp/IStreamGenerator.cs @@ -0,0 +1,7 @@ +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public interface IStreamGenerator + { + void Close(); + } +} diff --git a/iTechSharp/srcbc/openpgp/PGPKeyRing.cs b/iTechSharp/srcbc/openpgp/PGPKeyRing.cs new file mode 100644 index 0000000..63708f7 --- /dev/null +++ b/iTechSharp/srcbc/openpgp/PGPKeyRing.cs @@ -0,0 +1,77 @@ +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public abstract class PgpKeyRing + : PgpObject + { + internal PgpKeyRing() + { + } + + internal static TrustPacket ReadOptionalTrustPacket( + BcpgInputStream bcpgInput) + { + return (bcpgInput.NextPacketTag() == PacketTag.Trust) + ? (TrustPacket) bcpgInput.ReadPacket() + : null; + } + + internal static ArrayList ReadSignaturesAndTrust( + BcpgInputStream bcpgInput) + { + try + { + ArrayList sigList = new ArrayList(); + + while (bcpgInput.NextPacketTag() == PacketTag.Signature) + { + SignaturePacket signaturePacket = (SignaturePacket) bcpgInput.ReadPacket(); + TrustPacket trustPacket = ReadOptionalTrustPacket(bcpgInput); + + sigList.Add(new PgpSignature(signaturePacket, trustPacket)); + } + + return sigList; + } + catch (PgpException e) + { + throw new IOException("can't create signature object: " + e.Message, e); + } + } + + internal static void ReadUserIDs( + BcpgInputStream bcpgInput, + out ArrayList ids, + out ArrayList idTrusts, + out ArrayList idSigs) + { + ids = new ArrayList(); + idTrusts = new ArrayList(); + idSigs = new ArrayList(); + + while (bcpgInput.NextPacketTag() == PacketTag.UserId + || bcpgInput.NextPacketTag() == PacketTag.UserAttribute) + { + Packet obj = bcpgInput.ReadPacket(); + if (obj is UserIdPacket) + { + UserIdPacket id = (UserIdPacket)obj; + ids.Add(id.GetId()); + } + else + { + UserAttributePacket user = (UserAttributePacket) obj; + ids.Add(new PgpUserAttributeSubpacketVector(user.GetSubpackets())); + } + + idTrusts.Add( + ReadOptionalTrustPacket(bcpgInput)); + + idSigs.Add( + ReadSignaturesAndTrust(bcpgInput)); + } + } + } +} diff --git a/iTechSharp/srcbc/openpgp/PGPObject.cs b/iTechSharp/srcbc/openpgp/PGPObject.cs new file mode 100644 index 0000000..d38276c --- /dev/null +++ b/iTechSharp/srcbc/openpgp/PGPObject.cs @@ -0,0 +1,9 @@ +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public abstract class PgpObject + { + internal PgpObject() + { + } + } +} diff --git a/iTechSharp/srcbc/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs b/iTechSharp/srcbc/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs new file mode 100644 index 0000000..3116dc6 --- /dev/null +++ b/iTechSharp/srcbc/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Bcpg.Attr; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public class PgpUserAttributeSubpacketVectorGenerator + { + private ArrayList list = new ArrayList(); + + public virtual void SetImageAttribute( + ImageAttrib.Format imageType, + byte[] imageData) + { + if (imageData == null) + throw new ArgumentException("attempt to set null image", "imageData"); + + list.Add(new ImageAttrib(imageType, imageData)); + } + + public virtual PgpUserAttributeSubpacketVector Generate() + { + return new PgpUserAttributeSubpacketVector( + (UserAttributeSubpacket[]) list.ToArray(typeof(UserAttributeSubpacket))); + } + } +} diff --git a/iTechSharp/srcbc/openpgp/PgpCompressedData.cs b/iTechSharp/srcbc/openpgp/PgpCompressedData.cs new file mode 100644 index 0000000..18c8fb4 --- /dev/null +++ b/iTechSharp/srcbc/openpgp/PgpCompressedData.cs @@ -0,0 +1,50 @@ +using System.IO; + +using Org.BouncyCastle.Apache.Bzip2; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + ///
+ /// Return an output stream which will save the data being written to + /// the compressed object. + ///
+ ///
+ /// The stream created can be closed off by either calling Close()
+ /// on the stream or Close() on the generator. Closing the returned
+ /// stream does not close off the Stream parameter
+ /// Return an output stream which will compress the data as it is written to it. + /// The stream will be written out in chunks according to the size of the passed in buffer. + ///
+ ///
+ /// The stream created can be closed off by either calling Close()
+ /// on the stream or Close() on the generator. Closing the returned
+ /// stream does not close off the Stream parameter
+ /// Note: if the buffer is not a power of 2 in length only the largest power of 2 + /// bytes worth of the buffer will be used. + ///
+ ///+ /// Note: using this may break compatibility with RFC 1991 compliant tools. + /// Only recent OpenPGP implementations are capable of accepting these streams. + ///
+ ///+ /// If buffer is non null stream assumed to be partial, otherwise the length will be used + /// to output a fixed length packet. + ///
+ ///
+ /// The stream created can be closed off by either calling Close()
+ /// on the stream or Close() on the generator. Closing the returned
+ /// stream does not close off the Stream parameter
+ /// Return an output stream which will encrypt the data as it is written to it. + ///
+ ///
+ /// The stream created can be closed off by either calling Close()
+ /// on the stream or Close() on the generator. Closing the returned
+ /// stream does not close off the Stream parameter
+ /// Return an output stream which will encrypt the data as it is written to it. + /// The stream will be written out in chunks according to the size of the passed in buffer. + ///
+ ///
+ /// The stream created can be closed off by either calling Close()
+ /// on the stream or Close() on the generator. Closing the returned
+ /// stream does not close off the Stream parameter
+ /// Note: if the buffer is not a power of 2 in length only the largest power of 2 + /// bytes worth of the buffer will be used. + ///
+ ///+ /// Close off the encrypted object - this is equivalent to calling Close() on the stream + /// returned by the Open() method. + ///
+ ///+ /// Note: This does not close the underlying output stream, only the stream on top of + /// it created by the Open() method. + ///
+ ///+ /// A word for the unwary, the KeyId for an OpenPGP public key is calculated from + /// a hash that includes the time of creation, if you pass a different date to the + /// constructor below with the same public private key pair the KeyIs will not be the + /// same as for previous generations of the key, so ideally you only want to do + /// this once. + ///
+ ///+ /// Open a literal data packet, returning a stream to store the data inside the packet. + ///
+ ///
+ /// The stream created can be closed off by either calling Close()
+ /// on the stream or Close() on the generator. Closing the returned
+ /// stream does not close off the Stream parameter
+ /// Open a literal data packet, returning a stream to store the data inside the packet, + /// as an indefinite length stream. The stream is written out as a series of partial + /// packets with a chunk size determined by the size of the passed in buffer. + ///
+ ///
+ /// The stream created can be closed off by either calling Close()
+ /// on the stream or Close() on the generator. Closing the returned
+ /// stream does not close off the Stream parameter
+ /// Note: if the buffer is not a power of 2 in length only the largest power of 2 + /// bytes worth of the buffer will be used.
+ ///
+ /// Open a literal data packet for the passed in
+ /// The stream created can be closed off by either calling Close()
+ /// on the stream or Close() on the generator. Closing the returned
+ /// stream does not close off the Stream parameter
+ /// Note: if this class finds a PgpPublicKey or a PgpSecretKey it + /// will create a PgpPublicKeyRing, or a PgpSecretKeyRing for each + /// key found. If all you are trying to do is read a key ring file use + /// either PgpPublicKeyRingBundle or PgpSecretKeyRingBundle.
+ ///
+ /// Often PGP keyring files consist of multiple master keys, if you are trying to process
+ /// or construct one of these you should use the
+ /// Often PGP keyring files consist of multiple master keys, if you are trying to process
+ /// or construct one of these you should use the
+ /// Note: this overrides the generation of a creation time when the signature + /// is generated.
+ ///+ * In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Keys and + * Certificates will be returned using the appropriate java.security type.
+ */ + public class PemReader + { + private readonly TextReader reader; + private readonly IPasswordFinder pFinder; + + public TextReader Reader + { + get { return reader; } + } + + /** + * Create a new PemReader + * + * @param reader the Reader + */ + public PemReader( + TextReader reader) + : this(reader, null) + { + } + + /** + * Create a new PemReader with a password finder + * + * @param reader the Reader + * @param pFinder the password finder + */ + public PemReader( + TextReader reader, + IPasswordFinder pFinder) + { + if (reader == null) + throw new ArgumentNullException("reader"); + + this.reader = reader; + this.pFinder = pFinder; + } + + private const string BeginString = "-----BEGIN "; + + public object ReadObject() + { + string line; + while ((line = reader.ReadLine()) != null) + { + int startPos = line.IndexOf(BeginString); + if (startPos == -1) + continue; + + startPos += BeginString.Length; + + int endPos = line.IndexOf('-', startPos); + if (endPos == -1) + endPos = line.Length; + + string headerName = line.Substring(startPos, endPos - startPos).Trim(); + //Console.WriteLine("[" + headerName + "]"); + + string endMarker = "-----END " + headerName; + + switch (headerName) + { + case "PUBLIC KEY": + return ReadPublicKey(endMarker); + case "RSA PUBLIC KEY": + return ReadRsaPublicKey(endMarker); + case "CERTIFICATE REQUEST": + case "NEW CERTIFICATE REQUEST": + return ReadCertificateRequest(endMarker); + case "CERTIFICATE": + case "X509 CERTIFICATE": + return ReadCertificate(endMarker); + case "PKCS7": + return ReadPkcs7(endMarker); + case "X509 CRL": + return ReadCrl(endMarker); + case "ATTRIBUTE CERTIFICATE": + return ReadAttributeCertificate(endMarker); + case "RSA PRIVATE KEY": + return ReadKeyPair("RSA", endMarker); + case "DSA PRIVATE KEY": + return ReadKeyPair("DSA", endMarker); + // TODO Add back in when tests done, and return type issue resolved + //case "EC PARAMETERS": + // return ReadECParameters(endMarker); + case "EC PRIVATE KEY": + return ReadECPrivateKey(endMarker); + default: + // TODO Throw an exception for an unknown header? + + // Ignore contents + ReadBytes(endMarker); + break; + } + } + + return null; + } + + private byte[] ReadBytes( + string endMarker) + { + return ReadBytesAndFields(endMarker, null); + } + + private byte[] ReadBytesAndFields( + string endMarker, + IDictionary fields) + { + StringBuilder buf = new StringBuilder(); + + string line; + while ((line = reader.ReadLine()) != null + && line.IndexOf(endMarker) == -1) + { + int colonPos = line.IndexOf(':'); + + if (colonPos == -1) + { + buf.Append(line.Trim()); + } + else if (fields != null) + { + // Process field + string fieldName = line.Substring(0, colonPos).Trim(); + + if (fieldName.StartsWith("X-")) + fieldName = fieldName.Substring(2); + + string fieldValue = line.Substring(colonPos + 1).Trim(); + + // TODO Complain if field already specified? + fields[fieldName] = fieldValue; + } + } + + if (line == null) + { + throw new IOException(endMarker + " not found"); + } + + if (buf.Length % 4 != 0) + { + throw new IOException("base64 data appears to be truncated"); + } + + return Base64.Decode(buf.ToString()); + } + + private AsymmetricKeyParameter ReadRsaPublicKey( + string endMarker) + { + RsaPublicKeyStructure rsaPubStructure = RsaPublicKeyStructure.GetInstance( + Asn1Object.FromByteArray( + ReadBytes(endMarker))); + + return new RsaKeyParameters( + false, // not private + rsaPubStructure.Modulus, + rsaPubStructure.PublicExponent); + } + + private AsymmetricKeyParameter ReadPublicKey( + string endMarker) + { + return PublicKeyFactory.CreateKey( + ReadBytes(endMarker)); + } + + /** + * Reads in a X509Certificate. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + private X509Certificate ReadCertificate( + string endMarker) + { + byte[] bytes = ReadBytes(endMarker); + + try + { + return new X509CertificateParser().ReadCertificate(bytes); + } + catch (Exception e) + { + throw new IOException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a X509CRL. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + private X509Crl ReadCrl( + string endMarker) + { + byte[] bytes = ReadBytes(endMarker); + + try + { + return new X509CrlParser().ReadCrl(bytes); + } + catch (Exception e) + { + throw new IOException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a PKCS10 certification request. + * + * @return the certificate request. + * @throws IOException if an I/O error occured + */ + private Pkcs10CertificationRequest ReadCertificateRequest( + string endMarker) + { + byte[] bytes = ReadBytes(endMarker); + + try + { + return new Pkcs10CertificationRequest(bytes); + } + catch (Exception e) + { + throw new IOException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a X509 Attribute Certificate. + * + * @return the X509 Attribute Certificate + * @throws IOException if an I/O error occured + */ + private IX509AttributeCertificate ReadAttributeCertificate( + string endMarker) + { + byte[] bytes = ReadBytes(endMarker); + + return new X509V2AttributeCertificate(bytes); + } + + /** + * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS + * API. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + // TODO Consider returning Asn1.Pkcs.ContentInfo + private Asn1.Cms.ContentInfo ReadPkcs7( + string endMarker) + { + byte[] bytes = ReadBytes(endMarker); + + try + { + return Asn1.Cms.ContentInfo.GetInstance( + Asn1Object.FromByteArray(bytes)); + } + catch (Exception e) + { + throw new IOException("problem parsing PKCS7 object: " + e.ToString()); + } + } + + /** + * Read a Key Pair + */ + private AsymmetricCipherKeyPair ReadKeyPair( + string type, + string endMarker) + { + // + // extract the key + // + IDictionary fields = new Hashtable(); + byte[] keyBytes = ReadBytesAndFields(endMarker, fields); + + string procType = (string) fields["Proc-Type"]; + + if (procType == "4,ENCRYPTED") + { + if (pFinder == null) + throw new InvalidOperationException("No password finder specified, but a password is required"); + + char[] password = pFinder.GetPassword(); + + if (password == null) + throw new IOException("Password is null, but a password is required"); + + string dekInfo = (string) fields["DEK-Info"]; + string[] tknz = dekInfo.Split(','); + + string dekAlgName = tknz[0].Trim(); + byte[] iv = Hex.Decode(tknz[1].Trim()); + + keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv); + } + + try + { + AsymmetricKeyParameter pubSpec, privSpec; + Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(keyBytes); + + switch (type) + { + case "RSA": + { + RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq); + + pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent); + privSpec = new RsaPrivateCrtKeyParameters( + rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, + rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, + rsa.Coefficient); + + break; + } + + case "DSA": + { + // TODO Create an ASN1 object somewhere for this? + //DerInteger v = (DerInteger)seq[0]; + DerInteger p = (DerInteger)seq[1]; + DerInteger q = (DerInteger)seq[2]; + DerInteger g = (DerInteger)seq[3]; + DerInteger y = (DerInteger)seq[4]; + DerInteger x = (DerInteger)seq[5]; + + DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value); + + privSpec = new DsaPrivateKeyParameters(x.Value, parameters); + pubSpec = new DsaPublicKeyParameters(y.Value, parameters); + + break; + } + + default: + throw new ArgumentException("Unknown key type: " + type, "type"); + } + + return new AsymmetricCipherKeyPair(pubSpec, privSpec); + } + catch (Exception e) + { + throw new IOException( + "problem creating " + type + " private key: " + e.ToString()); + } + } + + // TODO Add an equivalent class for ECNamedCurveParameterSpec? + //private ECNamedCurveParameterSpec ReadECParameters( + private X9ECParameters ReadECParameters( + string endMarker) + { + byte[] bytes = ReadBytes(endMarker); + DerObjectIdentifier oid = (DerObjectIdentifier) Asn1Object.FromByteArray(bytes); + + //return ECNamedCurveTable.getParameterSpec(oid.Id); + return GetCurveParameters(oid.Id); + } + + //private static ECDomainParameters GetCurveParameters( + private static X9ECParameters GetCurveParameters( + string name) + { + // TODO ECGost3410NamedCurves support (returns ECDomainParameters though) + X9ECParameters ecP = X962NamedCurves.GetByName(name); + + if (ecP == null) + { + ecP = SecNamedCurves.GetByName(name); + if (ecP == null) + { + ecP = NistNamedCurves.GetByName(name); + if (ecP == null) + { + ecP = TeleTrusTNamedCurves.GetByName(name); + + if (ecP == null) + throw new Exception("unknown curve name: " + name); + } + } + } + + //return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); + return ecP; + } + + private AsymmetricCipherKeyPair ReadECPrivateKey( + string endMarker) + { + try + { + byte[] bytes = ReadBytes(endMarker); + ECPrivateKeyStructure pKey = new ECPrivateKeyStructure( + (Asn1Sequence) Asn1Object.FromByteArray(bytes)); + AlgorithmIdentifier algId = new AlgorithmIdentifier( + X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters()); + + PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object()); + SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pKey.GetPublicKey().GetBytes()); + + // TODO Are the keys returned here ECDSA, as Java version forces? + return new AsymmetricCipherKeyPair( + PublicKeyFactory.CreateKey(pubInfo), + PrivateKeyFactory.CreateKey(privInfo)); + } + catch (InvalidCastException e) + { + throw new IOException("wrong ASN.1 object found in stream.", e); + } + catch (Exception e) + { + throw new IOException("problem parsing EC private key.", e); + } + } + } +} diff --git a/iTechSharp/srcbc/openssl/PEMUtilities.cs b/iTechSharp/srcbc/openssl/PEMUtilities.cs new file mode 100644 index 0000000..ca944a8 --- /dev/null +++ b/iTechSharp/srcbc/openssl/PEMUtilities.cs @@ -0,0 +1,138 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.OpenSsl +{ + internal sealed class PemUtilities + { + internal static bool ParseDekAlgName( + string dekAlgName, + out string baseAlg, + out string mode) + { + baseAlg = dekAlgName; + mode = "ECB"; + + if (dekAlgName == "DES-EDE" || dekAlgName == "DES-EDE3") + return true; + + int pos = dekAlgName.LastIndexOf('-'); + if (pos < 0) + return false; + + baseAlg = dekAlgName.Substring(0, pos); + mode = dekAlgName.Substring(pos + 1); + + return true; + } + + internal static byte[] Crypt( + bool encrypt, + byte[] bytes, + char[] password, + string dekAlgName, + byte[] iv) + { + string baseAlg, mode; + if (!ParseDekAlgName(dekAlgName, out baseAlg, out mode)) + throw new ArgumentException("Unknown DEK algorithm: " + dekAlgName, "dekAlgName"); + + string padding; + switch (mode) + { + case "CBC": + case "ECB": + padding = "PKCS5Padding"; + break; + case "CFB": + case "OFB": + padding = "NoPadding"; + break; + default: + throw new ArgumentException("Unknown DEK algorithm: " + dekAlgName, "dekAlgName"); + } + + string algorithm; + + byte[] salt = iv; + switch (baseAlg) + { + case "AES-128": + case "AES-192": + case "AES-256": + algorithm = "AES"; + if (salt.Length > 8) + { + salt = new byte[8]; + Array.Copy(iv, 0, salt, 0, salt.Length); + } + break; + case "BF": + algorithm = "BLOWFISH"; + break; + case "DES": + algorithm = "DES"; + break; + case "DES-EDE": + case "DES-EDE3": + algorithm = "DESede"; + break; + case "RC2": + case "RC2-40": + case "RC2-64": + algorithm = "RC2"; + break; + default: + throw new ArgumentException("Unknown DEK algorithm: " + dekAlgName, "dekAlgName"); + } + + string cipherName = algorithm + "/" + mode + "/" + padding; + IBufferedCipher cipher = CipherUtilities.GetCipher(cipherName); + + ICipherParameters cParams = GetCipherParameters(password, baseAlg, salt); + + if (mode != "ECB") + { + cParams = new ParametersWithIV(cParams, iv); + } + + cipher.Init(encrypt, cParams); + + return cipher.DoFinal(bytes); + } + + private static ICipherParameters GetCipherParameters( + char[] password, + string baseAlg, + byte[] salt) + { + string algorithm; + int keyBits; + switch (baseAlg) + { + case "AES-128": keyBits = 128; algorithm = "AES128"; break; + case "AES-192": keyBits = 192; algorithm = "AES192"; break; + case "AES-256": keyBits = 256; algorithm = "AES256"; break; + case "BF": keyBits = 128; algorithm = "BLOWFISH"; break; + case "DES": keyBits = 64; algorithm = "DES"; break; + case "DES-EDE": keyBits = 128; algorithm = "DESEDE"; break; + case "DES-EDE3": keyBits = 192; algorithm = "DESEDE3"; break; + case "RC2": keyBits = 128; algorithm = "RC2"; break; + case "RC2-40": keyBits = 40; algorithm = "RC2"; break; + case "RC2-64": keyBits = 64; algorithm = "RC2"; break; + default: + return null; + } + + OpenSslPbeParametersGenerator pGen = new OpenSslPbeParametersGenerator(); + + pGen.Init(PbeParametersGenerator.Pkcs5PasswordToBytes(password), salt); + + return pGen.GenerateDerivedParameters(algorithm, keyBits); + } + } +} diff --git a/iTechSharp/srcbc/openssl/PEMWriter.cs b/iTechSharp/srcbc/openssl/PEMWriter.cs new file mode 100644 index 0000000..bea67b6 --- /dev/null +++ b/iTechSharp/srcbc/openssl/PEMWriter.cs @@ -0,0 +1,278 @@ +using System; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.OpenSsl +{ + ///
+ /// CertificationRequest ::= Sequence {
+ /// certificationRequestInfo CertificationRequestInfo,
+ /// signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
+ /// signature BIT STRING
+ /// }
+ ///
+ /// CertificationRequestInfo ::= Sequence {
+ /// version Integer { v1(0) } (v1,...),
+ /// subject Name,
+ /// subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+ /// attributes [0] Attributes{{ CRIAttributes }}
+ /// }
+ ///
+ /// Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }}
+ ///
+ /// Attr { ATTRIBUTE:IOSet } ::= Sequence {
+ /// type ATTRIBUTE.&id({IOSet}),
+ /// values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
+ /// }
+ ///
+ /// see
+ public class Pkcs10CertificationRequest
+ : CertificationRequest
+ {
+ private static readonly Hashtable algorithms = new Hashtable();
+ private static readonly Hashtable exParams = new Hashtable();
+ private static readonly Hashtable keyAlgorithms = new Hashtable();
+ private static readonly Hashtable oids = new Hashtable();
+ private static readonly ISet noParams = new HashSet();
+
+ static Pkcs10CertificationRequest()
+ {
+ algorithms.Add("MD2WITHRSAENCRYPTION", new DerObjectIdentifier("1.2.840.113549.1.1.2"));
+ algorithms.Add("MD2WITHRSA", new DerObjectIdentifier("1.2.840.113549.1.1.2"));
+ algorithms.Add("MD5WITHRSAENCRYPTION", new DerObjectIdentifier("1.2.840.113549.1.1.4"));
+ algorithms.Add("MD5WITHRSA", new DerObjectIdentifier("1.2.840.113549.1.1.4"));
+ algorithms.Add("RSAWITHMD5", new DerObjectIdentifier("1.2.840.113549.1.1.4"));
+ algorithms.Add("SHA1WITHRSAENCRYPTION", new DerObjectIdentifier("1.2.840.113549.1.1.5"));
+ algorithms.Add("SHA1WITHRSA", new DerObjectIdentifier("1.2.840.113549.1.1.5"));
+ algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
+ algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
+ algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
+ algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
+ algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
+ algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
+ algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
+ algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
+ algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+ algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+ algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+ algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+ algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+ algorithms.Add("RSAWITHSHA1", new DerObjectIdentifier("1.2.840.113549.1.1.5"));
+ algorithms.Add("RIPEMD160WITHRSAENCRYPTION", new DerObjectIdentifier("1.3.36.3.3.1.2"));
+ algorithms.Add("RIPEMD160WITHRSA", new DerObjectIdentifier("1.3.36.3.3.1.2"));
+ algorithms.Add("SHA1WITHDSA", new DerObjectIdentifier("1.2.840.10040.4.3"));
+ algorithms.Add("DSAWITHSHA1", new DerObjectIdentifier("1.2.840.10040.4.3"));
+ algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224);
+ algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256);
+ algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1);
+ algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224);
+ algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256);
+ algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384);
+ algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512);
+ algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1);
+ algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+ algorithms.Add("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+ algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+ algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+ algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+
+ //
+ // reverse mappings
+ //
+ oids.Add(new DerObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA");
+ oids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224WITHRSA");
+ oids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256WITHRSA");
+ oids.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption, "SHA384WITHRSA");
+ oids.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption, "SHA512WITHRSA");
+ oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, "GOST3411WITHGOST3410");
+ oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001, "GOST3411WITHECGOST3410");
+
+ oids.Add(new DerObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
+ oids.Add(new DerObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
+ oids.Add(new DerObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
+ oids.Add(X9ObjectIdentifiers.ECDsaWithSha1, "SHA1WITHECDSA");
+ oids.Add(X9ObjectIdentifiers.ECDsaWithSha224, "SHA224WITHECDSA");
+ oids.Add(X9ObjectIdentifiers.ECDsaWithSha256, "SHA256WITHECDSA");
+ oids.Add(X9ObjectIdentifiers.ECDsaWithSha384, "SHA384WITHECDSA");
+ oids.Add(X9ObjectIdentifiers.ECDsaWithSha512, "SHA512WITHECDSA");
+ oids.Add(OiwObjectIdentifiers.Sha1WithRsa, "SHA1WITHRSA");
+ oids.Add(OiwObjectIdentifiers.DsaWithSha1, "SHA1WITHDSA");
+ oids.Add(NistObjectIdentifiers.DsaWithSha224, "SHA224WITHDSA");
+ oids.Add(NistObjectIdentifiers.DsaWithSha256, "SHA256WITHDSA");
+
+ //
+ // key types
+ //
+ keyAlgorithms.Add(PkcsObjectIdentifiers.RsaEncryption, "RSA");
+ keyAlgorithms.Add(X9ObjectIdentifiers.IdDsa, "DSA");
+
+ //
+ // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
+ // The parameters field SHALL be NULL for RSA based signature algorithms.
+ //
+ noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1);
+ noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224);
+ noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256);
+ noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384);
+ noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512);
+ noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1);
+ noParams.Add(NistObjectIdentifiers.DsaWithSha224);
+ noParams.Add(NistObjectIdentifiers.DsaWithSha256);
+
+ //
+ // RFC 4491
+ //
+ noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+ noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+
+ //
+ // explicit params
+ //
+ AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+ exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20));
+
+ AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance);
+ exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28));
+
+ AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
+ exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32));
+
+ AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
+ exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48));
+
+ AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
+ exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64));
+ }
+
+ private static RsassaPssParameters CreatePssParams(
+ AlgorithmIdentifier hashAlgId,
+ int saltSize)
+ {
+ return new RsassaPssParameters(
+ hashAlgId,
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId),
+ new DerInteger(saltSize),
+ new DerInteger(1));
+ }
+
+ public Pkcs10CertificationRequest(
+ byte[] encoded)
+ : base((Asn1Sequence) Asn1Object.FromByteArray(encoded))
+ {
+ }
+
+ public Pkcs10CertificationRequest(
+ Asn1Sequence seq)
+ : base(seq)
+ {
+ }
+
+ public Pkcs10CertificationRequest(
+ Stream input)
+ : base((Asn1Sequence) Asn1Object.FromStream(input))
+ {
+ }
+
+ /// + * If a failure code is assciated with the exception it can be retrieved using + * the getFailureCode() method.
+ */ + public class TspValidationException + : TspException + { + private int failureCode; + + public TspValidationException( + string message) + : base(message) + { + this.failureCode = -1; + } + + public TspValidationException( + string message, + int failureCode) + : base(message) + { + this.failureCode = failureCode; + } + + /** + * Return the failure code associated with this exception - if one is set. + * + * @return the failure code if set, -1 otherwise. + */ + public int FailureCode + { + get { return failureCode; } + } + } +} diff --git a/iTechSharp/srcbc/tsp/TimeStampRequest.cs b/iTechSharp/srcbc/tsp/TimeStampRequest.cs new file mode 100644 index 0000000..7205a9a --- /dev/null +++ b/iTechSharp/srcbc/tsp/TimeStampRequest.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Base class for an RFC 3161 Time Stamp Request. + */ + public class TimeStampRequest + : X509ExtensionBase + { + private TimeStampReq req; + + public TimeStampRequest( + TimeStampReq req) + { + this.req = req; + } + + /** + * Create a TimeStampRequest from the past in byte array. + * + * @param req byte array containing the request. + * @throws IOException if the request is malformed. + */ + public TimeStampRequest( + byte[] req) + : this(new Asn1InputStream(req)) + { + } + + /** + * Create a TimeStampRequest from the past in input stream. + * + * @param in input stream containing the request. + * @throws IOException if the request is malformed. + */ + public TimeStampRequest( + Stream input) + : this(new Asn1InputStream(input)) + { + } + + private TimeStampRequest( + Asn1InputStream str) + { + try + { + this.req = TimeStampReq.GetInstance(str.ReadObject()); + } + catch (InvalidCastException e) + { + throw new IOException("malformed request: " + e); + } + catch (ArgumentException e) + { + throw new IOException("malformed request: " + e); + } + } + + public int Version + { + get { return req.Version.Value.IntValue; } + } + + public string MessageImprintAlgOid + { + get { return req.MessageImprint.HashAlgorithm.ObjectID.Id; } + } + + public byte[] GetMessageImprintDigest() + { + return req.MessageImprint.GetHashedMessage(); + } + + public string ReqPolicy + { + get + { + return req.ReqPolicy == null + ? null + : req.ReqPolicy.Id; + } + } + + public BigInteger Nonce + { + get + { + return req.Nonce == null + ? null + : req.Nonce.Value; + } + } + + public bool CertReq + { + get + { + return req.CertReq == null + ? false + : req.CertReq.IsTrue; + } + } + + /** + * Validate the timestamp request, checking the digest to see if it is of an + * accepted type and whether it is of the correct length for the algorithm specified. + * + * @param algorithms a set of string OIDS giving accepted algorithms. + * @param policies if non-null a set of policies we are willing to sign under. + * @param extensions if non-null a set of extensions we are willing to accept. + * @throws TspException if the request is invalid, or processing fails. + */ + public void Validate( + IList algorithms, + IList policies, + IList extensions) + { + if (!algorithms.Contains(this.MessageImprintAlgOid)) + { + throw new TspValidationException("request contains unknown algorithm.", PkiFailureInfo.BadAlg); + } + + if (policies != null && this.ReqPolicy != null && !policies.Contains(this.ReqPolicy)) + { + throw new TspValidationException("request contains unknown policy.", PkiFailureInfo.UnacceptedPolicy); + } + + if (this.Extensions != null && extensions != null) + { + foreach (DerObjectIdentifier oid in this.Extensions.ExtensionOids) + { + if (!extensions.Contains(oid.Id)) + { + throw new TspValidationException("request contains unknown extension.", + PkiFailureInfo.UnacceptedExtension); + } + } + } + + int digestLength = TspUtil.GetDigestLength(this.MessageImprintAlgOid); + + if (digestLength != this.GetMessageImprintDigest().Length) + { + throw new TspValidationException("imprint digest the wrong length.", + PkiFailureInfo.BadDataFormat); + } + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return req.GetEncoded(); + } + + internal X509Extensions Extensions + { + get { return req.Extensions; } + } + + protected override X509Extensions GetX509Extensions() + { + return Extensions; + } + } +} diff --git a/iTechSharp/srcbc/tsp/TimeStampRequestGenerator.cs b/iTechSharp/srcbc/tsp/TimeStampRequestGenerator.cs new file mode 100644 index 0000000..fc37d32 --- /dev/null +++ b/iTechSharp/srcbc/tsp/TimeStampRequestGenerator.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Generator for RFC 3161 Time Stamp Request objects. + */ + public class TimeStampRequestGenerator + { + private DerObjectIdentifier reqPolicy; + + private DerBoolean certReq; + + private Hashtable extensions = new Hashtable(); + private ArrayList extOrdering = new ArrayList(); + + public void SetReqPolicy( + string reqPolicy) + { + this.reqPolicy = new DerObjectIdentifier(reqPolicy); + } + + public void SetCertReq( + bool certReq) + { + this.certReq = DerBoolean.GetInstance(certReq); + } + + /** + * add a given extension field for the standard extensions tag (tag 3) + * @throws IOException + */ + public void AddExtension( + string oid, + bool critical, + Asn1Encodable value) + { + this.AddExtension(oid, critical, value.GetEncoded()); + } + + /** + * add a given extension field for the standard extensions tag + * The value parameter becomes the contents of the octet string associated + * with the extension. + */ + public void AddExtension( + string oid, + bool critical, + byte[] value) + { + DerObjectIdentifier derOid = new DerObjectIdentifier(oid); + extensions[derOid] = new X509Extension(critical, new DerOctetString(value)); + extOrdering.Add(derOid); + } + + public TimeStampRequest Generate( + string digestAlgorithm, + byte[] digest) + { + return this.Generate(digestAlgorithm, digest, null); + } + + public TimeStampRequest Generate( + string digestAlgorithmOid, + byte[] digest, + BigInteger nonce) + { + if (digestAlgorithmOid == null) + { + throw new ArgumentException("No digest algorithm specified"); + } + + DerObjectIdentifier digestAlgOid = new DerObjectIdentifier(digestAlgorithmOid); + + AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOid, DerNull.Instance); + MessageImprint messageImprint = new MessageImprint(algID, digest); + + X509Extensions ext = null; + + if (extOrdering.Count != 0) + { + ext = new X509Extensions(extOrdering, extensions); + } + + DerInteger derNonce = nonce == null + ? null + : new DerInteger(nonce); + + return new TimeStampRequest( + new TimeStampReq(messageImprint, reqPolicy, derNonce, certReq, ext)); + } + } +} diff --git a/iTechSharp/srcbc/tsp/TimeStampResponse.cs b/iTechSharp/srcbc/tsp/TimeStampResponse.cs new file mode 100644 index 0000000..fca71f7 --- /dev/null +++ b/iTechSharp/srcbc/tsp/TimeStampResponse.cs @@ -0,0 +1,173 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Base class for an RFC 3161 Time Stamp Response object. + */ + public class TimeStampResponse + { + private TimeStampResp resp; + private TimeStampToken timeStampToken; + + public TimeStampResponse( + TimeStampResp resp) + { + this.resp = resp; + + if (resp.TimeStampToken != null) + { + timeStampToken = new TimeStampToken(resp.TimeStampToken); + } + } + + /** + * Create a TimeStampResponse from a byte array containing an ASN.1 encoding. + * + * @param resp the byte array containing the encoded response. + * @throws TspException if the response is malformed. + * @throws IOException if the byte array doesn't represent an ASN.1 encoding. + */ + public TimeStampResponse( + byte[] resp) + : this(readTimeStampResp(new Asn1InputStream(resp))) + { + } + + /** + * Create a TimeStampResponse from an input stream containing an ASN.1 encoding. + * + * @param input the input stream containing the encoded response. + * @throws TspException if the response is malformed. + * @throws IOException if the stream doesn't represent an ASN.1 encoding. + */ + public TimeStampResponse( + Stream input) + : this(readTimeStampResp(new Asn1InputStream(input))) + { + } + + private static TimeStampResp readTimeStampResp( + Asn1InputStream input) + { + try + { + return TimeStampResp.GetInstance(input.ReadObject()); + } + catch (ArgumentException e) + { + throw new TspException("malformed timestamp response: " + e, e); + } + catch (InvalidCastException e) + { + throw new TspException("malformed timestamp response: " + e, e); + } + } + + public int Status + { + get { return resp.Status.Status.IntValue; } + } + + public string GetStatusString() + { + if (resp.Status.StatusString == null) + { + return null; + } + + StringBuilder statusStringBuf = new StringBuilder(); + PkiFreeText text = resp.Status.StatusString; + for (int i = 0; i != text.Count; i++) + { + statusStringBuf.Append(text[i].GetString()); + } + + return statusStringBuf.ToString(); + } + + public PkiFailureInfo GetFailInfo() + { + if (resp.Status.FailInfo == null) + { + return null; + } + + return new PkiFailureInfo(resp.Status.FailInfo); + } + + public TimeStampToken TimeStampToken + { + get { return timeStampToken; } + } + + /** + * Check this response against to see if it a well formed response for + * the passed in request. Validation will include checking the time stamp + * token if the response status is GRANTED or GRANTED_WITH_MODS. + * + * @param request the request to be checked against + * @throws TspException if the request can not match this response. + */ + public void Validate( + TimeStampRequest request) + { + TimeStampToken tok = this.TimeStampToken; + + if (tok != null) + { + TimeStampTokenInfo tstInfo = tok.TimeStampInfo; + + if (request.Nonce != null && !request.Nonce.Equals(tstInfo.Nonce)) + { + throw new TspValidationException("response contains wrong nonce value."); + } + + if (this.Status != (int) PkiStatus.Granted && this.Status != (int) PkiStatus.GrantedWithMods) + { + throw new TspValidationException("time stamp token found in failed request."); + } + + if (!Arrays.AreEqual(request.GetMessageImprintDigest(), tstInfo.GetMessageImprintDigest())) + { + throw new TspValidationException("response for different message imprint digest."); + } + + if (!tstInfo.MessageImprintAlgOid.Equals(request.MessageImprintAlgOid)) + { + throw new TspValidationException("response for different message imprint algorithm."); + } + + if (tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate] == null) + { + throw new TspValidationException("no signing certificate attribute present."); + } + + if (request.ReqPolicy != null && !request.ReqPolicy.Equals(tstInfo.Policy)) + { + throw new TspValidationException("TSA policy wrong for request."); + } + } + else if (this.Status == (int) PkiStatus.Granted || this.Status == (int) PkiStatus.GrantedWithMods) + { + throw new TspValidationException("no time stamp token found and one expected."); + } + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return resp.GetEncoded(); + } + } +} diff --git a/iTechSharp/srcbc/tsp/TimeStampResponseGenerator.cs b/iTechSharp/srcbc/tsp/TimeStampResponseGenerator.cs new file mode 100644 index 0000000..0ae3b30 --- /dev/null +++ b/iTechSharp/srcbc/tsp/TimeStampResponseGenerator.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Generator for RFC 3161 Time Stamp Responses. + */ + public class TimeStampResponseGenerator + { + private PkiStatus status; + + private Asn1EncodableVector statusStrings; + + private int failInfo; + private TimeStampTokenGenerator tokenGenerator; + private IList acceptedAlgorithms; + private IList acceptedPolicies; + private IList acceptedExtensions; + + public TimeStampResponseGenerator( + TimeStampTokenGenerator tokenGenerator, + IList acceptedAlgorithms) + : this(tokenGenerator, acceptedAlgorithms, null, null) + { + } + + public TimeStampResponseGenerator( + TimeStampTokenGenerator tokenGenerator, + IList acceptedAlgorithms, + IList acceptedPolicy) + : this(tokenGenerator, acceptedAlgorithms, acceptedPolicy, null) + { + } + + public TimeStampResponseGenerator( + TimeStampTokenGenerator tokenGenerator, + IList acceptedAlgorithms, + IList acceptedPolicies, + IList acceptedExtensions) + { + this.tokenGenerator = tokenGenerator; + this.acceptedAlgorithms = acceptedAlgorithms; + this.acceptedPolicies = acceptedPolicies; + this.acceptedExtensions = acceptedExtensions; + + statusStrings = new Asn1EncodableVector(); + } + + private void addStatusString( + string statusString) + { + statusStrings.Add(new DerUtf8String(statusString)); + } + + private void setFailInfoField(int field) + { + failInfo = failInfo | field; + } + + private PkiStatusInfo getPkiStatusInfo() + { + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger((int) status)); + + if (statusStrings.Count > 0) + { + v.Add(new PkiFreeText(new DerSequence(statusStrings))); + } + + if (failInfo != 0) + { + v.Add(new FailInfo(failInfo)); + } + + return new PkiStatusInfo(new DerSequence(v)); + } + + public TimeStampResponse Generate( + TimeStampRequest request, + BigInteger serialNumber, + DateTime genTime) + { + TimeStampResp resp; + + try + { + request.Validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions); + + status = PkiStatus.Granted; + this.addStatusString("Operation Okay"); + + PkiStatusInfo pkiStatusInfo = getPkiStatusInfo(); + + ContentInfo tstTokenContentInfo; + try + { + TimeStampToken token = tokenGenerator.Generate(request, serialNumber, genTime); + byte[] encoded = token.ToCmsSignedData().GetEncoded(); + + tstTokenContentInfo = ContentInfo.GetInstance(Asn1Object.FromByteArray(encoded)); + } + catch (IOException ioEx) + { + throw new TspException( + "Timestamp token received cannot be converted to ContentInfo", ioEx); + } + + resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo); + } + catch (TspValidationException e) + { + status = PkiStatus.Rejection; + + this.setFailInfoField(e.FailureCode); + this.addStatusString(e.Message); + + PkiStatusInfo pkiStatusInfo = getPkiStatusInfo(); + + resp = new TimeStampResp(pkiStatusInfo, null); + } + + try + { + return new TimeStampResponse(resp); + } + catch (IOException) + { + throw new TspException("created badly formatted response!"); + } + } + + class FailInfo + : DerBitString + { + internal FailInfo( + int failInfoValue) + : base(GetBytes(failInfoValue), GetPadBits(failInfoValue)) + { + } + } + } +} diff --git a/iTechSharp/srcbc/tsp/TimeStampToken.cs b/iTechSharp/srcbc/tsp/TimeStampToken.cs new file mode 100644 index 0000000..17b5853 --- /dev/null +++ b/iTechSharp/srcbc/tsp/TimeStampToken.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ess; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Tsp +{ + public class TimeStampToken + { + private readonly CmsSignedData tsToken; + private readonly SignerInformation tsaSignerInfo; +// private readonly DateTime genTime; + private readonly TimeStampTokenInfo tstInfo; + private readonly CertID certID; + + public TimeStampToken( + Asn1.Cms.ContentInfo contentInfo) + : this(new CmsSignedData(contentInfo)) + { + } + + public TimeStampToken( + CmsSignedData signedData) + { + this.tsToken = signedData; + + if (!this.tsToken.SignedContentTypeOid.Equals(PkcsObjectIdentifiers.IdCTTstInfo.Id)) + { + throw new TspValidationException("ContentInfo object not for a time stamp."); + } + + ICollection signers = tsToken.GetSignerInfos().GetSigners(); + + if (signers.Count != 1) + { + throw new ArgumentException("Time-stamp token signed by " + + signers.Count + + " signers, but it must contain just the TSA signature."); + } + + + IEnumerator signerEnum = signers.GetEnumerator(); + + signerEnum.MoveNext(); + tsaSignerInfo = (SignerInformation) signerEnum.Current; + + try + { + CmsProcessable content = tsToken.SignedContent; + MemoryStream bOut = new MemoryStream(); + + content.Write(bOut); + + this.tstInfo = new TimeStampTokenInfo( + TstInfo.GetInstance( + Asn1Object.FromByteArray(bOut.ToArray()))); + + Asn1.Cms.Attribute attr = tsaSignerInfo.SignedAttributes[ + PkcsObjectIdentifiers.IdAASigningCertificate]; + +// if (attr == null) +// { +// throw new TspValidationException( +// "no signing certificate attribute found, time stamp invalid."); +// } +// +// SigningCertificate signCert = SigningCertificate.GetInstance( +// attr.AttrValues[0]); +// +// this.certID = EssCertID.GetInstance(signCert.GetCerts()[0]); + + if (attr != null) + { + SigningCertificate signCert = SigningCertificate.GetInstance(attr.AttrValues[0]); + + this.certID = new CertID(EssCertID.GetInstance(signCert.GetCerts()[0])); + } + else + { + attr = tsaSignerInfo.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2]; + + if (attr == null) + throw new TspValidationException("no signing certificate attribute found, time stamp invalid."); + + SigningCertificateV2 signCertV2 = SigningCertificateV2.GetInstance(attr.AttrValues[0]); + + this.certID = new CertID(EssCertIDv2.GetInstance(signCertV2.GetCerts()[0])); + } + } + catch (CmsException e) + { + throw new TspException(e.Message, e.InnerException); + } + } + + public TimeStampTokenInfo TimeStampInfo + { + get { return tstInfo; } + } + + public SignerID SignerID + { + get { return tsaSignerInfo.SignerID; } + } + + public Asn1.Cms.AttributeTable SignedAttributes + { + get { return tsaSignerInfo.SignedAttributes; } + } + + public Asn1.Cms.AttributeTable UnsignedAttributes + { + get { return tsaSignerInfo.UnsignedAttributes; } + } + +// public IX509Store GetCertificatesAndCrls( +// string type) +// { +// return tsToken.GetCertificatesAndCrls(type); +// } + + public IX509Store GetCertificates( + string type) + { + return tsToken.GetCertificates(type); + } + + public IX509Store GetCrls( + string type) + { + return tsToken.GetCrls(type); + } + + /** + * Validate the time stamp token. + *+ * To be valid the token must be signed by the passed in certificate and + * the certificate must be the one referred to by the SigningCertificate + * attribute included in the hashed attributes of the token. The + * certificate must also have the ExtendedKeyUsageExtension with only + * KeyPurposeID.IdKPTimeStamping and have been valid at the time the + * timestamp was created. + *
+ *+ * A successful call to validate means all the above are true. + *
+ */ + public void Validate( + X509Certificate cert) + { + IDigest digest; + try + { + digest = DigestUtilities.GetDigest(certID.GetHashAlgorithm()); + } + catch (SecurityUtilityException e) + { + throw new TspException("cannot find algorithm: " + e.Message, e); + } + + try + { + byte[] certEncoded = cert.GetEncoded(); + digest.BlockUpdate(certEncoded, 0, certEncoded.Length); + byte[] hash = DigestUtilities.DoFinal(digest); + + if (!Arrays.AreEqual(certID.GetCertHash(), hash)) + { + throw new TspValidationException("certificate hash does not match certID hash."); + } + + if (certID.IssuerSerial != null) + { + if (!certID.IssuerSerial.Serial.Value.Equals(cert.SerialNumber)) + { + throw new TspValidationException("certificate serial number does not match certID for signature."); + } + + GeneralName[] names = certID.IssuerSerial.Issuer.GetNames(); + X509Name principal = PrincipalUtilities.GetIssuerX509Principal(cert); + bool found = false; + + for (int i = 0; i != names.Length; i++) + { + if (names[i].TagNo == 4 + && X509Name.GetInstance(names[i].Name).Equivalent(principal)) + { + found = true; + break; + } + } + + if (!found) + { + throw new TspValidationException("certificate name does not match certID for signature. "); + } + } + + TspUtil.ValidateCertificate(cert); + + cert.CheckValidity(tstInfo.GenTime); + + if (!tsaSignerInfo.Verify(cert)) + { + throw new TspValidationException("signature not created by certificate."); + } + } + catch (CmsException e) + { + if (e.InnerException != null) + { + throw new TspException(e.Message, e.InnerException); + } + + throw new TspException("CMS exception: " + e, e); + } + catch (CertificateEncodingException e) + { + throw new TspException("problem processing certificate: " + e, e); + } + } + + /** + * Return the underlying CmsSignedData object. + * + * @return the underlying CMS structure. + */ + public CmsSignedData ToCmsSignedData() + { + return tsToken; + } + + /** + * Return a ASN.1 encoded byte stream representing the encoded object. + * + * @throws IOException if encoding fails. + */ + public byte[] GetEncoded() + { + return tsToken.GetEncoded(); + } + + + // perhaps this should be done using an interface on the ASN.1 classes... + private class CertID + { + private EssCertID certID; + private EssCertIDv2 certIDv2; + + internal CertID(EssCertID certID) + { + this.certID = certID; + this.certIDv2 = null; + } + + internal CertID(EssCertIDv2 certID) + { + this.certIDv2 = certID; + this.certID = null; + } + + public string GetHashAlgorithm() + { + if (certID != null) + return "SHA-1"; + + if (NistObjectIdentifiers.IdSha256.Equals(certIDv2.HashAlgorithm.ObjectID)) + return "SHA-256"; + + return certIDv2.HashAlgorithm.ObjectID.Id; + } + + public byte[] GetCertHash() + { + return certID != null + ? certID.GetCertHash() + : certIDv2.GetCertHash(); + } + + public IssuerSerial IssuerSerial + { + get + { + return certID != null + ? certID.IssuerSerial + : certIDv2.IssuerSerial; + } + } + } + } +} diff --git a/iTechSharp/srcbc/tsp/TimeStampTokenGenerator.cs b/iTechSharp/srcbc/tsp/TimeStampTokenGenerator.cs new file mode 100644 index 0000000..5b9572a --- /dev/null +++ b/iTechSharp/srcbc/tsp/TimeStampTokenGenerator.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ess; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Tsp +{ + public class TimeStampTokenGenerator + { + private int accuracySeconds = -1; + private int accuracyMillis = -1; + private int accuracyMicros = -1; + private bool ordering = false; + private GeneralName tsa = null; + private string tsaPolicyOID; + + private AsymmetricKeyParameter key; + private X509Certificate cert; + private string digestOID; + private Asn1.Cms.AttributeTable signedAttr; + private Asn1.Cms.AttributeTable unsignedAttr; + private IX509Store x509Certs; + private IX509Store x509Crls; + + /** + * basic creation - only the default attributes will be included here. + */ + public TimeStampTokenGenerator( + AsymmetricKeyParameter key, + X509Certificate cert, + string digestOID, + string tsaPolicyOID) + : this(key, cert, digestOID, tsaPolicyOID, null, null) + { + } + + /** + * create with a signer with extra signed/unsigned attributes. + */ + public TimeStampTokenGenerator( + AsymmetricKeyParameter key, + X509Certificate cert, + string digestOID, + string tsaPolicyOID, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + this.key = key; + this.cert = cert; + this.digestOID = digestOID; + this.tsaPolicyOID = tsaPolicyOID; + this.unsignedAttr = unsignedAttr; + + TspUtil.ValidateCertificate(cert); + + // + // add the essCertid + // + Hashtable signedAttrs; + if (signedAttr != null) + { + signedAttrs = signedAttr.ToHashtable(); + } + else + { + signedAttrs = new Hashtable(); + } + + IDigest digest; + try + { + digest = DigestUtilities.GetDigest("SHA-1"); + } + catch (Exception e) + { + throw new TspException("Can't find a SHA-1 implementation.", e); + } + + try + { + byte[] certEncoded = cert.GetEncoded(); + digest.BlockUpdate(certEncoded, 0, certEncoded.Length); + byte[] hash = DigestUtilities.DoFinal(digest); + + EssCertID essCertid = new EssCertID(hash); + + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( + PkcsObjectIdentifiers.IdAASigningCertificate, + new DerSet(new SigningCertificate(essCertid))); + + signedAttrs[attr.AttrType] = attr; + } + catch (CertificateEncodingException e) + { + throw new TspException("Exception processing certificate.", e); + } + + this.signedAttr = new Asn1.Cms.AttributeTable(signedAttrs); + } + + public void SetCertificates( + IX509Store certificates) + { + this.x509Certs = certificates; + } + + public void SetCrls( + IX509Store crls) + { + this.x509Crls = crls; + } + + public void SetAccuracySeconds( + int accuracySeconds) + { + this.accuracySeconds = accuracySeconds; + } + + public void SetAccuracyMillis( + int accuracyMillis) + { + this.accuracyMillis = accuracyMillis; + } + + public void SetAccuracyMicros( + int accuracyMicros) + { + this.accuracyMicros = accuracyMicros; + } + + public void SetOrdering( + bool ordering) + { + this.ordering = ordering; + } + + public void SetTsa( + GeneralName tsa) + { + this.tsa = tsa; + } + + //------------------------------------------------------------------------------ + + public TimeStampToken Generate( + TimeStampRequest request, + BigInteger serialNumber, + DateTime genTime) + { + DerObjectIdentifier digestAlgOID = new DerObjectIdentifier(request.MessageImprintAlgOid); + + AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, DerNull.Instance); + MessageImprint messageImprint = new MessageImprint(algID, request.GetMessageImprintDigest()); + + Accuracy accuracy = null; + if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0) + { + DerInteger seconds = null; + if (accuracySeconds > 0) + { + seconds = new DerInteger(accuracySeconds); + } + + DerInteger millis = null; + if (accuracyMillis > 0) + { + millis = new DerInteger(accuracyMillis); + } + + DerInteger micros = null; + if (accuracyMicros > 0) + { + micros = new DerInteger(accuracyMicros); + } + + accuracy = new Accuracy(seconds, millis, micros); + } + + DerBoolean derOrdering = null; + if (ordering) + { + derOrdering = DerBoolean.GetInstance(ordering); + } + + DerInteger nonce = null; + if (request.Nonce != null) + { + nonce = new DerInteger(request.Nonce); + } + + DerObjectIdentifier tsaPolicy = new DerObjectIdentifier(tsaPolicyOID); + if (request.ReqPolicy != null) + { + tsaPolicy = new DerObjectIdentifier(request.ReqPolicy); + } + + TstInfo tstInfo = new TstInfo(tsaPolicy, messageImprint, + new DerInteger(serialNumber), new DerGeneralizedTime(genTime), accuracy, + derOrdering, nonce, tsa, request.Extensions); + + try + { + CmsSignedDataGenerator signedDataGenerator = new CmsSignedDataGenerator(); + + byte[] derEncodedTstInfo = tstInfo.GetDerEncoded(); + + if (request.CertReq) + { + signedDataGenerator.AddCertificates(x509Certs); + } + + signedDataGenerator.AddCrls(x509Crls); + signedDataGenerator.AddSigner(key, cert, digestOID, signedAttr, unsignedAttr); + + CmsSignedData signedData = signedDataGenerator.Generate( + PkcsObjectIdentifiers.IdCTTstInfo.Id, + new CmsProcessableByteArray(derEncodedTstInfo), + true); + + return new TimeStampToken(signedData); + } + catch (CmsException cmsEx) + { + throw new TspException("Error generating time-stamp token", cmsEx); + } + catch (IOException e) + { + throw new TspException("Exception encoding info", e); + } + catch (X509StoreException e) + { + throw new TspException("Exception handling CertStore", e); + } +// catch (InvalidAlgorithmParameterException e) +// { +// throw new TspException("Exception handling CertStore CRLs", e); +// } + } + } +} diff --git a/iTechSharp/srcbc/tsp/TimeStampTokenInfo.cs b/iTechSharp/srcbc/tsp/TimeStampTokenInfo.cs new file mode 100644 index 0000000..06112de --- /dev/null +++ b/iTechSharp/srcbc/tsp/TimeStampTokenInfo.cs @@ -0,0 +1,102 @@ +using System; + +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tsp +{ + public class TimeStampTokenInfo + { + private TstInfo tstInfo; + private DateTime genTime; + + public TimeStampTokenInfo( + TstInfo tstInfo) + { + this.tstInfo = tstInfo; + + try + { + this.genTime = tstInfo.GenTime.ToDateTime(); + } + catch (Exception e) + { + throw new TspException("unable to parse genTime field: " + e.Message); + } + } + + public bool IsOrdered + { + get { return tstInfo.Ordering.IsTrue; } + } + + public Accuracy Accuracy + { + get { return tstInfo.Accuracy; } + } + + public DateTime GenTime + { + get { return genTime; } + } + + public GenTimeAccuracy GenTimeAccuracy + { + get + { + return this.Accuracy == null + ? null + : new GenTimeAccuracy(this.Accuracy); + } + } + + public string Policy + { + get { return tstInfo.Policy.Id; } + } + + public BigInteger SerialNumber + { + get { return tstInfo.SerialNumber.Value; } + } + + public GeneralName Tsa + { + get { return tstInfo.Tsa; } + } + + /** + * @return the nonce value, null if there isn't one. + */ + public BigInteger Nonce + { + get + { + return tstInfo.Nonce == null + ? null + : tstInfo.Nonce.Value; + } + } + + public string MessageImprintAlgOid + { + get { return tstInfo.MessageImprint.HashAlgorithm.ObjectID.Id; } + } + + public byte[] GetMessageImprintDigest() + { + return tstInfo.MessageImprint.GetHashedMessage(); + } + + public byte[] GetEncoded() + { + return tstInfo.GetEncoded(); + } + + public TstInfo TstInfo + { + get { return tstInfo; } + } + } +} diff --git a/iTechSharp/srcbc/util/Arrays.cs b/iTechSharp/srcbc/util/Arrays.cs new file mode 100644 index 0000000..ffad2de --- /dev/null +++ b/iTechSharp/srcbc/util/Arrays.cs @@ -0,0 +1,134 @@ +using System; +using System.Text; + +namespace Org.BouncyCastle.Utilities +{ + + ///+ * The purpose of UrlBase64 encoding is to provide a compact encoding of binary + * data that is safe for use as an URL parameter. Base64 encoding does not + * produce encoded values that are safe for use in URLs, since "/" can be + * interpreted as a path delimiter; "+" is the encoded form of a space; and + * "=" is used to separate a name from the corresponding value in an URL + * parameter. + *
+ */ + public class UrlBase64 + { + private static readonly IEncoder encoder = new UrlBase64Encoder(); + + /** + * Encode the input data producing a URL safe base 64 encoded byte array. + * + * @return a byte array containing the URL safe base 64 encoded data. + */ + public static byte[] Encode( + byte[] data) + { + MemoryStream bOut = new MemoryStream(); + + try + { + encoder.Encode(data, 0, data.Length, bOut); + } + catch (IOException e) + { + throw new Exception("exception encoding URL safe base64 string: " + e.Message, e); + } + + return bOut.ToArray(); + } + + /** + * Encode the byte data writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + Stream outStr) + { + return encoder.Encode(data, 0, data.Length, outStr); + } + + /** + * Decode the URL safe base 64 encoded input data - white space will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + byte[] data) + { + MemoryStream bOut = new MemoryStream(); + + try + { + encoder.Decode(data, 0, data.Length, bOut); + } + catch (IOException e) + { + throw new Exception("exception decoding URL safe base64 string: " + e.Message, e); + } + + return bOut.ToArray(); + } + + /** + * decode the URL safe base 64 encoded byte data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int Decode( + byte[] data, + Stream outStr) + { + return encoder.Decode(data, 0, data.Length, outStr); + } + + /** + * decode the URL safe base 64 encoded string data - whitespace will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + string data) + { + MemoryStream bOut = new MemoryStream(); + + try + { + encoder.DecodeString(data, bOut); + } + catch (IOException e) + { + throw new Exception("exception decoding URL safe base64 string: " + e.Message, e); + } + + return bOut.ToArray(); + } + + /** + * Decode the URL safe base 64 encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int Decode( + string data, + Stream outStr) + { + return encoder.DecodeString(data, outStr); + } + } +} diff --git a/iTechSharp/srcbc/util/encoders/UrlBase64Encoder.cs b/iTechSharp/srcbc/util/encoders/UrlBase64Encoder.cs new file mode 100644 index 0000000..5611a83 --- /dev/null +++ b/iTechSharp/srcbc/util/encoders/UrlBase64Encoder.cs @@ -0,0 +1,31 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /** + * Convert binary data to and from UrlBase64 encoding. This is identical to + * Base64 encoding, except that the padding character is "." and the other + * non-alphanumeric characters are "-" and "_" instead of "+" and "/". + *+ * The purpose of UrlBase64 encoding is to provide a compact encoding of binary + * data that is safe for use as an URL parameter. Base64 encoding does not + * produce encoded values that are safe for use in URLs, since "/" can be + * interpreted as a path delimiter; "+" is the encoded form of a space; and + * "=" is used to separate a name from the corresponding value in an URL + * parameter. + *
+ */ + public class UrlBase64Encoder + : Base64Encoder + { + public UrlBase64Encoder() + { + encodingTable[encodingTable.Length - 2] = (byte) '-'; + encodingTable[encodingTable.Length - 1] = (byte) '_'; + padding = (byte) '.'; + // we must re-create the decoding table with the new encoded values. + InitialiseDecodingTable(); + } + } +} \ No newline at end of file diff --git a/iTechSharp/srcbc/util/io/BaseInputStream.cs b/iTechSharp/srcbc/util/io/BaseInputStream.cs new file mode 100644 index 0000000..3ff4a19 --- /dev/null +++ b/iTechSharp/srcbc/util/io/BaseInputStream.cs @@ -0,0 +1,47 @@ +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public abstract class BaseInputStream : Stream + { + private bool closed; + + public sealed override bool CanRead { get { return !closed; } } + public sealed override bool CanSeek { get { return false; } } + public sealed override bool CanWrite { get { return false; } } + public override void Close() { closed = true; } + public sealed override void Flush() {} + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override int Read(byte[] buffer, int offset, int count) + { + int pos = offset; + try + { + int end = offset + count; + while (pos < end) + { + int b = ReadByte(); + if (b == -1) break; + buffer[pos++] = (byte) b; + } + } + catch (IOException) + { + if (pos == offset) throw; + } + return pos - offset; + } + + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + public sealed override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + } +} diff --git a/iTechSharp/srcbc/util/io/BaseOutputStream.cs b/iTechSharp/srcbc/util/io/BaseOutputStream.cs new file mode 100644 index 0000000..6e6c6d3 --- /dev/null +++ b/iTechSharp/srcbc/util/io/BaseOutputStream.cs @@ -0,0 +1,47 @@ +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public abstract class BaseOutputStream : Stream + { + private bool closed; + + public sealed override bool CanRead { get { return false; } } + public sealed override bool CanSeek { get { return false; } } + public sealed override bool CanWrite { get { return !closed; } } + public override void Close() { closed = true; } + public override void Flush() {} + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + public sealed override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + + public override void Write(byte[] buffer, int offset, int count) + { + Debug.Assert(buffer != null); + Debug.Assert(0 <= offset && offset <= buffer.Length); + Debug.Assert(count >= 0); + + int end = offset + count; + + Debug.Assert(0 <= end && end <= buffer.Length); + + for (int i = offset; i < end; ++i) + { + this.WriteByte(buffer[i]); + } + } + + public virtual void Write(params byte[] buffer) + { + Write(buffer, 0, buffer.Length); + } + } +} diff --git a/iTechSharp/srcbc/util/io/PushbackStream.cs b/iTechSharp/srcbc/util/io/PushbackStream.cs new file mode 100644 index 0000000..9546942 --- /dev/null +++ b/iTechSharp/srcbc/util/io/PushbackStream.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.Utilities; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class PushbackStream + : FilterStream + { + private int buf = -1; + + public PushbackStream( + Stream s) + : base(s) + { + } + + public override int ReadByte() + { + if (buf != -1) + { + int tmp = buf; + buf = -1; + return tmp; + } + + return base.ReadByte(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (buf != -1 && count > 0) + { + // TODO Can this case be made more efficient? + buffer[offset] = (byte) buf; + buf = -1; + return 1; + } + + return base.Read(buffer, offset, count); + } + + public virtual void Unread(int b) + { + if (buf != -1) + throw new InvalidOperationException("Can only push back one byte"); + + buf = b & 0xFF; + } + } +} diff --git a/iTechSharp/srcbc/util/io/Streams.cs b/iTechSharp/srcbc/util/io/Streams.cs new file mode 100644 index 0000000..9e599f7 --- /dev/null +++ b/iTechSharp/srcbc/util/io/Streams.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public sealed class Streams + { + private const int BufferSize = 512; + + private Streams() + { + } + + public static void Drain(Stream inStr) + { + byte[] bs = new byte[BufferSize]; + while (inStr.Read(bs, 0, bs.Length) > 0) + { + } + } + + public static byte[] ReadAll(Stream inStr) + { + MemoryStream buf = new MemoryStream(); + PipeAll(inStr, buf); + return buf.ToArray(); + } + + public static int ReadFully(Stream inStr, byte[] buf) + { + return ReadFully(inStr, buf, 0, buf.Length); + } + + public static int ReadFully(Stream inStr, byte[] buf, int off, int len) + { + int totalRead = 0; + while (totalRead < len) + { + int numRead = inStr.Read(buf, off + totalRead, len - totalRead); + if (numRead < 1) + break; + totalRead += numRead; + } + return totalRead; + } + + public static void PipeAll(Stream inStr, Stream outStr) + { + byte[] bs = new byte[BufferSize]; + int numRead; + while ((numRead = inStr.Read(bs, 0, bs.Length)) > 0) + { + outStr.Write(bs, 0, numRead); + } + } + } +} diff --git a/iTechSharp/srcbc/util/net/IPAddress.cs b/iTechSharp/srcbc/util/net/IPAddress.cs new file mode 100644 index 0000000..b13edad --- /dev/null +++ b/iTechSharp/srcbc/util/net/IPAddress.cs @@ -0,0 +1,112 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Utilities.Net +{ + public class IPAddress + { + /** + * Validate the given IPv4 or IPv6 address. + * + * @param address the IP address as a string. + * + * @return true if a valid address, false otherwise + */ + public static bool IsValid( + string address) + { + return IsValidIPv4(address) || IsValidIPv6(address); + } + + /** + * Validate the given IPv4 address. + * + * @param address the IP address as a string. + * + * @return true if a valid IPv4 address, false otherwise + */ + private static bool IsValidIPv4( + string address) + { + if (address.Length == 0) + return false; + + BigInteger octet; + int octets = 0; + + string temp = address + "."; + + int pos; + int start = 0; + while (start < temp.Length + && (pos = temp.IndexOf('.', start)) > start) + { + if (octets == 4) + return false; + + try + { + octet = new BigInteger(temp.Substring(start, pos - start)); + } + catch (FormatException) + { + return false; + } + + if (octet.SignValue < 0 || octet.BitLength > 8) + return false; + + start = pos + 1; + ++octets; + } + + return octets == 4; + } + + /** + * Validate the given IPv6 address. + * + * @param address the IP address as a string. + * + * @return true if a valid IPv4 address, false otherwise + */ + private static bool IsValidIPv6( + string address) + { + if (address.Length == 0) + return false; + + BigInteger octet; + int octets = 0; + + string temp = address + ":"; + + int pos; + int start = 0; + while (start < temp.Length + && (pos = temp.IndexOf(':', start)) > start) + { + if (octets == 8) + return false; + + try + { + octet = new BigInteger(temp.Substring(start, pos - start), 16); + } + catch (FormatException) + { + return false; + } + + if (octet.SignValue < 0 || octet.BitLength > 16) + return false; + + start = pos + 1; + octets++; + } + + return octets == 8; + } + } +} diff --git a/iTechSharp/srcbc/util/zlib/Adler32.cs b/iTechSharp/srcbc/util/zlib/Adler32.cs new file mode 100644 index 0000000..7353475 --- /dev/null +++ b/iTechSharp/srcbc/util/zlib/Adler32.cs @@ -0,0 +1,88 @@ +using System; +/* + * $Id: Adler32.cs,v 1.1.1.1 2007/01/24 16:41:26 psoares33 Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class Adler32{ + + // largest prime smaller than 65536 + private const int BASE=65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + private const int NMAX=5552; + + internal long adler32(long adler, byte[] buf, int index, int len){ + if(buf == null){ return 1L; } + + long s1=adler&0xffff; + long s2=(adler>>16)&0xffff; + int k; + + while(len > 0) { + k=len+ /// Holder ::= SEQUENCE { + /// baseCertificateID [0] IssuerSerial OPTIONAL, + /// -- the issuer and serial number of + /// -- the holder's Public Key Certificate + /// entityName [1] GeneralNames OPTIONAL, + /// -- the name of the claimant or role + /// objectDigestInfo [2] ObjectDigestInfo OPTIONAL + /// -- used to directly authenticate the holder, + /// -- for example, an executable + /// } + ///+ ///
+ * digestedObjectType
can be one of the following:
+ *
otherObjectTypeID
must not be empty.This cannot be used if a v1 attribute certificate is used.
+ * + * @param digestedObjectType The digest object type. + * @param digestAlgorithm The algorithm identifier for the hash. + * @param otherObjectTypeID The object type ID if + *digestedObjectType
is
+ * otherObjectDigest
.
+ * @param objectDigest The hash value.
+ */
+ public AttributeCertificateHolder(
+ int digestedObjectType,
+ string digestAlgorithm,
+ string otherObjectTypeID,
+ byte[] objectDigest)
+ {
+ // TODO Allow 'objectDigest' to be null?
+
+ holder = new Holder(new ObjectDigestInfo(digestedObjectType, otherObjectTypeID,
+ new AlgorithmIdentifier(digestAlgorithm), Arrays.Clone(objectDigest)));
+ }
+
+ /**
+ * Returns the digest object type if an object digest info is used.
+ * + *
otherObjectTypeID
must not be empty.null
if no object
+ * digest info is set.
+ */
+ public string DigestAlgorithm
+ {
+ get
+ {
+ ObjectDigestInfo odi = holder.ObjectDigestInfo;
+
+ return odi == null
+ ? null
+ : odi.DigestAlgorithm.ObjectID.Id;
+ }
+ }
+
+ /**
+ * Returns the hash if an object digest info is used.
+ *
+ * @return The hash or null
if no object digest info is set.
+ */
+ public byte[] GetObjectDigest()
+ {
+ ObjectDigestInfo odi = holder.ObjectDigestInfo;
+
+ return odi == null
+ ? null
+ : odi.ObjectDigest.GetBytes();
+ }
+
+ /**
+ * Returns the digest algorithm ID if an object digest info is used.
+ *
+ * @return The digest algorithm ID or null
if no object
+ * digest info is set.
+ */
+ public string OtherObjectTypeID
+ {
+ get
+ {
+ ObjectDigestInfo odi = holder.ObjectDigestInfo;
+
+ return odi == null
+ ? null
+ : odi.OtherObjectTypeID.Id;
+ }
+ }
+
+ private GeneralNames GenerateGeneralNames(
+ X509Name principal)
+ {
+// return GeneralNames.GetInstance(new DerSequence(new GeneralName(principal)));
+ return new GeneralNames(new GeneralName(principal));
+ }
+
+ private bool MatchesDN(
+ X509Name subject,
+ GeneralNames targets)
+ {
+ GeneralName[] names = targets.GetNames();
+
+ for (int i = 0; i != names.Length; i++)
+ {
+ GeneralName gn = names[i];
+
+ if (gn.TagNo == GeneralName.DirectoryName)
+ {
+ try
+ {
+ if (X509Name.GetInstance(gn.Name).Equivalent(subject))
+ {
+ return true;
+ }
+ }
+ catch (Exception)
+ {
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private object[] GetNames(
+ GeneralName[] names)
+ {
+ ArrayList l = new ArrayList(names.Length);
+
+ for (int i = 0; i != names.Length; i++)
+ {
+ if (names[i].TagNo == GeneralName.DirectoryName)
+ {
+ l.Add(X509Name.GetInstance(names[i].Name));
+ }
+ }
+
+ return l.ToArray();
+ }
+
+ private X509Name[] GetPrincipals(
+ GeneralNames names)
+ {
+ object[] p = this.GetNames(names.GetNames());
+ ArrayList l = new ArrayList(p.Length);
+
+ for (int i = 0; i != p.Length; i++)
+ {
+ if (p[i] is X509Name)
+ {
+ l.Add(p[i]);
+ }
+ }
+
+ return (X509Name[]) l.ToArray(typeof(X509Name));
+ }
+
+ /**
+ * Return any principal objects inside the attribute certificate holder entity names field.
+ *
+ * @return an array of IPrincipal objects (usually X509Name), null if no entity names field is set.
+ */
+ public X509Name[] GetEntityNames()
+ {
+ if (holder.EntityName != null)
+ {
+ return GetPrincipals(holder.EntityName);
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the principals associated with the issuer attached to this holder
+ *
+ * @return an array of principals, null if no BaseCertificateID is set.
+ */
+ public X509Name[] GetIssuer()
+ {
+ if (holder.BaseCertificateID != null)
+ {
+ return GetPrincipals(holder.BaseCertificateID.Issuer);
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the serial number associated with the issuer attached to this holder.
+ *
+ * @return the certificate serial number, null if no BaseCertificateID is set.
+ */
+ public BigInteger SerialNumber
+ {
+ get
+ {
+ if (holder.BaseCertificateID != null)
+ {
+ return holder.BaseCertificateID.Serial.Value;
+ }
+
+ return null;
+ }
+ }
+
+ public object Clone()
+ {
+ return new AttributeCertificateHolder((Asn1Sequence)holder.ToAsn1Object());
+ }
+
+ public bool Match(
+// Certificate cert)
+ X509Certificate x509Cert)
+ {
+// if (!(cert is X509Certificate))
+// {
+// return false;
+// }
+//
+// X509Certificate x509Cert = (X509Certificate)cert;
+
+ try
+ {
+ if (holder.BaseCertificateID != null)
+ {
+ return holder.BaseCertificateID.Serial.Value.Equals(x509Cert.SerialNumber)
+ && MatchesDN(PrincipalUtilities.GetIssuerX509Principal(x509Cert), holder.BaseCertificateID.Issuer);
+ }
+
+ if (holder.EntityName != null)
+ {
+ if (MatchesDN(PrincipalUtilities.GetSubjectX509Principal(x509Cert), holder.EntityName))
+ {
+ return true;
+ }
+ }
+
+ if (holder.ObjectDigestInfo != null)
+ {
+ IDigest md = null;
+ try
+ {
+ md = DigestUtilities.GetDigest(DigestAlgorithm);
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+
+ switch (DigestedObjectType)
+ {
+ case ObjectDigestInfo.PublicKey:
+ {
+ // TODO: DSA Dss-parms
+
+ //byte[] b = x509Cert.GetPublicKey().getEncoded();
+ // TODO Is this the right way to encode?
+ byte[] b = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(
+ x509Cert.GetPublicKey()).GetEncoded();
+ md.BlockUpdate(b, 0, b.Length);
+ break;
+ }
+
+ case ObjectDigestInfo.PublicKeyCert:
+ {
+ byte[] b = x509Cert.GetEncoded();
+ md.BlockUpdate(b, 0, b.Length);
+ break;
+ }
+
+ // TODO Default handler?
+ }
+
+ // TODO Shouldn't this be the other way around?
+ if (!Arrays.AreEqual(DigestUtilities.DoFinal(md), GetObjectDigest()))
+ {
+ return false;
+ }
+ }
+ }
+ catch (CertificateEncodingException)
+ {
+ return false;
+ }
+
+ return false;
+ }
+
+ public override bool Equals(
+ object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj is AttributeCertificateHolder))
+ {
+ return false;
+ }
+
+ AttributeCertificateHolder other = (AttributeCertificateHolder)obj;
+
+ return this.holder.Equals(other.holder);
+ }
+
+ public override int GetHashCode()
+ {
+ return this.holder.GetHashCode();
+ }
+
+ public bool Match(
+ object obj)
+ {
+ if (!(obj is X509Certificate))
+ {
+ return false;
+ }
+
+// return Match((Certificate)obj);
+ return Match((X509Certificate)obj);
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/x509/AttributeCertificateIssuer.cs b/iTechSharp/srcbc/x509/AttributeCertificateIssuer.cs
new file mode 100644
index 0000000..26f4d8a
--- /dev/null
+++ b/iTechSharp/srcbc/x509/AttributeCertificateIssuer.cs
@@ -0,0 +1,177 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.X509
+{
+ /**
+ * Carrying class for an attribute certificate issuer.
+ */
+ public class AttributeCertificateIssuer
+ //: CertSelector, Selector
+ : IX509Selector
+ {
+ internal readonly Asn1Encodable form;
+
+ /**
+ * Set the issuer directly with the ASN.1 structure.
+ *
+ * @param issuer The issuer
+ */
+ internal AttributeCertificateIssuer(
+ AttCertIssuer issuer)
+ {
+ form = issuer.Issuer;
+ }
+
+ public AttributeCertificateIssuer(
+ X509Name principal)
+ {
+// form = new V2Form(GeneralNames.GetInstance(new DerSequence(new GeneralName(principal))));
+ form = new V2Form(new GeneralNames(new GeneralName(principal)));
+ }
+
+ private object[] GetNames()
+ {
+ GeneralNames name;
+ if (form is V2Form)
+ {
+ name = ((V2Form)form).IssuerName;
+ }
+ else
+ {
+ name = (GeneralNames)form;
+ }
+
+ GeneralName[] names = name.GetNames();
+
+ ArrayList l = new ArrayList(names.Length);
+
+ for (int i = 0; i != names.Length; i++)
+ {
+ if (names[i].TagNo == GeneralName.DirectoryName)
+ {
+ l.Add(X509Name.GetInstance(names[i].Name));
+ }
+ }
+
+ return l.ToArray();
+ }
+
+ /// + /// Use this in preference to trying to recreate a principal from a string, not all + /// DNs are what they should be, so it's best to leave them encoded where they + /// can be.
+ ///+ * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----" + * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7 + * objects.
+ */ + public class X509CertificateParser + { + private static readonly PemParser PemCertParser = new PemParser("CERTIFICATE"); + + private Asn1Set sData; + private int sDataObjectCount; + private Stream currentStream; + + private X509Certificate ReadDerCertificate( + Asn1InputStream dIn) + { + Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject(); + + if (seq.Count > 1 && seq[0] is DerObjectIdentifier) + { + if (seq[0].Equals(PkcsObjectIdentifiers.SignedData)) + { + sData = SignedData.GetInstance( + Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Certificates; + + return GetCertificate(); + } + } + + return CreateX509Certificate(X509CertificateStructure.GetInstance(seq)); + } + + private X509Certificate GetCertificate() + { + if (sData != null) + { + while (sDataObjectCount < sData.Count) + { + object obj = sData[sDataObjectCount++]; + + if (obj is Asn1Sequence) + { + return CreateX509Certificate( + X509CertificateStructure.GetInstance(obj)); + } + } + } + + return null; + } + + private X509Certificate ReadPemCertificate( + Stream inStream) + { + Asn1Sequence seq = PemCertParser.ReadPemObject(inStream); + + return seq == null + ? null + : CreateX509Certificate(X509CertificateStructure.GetInstance(seq)); + } + + protected virtual X509Certificate CreateX509Certificate( + X509CertificateStructure c) + { + return new X509Certificate(c); + } + + ///isIndirect
+ * is false
{@link #getCertificateIssuer()} will always
+ * return null
, previousCertificateIssuer
is
+ * ignored. If this isIndirect
is specified and this CrlEntry
+ * has no certificate issuer CRL entry extension
+ * previousCertificateIssuer
is returned by
+ * {@link #getCertificateIssuer()}.
+ *
+ * @param c
+ * TbsCertificateList.CrlEntry object.
+ * @param isIndirect
+ * true
if the corresponding CRL is a indirect
+ * CRL.
+ * @param previousCertificateIssuer
+ * Certificate issuer of the previous CrlEntry.
+ */
+ public X509CrlEntry(
+ CrlEntry c,
+ bool isIndirect,
+ X509Name previousCertificateIssuer)
+ {
+ this.c = c;
+ this.isIndirect = isIndirect;
+ this.previousCertificateIssuer = previousCertificateIssuer;
+ this.certificateIssuer = loadCertificateIssuer();
+ }
+
+ private X509Name loadCertificateIssuer()
+ {
+ if (!isIndirect)
+ {
+ return null;
+ }
+
+ Asn1OctetString ext = GetExtensionValue(X509Extensions.CertificateIssuer);
+ if (ext == null)
+ {
+ return previousCertificateIssuer;
+ }
+
+ try
+ {
+ GeneralName[] names = GeneralNames.GetInstance(
+ X509ExtensionUtilities.FromExtensionValue(ext)).GetNames();
+
+ for (int i = 0; i < names.Length; i++)
+ {
+ if (names[i].TagNo == GeneralName.DirectoryName)
+ {
+ return X509Name.GetInstance(names[i].Name);
+ }
+ }
+ }
+ catch (Exception)
+ {
+ }
+
+ return null;
+ }
+
+ public X509Name GetCertificateIssuer()
+ {
+ return certificateIssuer;
+ }
+
+ protected override X509Extensions GetX509Extensions()
+ {
+ return c.Extensions;
+ }
+
+ public byte[] GetEncoded()
+ {
+ try
+ {
+ return c.GetDerEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new CrlException(e.ToString());
+ }
+ }
+
+ public BigInteger SerialNumber
+ {
+ get { return c.UserCertificate.Value; }
+ }
+
+ public DateTime RevocationDate
+ {
+ get { return c.RevocationDate.ToDateTime(); }
+ }
+
+ public bool HasExtensions
+ {
+ get { return c.Extensions != null; }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder buf = new StringBuilder();
+ string nl = Platform.NewLine;
+
+ buf.Append(" userCertificate: ").Append(this.SerialNumber).Append(nl);
+ buf.Append(" revocationDate: ").Append(this.RevocationDate).Append(nl);
+ buf.Append(" certificateIssuer: ").Append(this.GetCertificateIssuer()).Append(nl);
+
+ X509Extensions extensions = c.Extensions;
+
+ if (extensions != null)
+ {
+ IEnumerator e = extensions.ExtensionOids.GetEnumerator();
+ if (e.MoveNext())
+ {
+ buf.Append(" crlEntryExtensions:").Append(nl);
+
+ do
+ {
+ DerObjectIdentifier oid = (DerObjectIdentifier)e.Current;
+ X509Extension ext = extensions.GetExtension(oid);
+
+ if (ext.Value != null)
+ {
+ Asn1Object obj = Asn1Object.FromByteArray(ext.Value.GetOctets());
+
+ buf.Append(" critical(")
+ .Append(ext.IsCritical)
+ .Append(") ");
+ try
+ {
+ if (oid.Equals(X509Extensions.ReasonCode))
+ {
+ buf.Append(new CrlReason(DerEnumerated.GetInstance(obj)));
+ }
+ else if (oid.Equals(X509Extensions.CertificateIssuer))
+ {
+ buf.Append("Certificate issuer: ").Append(
+ GeneralNames.GetInstance((Asn1Sequence)obj));
+ }
+ else
+ {
+ buf.Append(oid.Id);
+ buf.Append(" value = ").Append(Asn1Dump.DumpAsString(obj));
+ }
+ buf.Append(nl);
+ }
+ catch (Exception)
+ {
+ buf.Append(oid.Id);
+ buf.Append(" value = ").Append("*****").Append(nl);
+ }
+ }
+ else
+ {
+ buf.Append(nl);
+ }
+ }
+ while (e.MoveNext());
+ }
+ }
+
+ return buf.ToString();
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/x509/X509CrlParser.cs b/iTechSharp/srcbc/x509/X509CrlParser.cs
new file mode 100644
index 0000000..b170642
--- /dev/null
+++ b/iTechSharp/srcbc/x509/X509CrlParser.cs
@@ -0,0 +1,194 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Security.Certificates;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.X509
+{
+ public class X509CrlParser
+ {
+ private static readonly PemParser PemCrlParser = new PemParser("CRL");
+
+ private readonly bool lazyAsn1;
+
+ private Asn1Set sCrlData;
+ private int sCrlDataObjectCount;
+ private Stream currentCrlStream;
+
+ public X509CrlParser()
+ : this(false)
+ {
+ }
+
+ public X509CrlParser(
+ bool lazyAsn1)
+ {
+ this.lazyAsn1 = lazyAsn1;
+ }
+
+ private X509Crl ReadPemCrl(
+ Stream inStream)
+ {
+ Asn1Sequence seq = PemCrlParser.ReadPemObject(inStream);
+
+ return seq == null
+ ? null
+ : CreateX509Crl(CertificateList.GetInstance(seq));
+ }
+
+ private X509Crl ReadDerCrl(
+ Asn1InputStream dIn)
+ {
+ Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject();
+
+ if (seq.Count > 1 && seq[0] is DerObjectIdentifier)
+ {
+ if (seq[0].Equals(PkcsObjectIdentifiers.SignedData))
+ {
+ sCrlData = SignedData.GetInstance(
+ Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Crls;
+
+ return GetCrl();
+ }
+ }
+
+ return CreateX509Crl(CertificateList.GetInstance(seq));
+ }
+
+ private X509Crl GetCrl()
+ {
+ if (sCrlData == null || sCrlDataObjectCount >= sCrlData.Count)
+ {
+ return null;
+ }
+
+ return CreateX509Crl(
+ CertificateList.GetInstance(
+ sCrlData[sCrlDataObjectCount++]));
+ }
+
+ protected virtual X509Crl CreateX509Crl(
+ CertificateList c)
+ {
+ return new X509Crl(c);
+ }
+
+ /// + * id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } + * + * KeyUsage ::= BIT STRING { + * digitalSignature (0), + * nonRepudiation (1), + * keyEncipherment (2), + * dataEncipherment (3), + * keyAgreement (4), + * keyCertSign (5), + * cRLSign (6), + * encipherOnly (7), + * decipherOnly (8) } + *+ */ + public class X509KeyUsage + : Asn1Encodable + { + public const int DigitalSignature = 1 << 7; + public const int NonRepudiation = 1 << 6; + public const int KeyEncipherment = 1 << 5; + public const int DataEncipherment = 1 << 4; + public const int KeyAgreement = 1 << 3; + public const int KeyCertSign = 1 << 2; + public const int CrlSign = 1 << 1; + public const int EncipherOnly = 1 << 0; + public const int DecipherOnly = 1 << 15; + + private readonly int usage; + + /** + * Basic constructor. + * + * @param usage - the bitwise OR of the Key Usage flags giving the + * allowed uses for the key. + * e.g. (X509KeyUsage.keyEncipherment | X509KeyUsage.dataEncipherment) + */ + public X509KeyUsage( + int usage) + { + this.usage = usage; + } + + public override Asn1Object ToAsn1Object() + { + return new KeyUsage(usage); + } + } +} diff --git a/iTechSharp/srcbc/x509/X509SignatureUtil.cs b/iTechSharp/srcbc/x509/X509SignatureUtil.cs new file mode 100644 index 0000000..7a4ab14 --- /dev/null +++ b/iTechSharp/srcbc/x509/X509SignatureUtil.cs @@ -0,0 +1,128 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.X509 +{ + internal class X509SignatureUtilities + { + private static readonly Asn1Null derNull = DerNull.Instance; + + internal static void SetSignatureParameters( + ISigner signature, + Asn1Encodable parameters) + { + if (parameters != null && !derNull.Equals(parameters)) + { + // TODO Put back in +// AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm()); +// +// try +// { +// sigParams.Init(parameters.ToAsn1Object().GetDerEncoded()); +// } +// catch (IOException e) +// { +// throw new SignatureException("IOException decoding parameters: " + e.Message); +// } +// +// if (signature.getAlgorithm().EndsWith("MGF1")) +// { +// try +// { +// signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); +// } +// catch (GeneralSecurityException e) +// { +// throw new SignatureException("Exception extracting parameters: " + e.Message); +// } +// } + } + } + + internal static string GetSignatureName( + AlgorithmIdentifier sigAlgId) + { + Asn1Encodable parameters = sigAlgId.Parameters; + + if (parameters != null && !derNull.Equals(parameters)) + { + if (sigAlgId.ObjectID.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(parameters); + + return GetDigestAlgName(rsaParams.HashAlgorithm.ObjectID) + "withRSAandMGF1"; + } + if (sigAlgId.ObjectID.Equals(X9ObjectIdentifiers.ECDsaWithSha2)) + { + Asn1Sequence ecDsaParams = Asn1Sequence.GetInstance(parameters); + + return GetDigestAlgName((DerObjectIdentifier)ecDsaParams[0]) + "withECDSA"; + } + } + + return sigAlgId.ObjectID.Id; + } + + /** + * Return the digest algorithm using one of the standard JCA string + * representations rather than the algorithm identifier (if possible). + */ + private static string GetDigestAlgName( + DerObjectIdentifier digestAlgOID) + { + if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID)) + { + return "MD5"; + } + else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID)) + { + return "SHA1"; + } + else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID)) + { + return "SHA224"; + } + else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID)) + { + return "SHA256"; + } + else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID)) + { + return "SHA384"; + } + else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID)) + { + return "SHA512"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID)) + { + return "RIPEMD128"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID)) + { + return "RIPEMD160"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID)) + { + return "RIPEMD256"; + } + else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID)) + { + return "GOST3411"; + } + else + { + return digestAlgOID.Id; + } + } + } +} diff --git a/iTechSharp/srcbc/x509/X509Utilities.cs b/iTechSharp/srcbc/x509/X509Utilities.cs new file mode 100644 index 0000000..1940167 --- /dev/null +++ b/iTechSharp/srcbc/x509/X509Utilities.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections; +using System.Globalization; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.X509 +{ + internal class X509Utilities + { + private static readonly Hashtable algorithms = new Hashtable(); + private static readonly Hashtable exParams = new Hashtable(); + private static readonly ISet noParams = new HashSet(); + + static X509Utilities() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add(NistObjectIdentifiers.DsaWithSha224); + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + + // + // RFC 4491 + // + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20)); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); + exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28)); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32)); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48)); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); + } + + private static RsassaPssParameters CreatePssParams( + AlgorithmIdentifier hashAlgId, + int saltSize) + { + return new RsassaPssParameters( + hashAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), + new DerInteger(saltSize), + new DerInteger(1)); + } + + internal static DerObjectIdentifier GetAlgorithmOid( + string algorithmName) + { + algorithmName = algorithmName.ToUpper(CultureInfo.InvariantCulture); + + if (algorithms.ContainsKey(algorithmName)) + { + return (DerObjectIdentifier) algorithms[algorithmName]; + } + + return new DerObjectIdentifier(algorithmName); + } + + internal static AlgorithmIdentifier GetSigAlgID( + DerObjectIdentifier sigOid, + string algorithmName) + { + if (noParams.Contains(sigOid)) + { + return new AlgorithmIdentifier(sigOid); + } + + algorithmName = algorithmName.ToUpper(CultureInfo.InvariantCulture); + + if (exParams.ContainsKey(algorithmName)) + { + return new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]); + } + + return new AlgorithmIdentifier(sigOid, DerNull.Instance); + } + + internal static IEnumerable GetAlgNames() + { + return new EnumerableProxy(algorithms.Keys); + } + + internal static byte[] GetSignatureForObject( + DerObjectIdentifier sigOid, // TODO Redundant now? + string sigName, + AsymmetricKeyParameter privateKey, + SecureRandom random, + Asn1Encodable ae) + { + if (sigOid == null) + throw new ArgumentNullException("sigOid"); + + ISigner sig = SignerUtilities.GetSigner(sigName); + + if (random != null) + { + sig.Init(true, new ParametersWithRandom(privateKey, random)); + } + else + { + sig.Init(true, privateKey); + } + + byte[] encoded = ae.GetDerEncoded(); + sig.BlockUpdate(encoded, 0, encoded.Length); + + return sig.GenerateSignature(); + } + } +} diff --git a/iTechSharp/srcbc/x509/X509V1CertificateGenerator.cs b/iTechSharp/srcbc/x509/X509V1CertificateGenerator.cs new file mode 100644 index 0000000..02b58a1 --- /dev/null +++ b/iTechSharp/srcbc/x509/X509V1CertificateGenerator.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; + +namespace Org.BouncyCastle.X509 +{ + ///
Selector
like implementation to select
+ * attribute certificates from a given set of criteria.
+ *
+ * @see org.bouncycastle.x509.X509AttributeCertificate
+ * @see org.bouncycastle.x509.X509Store
+ */
+ public class X509AttrCertStoreSelector
+ : IX509Selector
+ {
+ // TODO: name constraints???
+
+ private IX509AttributeCertificate attributeCert;
+ private DateTimeObject attributeCertificateValid;
+ private AttributeCertificateHolder holder;
+ private AttributeCertificateIssuer issuer;
+ private BigInteger serialNumber;
+ private ISet targetNames = new HashSet();
+ private ISet targetGroups = new HashSet();
+
+ public X509AttrCertStoreSelector()
+ {
+ }
+
+ private X509AttrCertStoreSelector(
+ X509AttrCertStoreSelector o)
+ {
+ this.attributeCert = o.attributeCert;
+ this.attributeCertificateValid = o.attributeCertificateValid;
+ this.holder = o.holder;
+ this.issuer = o.issuer;
+ this.serialNumber = o.serialNumber;
+ this.targetGroups = new HashSet(o.targetGroups);
+ this.targetNames = new HashSet(o.targetNames);
+ }
+
+ /// true
if the object matches this selector.X509AttributeCertificate
+ * must contain at least one of the specified target names.
+ * + * Each attribute certificate may contain a target information extension + * limiting the servers where this attribute certificate can be used. If + * this extension is not present, the attribute certificate is not targeted + * and may be accepted by any server. + *
+ * + * @param name The name as a GeneralName (notnull
)
+ */
+ public void AddTargetName(
+ GeneralName name)
+ {
+ targetNames.Add(name);
+ }
+
+ /**
+ * Adds a target name criterion for the attribute certificate to the target
+ * information extension criteria. The X509AttributeCertificate
+ * must contain at least one of the specified target names.
+ * + * Each attribute certificate may contain a target information extension + * limiting the servers where this attribute certificate can be used. If + * this extension is not present, the attribute certificate is not targeted + * and may be accepted by any server. + *
+ * + * @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName + * @throws IOException if a parsing error occurs. + */ + public void AddTargetName( + byte[] name) + { + AddTargetName(GeneralName.GetInstance(Asn1Object.FromByteArray(name))); + } + + /** + * Adds a collection with target names criteria. Ifnull
is
+ * given any will do.
+ * + * The collection consists of either GeneralName objects or byte[] arrays representing + * DER encoded GeneralName structures. + *
+ * + * @param names A collection of target names. + * @throws IOException if a parsing error occurs. + * @see #AddTargetName(byte[]) + * @see #AddTargetName(GeneralName) + */ + public void SetTargetNames( + IEnumerable names) + { + targetNames = ExtractGeneralNames(names); + } + + /** + * Gets the target names. The collection consists ofList
s
+ * made up of an Integer
in the first entry and a DER encoded
+ * byte array or a String
in the second entry.
+ * The returned collection is immutable.
+ * + * @return The collection of target names + * @see #setTargetNames(Collection) + */ + public IEnumerable GetTargetNames() + { + return new EnumerableProxy(targetNames); + } + + /** + * Adds a target group criterion for the attribute certificate to the target + * information extension criteria. TheX509AttributeCertificate
+ * must contain at least one of the specified target groups.
+ * + * Each attribute certificate may contain a target information extension + * limiting the servers where this attribute certificate can be used. If + * this extension is not present, the attribute certificate is not targeted + * and may be accepted by any server. + *
+ * + * @param group The group as GeneralName form (notnull
)
+ */
+ public void AddTargetGroup(
+ GeneralName group)
+ {
+ targetGroups.Add(group);
+ }
+
+ /**
+ * Adds a target group criterion for the attribute certificate to the target
+ * information extension criteria. The X509AttributeCertificate
+ * must contain at least one of the specified target groups.
+ * + * Each attribute certificate may contain a target information extension + * limiting the servers where this attribute certificate can be used. If + * this extension is not present, the attribute certificate is not targeted + * and may be accepted by any server. + *
+ * + * @param name a byte array containing the group in ASN.1 DER encoded form of a GeneralName + * @throws IOException if a parsing error occurs. + */ + public void AddTargetGroup( + byte[] name) + { + AddTargetGroup(GeneralName.GetInstance(Asn1Object.FromByteArray(name))); + } + + /** + * Adds a collection with target groups criteria. Ifnull
is
+ * given any will do.
+ *
+ * The collection consists of GeneralName
objects or byte[]
+ * representing DER encoded GeneralNames.
+ *
List
s
+ * made up of an Integer
in the first entry and a DER encoded
+ * byte array or a String
in the second entry.
+ * The returned collection is immutable.
+ * + * @return The collection of target groups. + * @see #setTargetGroups(Collection) + */ + public IEnumerable GetTargetGroups() + { + return new EnumerableProxy(targetGroups); + } + + private ISet ExtractGeneralNames( + IEnumerable names) + { + ISet result = new HashSet(); + + if (names != null) + { + foreach (object o in names) + { + if (o is GeneralName) + { + result.Add(o); + } + else + { + result.Add(GeneralName.GetInstance(Asn1Object.FromByteArray((byte[]) o))); + } + } + } + + return result; + } + } +} diff --git a/iTechSharp/srcbc/x509/store/X509CertPairStoreSelector.cs b/iTechSharp/srcbc/x509/store/X509CertPairStoreSelector.cs new file mode 100644 index 0000000..2796971 --- /dev/null +++ b/iTechSharp/srcbc/x509/store/X509CertPairStoreSelector.cs @@ -0,0 +1,92 @@ +using System; + +namespace Org.BouncyCastle.X509.Store +{ + ///IX509Selector
implementation to select
+ /// certificate pairs, which are e.g. used for cross certificates. The set of
+ /// criteria is given from two X509CertStoreSelector
objects,
+ /// each of which, if present, must match the respective component of a pair.
+ /// X509CertificatePair
, this method
+ /// returns false
.
+ /// X509CertificatePair
to be tested.
+ /// true
if the object matches this selector.ISet
of DerObjectIdentifier
objects.
+ /// X509Store
s.+ /// The collection is copied. + ///
+ ///ICollection
.ICollection
of X509Name
objects
+ /// null
is specified, then no such
+ * optional information is provided.
+ *
+ * @param attrCert the IX509AttributeCertificate
being checked (or
+ * null
)
+ * @see #getAttrCertificateChecking()
+ */
+ public IX509AttributeCertificate AttrCertChecking
+ {
+ get { return attrCertChecking; }
+ set { this.attrCertChecking = value; }
+ }
+
+ /**
+ * If true
only complete CRLs are returned. Defaults to
+ * false
.
+ *
+ * @return true
if only complete CRLs are returned.
+ */
+ public bool CompleteCrlEnabled
+ {
+ get { return completeCrlEnabled; }
+ set { this.completeCrlEnabled = value; }
+ }
+
+ /**
+ * Returns if this selector must match CRLs with the delta CRL indicator
+ * extension set. Defaults to false
.
+ *
+ * @return Returns true
if only CRLs with the delta CRL
+ * indicator extension are selected.
+ */
+ public bool DeltaCrlIndicatorEnabled
+ {
+ get { return deltaCrlIndicatorEnabled; }
+ set { this.deltaCrlIndicatorEnabled = value; }
+ }
+
+ /**
+ * The issuing distribution point.
+ * + * The issuing distribution point extension is a CRL extension which + * identifies the scope and the distribution point of a CRL. The scope + * contains among others information about revocation reasons contained in + * the CRL. Delta CRLs and complete CRLs must have matching issuing + * distribution points.
+ *+ * The byte array is cloned to protect against subsequent modifications.
+ *+ * You must also enable or disable this criteria with + * {@link #setIssuingDistributionPointEnabled(bool)}.
+ * + * @param issuingDistributionPoint The issuing distribution point to set. + * This is the DER encoded OCTET STRING extension value. + * @see #getIssuingDistributionPoint() + */ + public byte[] IssuingDistributionPoint + { + get { return Arrays.Clone(issuingDistributionPoint); } + set { this.issuingDistributionPoint = Arrays.Clone(value); } + } + + /** + * Whether the issuing distribution point criteria should be applied. + * Defaults tofalse
.
+ * + * You may also set the issuing distribution point criteria if not a missing + * issuing distribution point should be assumed.
+ * + * @return Returns if the issuing distribution point check is enabled. + */ + public bool IssuingDistributionPointEnabled + { + get { return issuingDistributionPointEnabled; } + set { this.issuingDistributionPointEnabled = value; } + } + + /** + * The maximum base CRL number. Defaults tonull
.
+ *
+ * @return Returns the maximum base CRL number.
+ * @see #setMaxBaseCRLNumber(BigInteger)
+ */
+ public BigInteger MaxBaseCrlNumber
+ {
+ get { return maxBaseCrlNumber; }
+ set { this.maxBaseCrlNumber = value; }
+ }
+
+ public virtual bool Match(
+ object obj)
+ {
+ X509Crl c = obj as X509Crl;
+
+ if (c == null)
+ return false;
+
+ if (dateAndTime != null)
+ {
+ DateTime dt = dateAndTime.Value;
+ DateTime tu = c.ThisUpdate;
+ DateTimeObject nu = c.NextUpdate;
+
+ if (dt.CompareTo(tu) < 0 || nu == null || dt.CompareTo(nu.Value) >= 0)
+ return false;
+ }
+
+ if (issuers != null)
+ {
+ X509Name i = c.IssuerDN;
+
+ bool found = false;
+
+ foreach (X509Name issuer in issuers)
+ {
+ if (issuer.Equivalent(i))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return false;
+ }
+
+ if (maxCrlNumber != null || minCrlNumber != null)
+ {
+ Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CrlNumber);
+ if (extVal == null)
+ return false;
+
+ BigInteger cn = CrlNumber.GetInstance(
+ X509ExtensionUtilities.FromExtensionValue(extVal)).PositiveValue;
+
+ if (maxCrlNumber != null && cn.CompareTo(maxCrlNumber) > 0)
+ return false;
+
+ if (minCrlNumber != null && cn.CompareTo(minCrlNumber) < 0)
+ return false;
+ }
+
+ DerInteger dci = null;
+ try
+ {
+ Asn1OctetString bytes = c.GetExtensionValue(X509Extensions.DeltaCrlIndicator);
+ if (bytes != null)
+ {
+ dci = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(bytes));
+ }
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+
+ if (dci == null)
+ {
+ if (DeltaCrlIndicatorEnabled)
+ return false;
+ }
+ else
+ {
+ if (CompleteCrlEnabled)
+ return false;
+
+ if (maxBaseCrlNumber != null && dci.PositiveValue.CompareTo(maxBaseCrlNumber) > 0)
+ return false;
+ }
+
+ if (issuingDistributionPointEnabled)
+ {
+ Asn1OctetString idp = c.GetExtensionValue(X509Extensions.IssuingDistributionPoint);
+ if (issuingDistributionPoint == null)
+ {
+ if (idp != null)
+ return false;
+ }
+ else
+ {
+ if (!Arrays.AreEqual(idp.GetOctets(), issuingDistributionPoint))
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/x509/store/X509StoreException.cs b/iTechSharp/srcbc/x509/store/X509StoreException.cs
new file mode 100644
index 0000000..f6a5e23
--- /dev/null
+++ b/iTechSharp/srcbc/x509/store/X509StoreException.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Org.BouncyCastle.X509.Store
+{
+ public class X509StoreException
+ : Exception
+ {
+ public X509StoreException()
+ {
+ }
+
+ public X509StoreException(
+ string message)
+ : base(message)
+ {
+ }
+
+ public X509StoreException(
+ string message,
+ Exception e)
+ : base(message, e)
+ {
+ }
+ }
+}
diff --git a/iTechSharp/srcbc/x509/store/X509StoreFactory.cs b/iTechSharp/srcbc/x509/store/X509StoreFactory.cs
new file mode 100644
index 0000000..9cddb99
--- /dev/null
+++ b/iTechSharp/srcbc/x509/store/X509StoreFactory.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Globalization;
+
+namespace Org.BouncyCastle.X509.Store
+{
+ public sealed class X509StoreFactory
+ {
+ private X509StoreFactory()
+ {
+ }
+
+ public static IX509Store Create(
+ string type,
+ IX509StoreParameters parameters)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+
+ string[] parts = type.ToUpper(CultureInfo.InvariantCulture).Split('/');
+
+ if (parts.Length < 2)
+ throw new ArgumentException("type");
+
+
+ switch (parts[0])
+ {
+ case "ATTRIBUTECERTIFICATE":
+ case "CERTIFICATE":
+ case "CERTIFICATEPAIR":
+ case "CRL":
+ {
+ if (parts[1] == "COLLECTION")
+ {
+ X509CollectionStoreParameters p = (X509CollectionStoreParameters) parameters;
+ return new X509CollectionStore(p.GetCollection());
+ }
+ break;
+ }
+ }
+
+ throw new NoSuchStoreException("X.509 store type '" + type + "' not available.");
+ }
+ }
+}