Initial Commit

This commit is contained in:
2023-06-21 12:46:23 -04:00
commit c70248a520
1352 changed files with 336780 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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;
};
}
}

View File

@@ -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") {
}
}
}

View File

@@ -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 <CODE>PdfObject</CODE>.
*
* @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) {}
}
}

View File

@@ -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. <CODE>null</CODE> 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 <CODE>Element.ALIGN_LEFT</CODE>,
* <CODE>Element.ALIGN_CENTER</CODE> or <CODE>Element.ALIGN_RIGHT</CODE>.
*/
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. <CODE>null</CODE> if no text.
* @return the text font. <CODE>null</CODE> 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 <CODE>Element.ALIGN_LEFT</CODE>,
* <CODE>Element.ALIGN_CENTER</CODE> or <CODE>Element.ALIGN_RIGHT</CODE>.
* @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 <CODE>PdfContentByte</CODE>. The
* barcode is always placed at coodinates (0, 0). Use the
* translation matrix to move it elsewhere.<p>
* The bars and text are written in the following colors:<p>
* <P><TABLE BORDER=1>
* <TR>
* <TH><P><CODE>barColor</CODE></TH>
* <TH><P><CODE>textColor</CODE></TH>
* <TH><P>Result</TH>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with current fill color</TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* </TABLE>
* @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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 <CODE>PdfContentByte</CODE> to create the template. It
* serves no other use
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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 <CODE>Image</CODE> with the barcode.
* @param cb the <CODE>PdfContentByte</CODE> to create the <CODE>Image</CODE>. It
* serves no other use
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @return the <CODE>Image</CODE>
* @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);
}
}

View File

@@ -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.<p>
* The code types allowed are:<br>
* <ul>
* <li><b>CODE128</b> - plain barcode 128.
* <li><b>CODE128_UCC</b> - support for UCC/EAN-128 with a full list of AI.
* <li><b>CODE128_RAW</b> - raw mode. The code attribute has the actual codes from 0
* to 105 followed by '&#92;uffff' and the human readable text.
* </ul>
* The default parameters are:
* <pre>
* x = 0.8f;
* font = BaseFont.CreateFont("Helvetica", "winansi", false);
* size = 8;
* baseline = size;
* barHeight = size * 3;
* textint= Element.ALIGN_CENTER;
* codeType = CODE128;
* </pre>
*
* @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 <CODE>true</CODE> if the next <CODE>numDigits</CODE>
* starting from index <CODE>textIndex</CODE> 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 <CODE>true</CODE> 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 <CODE>PdfContentByte</CODE>. The
* barcode is always placed at coodinates (0, 0). Use the
* translation matrix to move it elsewhere.<p>
* The bars and text are written in the following colors:<p>
* <P><TABLE BORDER=1>
* <TR>
* <TH><P><CODE>barColor</CODE></TH>
* <TH><P><CODE>textColor</CODE></TH>
* <TH><P>Result</TH>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with current fill color</TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* </TABLE>
* @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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:
* <p>
* <code>(01)00000090311314(10)ABC123(15)060916</code>
* @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;
}
}
}

View File

@@ -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:
* <pre>
*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;
* </pre>
*
* @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 <CODE>BARS</CODE>.
*/
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 <CODE>PdfContentByte</CODE>. The
* barcode is always placed at coodinates (0, 0). Use the
* translation matrix to move it elsewhere.<p>
* The bars and text are written in the following colors:<p>
* <P><TABLE BORDER=1>
* <TR>
* <TH><P><CODE>barColor</CODE></TH>
* <TH><P><CODE>textColor</CODE></TH>
* <TH><P>Result</TH>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with current fill color</TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* </TABLE>
* @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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;
}
}
}

View File

