Initial Commit
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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") {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 '\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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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’s text, in characters.
|
||||
* It is only meaningful for text fields.
|
||||
* @param maxCharacterLength the maximum length of the field’s text, in characters
|
||||
*/
|
||||
public int MaxCharacterLength {
|
||||
set {
|
||||
this.maxCharacterLength = value;
|
||||
}
|
||||
get {
|
||||
return maxCharacterLength;
|
||||
}
|
||||
}
|
||||
|
||||
public PdfWriter Writer {
|
||||
get {
|
||||
return writer;
|
||||
}
|
||||
set {
|
||||
writer = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the field keys from <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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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[] {"input1.pdf", "input2.pdf"};
|
||||
* String outputFile = "output.pdf";
|
||||
* int firstPage=1;
|
||||
* Document document = new Document();
|
||||
* PdfWriter writer = PdfWriter.GetInstance(document, new FileOutputStream(outputFile));
|
||||
* document.SetPageSize(PageSize.A4);
|
||||
* float W = PageSize.A4.GetWidth() / 2;
|
||||
* float H = PageSize.A4.GetHeight() / 2;
|
||||
* document.Open();
|
||||
* PdfContentByte cb = writer.GetDirectContent();
|
||||
* for (int i = 0; i < files.length; i++) {
|
||||
* PdfReader currentReader = new PdfReader(files[i]);
|
||||
* currentReader.ConsolidateNamedDestinations();
|
||||
* for (int page = 1; page <= currentReader.GetNumberOfPages(); page++) {
|
||||
* PdfImportedPage importedPage = writer.GetImportedPage(currentReader, page);
|
||||
* float a = 0.5f;
|
||||
* float e = (page % 2 == 0) ? W : 0;
|
||||
* float f = (page % 4 == 1 || page % 4 == 2) ? H : 0;
|
||||
* ArrayList links = currentReader.GetLinks(page);
|
||||
* cb.AddTemplate(importedPage, a, 0, 0, a, e, f);
|
||||
* for (int j = 0; j < links.Size(); j++) {
|
||||
* PdfAnnotation.PdfImportedLink link = (PdfAnnotation.PdfImportedLink)links.Get(j);
|
||||
* if (link.IsInternal()) {
|
||||
* int dPage = link.GetDestinationPage();
|
||||
* int newDestPage = (dPage-1)/4 + firstPage;
|
||||
* float ee = (dPage % 2 == 0) ? W : 0;
|
||||
* float ff = (dPage % 4 == 1 || dPage % 4 == 2) ? H : 0;
|
||||
* link.SetDestinationPage(newDestPage);
|
||||
* link.TransformDestination(a, 0, 0, a, ee, ff);
|
||||
* }
|
||||
* link.TransformRect(a, 0, 0, a, e, f);
|
||||
* writer.AddAnnotation(link.CreateAnnotation(writer));
|
||||
* }
|
||||
* if (page % 4 == 0)
|
||||
* document.NewPage();
|
||||
* }
|
||||
* if (i < files.length - 1)
|
||||
* document.NewPage();
|
||||
* firstPage += (currentReader.GetNumberOfPages()+3)/4;
|
||||
* }
|
||||
* document.Close();
|
||||
* </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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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 "<<" 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user