@@ -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:
* <pre>
*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;
* </pre>
*
* @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 <CODE>BARS</CODE>.
*/
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 <CODE>PdfContentByte</CODE>. The
* barcode is always placed at coodinates (0, 0). Use the
* translation matrix to move it elsewhere.<p>
* The bars and text are written in the following colors:<p>
* <P><TABLE BORDER=1>
* <TR>
* <TH><P><CODE>barColor</CODE></TH>
* <TH><P><CODE>textColor</CODE></TH>
* <TH><P>Result</TH>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with current fill color</TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* </TABLE>
* @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,697 @@
using System;
using iTextSharp.text;
using System.Collections;
/*
* 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 {
/** Generates barcodes in several formats: EAN13, EAN8, UPCA, UPCE,
* supplemental 2 and 5. The default parameters are:
* <pre>
*x = 0.8f;
*font = BaseFont.CreateFont("Helvetica", "winansi", false);
*size = 8;
*baseline = size;
*barHeight = size * 3;
*guardBars = true;
*codeType = EAN13;
*code = "";
* </pre>
*
* @author Paulo Soares (psoares@consiste.pt)
*/
public class BarcodeEAN : Barcode {
/** The bar positions that are guard bars.*/
private static readonly int[] GUARD_EMPTY = {};
/** The bar positions that are guard bars.*/
private static readonly int[] GUARD_UPCA = {0, 2, 4, 6, 28, 30, 52, 54, 56, 58};
/** The bar positions that are guard bars.*/
private static readonly int[] GUARD_EAN13 = {0, 2, 28, 30, 56, 58};
/** The bar positions that are guard bars.*/
private static readonly int[] GUARD_EAN8 = {0, 2, 20, 22, 40, 42};
/** The bar positions that are guard bars.*/
private static readonly int[] GUARD_UPCE = {0, 2, 28, 30, 32};
/** The x coordinates to place the text.*/
private static readonly float[] TEXTPOS_EAN13 = {6.5f, 13.5f, 20.5f, 27.5f, 34.5f, 41.5f, 53.5f, 60.5f, 67.5f, 74.5f, 81.5f, 88.5f};
/** The x coordinates to place the text.*/
private static readonly float[] TEXTPOS_EAN8 = {6.5f, 13.5f, 20.5f, 27.5f, 39.5f, 46.5f, 53.5f, 60.5f};
/** The basic bar widths.*/
private static readonly byte[][] BARS =
{
new byte[] {3, 2, 1, 1}, // 0
new byte[] {2, 2, 2, 1}, // 1
new byte[] {2, 1, 2, 2}, // 2
new byte[] {1, 4, 1, 1}, // 3
new byte[] {1, 1, 3, 2}, // 4
new byte[] {1, 2, 3, 1}, // 5
new byte[] {1, 1, 1, 4}, // 6
new byte[] {1, 3, 1, 2}, // 7
new byte[] {1, 2, 1, 3}, // 8
new byte[] {3, 1, 1, 2} // 9
};
/** The total number of bars for EAN13.*/
private const int TOTALBARS_EAN13 = 11 + 12 * 4;
/** The total number of bars for EAN8.*/
private const int TOTALBARS_EAN8 = 11 + 8 * 4;
/** The total number of bars for UPCE.*/
private const int TOTALBARS_UPCE = 9 + 6 * 4;
/** The total number of bars for supplemental 2.*/
private const int TOTALBARS_SUPP2 = 13;
/** The total number of bars for supplemental 5.*/
private const int TOTALBARS_SUPP5 = 31;
/** Marker for odd parity.*/
private const byte ODD = 0;
/** Marker for even parity.*/
private const byte EVEN = 1;
/** Sequence of parities to be used with EAN13.*/
private static readonly byte[][] PARITY13 =
{
new byte[] {ODD, ODD, ODD, ODD, ODD, ODD}, // 0
new byte[] {ODD, ODD, EVEN, ODD, EVEN, EVEN}, // 1
new byte[] {ODD, ODD, EVEN, EVEN, ODD, EVEN}, // 2
new byte[] {ODD, ODD, EVEN, EVEN, EVEN, ODD}, // 3
new byte[] {ODD, EVEN, ODD, ODD, EVEN, EVEN}, // 4
new byte[] {ODD, EVEN, EVEN, ODD, ODD, EVEN}, // 5
new byte[] {ODD, EVEN, EVEN, EVEN, ODD, ODD}, // 6
new byte[] {ODD, EVEN, ODD, EVEN, ODD, EVEN}, // 7
new byte[] {ODD, EVEN, ODD, EVEN, EVEN, ODD}, // 8
new byte[] {ODD, EVEN, EVEN, ODD, EVEN, ODD} // 9
};
/** Sequence of parities to be used with supplemental 2.*/
private static readonly byte[][] PARITY2 =
{
new byte[] {ODD, ODD}, // 0
new byte[] {ODD, EVEN}, // 1
new byte[] {EVEN, ODD}, // 2
new byte[] {EVEN, EVEN} // 3
};
/** Sequence of parities to be used with supplemental 2.*/
private static readonly byte[][] PARITY5 =
{
new byte[] {EVEN, EVEN, ODD, ODD, ODD}, // 0
new byte[] {EVEN, ODD, EVEN, ODD, ODD}, // 1
new byte[] {EVEN, ODD, ODD, EVEN, ODD}, // 2
new byte[] {EVEN, ODD, ODD, ODD, EVEN}, // 3
new byte[] {ODD, EVEN, EVEN, ODD, ODD}, // 4
new byte[] {ODD, ODD, EVEN, EVEN, ODD}, // 5
new byte[] {ODD, ODD, ODD, EVEN, EVEN}, // 6
new byte[] {ODD, EVEN, ODD, EVEN, ODD}, // 7
new byte[] {ODD, EVEN, ODD, ODD, EVEN}, // 8
new byte[] {ODD, ODD, EVEN, ODD, EVEN} // 9
};
/** Sequence of parities to be used with UPCE.*/
private static readonly byte[][] PARITYE =
{
new byte[] {EVEN, EVEN, EVEN, ODD, ODD, ODD}, // 0
new byte[] {EVEN, EVEN, ODD, EVEN, ODD, ODD}, // 1
new byte[] {EVEN, EVEN, ODD, ODD, EVEN, ODD}, // 2
new byte[] {EVEN, EVEN, ODD, ODD, ODD, EVEN}, // 3
new byte[] {EVEN, ODD, EVEN, EVEN, ODD, ODD}, // 4
new byte[] {EVEN, ODD, ODD, EVEN, EVEN, ODD}, // 5
new byte[] {EVEN, ODD, ODD, ODD, EVEN, EVEN}, // 6
new byte[] {EVEN, ODD, EVEN, ODD, EVEN, ODD}, // 7
new byte[] {EVEN, ODD, EVEN, ODD, ODD, EVEN}, // 8
new byte[] {EVEN, ODD, ODD, EVEN, ODD, EVEN} // 9
};
/** Creates new BarcodeEAN */
public BarcodeEAN() {
x = 0.8f;
font = BaseFont.CreateFont("Helvetica", "winansi", false);
size = 8;
baseline = size;
barHeight = size * 3;
guardBars = true;
codeType = EAN13;
code = "";
}
/** Calculates the EAN parity character.
* @param code the code
* @return the parity character
*/
public static int CalculateEANParity(string code) {
int mul = 3;
int total = 0;
for (int k = code.Length - 1; k >= 0; --k) {
int n = code[k] - '0';
total += mul * n;
mul ^= 2;
}
return (10 - (total % 10)) % 10;
}
/** Converts an UPCA code into an UPCE code. If the code can not
* be converted a <CODE>null</CODE> is returned.
* @param text the code to convert. It must have 12 numeric characters
* @return the 8 converted digits or <CODE>null</CODE> 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 <CODE>PdfContentByte</CODE>. The
* barcode is always placed at coodinates (0, 0). Use the
* translation matrix to move it elsewhere.<p>
* The bars and text are written in the following colors:<p>
* <P><TABLE BORDER=1>
* <TR>
* <TH><P><CODE>barColor</CODE></TH>
* <TH><P><CODE>textColor</CODE></TH>
* <TH><P>Result</TH>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with current fill color</TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* </TABLE>
* @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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;
}
}
}

View File

@@ -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.<p>
* The default parameters are:
* <pre>
*n = 8; // horizontal distance between the two barcodes
* </pre>
*
* @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 <CODE>PdfContentByte</CODE>. The
* barcode is always placed at coodinates (0, 0). Use the
* translation matrix to move it elsewhere.<p>
* The bars and text are written in the following colors:<p>
* <P><TABLE BORDER=1>
* <TR>
* <TH><P><CODE>barColor</CODE></TH>
* <TH><P><CODE>textColor</CODE></TH>
* <TH><P>Result</TH>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with current fill color</TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* </TABLE>
* @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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.");
}
}
}

View File

@@ -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:
* <pre>
*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;
* </pre>
*
* @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 <CODE>text</CODE>.
* @param text the text
* @return a <CODE>string</CODE> 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 <CODE>PdfContentByte</CODE>. The
* barcode is always placed at coodinates (0, 0). Use the
* translation matrix to move it elsewhere.<p>
* The bars and text are written in the following colors:<p>
* <P><TABLE BORDER=1>
* <TR>
* <TH><P><CODE>barColor</CODE></TH>
* <TH><P><CODE>textColor</CODE></TH>
* <TH><P>Result</TH>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with current fill color</TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* </TABLE>
* @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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:
* <pre>
*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
* </pre>
*
* @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 <CODE>PdfContentByte</CODE>. The
* barcode is always placed at coodinates (0, 0). Use the
* translation matrix to move it elsewhere.<p>
* The bars and text are written in the following colors:<p>
* <P><TABLE BORDER=1>
* <TR>
* <TH><P><CODE>barColor</CODE></TH>
* <TH><P><CODE>textColor</CODE></TH>
* <TH><P>Result</TH>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with current fill color</TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>null</CODE></TD>
* <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>null</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* <TR>
* <TD><P><CODE>barColor</CODE></TD>
* <TD><P><CODE>textColor</CODE></TD>
* <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
* </TR>
* </TABLE>
* @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
* @param barColor the color of the bars. It can be <CODE>null</CODE>
* @param textColor the color of the text. It can be <CODE>null</CODE>
* @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;
}
}
}

View File

@@ -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 <CODE>EDIT</CODE> 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 <CODE>TextField</CODE>.
* @param writer the document <CODE>PdfWriter</CODE>
* @param box the field location and dimensions
* @param fieldName the field name. If <CODE>null</CODE> 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 <CODE>null</CODE>.
* @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 <CODE>PdfBorderDictionary</CODE>
* and can be <CODE>STYLE_SOLID</CODE>, <CODE>STYLE_DASHED</CODE>,
* <CODE>STYLE_BEVELED</CODE>, <CODE>STYLE_INSET</CODE> and
* <CODE>STYLE_UNDERLINE</CODE>.
* @param borderStyle the border style
*/
public int BorderStyle {
set {
this.borderStyle = value;
}
get {
return borderStyle;
}
}
/** Sets the border color. Set to <CODE>null</CODE> 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 <CODE>null</CODE> for
* transparent background.
* @param backgroundColor the background color
*/
public Color BackgroundColor {
set {
this.backgroundColor = value;
}
get {
return backgroundColor;
}
}
/** Sets the text color. If <CODE>null</CODE> 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 <CODE>null</CODE> 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 <CODE>Element.ALIGN_LEFT</CODE>,
* <CODE>Element.ALIGN_CENTER</CODE> and <CODE>Element.ALIGN_RIGHT</CODE>.
* @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
* <CODE>VISIBLE</CODE>, <CODE>HIDDEN</CODE>, <CODE>VISIBLE_BUT_DOES_NOT_PRINT</CODE>
* and <CODE>HIDDEN_BUT_PRINTABLE</CODE>.
* @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 <CODE>null</CODE> 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
* <CODE>READ_ONLY</CODE>, <CODE>REQUIRED</CODE>,
* <CODE>MULTILINE</CODE>, <CODE>DO_NOT_SCROLL</CODE>,
* <CODE>PASSWORD</CODE>, <CODE>FILE_SELECTION</CODE>,
* <CODE>DO_NOT_SPELL_CHECK</CODE> and <CODE>EDIT</CODE>.
* @param options the option flags
*/
public int Options {
set {
this.options = value;
}
get {
return options;
}
}
/** Sets the maximum length of the field<6C>s text, in characters.
* It is only meaningful for text fields.
* @param maxCharacterLength the maximum length of the field<6C>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 <CODE>from</CODE> to <CODE>to</CODE>. The moved keys
* are removed from <CODE>from</CODE>.
* @param from the source
* @param to the destination. It may be <CODE>null</CODE>
*/
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);
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <CODE>StringBuilder</CODE> but works with <CODE>byte</CODE> 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 <CODE>true</CODE> always output floating point numbers with 6 decimal digits.
* If <CODE>false</CODE> 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.
* <P>
* 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 <CODE>int</CODE>. The size of the array will grow by one.
* @param b the int to be appended
* @return a reference to this <CODE>ByteBuffer</CODE> 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 <CODE>byte</CODE> array. The buffer will grow by
* <CODE>len</CODE> 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 <CODE>ByteBuffer</CODE> 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 <CODE>ByteBuffer</CODE> object
*/
public ByteBuffer Append(byte[] b) {
return Append(b, 0, b.Length);
}
/**
* Appends a <CODE>string</CODE> to the buffer. The <CODE>string</CODE> is
* converted according to the encoding ISO-8859-1.
* @param str the <CODE>string</CODE> to be appended
* @return a reference to this <CODE>ByteBuffer</CODE> object
*/
public ByteBuffer Append(string str) {
if (str != null)
return Append(DocWriter.GetISOBytes(str));
return this;
}
/**
* Appends a <CODE>char</CODE> to the buffer. The <CODE>char</CODE> is
* converted according to the encoding ISO-8859-1.
* @param c the <CODE>char</CODE> to be appended
* @return a reference to this <CODE>ByteBuffer</CODE> object
*/
public ByteBuffer Append(char c) {
return Append_i(c);
}
/**
* Appends another <CODE>ByteBuffer</CODE> to this buffer.
* @param buf the <CODE>ByteBuffer</CODE> to be appended
* @return a reference to this <CODE>ByteBuffer</CODE> object
*/
public ByteBuffer Append(ByteBuffer buf) {
return Append(buf.buf, 0, buf.count);
}
/**
* Appends the string representation of an <CODE>int</CODE>.
* @param i the <CODE>int</CODE> to be appended
* @return a reference to this <CODE>ByteBuffer</CODE> 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 <CODE>float</CODE> according
* to the Pdf conventions.
* @param i the <CODE>float</CODE> to be appended
* @return a reference to this <CODE>ByteBuffer</CODE> object
*/
public ByteBuffer Append(float i) {
return Append((double)i);
}
/**
* Appends a string representation of a <CODE>double</CODE> according
* to the Pdf conventions.
* @param d the <CODE>double</CODE> to be appended
* @return a reference to this <CODE>ByteBuffer</CODE> object
*/
public ByteBuffer Append(double d) {
Append(FormatDouble(d, this));
return this;
}
/**
* Outputs a <CODE>double</CODE> into a format suitable for the PDF.
* @param d a double
* @return the <CODE>string</CODE> representation of the <CODE>double</CODE>
*/
public static string FormatDouble(double d) {
return FormatDouble(d, null);
}
/**
* Outputs a <CODE>double</CODE> into a format suitable for the PDF.
* @param d a double
* @param buf a ByteBuffer
* @return the <CODE>String</CODE> representation of the <CODE>double</CODE> if
* <CODE>buf</CODE> is <CODE>null</CODE>. If <CODE>buf</CODE> is <B>not</B> <CODE>null</CODE>,
* then the double is appended directly to the buffer and this methods returns <CODE>null</CODE>.
*/
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 <code>count</code> 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 <code>out.Write(buf, 0, count)</code>.
*
* @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);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,646 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.util;
/*
* $Id: CJKFont.cs,v 1.9 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 {
/**
* Creates a CJK font compatible with the fonts in the Adobe Asian font Pack.
*
* @author Paulo Soares (psoares@consiste.pt)
*/
internal class CJKFont : BaseFont {
/** The encoding used in the PDF document for CJK fonts
*/
internal const string CJK_ENCODING = "UNICODEBIGUNMARKED";
private const int FIRST = 0;
private const int BRACKET = 1;
private const int SERIAL = 2;
private const int V1Y = 880;
internal static Properties cjkFonts = new Properties();
internal static Properties cjkEncodings = new Properties();
internal static Hashtable allCMaps = Hashtable.Synchronized(new Hashtable());
internal static Hashtable allFonts = Hashtable.Synchronized(new Hashtable());
private static bool propertiesLoaded = false;
/** The font name */
private string fontName;
/** The style modifier */
private string style = "";
/** The CMap name associated with this font */
private string CMap;
private bool cidDirect = false;
private char[] translationMap;
private IntHashtable vMetrics;
private IntHashtable hMetrics;
private Hashtable fontDesc;
private bool vertical = false;
private static void LoadProperties() {
if (propertiesLoaded)
return;
lock (allFonts) {
if (propertiesLoaded)
return;
try {
Stream isp = GetResourceStream(RESOURCE_PATH + "cjkfonts.properties");
cjkFonts.Load(isp);
isp.Close();
isp = GetResourceStream(RESOURCE_PATH + "cjkencodings.properties");
cjkEncodings.Load(isp);
isp.Close();
}
catch {
cjkFonts = new Properties();
cjkEncodings = new Properties();
}
propertiesLoaded = true;
}
}
/** Creates a CJK font.
* @param fontName the name of the font
* @param enc the encoding of the font
* @param emb always <CODE>false</CODE>. 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 <CODE>true</CODE> 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 <CODE>char</CODE> in normalized 1000 units.
* @param char1 the unicode <CODE>char</CODE> 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 <CODE>key</CODE>. Valid values
* for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>, <CODE>DESCENT</CODE>
* and <CODE>ITALICANGLE</CODE>.
* @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.<br>
* 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.<br>
* 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.<br>
* 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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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 <CODE>PDfSpotColor</CODE>
*/
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 <CODE>SpotColor</CODE> object.
* @return the <CODE>PdfSpotColor</CODE>
*/
internal PdfObject GetSpotColor(PdfWriter writer) {
return spotcolor.GetSpotObject(writer);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <CODE>PdfString</CODE>.
* <P>
* 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 <CODE>true</CODE> if the character can be used to split a string, <CODE>false</CODE> 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]);
}
}
}

View File

@@ -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.<br>
* 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 <CODE>key</CODE>. Valid values
* for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>, <CODE>DESCENT</CODE>,
* <CODE>ITALICANGLE</CODE>, <CODE>BBOXLLX</CODE>, <CODE>BBOXLLY</CODE>, <CODE>BBOXURX</CODE>
* and <CODE>BBOXURY</CODE>.
* @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.<br>
* 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.<br>
* 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 <CODE>c</CODE>
* or the <CODE>name</CODE>. If the <CODE>name</CODE> 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 <CODE>true</CODE> 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 <CODE>char</CODE> in normalized 1000 units.
* @param char1 the unicode <CODE>char</CODE> 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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 <CODE>InputStream</CODE> 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 <CODE>PdfDictionary</CODE>
* 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 <CODE>null</CODE> if the field does not
* exist or has no value defined.
* @param name the fully qualified field name
* @return the field value or <CODE>null</CODE>
*/
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;
}
}
}
}

View File

@@ -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 <CODE>true</CODE> if the field was found and removed,
* <CODE>false</CODE> 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 <CODE>PdfObject</CODE>.
* @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 <CODE>null</CODE> 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 <CODE>true</CODE> if the value was inserted,
* <CODE>false</CODE> 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 <CODE>true</CODE> if the value was inserted,
* <CODE>false</CODE> 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 <CODE>FdfReader</CODE>
* @param fdf the <CODE>FdfReader</CODE>
*/
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 <CODE>PdfReader</CODE>
* @param pdf the <CODE>PdfReader</CODE>
*/
public void SetFields(PdfReader pdf) {
SetFields(pdf.AcroFields);
}
/** Sets all the fields from this <CODE>AcroFields</CODE>
* @param acro the <CODE>AcroFields</CODE>
*/
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;
}
}
}
}

View File

@@ -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 <CODE>TrueTypeFontUnicode</CODE>
*/
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;
/** <CODE>true</CODE> 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 <CODE>BaseFont</CODE>
*/
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 <CODE>BaseFont</CODE> of this font.
* @return the <CODE>BaseFont</CODE> 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 <CODE>PdfWriter</CODE> 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 <CODE>false</CODE>
* to include all.
* @param subset new value of property subset
*/
public bool Subset {
set {
this.subset = value;
}
get {
return subset;
}
}
}
}

View File

@@ -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.
* <p>
* 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 <CODE>Font</CODE> to be searched for valid characters.
* @param font the <CODE>Font</CODE>
*/
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 <CODE>Phrase</CODE> 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;
}
}
}

View File

@@ -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];
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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 <CODE>Chunk</CODE>.
* @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 <CODE>getHyphenatedWordPost()</CODE>.
* @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 <CODE>getHyphenatedWordPre()</CODE>.
* @return the second part of the hyphenated word
*/
public string HyphenatedWordPost {
get {
return post;
}
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Text;
using System.Collections;
using System.IO;
namespace iTextSharp.text.pdf
{
/// <summary>
/// Summary description for ICC_Profile.
/// </summary>
public class ICC_Profile
{
protected byte[] data;
protected int numComponents;
private static Hashtable cstags = new Hashtable();
protected ICC_Profile() {
}
public static ICC_Profile GetInstance(byte[] data) {
if (data.Length < 128 | data[36] != 0x61 || data[37] != 0x63
|| data[38] != 0x73 || data[39] != 0x70)
throw new ArgumentException("Invalid ICC profile");
ICC_Profile icc = new ICC_Profile();
icc.data = data;
object cs = cstags[Encoding.ASCII.GetString(data, 16, 4)];
icc.numComponents = (cs == null ? 0 : (int)cs);
return icc;
}
public static ICC_Profile GetInstance(Stream file) {
byte[] head = new byte[128];
int remain = head.Length;
int ptr = 0;
while (remain > 0) {
int n = file.Read(head, ptr, remain);
if (n <= 0)
throw new ArgumentException("Invalid ICC profile");
remain -= n;
ptr += n;
}
if (head[36] != 0x61 || head[37] != 0x63
|| head[38] != 0x73 || head[39] != 0x70)
throw new ArgumentException("Invalid ICC profile");
remain = ((head[0] & 0xff) << 24) | ((head[1] & 0xff) << 16)
| ((head[2] & 0xff) << 8) | (head[3] & 0xff);
byte[] icc = new byte[remain];
System.Array.Copy(head, 0, icc, 0, head.Length);
remain -= head.Length;
ptr = head.Length;
while (remain > 0) {
int n = file.Read(icc, ptr, remain);
if (n <= 0)
throw new ArgumentException("Invalid ICC profile");
remain -= n;
ptr += n;
}
return GetInstance(icc);
}
public static ICC_Profile GetInstance(String fname) {
FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read, FileShare.Read);
ICC_Profile icc = GetInstance(fs);
fs.Close();
return icc;
}
public byte[] Data {
get {
return data;
}
}
public int NumComponents {
get {
return numComponents;
}
}
static ICC_Profile() {
cstags["XYZ "] = 3;
cstags["Lab "] = 3;
cstags["Luv "] = 3;
cstags["YCbr"] = 3;
cstags["Yxy "] = 3;
cstags["RGB "] = 3;
cstags["GRAY"] = 1;
cstags["HSV "] = 3;
cstags["HLS "] = 3;
cstags["CMYK"] = 4;
cstags["CMY "] = 3;
cstags["2CLR"] = 2;
cstags["3CLR"] = 3;
cstags["4CLR"] = 4;
cstags["5CLR"] = 5;
cstags["6CLR"] = 6;
cstags["7CLR"] = 7;
cstags["8CLR"] = 8;
cstags["9CLR"] = 9;
cstags["ACLR"] = 10;
cstags["BCLR"] = 11;
cstags["CCLR"] = 12;
cstags["DCLR"] = 13;
cstags["ECLR"] = 14;
cstags["FCLR"] = 15;
}
}
}

View File

@@ -0,0 +1,84 @@
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 {
/**
* Classes implementing this interface can create custom encodings or
* replace existing ones. It is used in the context of <code>PdfEncoding</code>.
* @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 <CODE>null</CODE> 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 <CODE>null</CODE> 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 <CODE>null</CODE> if no conversion is supported
*/
String ByteToChar(byte[] b, String encoding);
}
}

View File

@@ -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 <code>Chunk</code> 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 <CODE>getHyphenatedWordPost()</CODE>.
* @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 <CODE>getHyphenatedWordPre()</CODE>.
* @return the second part of the hyphenated word
*/
string HyphenatedWordPost {
get;
}
}
}

View File

@@ -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 <CODE>PdfIndirectReference</CODE> that represents this layer.
* @return the <CODE>PdfIndirectReference</CODE> that represents this layer
*/
PdfIndirectReference Ref {
get;
}
/**
* Gets the object representing the layer.
* @return the object representing the layer
*/
PdfObject PdfObject {
get;
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace iTextSharp.text.pdf
{
/// <summary>
/// Summary description for IPdfPCellEvent.
/// </summary>
public interface IPdfPCellEvent {
/** This method is called at the end of the cell rendering. The text or graphics are added to
* one of the 4 <CODE>PdfContentByte</CODE> contained in
* <CODE>canvases</CODE>.<br>
* The indexes to <CODE>canvases</CODE> are:<p>
* <ul>
* <li><CODE>PdfPTable.BASECANVAS</CODE> - the original <CODE>PdfContentByte</CODE>. Anything placed here
* will be under the cell.
* <li><CODE>PdfPTable.BACKGROUNDCANVAS</CODE> - the layer where the background goes to.
* <li><CODE>PdfPTable.LINECANVAS</CODE> - the layer where the lines go to.
* <li><CODE>PdfPTable.TEXTCANVAS</CODE> - the layer where the text go to. Anything placed here
* will be over the cell.
* </ul>
* The layers are placed in sequence on top of each other.
* <p>
* @param cell the cell
* @param position the coordinates of the cell
* @param canvases an array of <CODE>PdfContentByte</CODE>
*/
void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases);
}
}

View File

@@ -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 <CODE>PdfPTable</CODE>.
*
* @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 <CODE>PdfContentByte</CODE> contained in
* <CODE>canvases</CODE>.<br>
* The indexes to <CODE>canvases</CODE> are:<p>
* <ul>
* <li><CODE>PdfPTable.BASECANVAS</CODE> - the original <CODE>PdfContentByte</CODE>. Anything placed here
* will be under the table.
* <li><CODE>PdfPTable.BACKGROUNDCANVAS</CODE> - the layer where the background goes to.
* <li><CODE>PdfPTable.LINECANVAS</CODE> - the layer where the lines go to.
* <li><CODE>PdfPTable.TEXTCANVAS</CODE> - the layer where the text go to. Anything placed here
* will be over the table.
* </ul>
* The layers are placed in sequence on top of each other.
* <p>
* The <CODE>widths</CODE> and <CODE>heights</CODE> have the coordinates of the cells.<br>
* The size of the <CODE>widths</CODE> array is the number of rows.
* Each sub-array in <CODE>widths</CODE> 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 <CODE>widths</CODE>
* are the same.<br>
* For the <CODE>heights</CODE> 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 <CODE>PdfPTable</CODE> 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 <CODE>PdfContentByte</CODE>
*/
void TableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases);
}
}

View File

@@ -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 <CODE>PdfWriter</CODE> for this document
* @param document the document
*/
void OnOpenDocument(PdfWriter writer, Document document);
/**
* Called when a page is initialized.
* <P>
* Note that if even if a page is not written this method is still
* called. It is preferable to use <CODE>onEndPage</CODE> to avoid
* infinite loops.
*
* @param writer the <CODE>PdfWriter</CODE> 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 <CODE>PdfWriter</CODE> for this document
* @param document the document
*/
void OnEndPage(PdfWriter writer, Document document);
/**
* Called when the document is closed.
* <P>
* Note that this method is called with the page number equal
* to the last page plus one.
*
* @param writer the <CODE>PdfWriter</CODE> for this document
* @param document the document
*/
void OnCloseDocument(PdfWriter writer, Document document);
/**
* Called when a Paragraph is written.
* <P>
* <CODE>paragraphPosition</CODE> will hold the height at which the
* paragraph will be written to. This is useful to insert bookmarks with
* more control.
*
* @param writer the <CODE>PdfWriter</CODE> 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.
* <P>
* <CODE>paragraphPosition</CODE> will hold the height of the end of the paragraph.
*
* @param writer the <CODE>PdfWriter</CODE> 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.
* <P>
* <CODE>position</CODE> will hold the height at which the
* chapter will be written to.
*
* @param writer the <CODE>PdfWriter</CODE> 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.
* <P>
* <CODE>position</CODE> will hold the height of the end of the chapter.
*
* @param writer the <CODE>PdfWriter</CODE> 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.
* <P>
* <CODE>position</CODE> will hold the height at which the
* section will be written to.
*
* @param writer the <CODE>PdfWriter</CODE> 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.
* <P>
* <CODE>position</CODE> will hold the height of the section end.
*
* @param writer the <CODE>PdfWriter</CODE> 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 <CODE>Chunk</CODE> with a generic tag is written.
* <P>
* It is usefull to pinpoint the <CODE>Chunk</CODE> location to generate
* bookmarks, for example.
*
* @param writer the <CODE>PdfWriter</CODE> for this document
* @param document the document
* @param rect the <CODE>Rectangle</CODE> containing the <CODE>Chunk</CODE>
* @param text the text of the tag
*/
void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, string text);
}
}

View File

@@ -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.
// <P>
// 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.
// <P>
// <A HREF="/resources/classes/Acme/IntHashtable.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @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");
}
}
}
}

View File

@@ -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 <code>newstring</code> to the end of <code>oldstring</code>.
*/
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;
}
}
}
}
}

View File

@@ -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 <CODE>Document.add</CODE>.
* @author Steve Appling
*/
public class MultiColumnText : IElement {
/** special constant for automatic calculation of height */
public const float AUTOMATIC = -1f;
/**
* total desiredHeight of columns. If <CODE>AUTOMATIC</CODE>, 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 <CODE>AUTOMATIC</CODE>, 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 <CODE>ColumnDef</CODE> 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 <CODE>AUTOMATIC</CODE>.
* 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 <CODE>AUTOMATIC</CODE>, 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 <CODE>setArabicOptions</CODE>
* 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 <CODE>Phrase</CODE>
* or a <CODE>Chunk</CODE> 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
* <CODE>ElementListener</CODE>.
*
* @param listener an <CODE>ElementListener</CODE>
* @return <CODE>true</CODE> 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 <CODE>spaceCharRatio</CODE> times more than extra character spacing.
* If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> 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 <CODE>Rectangle.LEFT_BORDER</CODE>
* or <CODE>Rectangle.RIGHT_BORDER</CODE>
* @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]);
}
}
}
}

View File

@@ -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 ();
}
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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 <CODE>PdfIndirectReference</CODE>.
*
* @param reader a <CODE>PdfReader</CODE>
* @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 <CODE>PdfIndirectReference</CODE>.
*
* @param reader a <CODE>PdfReader</CODE>
* @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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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 <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> 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 <CODE>null</CODE>.
* @param operation (Windows-specific) the operation to perform: "open" - Open a document,
* "print" - Print a document.
* It can be <CODE>null</CODE>.
* @param defaultDir (Windows-specific) the default directory in standard DOS syntax.
* It can be <CODE>null</CODE>.
*/
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 <CODE>null</CODE>.
* @param operation (Windows-specific) the operation to perform: "open" - Open a document,
* "print" - Print a document.
* It can be <CODE>null</CODE>.
* @param defaultDir (Windows-specific) the default directory in standard DOS syntax.
* It can be <CODE>null</CODE>.
* @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 <CODE>true</CODE>, 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 <CODE>PdfName</CODE>
* or <CODE>String</CODE> (ON, OFF, or Toggle) followed by one or more optional content group dictionaries
* <CODE>PdfLayer</CODE> or a <CODE>PdfIndirectReference</CODE> to a <CODE>PdfLayer</CODE>.<br>
* The array elements are processed from left to right; each name is applied
* to the subsequent groups until the next name is encountered:
* <ul>
* <li>ON sets the state of subsequent groups to ON</li>
* <li>OFF sets the state of subsequent groups to OFF</li>
* <li>Toggle reverses the state of subsequent groups</li>
* </ul>
* @param preserveRB if <CODE>true</CODE>, 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
* <CODE>state</CODE> array are applied. That is, if a group is set to ON (either by ON or Toggle) during
* processing of the <CODE>state</CODE> 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.<br>
* If <CODE>false</CODE>, 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;
}
}
}

View File

@@ -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 <CODE>PdfAnnotation</CODE> 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 <CODE>PdfAnnotation</CODE> 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 <CODE>PdfAnnotation</CODE> 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 <CODE>PdfWriter</CODE>
* @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 <CODE>null</CODE>
* the file will be read from the disk
* @param file the path to the file. It will only be used if
* <CODE>fileStore</CODE> is not <CODE>null</CODE>
* @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
* <CODE>HIGHLIGHT_NONE</CODE>, <CODE>HIGHLIGHT_INVERT</CODE>,
* <CODE>HIGHLIGHT_OUTLINE</CODE> and <CODE>HIGHLIGHT_PUSH</CODE>;
* @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.
* <pre>
* String[] files = new String[] {&quot;input1.pdf&quot;, &quot;input2.pdf&quot;};
* String outputFile = &quot;output.pdf&quot;;
* 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 &lt; files.length; i++) {
* PdfReader currentReader = new PdfReader(files[i]);
* currentReader.ConsolidateNamedDestinations();
* for (int page = 1; page &lt;= 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 &lt; 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 &lt; files.length - 1)
* document.NewPage();
* firstPage += (currentReader.GetNumberOfPages()+3)/4;
* }
* document.Close();
* </pre>
*/
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;
}
}
}
}

View File

@@ -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 <CODE>PdfAppearance</CODE>.
*/
internal PdfAppearance() : base() {
separator = ' ';
}
internal PdfAppearance(PdfIndirectReference iref) {
thisReference = iref;
}
/**
* Creates new PdfTemplate
*
* @param wr the <CODE>PdfWriter</CODE>
*/
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;
}
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfArray</CODE> is the PDF Array object.
* <P>
* 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 (]).<BR>
* 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 <CODE>PdfArray</CODE>-object.
*/
public PdfArray() : base(ARRAY) {
arrayList = new ArrayList();
}
/**
* Constructs an <CODE>PdfArray</CODE>-object, containing 1 <CODE>PdfObject</CODE>.
*
* @param object a <CODE>PdfObject</CODE> 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 <CODE>PdfArray</CODE>-object, containing all the <CODE>PdfObject</CODE>s in a given <CODE>PdfArray</CODE>.
*
* @param array a <CODE>PdfArray</CODE> 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 <CODE>PdfArray</CODE>.
*
* @return an array of <CODE>byte</CODE>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 <CODE>PdfObject</CODE>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 <CODE>PdfObject</CODE> to the <CODE>PdfArray</CODE>.
*
* @param object <CODE>PdfObject</CODE> to add
* @return <CODE>true</CODE>
*/
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 <CODE>PdfObject</CODE> to the <CODE>PdfArray</CODE>.
* <P>
* The newly added object will be the first element in the <CODE>ArrayList</CODE>.
*
* @param object <CODE>PdfObject</CODE> to add
*/
public void AddFirst(PdfObject obj) {
arrayList.Insert(0, obj);
}
/**
* Checks if the <CODE>PdfArray</CODE> allready contains a certain <CODE>PdfObject</CODE>.
*
* @param object <CODE>PdfObject</CODE> to check
* @return <CODE>true</CODE>
*/
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;
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfBoolean</CODE> is the bool object represented by the keywords <VAR>true</VAR> or <VAR>false</VAR>.
* <P>
* 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 <CODE>PdfBoolean</CODE> */
public const string TRUE = "true";
/** A possible value of <CODE>PdfBoolean</CODE> */
public const string FALSE = "false";
// membervariables
/** the bool value of this object */
private bool value;
// constructors
/**
* Constructs a <CODE>PdfBoolean</CODE>-object.
*
* @param value the value of the new <CODE>PdfObject</CODE>
*/
public PdfBoolean(bool value) : base(BOOLEAN) {
if (value) {
this.Content = TRUE;
}
else {
this.Content = FALSE;
}
this.value = value;
}
/**
* Constructs a <CODE>PdfBoolean</CODE>-object.
*
* @param value the value of the new <CODE>PdfObject</CODE>, represented as a <CODE>string</CODE>
*
* @throws BadPdfFormatException thrown if the <VAR>value</VAR> isn't '<CODE>true</CODE>' or '<CODE>false</CODE>'
*/
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 <CODE>PdfBoolean</CODE>-object.
*
* @return the actual value of the object.
*/
public bool BooleanValue {
get {
return value;
}
}
public override string ToString() {
return value ? TRUE : FALSE;
}
}
}

View File

@@ -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 <CODE>PdfBorderArray</CODE> defines the border of a <CODE>PdfAnnotation</CODE>.
*
* @see PdfArray
*/
public class PdfBorderArray : PdfArray {
// constructors
/**
* Constructs a new <CODE>PdfBorderArray</CODE>.
*/
public PdfBorderArray(float hRadius, float vRadius, float width) : this(hRadius, vRadius, width, null) {}
/**
* Constructs a new <CODE>PdfBorderArray</CODE>.
*/
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);
}
}
}

View File

@@ -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 <CODE>PdfBorderDictionary</CODE> 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 <CODE>PdfBorderDictionary</CODE>.
*/
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) {}
}
}

View File

@@ -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 <CODE>PdfCell</CODE> is the PDF translation of a <CODE>Cell</CODE>.
* <P>
* A <CODE>PdfCell</CODE> is an <CODE>ArrayList</CODE> of <CODE>PdfLine</CODE>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 <CODE>PdfTable</CODE> */
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 <CODE>PdfCell</CODE>-object.
*
* @param cell the original <CODE>Cell</CODE>
* @param rownumber the number of the <CODE>Row</CODE> the <CODE>Cell</CODE> was in.
* @param left the left border of the <CODE>PdfCell</CODE>
* @param right the right border of the <CODE>PdfCell</CODE>
* @param top the top border of the <CODE>PdfCell</CODE>
* @param cellspacing the cellspacing of the <CODE>Table</CODE>
* @param cellpadding the cellpadding of the <CODE>Table</CODE>
*/
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.
* <P>
* 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 <CODE>ArrayList</CODE> of <CODE>PdfLine</CODE>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.
* <P>
* 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 <CODE>ArrayList</CODE> of <CODE>Image</CODE>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 <CODE>PdfTable</CODE>.
*
* @return <CODE>void</CODE>
*/
internal void SetHeader() {
header = true;
}
/**
* Indicates that this cell belongs to the header of a <CODE>PdfTable</CODE>.
*/
internal bool Header {
get {
return header;
}
}
/**
* Checks if the cell may be removed.
* <P>
* Headers may allways be removed, even if they are drawn only partially:
* they will be repeated on each following page anyway!
*
* @return <CODE>true</CODE> if all the lines are allready drawn; <CODE>false</CODE> 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 <CODE>Rectangle</CODE>
*/
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;
}
}
}
}

View File

@@ -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 <CODE>PdfChunk</CODE> is the PDF translation of a <CODE>Chunk</CODE>.
* <P>
* A <CODE>PdfChunk</CODE> is a <CODE>PdfString</CODE> in a certain
* <CODE>PdfFont</CODE> and <CODE>Color</CODE>.
*
* @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 <CODE>attributes</CODE>. */
private static Hashtable keysAttributes = new Hashtable();
/** The allowed attributes in variable <CODE>noStroke</CODE>. */
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 <CODE>PdfChunk</CODE>. */
protected PdfFont font;
protected BaseFont baseFont;
protected ISplitCharacter splitCharacter;
/**
* Metric attributes.
* <P>
* This attributes require the mesurement of characters widths when rendering
* such as underline.
*/
protected Hashtable attributes = new Hashtable();
/**
* Non metric attributes.
* <P>
* This attributes do not require the mesurement of characters widths when rendering
* such as Color.
*/
protected Hashtable noStroke = new Hashtable();
/** <CODE>true</CODE> if the chunk split was cause by a newline. */
protected bool newlineSplit;
/** The image in this <CODE>PdfChunk</CODE>, 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 <CODE>PdfChunk</CODE>-object.
*
* @param string the content of the <CODE>PdfChunk</CODE>-object
* @param font the <CODE>PdfFont</CODE>
* @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 <CODE>PdfChunk</CODE>-object.
*
* @param chunk the original <CODE>Chunk</CODE>-object
* @param action the <CODE>PdfAction</CODE> if the <CODE>Chunk</CODE> comes from an <CODE>Anchor</CODE>
*/
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 <FF00> is translated as '\n'.
* It has only meaning with CJK fonts with Identity encoding.
* @param c the CID code
* @return the Unicode equivalent
*/
public int GetUnicodeEquivalent(int c) {
return baseFont.GetUnicodeEquivalent(c);
}
protected int GetWord(string text, int start) {
int len = text.Length;
while (start < len) {
if (!char.IsLetter(text[start]))
break;
++start;
}
return start;
}
/**
* Splits this <CODE>PdfChunk</CODE> if it's too long for the given width.
* <P>
* Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
*
* @param width a given width
* @return the <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE> if it's too long for the given width.
* <P>
* Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
*
* @param width a given width
* @return the <CODE>PdfChunk</CODE> 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 <CODE>Chunk</CODE>.
*
* @return a <CODE>PdfFont</CODE>
*/
internal PdfFont Font {
get {
return font;
}
}
/**
* Returns the color of this <CODE>Chunk</CODE>.
*
* @return a <CODE>Color</CODE>
*/
internal Color Color {
get {
return (Color)noStroke[Chunk.COLOR];
}
}
/**
* Returns the width of this <CODE>PdfChunk</CODE>.
*
* @return a width
*/
internal float Width {
get {
return font.Width(this.value);
}
}
/**
* Checks if the <CODE>PdfChunk</CODE> split was caused by a newline.
* @return <CODE>true</CODE> if the <CODE>PdfChunk</CODE> split was caused by a newline.
*/
public bool IsNewlineSplit() {
return newlineSplit;
}
/**
* Gets the width of the <CODE>PdfChunk</CODE> 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 <CODE>attributes</CODE>
* and <CODE>noStroke</CODE>.
* @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 <CODE>true</CODE> if the attribute exists
*/
internal bool IsAttribute(string name) {
if (attributes.ContainsKey(name))
return true;
return noStroke.ContainsKey(name);
}
/**
* Checks if this <CODE>PdfChunk</CODE> needs some special metrics handling.
* @return <CODE>true</CODE> if this <CODE>PdfChunk</CODE> needs some special metrics handling.
*/
internal bool IsStroked() {
return (attributes.Count > 0);
}
/**
* Checks if this <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE>.
* @return <CODE>true</CODE> if an image is present
*/
internal bool IsImage() {
return image != null;
}
/**
* Gets the image in the <CODE>PdfChunk</CODE>.
* @return the image or <CODE>null</CODE>
*/
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 <CODE>string</CODE>
*/
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 <VAR>' '</VAR> and <VAR>'-'</VAR>-characters on the right of a <CODE>string</CODE>.
* <P>
* @param string the <CODE>string<CODE> that has to be trimmed.
* @return the trimmed <CODE>string</CODE>
*/
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));
}
}
}

View File

@@ -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 <CODE>PdfColor</CODE> defines a Color (it's a <CODE>PdfArray</CODE> containing 3 values).
*
* @see PdfDictionary
*/
internal class PdfColor : PdfArray {
// constructors
/**
* Constructs a new <CODE>PdfColor</CODE>.
*
* @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) {}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <CODE>ArrayList</CODE> to use. It will be cleared before using. If it's
* <CODE>null</CODE> will create a new <CODE>ArrayList</CODE>
* @return the same <CODE>ArrayList</CODE> 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 "&lt;&lt;" 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 <CODE>true</CODE> if a token was read, <CODE>false</CODE> 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;
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfContents</CODE> is a <CODE>PdfStream</CODE> containing the contents (text + graphics) of a <CODE>PdfPage</CODE>.
*/
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 <CODE>PdfContents</CODE>-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);
}
}
}

View File

@@ -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 <CODE>true</CODE>.
* @param rotateContents <CODE>true</CODE> to set auto-rotation, <CODE>false</CODE>
* 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 <CODE>Document</CODE> was closed and that no other
* <CODE>Elements</CODE> will be added.
* <P>
* 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.<p>
* The general usage to stamp something in a page is:
* <p>
* <pre>
* 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);
* </pre>
* @param iPage an imported page
* @return the <CODE>PageStamp</CODE>
*/
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 <CODE>PdfContentByte</CODE>. All
* the members are copied by reference but the buffer stays different.
*
* @return a copy of this <CODE>PdfContentByte</CODE>
*/
public override PdfContentByte Duplicate {
get {
return new PdfCopy.StampContent(writer, pageResources);
}
}
internal override PageResources PageResources {
get {
return pageResources;
}
}
}
}
}

View File

@@ -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
* <CODE>List</CODE> of <CODE>Integer</CODE>. 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 <code>true</code> for 128 bit key length, <code>false</code> 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 <CODE>null</CODE> 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 <code>true</code> 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.
* <p>
* 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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 <CODE>PdfDashPattern</CODE> 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 <CODE>PdfDashPattern</CODE>.
*/
public PdfDashPattern() : base() {}
/**
* Constructs a new <CODE>PdfDashPattern</CODE>.
*/
public PdfDashPattern(float dash) : base(new PdfNumber(dash)) {
this.dash = dash;
}
/**
* Constructs a new <CODE>PdfDashPattern</CODE>.
*/
public PdfDashPattern(float dash, float gap) : base(new PdfNumber(dash)) {
Add(new PdfNumber(gap));
this.dash = dash;
this.gap = gap;
}
/**
* Constructs a new <CODE>PdfDashPattern</CODE>.
*/
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 <CODE>PdfArray</CODE>.
*
* @return an array of <CODE>byte</CODE>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);
}
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfDate</CODE> is the PDF date object.
* <P>
* 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 <CODE>PdfString</CODE> of the form:
* <P><BLOCKQUOTE>
* (D:YYYYMMDDHHmmSSOHH'mm')
* </BLOCKQUOTE><P>
* 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 <CODE>PdfDate</CODE>-object.
*
* @param d the date that has to be turned into a <CODE>PdfDate</CODE>-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 <CODE>PdfDate</CODE>-object, representing the current day and time.
*/
public PdfDate() : this(DateTime.Now) {}
/**
* Adds a number of leading zeros to a given <CODE>string</CODE> in order to get a <CODE>string</CODE>
* of a certain length.
*
* @param i a given number
* @param length the length of the resulting <CODE>string</CODE>
* @return the resulting <CODE>string</CODE>
*/
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();
}
}
}

View File

@@ -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 <CODE>PdfColor</CODE> defines a Color (it's a <CODE>PdfArray</CODE> 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 <CODE>PdfDestination</CODE>.
* <P>
* If <VAR>type</VAR> equals <VAR>FITB</VAR>, the bounding box of a page
* will fit the window of the Reader. Otherwise the type will be set to
* <VAR>FIT</VAR> 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 <CODE>PdfDestination</CODE>.
* <P>
* If <VAR>type</VAR> equals <VAR>FITBH</VAR> / <VAR>FITBV</VAR>,
* 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 <VAR>type</VAR> equals <VAR>FITH</VAR>
* or <VAR>FITV</VAR> 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 <VAR>FITH</VAR>.
*
* @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 <CODE>PdfDestination</CODE>.
* <P>
* 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 <VAR>PdfDestination.XYZ</VAR>
* @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 <CODE>PdfDestination</CODE>.
* <P>
* 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 <CODE>true</CODE> or <CODE>false</CODE>
*/
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;
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfDictionary</CODE> is the Pdf dictionary object.
* <P>
* A dictionary is an associative table containing pairs of objects. The first element
* of each pair is called the <I>key</I> and the second element is called the <I>value</I>.
* Unlike dictionaries in the PostScript language, a key must be a <CODE>PdfName</CODE>.
* A value can be any kind of <CODE>PdfObject</CODE>, 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.<BR>
* A dictionary is represented by two left angle brackets (<<), followed by a sequence of
* key-value pairs, followed by two right angle brackets (>>).<BR>
* This object is described in the 'Portable Document Format Reference Manual version 1.3'
* section 4.7 (page 40-41).
* <P>
*
* @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 <CODE>PdfDictionary</CODE>-object.
*/
public PdfDictionary() : base(DICTIONARY) {
hashMap = new Hashtable();
}
/**
* Constructs a <CODE>PdfDictionary</CODE>-object of a certain type.
*
* @param type a <CODE>PdfName</CODE>
*/
public PdfDictionary(PdfName type) : this() {
dictionaryType = type;
Put(PdfName.TYPE, dictionaryType);
}
// methods overriding some methods in PdfObject
/**
* Returns the PDF representation of this <CODE>PdfDictionary</CODE>.
*
* @return an array of <CODE>byte</CODE>
*/
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 <CODE>PdfObject</CODE> and its key to the <CODE>PdfDictionary</CODE>.
* If the value is <CODE>null</CODE> or <CODE>PdfNull</CODE> the key is deleted.
*
* @param key key of the entry (a <CODE>PdfName</CODE>)
* @param value value of the entry (a <CODE>PdfObject</CODE>)
*/
public void Put(PdfName key, PdfObject value) {
if (value == null || value.IsNull())
hashMap.Remove(key);
else
hashMap[key] = value;
}
/**
* Adds a <CODE>PdfObject</CODE> and its key to the <CODE>PdfDictionary</CODE>.
* If the value is null it does nothing.
*
* @param key key of the entry (a <CODE>PdfName</CODE>)
* @param value value of the entry (a <CODE>PdfObject</CODE>)
*/
public void PutEx(PdfName key, PdfObject value) {
if (value == null)
return;
Put(key, value);
}
/**
* Removes a <CODE>PdfObject</CODE> and its key from the <CODE>PdfDictionary</CODE>.
*
* @param key key of the entry (a <CODE>PdfName</CODE>)
*/
public void Remove(PdfName key) {
hashMap.Remove(key);
}
/**
* Gets a <CODE>PdfObject</CODE> with a certain key from the <CODE>PdfDictionary</CODE>.
*
* @param key key of the entry (a <CODE>PdfName</CODE>)
* @return the previous </CODE>PdfObject</CODE> corresponding with the <VAR>key</VAR>
*/
public PdfObject Get(PdfName key) {
return (PdfObject) hashMap[key];
}
// methods concerning the type of Dictionary
/**
* Checks if a <CODE>Dictionary</CODE> is of the type FONT.
*
* @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
*/
public bool IsFont() {
return FONT.Equals(dictionaryType);
}
/**
* Checks if a <CODE>Dictionary</CODE> is of the type PAGE.
*
* @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
*/
public bool IsPage() {
return PAGE.Equals(dictionaryType);
}
/**
* Checks if a <CODE>Dictionary</CODE> is of the type PAGES.
*
* @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
*/
public bool IsPages() {
return PAGES.Equals(dictionaryType);
}
/**
* Checks if a <CODE>Dictionary</CODE> is of the type CATALOG.
*
* @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
*/
public bool IsCatalog() {
return CATALOG.Equals(dictionaryType);
}
/**
* Checks if a <CODE>Dictionary</CODE> is of the type OUTLINES.
*
* @return <CODE>true</CODE> if it is, <CODE>false</CODE> 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;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <CODE>string</CODE> to a </CODE>byte</CODE> array according
* to the font's encoding.
* @param text the <CODE>string</CODE> to be converted
* @return an array of <CODE>byte</CODE> 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 <CODE>String</CODE> to a </CODE>byte</CODE> array according
* to the font's encoding.
* @return an array of <CODE>byte</CODE> representing the conversion according to the font's encoding
* @param encoding the encoding
* @param char1 the <CODE>char</CODE> 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 <CODE>text</CODE> only has PdfDocEncoding characters.
* @param text the <CODE>String</CODE> to test
* @return <CODE>true</CODE> 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 <CODE>name</CODE> 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 <CODE>CRLF_CID_NEWLINE</CODE>
*/
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 <CODE>byte</CODE> array encoded as <CODE>name</CODE>
* to a CID string. This is needed to reach some CJK characters
* that don't exist in 16 bit Unicode.</p>
* The font to use this result must use the encoding "Identity-H"
* or "Identity-V".</p>
* See ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/.
* @param name the CJK encoding name
* @param seq the <CODE>byte</CODE> 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 <CODE>byte</CODE> array encoded as <CODE>name</CODE>
* to a CID string. This is needed to reach some CJK characters
* that don't exist in 16 bit Unicode.</p>
* The font to use this result must use the encoding "Identity-H"
* or "Identity-V".</p>
* See ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/.
* @param name the CJK encoding name
* @param start the start offset in the data
* @param length the number of bytes to convert
* @param seq the <CODE>byte</CODE> 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;
}
}
}
}

View File

@@ -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; i<publicKeyHandler.GetRecipientsSize(); i++)
{
encodedRecipient = publicKeyHandler.GetEncodedRecipient(i);
sh.TransformBlock(encodedRecipient, 0, encodedRecipient.Length, encodedRecipient, 0);
}
if (!encryptMetadata)
sh.TransformBlock(metadataPad, 0, metadataPad.Length, metadataPad, 0);
sh.TransformFinalBlock(seed, 0, 0);
byte[] mdResult = sh.Hash;
SetupByEncryptionKey(mdResult, keyLength);
} else {
dic.Put(PdfName.FILTER, PdfName.STANDARD);
dic.Put(PdfName.O, new PdfLiteral(PdfContentByte.EscapeString(ownerKey)));
dic.Put(PdfName.U, new PdfLiteral(PdfContentByte.EscapeString(userKey)));
dic.Put(PdfName.P, new PdfNumber(permissions));
dic.Put(PdfName.R, new PdfNumber(revision));
if (revision == STANDARD_ENCRYPTION_40) {
dic.Put(PdfName.V, new PdfNumber(1));
}
else if (revision == STANDARD_ENCRYPTION_128 && encryptMetadata) {
dic.Put(PdfName.V, new PdfNumber(2));
dic.Put(PdfName.LENGTH, new PdfNumber(128));
}
else {
if (!encryptMetadata)
dic.Put(PdfName.ENCRYPTMETADATA, PdfBoolean.PDFFALSE);
dic.Put(PdfName.R, new PdfNumber(AES_128));
dic.Put(PdfName.V, new PdfNumber(4));
dic.Put(PdfName.LENGTH, new PdfNumber(128));
PdfDictionary stdcf = new PdfDictionary();
stdcf.Put(PdfName.LENGTH, new PdfNumber(16));
stdcf.Put(PdfName.AUTHEVENT, PdfName.DOCOPEN);
if (revision == AES_128)
stdcf.Put(PdfName.CFM, PdfName.AESV2);
else
stdcf.Put(PdfName.CFM, PdfName.V2);
PdfDictionary cf = new PdfDictionary();
cf.Put(PdfName.STDCF, stdcf);
dic.Put(PdfName.CF, cf);
dic.Put(PdfName.STRF, PdfName.STDCF);
dic.Put(PdfName.STMF, PdfName.STDCF);
}
}
return dic;
}
public PdfObject FileID {
get {
return CreateInfoId(documentID);
}
}
public OutputStreamEncryption GetEncryptionStream(Stream os) {
return new OutputStreamEncryption(os, key, 0, keySize, revision);
}
public int CalculateStreamSize(int n) {
if (revision == AES_128)
return (n & 0x7ffffff0) + 32;
else
return n;
}
public byte[] EncryptByteArray(byte[] b) {
MemoryStream ba = new MemoryStream();
OutputStreamEncryption os2 = GetEncryptionStream(ba);
os2.Write(b, 0, b.Length);
os2.Finish();
return ba.ToArray();
}
public StandardDecryption GetDecryptor() {
return new StandardDecryption(key, 0, keySize, revision);
}
public byte[] DecryptByteArray(byte[] b) {
MemoryStream ba = new MemoryStream();
StandardDecryption dec = GetDecryptor();
byte[] b2 = dec.Update(b, 0, b.Length);
if (b2 != null)
ba.Write(b2, 0, b2.Length);
b2 = dec.Finish();
if (b2 != null)
ba.Write(b2, 0, b2.Length);
return ba.ToArray();
}
public void AddRecipient(X509Certificate cert, int permission) {
documentID = CreateDocumentId();
publicKeyHandler.AddRecipient(new PdfPublicKeyRecipient(cert, permission));
}
public byte[] ComputeUserPassword(byte[] ownerPassword) {
byte[] userPad = ComputeOwnerKey(ownerKey, PadPassword(ownerPassword));
for (int i = 0; i < userPad.Length; i++) {
bool match = true;
for (int j = 0; j < userPad.Length - i; j++) {
if (userPad[i + j] != pad[j]) {
match = false;
break;
}
}
if (!match) continue;
byte[] userPassword = new byte[i];
System.Array.Copy(userPad, 0, userPassword, 0, i);
return userPassword;
}
return userPad;
}
}
}

View File

@@ -0,0 +1,314 @@
using System;
using System.IO;
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 {
/** This class takes any PDF and returns exactly the same but
* encrypted. All the content, links, outlines, etc, are kept.
* It is also possible to change the info dictionary.
*/
public sealed class PdfEncryptor {
private PdfEncryptor(){
}
/** Entry point to encrypt a PDF document. The encryption parameters are the same as in
* <code>PdfWriter</code>. 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 <code>true</code> for 128 bit key length, <code>false</code> 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
* <code>PdfWriter</code>. 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 <code>true</code> for 128 bit key length, <code>false</code> for 40 bit key length
* @param newInfo an optional <CODE>String</CODE> map to add or change
* the info dictionary. Entries with <CODE>null</CODE>
* 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
* <code>PdfWriter</code>. 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 <code>true</code> for 128 bit key length, <code>false</code> 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
* <code>PdfWriter</code>. 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 <code>true</code> for 128 bit key length, <code>false</code> 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 <CODE>String</CODE> map to add or change
* the info dictionary. Entries with <CODE>null</CODE>
* 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
* <code>PdfWriter</code>. 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 <CODE>String</CODE> map to add or change
* the info dictionary. Entries with <CODE>null</CODE>
* 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
* <code>PdfWriter</code>. 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;
}
}
}

View File

@@ -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) {}
}
}

View File

@@ -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 <CODE>PdfWriter</CODE>
* @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 <CODE>PdfWriter</CODE>
* @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 <CODE>null</CODE>
* it takes precedence over <CODE>filePath</CODE>
* @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 <CODE>PdfWriter</CODE>
* @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 <CODE>null</CODE>
* it takes precedence over <CODE>filePath</CODE>
* @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 <CODE>PdfWriter</CODE>
* @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 <CODE>null</CODE>
* it takes precedence over <CODE>filePath</CODE>
* @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 <CODE>PdfWriter</CODE>
* @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);
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfFont</CODE> is the Pdf Font object.
* <P>
* 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.<BR>
* 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 <CODE>PdfFont</CODE> with another
*
* @param object the other <CODE>PdfFont</CODE>
* @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;
}
}
}
}

View File

@@ -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 <CODE>PdfAnnotation</CODE> 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);
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfFormObject</CODE> 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 <CODE>PdfFormXObject</CODE>-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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
namespace iTextSharp.text.pdf {
/**
* A <CODE>PdfICCBased</CODE> 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();
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfImage</CODE> is a <CODE>PdfStream</CODE> containing an image-<CODE>Dictionary</CODE> and -stream.
*/
public class PdfImage : PdfStream {
internal const int TRANSFERSIZE = 4096;
// membervariables
/** This is the <CODE>PdfName</CODE> of the image. */
protected PdfName name = null;
// constructor
/**
* Constructs a <CODE>PdfImage</CODE>-object.
*
* @param image the <CODE>Image</CODE>-object
* @param name the <CODE>PdfName</CODE> 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 <CODE>PdfName</CODE> 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;
}
}
}

View File

@@ -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 <CODE>PdfImportedPage</CODE>-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;
}
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfIndirectObject</CODE> is the Pdf indirect object.
* <P>
* An <I>indirect object</I> is an object that has been labeled so that it can be referenced by
* other objects. Any type of <CODE>PdfObject</CODE> may be labeled as an indirect object.<BR>
* An indirect object consists of an object identifier, a direct object, and the <B>endobj</B>
* keyword. The <I>object identifier</I> consists of an integer <I>object number</I>, an integer
* <I>generation number</I>, and the <B>obj</B> keyword.<BR>
* 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 <CODE>PdfIndirectObject</CODE>.
*
* @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 <CODE>PdfIndirectObject</CODE>.
*
* @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 <CODE>PdfIndirectReference</CODE> to this <CODE>PdfIndirectObject</CODE>.
*
* @return a <CODE>PdfIndirectReference</CODE>
*/
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);
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfIndirectReference</CODE> contains a reference to a <CODE>PdfIndirectObject</CODE>.
* <P>
* 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 <I>indirect reference</I> is a reference
* to an indirect object, and consists of the indirect object's object number, generation number
* and the <B>R</B> keyword.<BR>
* 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 <CODE>PdfIndirectReference</CODE>.
*
* @param type the type of the <CODE>PdfObject</CODE> 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 <CODE>PdfIndirectReference</CODE>.
*
* @param type the type of the <CODE>PdfObject</CODE> 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();
}
}
}

View File

@@ -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 <CODE>PdfWriter</CODE>
* @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 <CODE>null</CODE> if the layer has no parent
*/
public PdfLayer Parent {
get {
return parent;
}
}
/**
* Gets the children layers.
* @return the children layers or <CODE>null</CODE> if the layer has no children
*/
public ArrayList Children {
get {
return children;
}
}
/**
* Gets the <CODE>PdfIndirectReference</CODE> that represents this layer.
* @return the <CODE>PdfIndirectReference</CODE> 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 <CODE>this</CODE>.
* @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 <B>Artwork</B>, for graphic-design or publishing
* applications, and <B>Technical</B>, 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, <B>es-MX</B> 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, <B>Trapping</B>, <B>PrintersMarks</B> and <B>Watermark</B>
* @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 <CODE>false</CODE>
* 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;
}
}
}
}

View File

@@ -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 <B>ON</B> and invisible when it is <B>OFF</B>. 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 <B>ON</B>.
*/
public static readonly PdfName ALLON = new PdfName("AllOn");
/**
* Visible if any of the entries are <B>ON</B>.
*/
public static readonly PdfName ANYON = new PdfName("AnyOn");
/**
* Visible if any of the entries are <B>OFF</B>.
*/
public static readonly PdfName ANYOFF = new PdfName("AnyOff");
/**
* Visible only if all of the entries are <B>OFF</B>.
*/
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 <CODE>PdfIndirectReference</CODE> that represents this membership layer.
* @return the <CODE>PdfIndirectReference</CODE> 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 <CODE>this</CODE>.
* @return the dictionary representing the layer
*/
public PdfObject PdfObject {
get {
return this;
}
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfLine</CODE> defines an array with <CODE>PdfChunk</CODE>-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;
/** <CODE>true</CODE> 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 <CODE>PdfLine</CODE>-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 <CODE>PdfChunk</CODE> to the <CODE>PdfLine</CODE>.
*
* @param chunk the <CODE>PdfChunk</CODE> to add
* @return <CODE>null</CODE> if the chunk could be added completely; if not
* a <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE>s.
*
* @return an <CODE>Iterator</CODE>
*/
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 <CODE>true</CODE> if the alignment equals <VAR>ALIGN_JUSTIFIED</VAR> 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.
* <P>
* The alignment of the last line of for instance a <CODE>Paragraph</CODE>
* that has to be justified, has to be reset to <VAR>ALIGN_LEFT</VAR>.
*/
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.
* <P>
* This is only necessary for the first line of a <CODE>ListItem</CODE>.
*
* @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 <CODE>PdfChunk</CODE> if the line has a listsymbol; <CODE>null</CODE> 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 <CODE>string</CODE>
*/
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 <CODE>true</CODE> if a newline caused the line split
*/
public bool NewlineSplit {
get {
return newlineSplit && (alignment != Element.ALIGN_JUSTIFIED_ALL);
}
}
/**
* Gets the index of the last <CODE>PdfChunk</CODE> with metric attributes
* @return the last <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE> by index.
* @param idx the index
* @return the <CODE>PdfChunk</CODE> 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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <CODE>String</CODE>
* and the value is a <CODE>PdfObject</CODE>. 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;
}
}
}

View File

@@ -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 {
/**
* <CODE>PdfNull</CODE> is the Null object represented by the keyword <VAR>null</VAR>.
* <P>
* 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 <CODE>PdfNull</CODE>-object. */
public static PdfNull PDFNULL = new PdfNull();
// constructors
/**
* Constructs a <CODE>PdfNull</CODE>-object.
* <P>
* You never need to do this yourself, you can always use the static object <VAR>PDFNULL</VAR>.
*/
public PdfNull() : base(NULL, "null") {}
public override String ToString() {
return "null";
}
}
}

Some files were not shown because too many files have changed in this diff Show More