author | sandman <sandman> | 2002-05-23 23:51:52 (UTC) |
---|---|---|
committer | sandman <sandman> | 2002-05-23 23:51:52 (UTC) |
commit | 2f3bb7b07f833273d966d41813e68bfe8b9d8d76 (patch) (unidiff) | |
tree | 00beb1bd9e7f4ba79e22334a0d258269b28f4564 | |
parent | 6e82b45dd416ceeba78765717b700e853c96a137 (diff) | |
download | opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.zip opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.gz opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.bz2 |
Port to xpdf 1.01
69 files changed, 2201 insertions, 715 deletions
diff --git a/noncore/unsupported/qpdf/QOutputDev.h b/noncore/unsupported/qpdf/QOutputDev.h index 2958062..f3c5a01 100644 --- a/noncore/unsupported/qpdf/QOutputDev.h +++ b/noncore/unsupported/qpdf/QOutputDev.h | |||
@@ -76,12 +76,19 @@ public: | |||
76 | // (Upside-down means (0,0) is the top left corner of the page.) | 76 | // (Upside-down means (0,0) is the top left corner of the page.) |
77 | virtual GBool upsideDown() { return gTrue; } | 77 | virtual GBool upsideDown() { return gTrue; } |
78 | 78 | ||
79 | // Does this device use drawChar() or drawString()? | 79 | // Does this device use drawChar() or drawString()? |
80 | virtual GBool useDrawChar() { return gTrue; } | 80 | virtual GBool useDrawChar() { return gTrue; } |
81 | 81 | ||
82 | // Does this device use beginType3Char/endType3Char? Otherwise, | ||
83 | // text in Type 3 fonts will be drawn with drawChar/drawString. | ||
84 | virtual GBool interpretType3Chars() { return gFalse; } | ||
85 | |||
86 | // Does this device need non-text content? | ||
87 | virtual GBool needNonText() { return gFalse; } | ||
88 | |||
82 | //----- initialization and control | 89 | //----- initialization and control |
83 | 90 | ||
84 | // Start a page. | 91 | // Start a page. |
85 | virtual void startPage(int pageNum, GfxState *state); | 92 | virtual void startPage(int pageNum, GfxState *state); |
86 | 93 | ||
87 | // End a page. | 94 | // End a page. |
diff --git a/noncore/unsupported/qpdf/README b/noncore/unsupported/qpdf/README index 36ce6bc..65e7aaf 100644 --- a/noncore/unsupported/qpdf/README +++ b/noncore/unsupported/qpdf/README | |||
@@ -1,10 +1,10 @@ | |||
1 | 1 | ||
2 | QPDF - a PDF viewer for the Qtopia environment | 2 | QPDF - a PDF viewer for the Qtopia environment |
3 | 3 | ||
4 | This tool is based on xpdf (currently 1.00). It uses the (mostly unmodified - | 4 | This tool is based on xpdf (currently 1.01). It uses the (mostly unmodified - |
5 | see below) xpdf PDF rendering engine. The Qtopia adaption was done with a new | 5 | see below) xpdf PDF rendering engine. The Qtopia adaption was done with a new |
6 | OutputDev which renders directly to a QPixmap via QPainter calls. | 6 | OutputDev which renders directly to a QPixmap via QPainter calls. |
7 | 7 | ||
8 | Changes in 20020406: | 8 | Changes in 20020406: |
9 | - Font substitution handling improved. | 9 | - Font substitution handling improved. |
10 | - Unknown characters are simply ignored now. | 10 | - Unknown characters are simply ignored now. |
@@ -17,18 +17,25 @@ Changes in 20020407: | |||
17 | 17 | ||
18 | Changes in 20020408: | 18 | Changes in 20020408: |
19 | - Progress indicator added | 19 | - Progress indicator added |
20 | - Problems with type 3 fonts (not fully supported by XPDF) solved | 20 | - Problems with type 3 fonts (not fully supported by XPDF) solved |
21 | - Heavy optimizations in the image rendering code | 21 | - Heavy optimizations in the image rendering code |
22 | 22 | ||
23 | Changed in 20020413: | 23 | Changes in 20020413: |
24 | - Fixed crash in find routine | 24 | - Fixed crash in find routine |
25 | - Stylus selection reworked | 25 | - Stylus selection reworked |
26 | - Cursor-key navigation added | 26 | - Cursor-key navigation added |
27 | - Various crashes related to recursive calling of XPDF fixed | 27 | - Various crashes related to recursive calling of XPDF fixed |
28 | 28 | ||
29 | Changes in 20020417: | ||
30 | - Fixed crash in XPDF regarding 0-length strings. | ||
31 | - Fast sqrt, rint and fabs functions added. | ||
32 | |||
33 | Changes in 20020524: | ||
34 | - Ported to xpdf 1.01 | ||
35 | |||
29 | 36 | ||
30 | Changes to xpdf: | 37 | Changes to xpdf: |
31 | - xpdf calculates nearly everything with doubles. Since ARMs are not equipped | 38 | - xpdf calculates nearly everything with doubles. Since ARMs are not equipped |
32 | with a FPU, all doubles have been replaced with a C++ class "fouble" (fixed | 39 | with a FPU, all doubles have been replaced with a C++ class "fouble" (fixed |
33 | double), which operates on 32bit integers with fixed point arithmetic. | 40 | double), which operates on 32bit integers with fixed point arithmetic. |
34 | This gave a speedup of up to 800% for image rendering. | 41 | This gave a speedup of up to 800% for image rendering. |
@@ -49,41 +56,25 @@ ToDo: | |||
49 | in detail. | 56 | in detail. |
50 | 57 | ||
51 | - Links are currently simply ignored. | 58 | - Links are currently simply ignored. |
52 | 59 | ||
53 | 60 | ||
54 | Install: | 61 | Install: |
55 | - xpdf-1.00 | 62 | - Qpdf is now fully integrated into Opie. For compilation and installation |
56 | Get the tarball for xpdf, version 1.0, untar it and ./configure it. | 63 | instructions see http://opie.handhelds.org. |
57 | (No special flags are needed for ./configure - it simply has to run) | ||
58 | |||
59 | - qpdf | ||
60 | Make sure your QPEDIR / TMAKEPATH variables are correctly ! | ||
61 | |||
62 | cd into the xpdf directory (xpdf-1.00) and untar the qpdf tarball. This | ||
63 | should create a subdirectory qpdf. | ||
64 | cd into this directory and start the script "./setup-qpdf". This | ||
65 | incorporates the above mentioned patches into xpdf. | ||
66 | |||
67 | Now do a make. | ||
68 | |||
69 | Copy the files qpdf, qpdf_icon.png and qpdf.desktop to the appropriate | ||
70 | directories on your iPaq or: | ||
71 | If you want a ipk, just run ./mkipkg | ||
72 | 64 | ||
73 | - compress / uncompress | 65 | - compress / uncompress |
74 | If you run a normal familiar installation, it the standard gzip (I tested | 66 | If you run a normal familiar installation, the standard gzip (I tested |
75 | 1.2.4-33 ipkg) can handle the compression format used in PDF files, when | 67 | 1.2.4-33 ipkg) can handle the compression format used in PDF files, when |
76 | called as uncompress. The BusyBox version of gzip can _not_ handle this | 68 | called as uncompress. The BusyBox version of gzip can _not_ handle this |
77 | old format. | 69 | old format. |
78 | 70 | ||
79 | If you do not have a working uncompress installed on your iPaq, you can | 71 | If you do not have a working uncompress installed on your iPaq, you could |
80 | simply use the one in the contrib directory of the tarball (make uncompress | 72 | simply use the old compress package. |
81 | a link to compress). | 73 | (I could not find an official tarball for compress -- I used the SuSE |
82 | [I could not find an official tarball for compress -- this is the SuSE | 74 | version cross-compiled for ARM for myself, but I will make an ipk soon) |
83 | version cross-compiled for ARM] | 75 | |
84 | |||
85 | 76 | ||
86 | Have fun ;) | 77 | Have fun ;) |
87 | 78 | ||
88 | Robert (griebl@gmx.de) | 79 | Robert (griebl@gmx.de) |
89 | \ No newline at end of file | 80 | \ No newline at end of file |
diff --git a/noncore/unsupported/qpdf/UTF8.h b/noncore/unsupported/qpdf/UTF8.h index aacf663..95adecf 100644 --- a/noncore/unsupported/qpdf/UTF8.h +++ b/noncore/unsupported/qpdf/UTF8.h | |||
@@ -19,6 +19,20 @@ static int mapUTF8 ( Unicode u, char *buf, int bufSize ) | |||
19 | ::memcpy ( buf, utf. data ( ), len ); | 19 | ::memcpy ( buf, utf. data ( ), len ); |
20 | return len; | 20 | return len; |
21 | } | 21 | } |
22 | else | 22 | else |
23 | return 0; | 23 | return 0; |
24 | } | 24 | } |
25 | |||
26 | static int mapUCS2 ( Unicode u, char *buf, int bufSize) | ||
27 | { | ||
28 | if (u <= 0xffff) { | ||
29 | if (bufSize < 2) | ||
30 | return 0; | ||
31 | |||
32 | buf[0] = (char)((u >> 8) & 0xff); | ||
33 | buf[1] = (char)(u & 0xff); | ||
34 | return 2; | ||
35 | } | ||
36 | else | ||
37 | return 0; | ||
38 | } | ||
diff --git a/noncore/unsupported/qpdf/qpdf.cpp b/noncore/unsupported/qpdf/qpdf.cpp index 6c268ec..f338509 100644 --- a/noncore/unsupported/qpdf/qpdf.cpp +++ b/noncore/unsupported/qpdf/qpdf.cpp | |||
@@ -13,18 +13,18 @@ | |||
13 | 13 | ||
14 | #include "QPEOutputDev.h" | 14 | #include "QPEOutputDev.h" |
15 | 15 | ||
16 | #include <qpe/qpeapplication.h> | 16 | #include <qpe/qpeapplication.h> |
17 | #include <qpe/resource.h> | 17 | #include <qpe/resource.h> |
18 | #include <qpe/applnk.h> | 18 | #include <qpe/applnk.h> |
19 | #include <qpe/fileselector.h> | ||
20 | #include <qpe/qcopenvelope_qws.h> | 19 | #include <qpe/qcopenvelope_qws.h> |
21 | 20 | ||
22 | 21 | ||
23 | #include <qclipboard.h> | 22 | #include <qclipboard.h> |
24 | #include <qtoolbar.h> | 23 | #include <qtoolbar.h> |
24 | #include <qtoolbutton.h> | ||
25 | #include <qmenubar.h> | 25 | #include <qmenubar.h> |
26 | #include <qpopupmenu.h> | 26 | #include <qpopupmenu.h> |
27 | #include <qwidgetstack.h> | 27 | #include <qwidgetstack.h> |
28 | #include <qtimer.h> | 28 | #include <qtimer.h> |
29 | #include <qfileinfo.h> | 29 | #include <qfileinfo.h> |
30 | #include <qstring.h> | 30 | #include <qstring.h> |
@@ -34,12 +34,18 @@ | |||
34 | #include <qdialog.h> | 34 | #include <qdialog.h> |
35 | #include <qlabel.h> | 35 | #include <qlabel.h> |
36 | #include <qmessagebox.h> | 36 | #include <qmessagebox.h> |
37 | 37 | ||
38 | #include "qpdf.h" | 38 | #include "qpdf.h" |
39 | 39 | ||
40 | #ifdef QPDF_QPE_ONLY | ||
41 | #include <qpe/fileselector.h> | ||
42 | #else | ||
43 | #include <opie/ofileselector.h> | ||
44 | #endif | ||
45 | |||
40 | 46 | ||
41 | int main ( int argc, char **argv ) | 47 | int main ( int argc, char **argv ) |
42 | { | 48 | { |
43 | QPEApplication app ( argc, argv ); | 49 | QPEApplication app ( argc, argv ); |
44 | 50 | ||
45 | // read config file | 51 | // read config file |
@@ -78,13 +84,18 @@ QPdfDlg::QPdfDlg ( ) : QMainWindow ( ) | |||
78 | m_stack-> setSizePolicy ( QSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding )); | 84 | m_stack-> setSizePolicy ( QSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding )); |
79 | setCentralWidget ( m_stack ); | 85 | setCentralWidget ( m_stack ); |
80 | 86 | ||
81 | m_outdev = new QPEOutputDev ( m_stack ); | 87 | m_outdev = new QPEOutputDev ( m_stack ); |
82 | connect ( m_outdev, SIGNAL( selectionChanged ( const QRect & )), this, SLOT( copyToClipboard ( const QRect & ))); | 88 | connect ( m_outdev, SIGNAL( selectionChanged ( const QRect & )), this, SLOT( copyToClipboard ( const QRect & ))); |
83 | 89 | ||
90 | #ifdef QPDF_QPE_ONLY | ||
84 | m_filesel = new FileSelector ( "application/pdf", m_stack, "fs", false, true ); | 91 | m_filesel = new FileSelector ( "application/pdf", m_stack, "fs", false, true ); |
92 | #else | ||
93 | m_filesel = new OFileSelector ( "application/pdf", m_stack, "fs", false, true ); | ||
94 | #endif | ||
95 | |||
85 | connect ( m_filesel, SIGNAL( closeMe ( )), this, SLOT( closeFileSelector ( ))); | 96 | connect ( m_filesel, SIGNAL( closeMe ( )), this, SLOT( closeFileSelector ( ))); |
86 | connect ( m_filesel, SIGNAL( fileSelected ( const DocLnk & )), this, SLOT( openFile ( const DocLnk & ))); | 97 | connect ( m_filesel, SIGNAL( fileSelected ( const DocLnk & )), this, SLOT( openFile ( const DocLnk & ))); |
87 | 98 | ||
88 | m_tb_menu = new QToolBar ( this ); | 99 | m_tb_menu = new QToolBar ( this ); |
89 | m_tb_menu-> setHorizontalStretchable ( true ); | 100 | m_tb_menu-> setHorizontalStretchable ( true ); |
90 | 101 | ||
diff --git a/noncore/unsupported/qpdf/qpdf.h b/noncore/unsupported/qpdf/qpdf.h index b4ce554..8b3cff9 100644 --- a/noncore/unsupported/qpdf/qpdf.h +++ b/noncore/unsupported/qpdf/qpdf.h | |||
@@ -2,18 +2,20 @@ | |||
2 | #define __QPDF_H__ | 2 | #define __QPDF_H__ |
3 | 3 | ||
4 | #include "aconf.h" | 4 | #include "aconf.h" |
5 | 5 | ||
6 | #include <qmainwindow.h> | 6 | #include <qmainwindow.h> |
7 | 7 | ||
8 | #define QPDF_QPE_ONLY 1 // ofileselector does not work right currently | ||
8 | 9 | ||
9 | class QPEOutputDev; | 10 | class QPEOutputDev; |
10 | class PDFDoc; | 11 | class PDFDoc; |
11 | 12 | ||
12 | class DocLnk; | 13 | class DocLnk; |
13 | class FileSelector; | 14 | class FileSelector; |
15 | class OFileSelector; | ||
14 | class QWidgetStack; | 16 | class QWidgetStack; |
15 | class QLineEdit; | 17 | class QLineEdit; |
16 | 18 | ||
17 | 19 | ||
18 | class QPdfDlg : public QMainWindow { | 20 | class QPdfDlg : public QMainWindow { |
19 | Q_OBJECT | 21 | Q_OBJECT |
@@ -65,13 +67,18 @@ protected: | |||
65 | virtual void resizeEvent ( QResizeEvent *e ); | 67 | virtual void resizeEvent ( QResizeEvent *e ); |
66 | virtual void focusInEvent ( QFocusEvent *e ); | 68 | virtual void focusInEvent ( QFocusEvent *e ); |
67 | 69 | ||
68 | private: | 70 | private: |
69 | QWidgetStack *m_stack; | 71 | QWidgetStack *m_stack; |
70 | QPEOutputDev *m_outdev; | 72 | QPEOutputDev *m_outdev; |
73 | |||
74 | #ifdef QPDF_QPE_ONLY | ||
71 | FileSelector *m_filesel; | 75 | FileSelector *m_filesel; |
76 | #else | ||
77 | OFileSelector *m_filesel; | ||
78 | #endif | ||
72 | 79 | ||
73 | QToolBar *m_tb_menu, *m_tb_tool, *m_tb_find; | 80 | QToolBar *m_tb_menu, *m_tb_tool, *m_tb_find; |
74 | QLineEdit *m_findedit; | 81 | QLineEdit *m_findedit; |
75 | QPopupMenu *m_pm_zoom; | 82 | QPopupMenu *m_pm_zoom; |
76 | 83 | ||
77 | QToolButton *m_to_find, *m_to_full; | 84 | QToolButton *m_to_find, *m_to_full; |
diff --git a/noncore/unsupported/qpdf/qpdf.pro b/noncore/unsupported/qpdf/qpdf.pro index 0c2e38b..fe5abfb 100644 --- a/noncore/unsupported/qpdf/qpdf.pro +++ b/noncore/unsupported/qpdf/qpdf.pro | |||
@@ -10,13 +10,13 @@ SOURCES = xpdf/Array.cc \ | |||
10 | xpdf/Catalog.cc \ | 10 | xpdf/Catalog.cc \ |
11 | xpdf/CharCodeToUnicode.cc \ | 11 | xpdf/CharCodeToUnicode.cc \ |
12 | xpdf/Decrypt.cc \ | 12 | xpdf/Decrypt.cc \ |
13 | xpdf/Dict.cc \ | 13 | xpdf/Dict.cc \ |
14 | xpdf/Error.cc \ | 14 | xpdf/Error.cc \ |
15 | xpdf/FontEncodingTables.cc \ | 15 | xpdf/FontEncodingTables.cc \ |
16 | xpdf/FormWidget.cc \ | 16 | xpdf/Annot.cc \ |
17 | xpdf/Function.cc \ | 17 | xpdf/Function.cc \ |
18 | xpdf/Gfx.cc \ | 18 | xpdf/Gfx.cc \ |
19 | xpdf/GfxFont.cc \ | 19 | xpdf/GfxFont.cc \ |
20 | xpdf/GfxState.cc \ | 20 | xpdf/GfxState.cc \ |
21 | xpdf/GlobalParams.cc \ | 21 | xpdf/GlobalParams.cc \ |
22 | xpdf/Lexer.cc \ | 22 | xpdf/Lexer.cc \ |
@@ -24,12 +24,13 @@ SOURCES = xpdf/Array.cc \ | |||
24 | xpdf/NameToCharCode.cc \ | 24 | xpdf/NameToCharCode.cc \ |
25 | xpdf/Object.cc \ | 25 | xpdf/Object.cc \ |
26 | xpdf/OutputDev.cc \ | 26 | xpdf/OutputDev.cc \ |
27 | xpdf/PDFDoc.cc \ | 27 | xpdf/PDFDoc.cc \ |
28 | xpdf/Page.cc \ | 28 | xpdf/Page.cc \ |
29 | xpdf/Parser.cc \ | 29 | xpdf/Parser.cc \ |
30 | xpdf/PSTokenizer.cc \ | ||
30 | xpdf/Stream.cc \ | 31 | xpdf/Stream.cc \ |
31 | xpdf/TextOutputDev.cc \ | 32 | xpdf/TextOutputDev.cc \ |
32 | xpdf/UnicodeMap.cc \ | 33 | xpdf/UnicodeMap.cc \ |
33 | xpdf/XRef.cc \ | 34 | xpdf/XRef.cc \ |
34 | goo/GHash.cc \ | 35 | goo/GHash.cc \ |
35 | goo/GString.cc \ | 36 | goo/GString.cc \ |
@@ -49,12 +50,12 @@ INCLUDEPATH += . \ | |||
49 | .. \ | 50 | .. \ |
50 | xpdf \ | 51 | xpdf \ |
51 | $(OPIEDIR)/include \ | 52 | $(OPIEDIR)/include \ |
52 | ../goo \ | 53 | ../goo \ |
53 | goo | 54 | goo |
54 | 55 | ||
55 | LIBS += -L $(OPIEDIR)/lib -lqpe | 56 | LIBS += -L $(OPIEDIR)/lib -lqpe -lopie |
56 | 57 | ||
57 | DESTDIR = $(OPIEDIR)/bin | 58 | DESTDIR = $(OPIEDIR)/bin |
58 | TARGET = qpdf | 59 | TARGET = qpdf |
59 | 60 | ||
60 | TRANSLATIONS = ../../i18n/de/qpdf.ts | 61 | TRANSLATIONS = ../../i18n/de/qpdf.ts |
diff --git a/noncore/unsupported/qpdf/xpdf/FormWidget.cc b/noncore/unsupported/qpdf/xpdf/Annot.cc index 05c67a4..49ae50a 100644 --- a/noncore/unsupported/qpdf/xpdf/FormWidget.cc +++ b/noncore/unsupported/qpdf/xpdf/Annot.cc | |||
@@ -1,29 +1,29 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // FormWidget.cc | 3 | // Annot.cc |
4 | // | 4 | // |
5 | // Copyright 2000 Derek B. Noonburg | 5 | // Copyright 2000-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
12 | 12 | ||
13 | #include <aconf.h> | 13 | #include <aconf.h> |
14 | #include "gmem.h" | 14 | #include "gmem.h" |
15 | #include "Object.h" | 15 | #include "Object.h" |
16 | #include "Gfx.h" | 16 | #include "Gfx.h" |
17 | #include "FormWidget.h" | 17 | #include "Annot.h" |
18 | 18 | ||
19 | //------------------------------------------------------------------------ | 19 | //------------------------------------------------------------------------ |
20 | // FormWidget | 20 | // Annot |
21 | //------------------------------------------------------------------------ | 21 | //------------------------------------------------------------------------ |
22 | 22 | ||
23 | FormWidget::FormWidget(XRef *xrefA, Dict *dict) { | 23 | Annot::Annot(XRef *xrefA, Dict *dict) { |
24 | Object apObj, asObj, obj1, obj2; | 24 | Object apObj, asObj, obj1, obj2; |
25 | fouble t; | 25 | fouble t; |
26 | 26 | ||
27 | ok = gFalse; | 27 | ok = gFalse; |
28 | xref = xrefA; | 28 | xref = xrefA; |
29 | 29 | ||
@@ -74,66 +74,65 @@ FormWidget::FormWidget(XRef *xrefA, Dict *dict) { | |||
74 | xMin = yMin = 0; | 74 | xMin = yMin = 0; |
75 | xMax = yMax = 1; | 75 | xMax = yMax = 1; |
76 | } | 76 | } |
77 | obj1.free(); | 77 | obj1.free(); |
78 | } | 78 | } |
79 | 79 | ||
80 | FormWidget::~FormWidget() { | 80 | Annot::~Annot() { |
81 | appearance.free(); | 81 | appearance.free(); |
82 | } | 82 | } |
83 | 83 | ||
84 | void FormWidget::draw(Gfx *gfx) { | 84 | void Annot::draw(Gfx *gfx) { |
85 | Object obj; | 85 | Object obj; |
86 | 86 | ||
87 | if (appearance.fetch(xref, &obj)->isStream()) { | 87 | if (appearance.fetch(xref, &obj)->isStream()) { |
88 | gfx->doWidgetForm(&obj, xMin, yMin, xMax, yMax); | 88 | gfx->doAnnot(&obj, xMin, yMin, xMax, yMax); |
89 | } | 89 | } |
90 | obj.free(); | 90 | obj.free(); |
91 | } | 91 | } |
92 | 92 | ||
93 | //------------------------------------------------------------------------ | 93 | //------------------------------------------------------------------------ |
94 | // FormWidgets | 94 | // Annots |
95 | //------------------------------------------------------------------------ | 95 | //------------------------------------------------------------------------ |
96 | 96 | ||
97 | FormWidgets::FormWidgets(XRef *xref, Object *annots) { | 97 | Annots::Annots(XRef *xref, Object *annotsObj) { |
98 | FormWidget *widget; | 98 | Annot *annot; |
99 | Object obj1, obj2; | 99 | Object obj1, obj2; |
100 | int size; | 100 | int size; |
101 | int i; | 101 | int i; |
102 | 102 | ||
103 | widgets = NULL; | 103 | annots = NULL; |
104 | size = 0; | 104 | size = 0; |
105 | nWidgets = 0; | 105 | nAnnots = 0; |
106 | 106 | ||
107 | if (annots->isArray()) { | 107 | if (annotsObj->isArray()) { |
108 | for (i = 0; i < annots->arrayGetLength(); ++i) { | 108 | for (i = 0; i < annotsObj->arrayGetLength(); ++i) { |
109 | if (annots->arrayGet(i, &obj1)->isDict()) { | 109 | if (annotsObj->arrayGet(i, &obj1)->isDict()) { |
110 | obj1.dictLookup("Subtype", &obj2); | 110 | obj1.dictLookup("Subtype", &obj2); |
111 | if (obj2.isName("Widget") || | 111 | if (obj2.isName("Widget") || |
112 | obj2.isName("Stamp")) { | 112 | obj2.isName("Stamp")) { |
113 | widget = new FormWidget(xref, obj1.getDict()); | 113 | annot = new Annot(xref, obj1.getDict()); |
114 | if (widget->isOk()) { | 114 | if (annot->isOk()) { |
115 | if (nWidgets >= size) { | 115 | if (nAnnots >= size) { |
116 | size += 16; | 116 | size += 16; |
117 | widgets = (FormWidget **)grealloc(widgets, | 117 | annots = (Annot **)grealloc(annots, size * sizeof(Annot *)); |
118 | size * sizeof(FormWidget *)); | ||
119 | } | 118 | } |
120 | widgets[nWidgets++] = widget; | 119 | annots[nAnnots++] = annot; |
121 | } else { | 120 | } else { |
122 | delete widget; | 121 | delete annot; |
123 | } | 122 | } |
124 | } | 123 | } |
125 | obj2.free(); | 124 | obj2.free(); |
126 | } | 125 | } |
127 | obj1.free(); | 126 | obj1.free(); |
128 | } | 127 | } |
129 | } | 128 | } |
130 | } | 129 | } |
131 | 130 | ||
132 | FormWidgets::~FormWidgets() { | 131 | Annots::~Annots() { |
133 | int i; | 132 | int i; |
134 | 133 | ||
135 | for (i = 0; i < nWidgets; ++i) { | 134 | for (i = 0; i < nAnnots; ++i) { |
136 | delete widgets[i]; | 135 | delete annots[i]; |
137 | } | 136 | } |
138 | gfree(widgets); | 137 | gfree(annots); |
139 | } | 138 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/FormWidget.h b/noncore/unsupported/qpdf/xpdf/Annot.h index 7f07889..0cc33dd 100644 --- a/noncore/unsupported/qpdf/xpdf/FormWidget.h +++ b/noncore/unsupported/qpdf/xpdf/Annot.h | |||
@@ -1,67 +1,69 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // FormWidget.h | 3 | // Annot.h |
4 | // | 4 | // |
5 | // Copyright 2000 Derek B. Noonburg | 5 | // Copyright 2000-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef FORMWIDGET_H | 9 | #ifndef ANNOT_H |
10 | #define FORMWIDGET_H | 10 | #define ANNOT_H |
11 | 11 | ||
12 | #ifdef __GNUC__ | 12 | #ifdef __GNUC__ |
13 | #pragma interface | 13 | #pragma interface |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #include <aconf.h> | ||
17 | |||
16 | class XRef; | 18 | class XRef; |
17 | class Gfx; | 19 | class Gfx; |
18 | 20 | ||
19 | //------------------------------------------------------------------------ | 21 | //------------------------------------------------------------------------ |
20 | // FormWidget | 22 | // Annot |
21 | //------------------------------------------------------------------------ | 23 | //------------------------------------------------------------------------ |
22 | 24 | ||
23 | class FormWidget { | 25 | class Annot { |
24 | public: | 26 | public: |
25 | 27 | ||
26 | FormWidget(XRef *xrefA, Dict *dict); | 28 | Annot(XRef *xrefA, Dict *dict); |
27 | ~FormWidget(); | 29 | ~Annot(); |
28 | GBool isOk() { return ok; } | 30 | GBool isOk() { return ok; } |
29 | 31 | ||
30 | void draw(Gfx *gfx); | 32 | void draw(Gfx *gfx); |
31 | 33 | ||
32 | // Get appearance object. | 34 | // Get appearance object. |
33 | Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); } | 35 | Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); } |
34 | 36 | ||
35 | private: | 37 | private: |
36 | 38 | ||
37 | XRef *xref; // the xref table for this PDF file | 39 | XRef *xref; // the xref table for this PDF file |
38 | Object appearance; // a reference to the Form XObject stream | 40 | Object appearance; // a reference to the Form XObject stream |
39 | // for the normal appearance | 41 | // for the normal appearance |
40 | fouble xMin, yMin, // widget rectangle | 42 | fouble xMin, yMin, // annotation rectangle |
41 | xMax, yMax; | 43 | xMax, yMax; |
42 | GBool ok; | 44 | GBool ok; |
43 | }; | 45 | }; |
44 | 46 | ||
45 | //------------------------------------------------------------------------ | 47 | //------------------------------------------------------------------------ |
46 | // FormWidgets | 48 | // Annots |
47 | //------------------------------------------------------------------------ | 49 | //------------------------------------------------------------------------ |
48 | 50 | ||
49 | class FormWidgets { | 51 | class Annots { |
50 | public: | 52 | public: |
51 | 53 | ||
52 | // Extract widgets from array of annotations. | 54 | // Extract non-link annotations from array of annotations. |
53 | FormWidgets(XRef *xref, Object *annots); | 55 | Annots(XRef *xref, Object *annotsObj); |
54 | 56 | ||
55 | ~FormWidgets(); | 57 | ~Annots(); |
56 | 58 | ||
57 | // Iterate through list of widgets. | 59 | // Iterate through list of annotations. |
58 | int getNumWidgets() { return nWidgets; } | 60 | int getNumAnnots() { return nAnnots; } |
59 | FormWidget *getWidget(int i) { return widgets[i]; } | 61 | Annot *getAnnot(int i) { return annots[i]; } |
60 | 62 | ||
61 | private: | 63 | private: |
62 | 64 | ||
63 | FormWidget **widgets; | 65 | Annot **annots; |
64 | int nWidgets; | 66 | int nAnnots; |
65 | }; | 67 | }; |
66 | 68 | ||
67 | #endif | 69 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/Array.cc b/noncore/unsupported/qpdf/xpdf/Array.cc index 5743fe6..fbdde49 100644 --- a/noncore/unsupported/qpdf/xpdf/Array.cc +++ b/noncore/unsupported/qpdf/xpdf/Array.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Array.cc | 3 | // Array.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/Array.h b/noncore/unsupported/qpdf/xpdf/Array.h index 1616fc3..a118f68 100644 --- a/noncore/unsupported/qpdf/xpdf/Array.h +++ b/noncore/unsupported/qpdf/xpdf/Array.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Array.h | 3 | // Array.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef ARRAY_H | 9 | #ifndef ARRAY_H |
10 | #define ARRAY_H | 10 | #define ARRAY_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFont.h b/noncore/unsupported/qpdf/xpdf/BuiltinFont.h index b4fa24c..a795311 100644 --- a/noncore/unsupported/qpdf/xpdf/BuiltinFont.h +++ b/noncore/unsupported/qpdf/xpdf/BuiltinFont.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // BuiltinFont.h | 3 | // BuiltinFont.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef BUILTINFONT_H | 9 | #ifndef BUILTINFONT_H |
10 | #define BUILTINFONT_H | 10 | #define BUILTINFONT_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc index 6833972..845abcd 100644 --- a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc +++ b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // BuiltinFontTables.cc | 3 | // BuiltinFontTables.cc |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #include <aconf.h> | 9 | #include <aconf.h> |
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include "FontEncodingTables.h" | 11 | #include "FontEncodingTables.h" |
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h index 9a17ce9..3a8892e 100644 --- a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h +++ b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // BuiltinFontTables.h | 3 | // BuiltinFontTables.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef BUILTINFONTTABLES_H | 9 | #ifndef BUILTINFONTTABLES_H |
10 | #define BUILTINFONTTABLES_H | 10 | #define BUILTINFONTTABLES_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/CMap.cc b/noncore/unsupported/qpdf/xpdf/CMap.cc index 57809f0..b49cffd 100644 --- a/noncore/unsupported/qpdf/xpdf/CMap.cc +++ b/noncore/unsupported/qpdf/xpdf/CMap.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // CMap.cc | 3 | // CMap.cc |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -17,12 +17,13 @@ | |||
17 | #include <ctype.h> | 17 | #include <ctype.h> |
18 | #include "gmem.h" | 18 | #include "gmem.h" |
19 | #include "gfile.h" | 19 | #include "gfile.h" |
20 | #include "GString.h" | 20 | #include "GString.h" |
21 | #include "Error.h" | 21 | #include "Error.h" |
22 | #include "GlobalParams.h" | 22 | #include "GlobalParams.h" |
23 | #include "PSTokenizer.h" | ||
23 | #include "CMap.h" | 24 | #include "CMap.h" |
24 | 25 | ||
25 | //------------------------------------------------------------------------ | 26 | //------------------------------------------------------------------------ |
26 | 27 | ||
27 | struct CMapVectorEntry { | 28 | struct CMapVectorEntry { |
28 | GBool isVector; | 29 | GBool isVector; |
@@ -31,21 +32,26 @@ struct CMapVectorEntry { | |||
31 | CID cid; | 32 | CID cid; |
32 | }; | 33 | }; |
33 | }; | 34 | }; |
34 | 35 | ||
35 | //------------------------------------------------------------------------ | 36 | //------------------------------------------------------------------------ |
36 | 37 | ||
38 | static int getCharFromFile(void *data) { | ||
39 | return fgetc((FILE *)data); | ||
40 | } | ||
41 | |||
42 | //------------------------------------------------------------------------ | ||
43 | |||
37 | CMap *CMap::parse(CMapCache *cache, GString *collectionA, | 44 | CMap *CMap::parse(CMapCache *cache, GString *collectionA, |
38 | GString *cMapNameA) { | 45 | GString *cMapNameA) { |
39 | FILE *f; | 46 | FILE *f; |
40 | CMap *cmap; | 47 | CMap *cmap; |
41 | char buf[256]; | 48 | PSTokenizer *pst; |
42 | GBool inCodeSpace, inCIDRange; | 49 | char tok1[256], tok2[256], tok3[256]; |
43 | char *tok1, *tok2, *tok3; | 50 | int n1, n2, n3; |
44 | Guint start, end; | 51 | Guint start, end; |
45 | Guint n; | ||
46 | 52 | ||
47 | if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) { | 53 | if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) { |
48 | 54 | ||
49 | // Check for an identity CMap. | 55 | // Check for an identity CMap. |
50 | if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) { | 56 | if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) { |
51 | return new CMap(collectionA->copy(), cMapNameA->copy(), 0); | 57 | return new CMap(collectionA->copy(), cMapNameA->copy(), 0); |
@@ -58,56 +64,70 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA, | |||
58 | cMapNameA->getCString(), collectionA->getCString()); | 64 | cMapNameA->getCString(), collectionA->getCString()); |
59 | return NULL; | 65 | return NULL; |
60 | } | 66 | } |
61 | 67 | ||
62 | cmap = new CMap(collectionA->copy(), cMapNameA->copy()); | 68 | cmap = new CMap(collectionA->copy(), cMapNameA->copy()); |
63 | 69 | ||
64 | inCodeSpace = inCIDRange = gFalse; | 70 | pst = new PSTokenizer(&getCharFromFile, f); |
65 | while (getLine(buf, sizeof(buf), f)) { | 71 | pst->getToken(tok1, sizeof(tok1), &n1); |
66 | tok1 = strtok(buf, " \t\r\n"); | 72 | while (pst->getToken(tok2, sizeof(tok2), &n2)) { |
67 | if (!tok1 || tok1[0] == '%') { | 73 | if (!strcmp(tok2, "usecmap")) { |
68 | continue; | ||
69 | } | ||
70 | tok2 = strtok(NULL, " \t\r\n"); | ||
71 | tok3 = strtok(NULL, " \t\r\n"); | ||
72 | if (inCodeSpace) { | ||
73 | if (!strcmp(tok1, "endcodespacerange")) { | ||
74 | inCodeSpace = gFalse; | ||
75 | } else if (tok2 && tok1[0] == '<' && tok2[0] == '<' && | ||
76 | (n = strlen(tok1)) == strlen(tok2) && | ||
77 | n >= 4 && (n & 1) == 0) { | ||
78 | tok1[n - 1] = tok2[n - 1] = '\0'; | ||
79 | sscanf(tok1 + 1, "%x", &start); | ||
80 | sscanf(tok2 + 1, "%x", &end); | ||
81 | n = (n - 2) / 2; | ||
82 | cmap->addCodeSpace(cmap->vector, start, end, n); | ||
83 | } | ||
84 | } else if (inCIDRange) { | ||
85 | if (!strcmp(tok1, "endcidrange")) { | ||
86 | inCIDRange = gFalse; | ||
87 | } else if (tok2 && tok3 && tok1[0] == '<' && tok2[0] == '<' && | ||
88 | (n = strlen(tok1)) == strlen(tok2) && | ||
89 | n >= 4 && (n & 1) == 0) { | ||
90 | tok1[n - 1] = tok2[n - 1] = '\0'; | ||
91 | sscanf(tok1 + 1, "%x", &start); | ||
92 | sscanf(tok2 + 1, "%x", &end); | ||
93 | n = (n - 2) / 2; | ||
94 | cmap->addCIDs(start, end, n, (CID)atoi(tok3)); | ||
95 | } | ||
96 | } else if (tok2 && !strcmp(tok2, "usecmap")) { | ||
97 | if (tok1[0] == '/') { | 74 | if (tok1[0] == '/') { |
98 | cmap->useCMap(cache, tok1 + 1); | 75 | cmap->useCMap(cache, tok1 + 1); |
99 | } | 76 | } |
77 | pst->getToken(tok1, sizeof(tok1), &n1); | ||
100 | } else if (!strcmp(tok1, "/WMode")) { | 78 | } else if (!strcmp(tok1, "/WMode")) { |
101 | cmap->wMode = atoi(tok2); | 79 | cmap->wMode = atoi(tok2); |
102 | } else if (tok2 && !strcmp(tok2, "begincodespacerange")) { | 80 | pst->getToken(tok1, sizeof(tok1), &n1); |
103 | inCodeSpace = gTrue; | 81 | } else if (!strcmp(tok2, "begincodespacerange")) { |
104 | } else if (tok2 && !strcmp(tok2, "begincidrange")) { | 82 | while (pst->getToken(tok1, sizeof(tok1), &n1)) { |
105 | inCIDRange = gTrue; | 83 | if (!strcmp(tok1, "endcodespacerange")) { |
84 | break; | ||
85 | } | ||
86 | if (!pst->getToken(tok2, sizeof(tok2), &n2) || | ||
87 | !strcmp(tok2, "endcodespacerange")) { | ||
88 | error(-1, "Illegal entry in codespacerange block in CMap"); | ||
89 | break; | ||
90 | } | ||
91 | if (tok1[0] == '<' && tok2[0] == '<' && | ||
92 | n1 == n2 && n1 >= 4 && (n1 & 1) == 0) { | ||
93 | tok1[n1 - 1] = tok2[n1 - 1] = '\0'; | ||
94 | sscanf(tok1 + 1, "%x", &start); | ||
95 | sscanf(tok2 + 1, "%x", &end); | ||
96 | n1 = (n1 - 2) / 2; | ||
97 | cmap->addCodeSpace(cmap->vector, start, end, n1); | ||
98 | } | ||
99 | } | ||
100 | pst->getToken(tok1, sizeof(tok1), &n1); | ||
101 | } else if (!strcmp(tok2, "begincidrange")) { | ||
102 | while (pst->getToken(tok1, sizeof(tok1), &n1)) { | ||
103 | if (!strcmp(tok1, "endcidrange")) { | ||
104 | break; | ||
105 | } | ||
106 | if (!pst->getToken(tok2, sizeof(tok2), &n2) || | ||
107 | !strcmp(tok2, "endcidrange") || | ||
108 | !pst->getToken(tok3, sizeof(tok3), &n3) || | ||
109 | !strcmp(tok3, "endcidrange")) { | ||
110 | error(-1, "Illegal entry in cidrange block in CMap"); | ||
111 | break; | ||
112 | } | ||
113 | if (tok1[0] == '<' && tok2[0] == '<' && | ||
114 | n1 == n2 && n1 >= 4 && (n1 & 1) == 0) { | ||
115 | tok1[n1 - 1] = tok2[n1 - 1] = '\0'; | ||
116 | sscanf(tok1 + 1, "%x", &start); | ||
117 | sscanf(tok2 + 1, "%x", &end); | ||
118 | n1 = (n1 - 2) / 2; | ||
119 | cmap->addCIDs(start, end, n1, (CID)atoi(tok3)); | ||
120 | } | ||
121 | } | ||
122 | pst->getToken(tok1, sizeof(tok1), &n1); | ||
123 | } else { | ||
124 | strcpy(tok1, tok2); | ||
106 | } | 125 | } |
107 | } | 126 | } |
127 | delete pst; | ||
108 | 128 | ||
109 | fclose(f); | 129 | fclose(f); |
110 | 130 | ||
111 | return cmap; | 131 | return cmap; |
112 | } | 132 | } |
113 | 133 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/CMap.h b/noncore/unsupported/qpdf/xpdf/CMap.h index 8b29ef7..fe49acf 100644 --- a/noncore/unsupported/qpdf/xpdf/CMap.h +++ b/noncore/unsupported/qpdf/xpdf/CMap.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // CMap.h | 3 | // CMap.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef CMAP_H | 9 | #ifndef CMAP_H |
10 | #define CMAP_H | 10 | #define CMAP_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Catalog.cc b/noncore/unsupported/qpdf/xpdf/Catalog.cc index 6a0c2d5..1212e2e 100644 --- a/noncore/unsupported/qpdf/xpdf/Catalog.cc +++ b/noncore/unsupported/qpdf/xpdf/Catalog.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Catalog.cc | 3 | // Catalog.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -143,13 +143,13 @@ GString *Catalog::readMetadata() { | |||
143 | 143 | ||
144 | if (!metadata.isStream()) { | 144 | if (!metadata.isStream()) { |
145 | return NULL; | 145 | return NULL; |
146 | } | 146 | } |
147 | dict = metadata.streamGetDict(); | 147 | dict = metadata.streamGetDict(); |
148 | if (!dict->lookup("Subtype", &obj)->isName("XML")) { | 148 | if (!dict->lookup("Subtype", &obj)->isName("XML")) { |
149 | error(-1, "Unknown Metadata type: '%s'\n", | 149 | error(-1, "Unknown Metadata type: '%s'", |
150 | obj.isName() ? obj.getName() : "???"); | 150 | obj.isName() ? obj.getName() : "???"); |
151 | } | 151 | } |
152 | obj.free(); | 152 | obj.free(); |
153 | s = new GString(); | 153 | s = new GString(); |
154 | metadata.streamReset(); | 154 | metadata.streamReset(); |
155 | while ((c = metadata.streamGetChar()) != EOF) { | 155 | while ((c = metadata.streamGetChar()) != EOF) { |
@@ -262,16 +262,16 @@ LinkDest *Catalog::findDest(GString *name) { | |||
262 | if (!found) | 262 | if (!found) |
263 | return NULL; | 263 | return NULL; |
264 | 264 | ||
265 | // construct LinkDest | 265 | // construct LinkDest |
266 | dest = NULL; | 266 | dest = NULL; |
267 | if (obj1.isArray()) { | 267 | if (obj1.isArray()) { |
268 | dest = new LinkDest(obj1.getArray(), gTrue); | 268 | dest = new LinkDest(obj1.getArray()); |
269 | } else if (obj1.isDict()) { | 269 | } else if (obj1.isDict()) { |
270 | if (obj1.dictLookup("D", &obj2)->isArray()) | 270 | if (obj1.dictLookup("D", &obj2)->isArray()) |
271 | dest = new LinkDest(obj2.getArray(), gTrue); | 271 | dest = new LinkDest(obj2.getArray()); |
272 | else | 272 | else |
273 | error(-1, "Bad named destination value"); | 273 | error(-1, "Bad named destination value"); |
274 | obj2.free(); | 274 | obj2.free(); |
275 | } else { | 275 | } else { |
276 | error(-1, "Bad named destination value"); | 276 | error(-1, "Bad named destination value"); |
277 | } | 277 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/Catalog.h b/noncore/unsupported/qpdf/xpdf/Catalog.h index 197f5b8..afad803 100644 --- a/noncore/unsupported/qpdf/xpdf/Catalog.h +++ b/noncore/unsupported/qpdf/xpdf/Catalog.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Catalog.h | 3 | // Catalog.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef CATALOG_H | 9 | #ifndef CATALOG_H |
10 | #define CATALOG_H | 10 | #define CATALOG_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc index 6793398..912981e 100644 --- a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc +++ b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // CharCodeToUnicode.cc | 3 | // CharCodeToUnicode.cc |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -15,12 +15,13 @@ | |||
15 | #include <string.h> | 15 | #include <string.h> |
16 | #include "gmem.h" | 16 | #include "gmem.h" |
17 | #include "gfile.h" | 17 | #include "gfile.h" |
18 | #include "GString.h" | 18 | #include "GString.h" |
19 | #include "Error.h" | 19 | #include "Error.h" |
20 | #include "GlobalParams.h" | 20 | #include "GlobalParams.h" |
21 | #include "PSTokenizer.h" | ||
21 | #include "CharCodeToUnicode.h" | 22 | #include "CharCodeToUnicode.h" |
22 | 23 | ||
23 | //------------------------------------------------------------------------ | 24 | //------------------------------------------------------------------------ |
24 | 25 | ||
25 | #define maxUnicodeString 8 | 26 | #define maxUnicodeString 8 |
26 | 27 | ||
@@ -29,12 +30,32 @@ struct CharCodeToUnicodeString { | |||
29 | Unicode u[maxUnicodeString]; | 30 | Unicode u[maxUnicodeString]; |
30 | int len; | 31 | int len; |
31 | }; | 32 | }; |
32 | 33 | ||
33 | //------------------------------------------------------------------------ | 34 | //------------------------------------------------------------------------ |
34 | 35 | ||
36 | static int getCharFromString(void *data) { | ||
37 | char *p; | ||
38 | int c; | ||
39 | |||
40 | p = *(char **)data; | ||
41 | if (*p) { | ||
42 | c = *p++; | ||
43 | *(char **)data = p; | ||
44 | } else { | ||
45 | c = EOF; | ||
46 | } | ||
47 | return c; | ||
48 | } | ||
49 | |||
50 | static int getCharFromFile(void *data) { | ||
51 | return fgetc((FILE *)data); | ||
52 | } | ||
53 | |||
54 | //------------------------------------------------------------------------ | ||
55 | |||
35 | CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) { | 56 | CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) { |
36 | FILE *f; | 57 | FILE *f; |
37 | Unicode *mapA; | 58 | Unicode *mapA; |
38 | CharCode size, mapLenA; | 59 | CharCode size, mapLenA; |
39 | char buf[64]; | 60 | char buf[64]; |
40 | Unicode u; | 61 | Unicode u; |
@@ -72,98 +93,83 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) { | |||
72 | } | 93 | } |
73 | 94 | ||
74 | CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) { | 95 | CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) { |
75 | return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0); | 96 | return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0); |
76 | } | 97 | } |
77 | 98 | ||
78 | static char *getLineFromString(char *buf, int size, char **s) { | ||
79 | char c; | ||
80 | int i; | ||
81 | |||
82 | i = 0; | ||
83 | while (i < size - 1 && **s) { | ||
84 | buf[i++] = c = *(*s)++; | ||
85 | if (c == '\x0a') { | ||
86 | break; | ||
87 | } | ||
88 | if (c == '\x0d') { | ||
89 | if (**s == '\x0a' && i < size - 1) { | ||
90 | buf[i++] = '\x0a'; | ||
91 | ++*s; | ||
92 | } | ||
93 | break; | ||
94 | } | ||
95 | } | ||
96 | buf[i] = '\0'; | ||
97 | if (i == 0) { | ||
98 | return NULL; | ||
99 | } | ||
100 | return buf; | ||
101 | } | ||
102 | |||
103 | CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) { | 99 | CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) { |
104 | CharCodeToUnicode *ctu; | 100 | CharCodeToUnicode *ctu; |
105 | char *p; | 101 | char *p; |
106 | 102 | ||
107 | ctu = new CharCodeToUnicode(NULL); | 103 | ctu = new CharCodeToUnicode(NULL); |
108 | p = buf->getCString(); | 104 | p = buf->getCString(); |
109 | ctu->parseCMap1((char *(*)(char *, int, void *))&getLineFromString, | 105 | ctu->parseCMap1(&getCharFromString, &p, nBits); |
110 | &p, nBits); | ||
111 | return ctu; | 106 | return ctu; |
112 | } | 107 | } |
113 | 108 | ||
114 | void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *), | 109 | void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, |
115 | void *data, int nBits) { | 110 | int nBits) { |
116 | char buf[256]; | 111 | PSTokenizer *pst; |
117 | GBool inBFChar, inBFRange; | 112 | char tok1[256], tok2[256], tok3[256]; |
118 | char *tok1, *tok2, *tok3; | ||
119 | int nDigits, n1, n2, n3; | 113 | int nDigits, n1, n2, n3; |
120 | CharCode oldLen, i; | 114 | CharCode oldLen, i; |
121 | CharCode code1, code2; | 115 | CharCode code1, code2; |
122 | Unicode u; | 116 | Unicode u; |
123 | char uHex[5]; | 117 | char uHex[5]; |
124 | int j; | 118 | int j; |
125 | GString *name; | 119 | GString *name; |
126 | FILE *f; | 120 | FILE *f; |
127 | 121 | ||
128 | nDigits = nBits / 4; | 122 | nDigits = nBits / 4; |
129 | inBFChar = inBFRange = gFalse; | 123 | pst = new PSTokenizer(getCharFunc, data); |
130 | while ((*getLineFunc)(buf, sizeof(buf), data)) { | 124 | pst->getToken(tok1, sizeof(tok1), &n1); |
131 | tok1 = strtok(buf, " \t\r\n"); | 125 | while (pst->getToken(tok2, sizeof(tok2), &n2)) { |
132 | if (!tok1 || tok1[0] == '%') { | 126 | if (!strcmp(tok2, "usecmap")) { |
133 | continue; | 127 | if (tok1[0] == '/') { |
134 | } | 128 | name = new GString(tok1 + 1); |
135 | tok2 = strtok(NULL, " \t\r\n"); | 129 | if ((f = globalParams->findToUnicodeFile(name))) { |
136 | tok3 = strtok(NULL, " \t\r\n"); | 130 | parseCMap1(&getCharFromFile, f, nBits); |
137 | if (inBFChar) { | 131 | fclose(f); |
138 | if (!strcmp(tok1, "endbfchar")) { | 132 | } else { |
139 | inBFChar = gFalse; | 133 | error(-1, "Couldn't find ToUnicode CMap file for '%s'", |
140 | } else if (tok2) { | 134 | name->getCString()); |
141 | n1 = strlen(tok1); | 135 | } |
142 | n2 = strlen(tok2); | 136 | delete name; |
137 | } | ||
138 | pst->getToken(tok1, sizeof(tok1), &n1); | ||
139 | } else if (!strcmp(tok2, "beginbfchar")) { | ||
140 | while (pst->getToken(tok1, sizeof(tok1), &n1)) { | ||
141 | if (!strcmp(tok1, "endbfchar")) { | ||
142 | break; | ||
143 | } | ||
144 | if (!pst->getToken(tok2, sizeof(tok2), &n2) || | ||
145 | !strcmp(tok2, "endbfchar")) { | ||
146 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); | ||
147 | break; | ||
148 | } | ||
143 | if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && | 149 | if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && |
144 | tok2[0] == '<' && tok2[n2 - 1] == '>')) { | 150 | tok2[0] == '<' && tok2[n2 - 1] == '>')) { |
145 | error(-1, "Illegal line in bfchar block in ToUnicode CMap"); | 151 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); |
146 | continue; | 152 | continue; |
147 | } | 153 | } |
148 | tok1[n1 - 1] = tok2[n2 - 1] = '\0'; | 154 | tok1[n1 - 1] = tok2[n2 - 1] = '\0'; |
149 | if (sscanf(tok1 + 1, "%x", &code1) != 1) { | 155 | if (sscanf(tok1 + 1, "%x", &code1) != 1) { |
150 | error(-1, "Illegal line in bfchar block in ToUnicode CMap"); | 156 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); |
151 | continue; | 157 | continue; |
152 | } | 158 | } |
153 | if (code1 >= mapLen) { | 159 | if (code1 >= mapLen) { |
154 | oldLen = mapLen; | 160 | oldLen = mapLen; |
155 | mapLen = (code1 + 256) & ~255; | 161 | mapLen = (code1 + 256) & ~255; |
156 | map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode)); | 162 | map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode)); |
157 | for (i = oldLen; i < mapLen; ++i) { | 163 | for (i = oldLen; i < mapLen; ++i) { |
158 | map[i] = 0; | 164 | map[i] = 0; |
159 | } | 165 | } |
160 | } | 166 | } |
161 | if (n2 == 6) { | 167 | if (n2 == 6) { |
162 | if (sscanf(tok2 + 1, "%x", &u) != 1) { | 168 | if (sscanf(tok2 + 1, "%x", &u) != 1) { |
163 | error(-1, "Illegal line in bfchar block in ToUnicode CMap"); | 169 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); |
164 | continue; | 170 | continue; |
165 | } | 171 | } |
166 | map[code1] = u; | 172 | map[code1] = u; |
167 | } else { | 173 | } else { |
168 | map[code1] = 0; | 174 | map[code1] = 0; |
169 | if (sMapLen == sMapSize) { | 175 | if (sMapLen == sMapSize) { |
@@ -174,50 +180,54 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *), | |||
174 | sMap[sMapLen].c = code1; | 180 | sMap[sMapLen].c = code1; |
175 | sMap[sMapLen].len = (n2 - 2) / 4; | 181 | sMap[sMapLen].len = (n2 - 2) / 4; |
176 | for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) { | 182 | for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) { |
177 | strncpy(uHex, tok2 + 1 + j*4, 4); | 183 | strncpy(uHex, tok2 + 1 + j*4, 4); |
178 | uHex[4] = '\0'; | 184 | uHex[4] = '\0'; |
179 | if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) { | 185 | if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) { |
180 | error(-1, "Illegal line in bfchar block in ToUnicode CMap"); | 186 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); |
181 | } | 187 | } |
182 | } | 188 | } |
183 | ++sMapLen; | 189 | ++sMapLen; |
184 | } | 190 | } |
185 | } else { | ||
186 | error(-1, "Illegal bfchar block in ToUnicode CMap"); | ||
187 | } | 191 | } |
188 | } else if (inBFRange) { | 192 | pst->getToken(tok1, sizeof(tok1), &n1); |
189 | if (!strcmp(tok1, "endbfrange")) { | 193 | } else if (!strcmp(tok2, "beginbfrange")) { |
190 | inBFRange = gFalse; | 194 | while (pst->getToken(tok1, sizeof(tok1), &n1)) { |
191 | } else if (tok2 && tok3) { | 195 | if (!strcmp(tok1, "endbfrange")) { |
192 | n1 = strlen(tok1); | 196 | break; |
193 | n2 = strlen(tok2); | 197 | } |
194 | n3 = strlen(tok3); | 198 | if (!pst->getToken(tok2, sizeof(tok2), &n2) || |
199 | !strcmp(tok2, "endbfrange") || | ||
200 | !pst->getToken(tok3, sizeof(tok3), &n3) || | ||
201 | !strcmp(tok3, "endbfrange")) { | ||
202 | error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); | ||
203 | break; | ||
204 | } | ||
195 | if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && | 205 | if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && |
196 | n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' && | 206 | n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' && |
197 | tok3[0] == '<' && tok3[n3 - 1] == '>')) { | 207 | tok3[0] == '<' && tok3[n3 - 1] == '>')) { |
198 | error(-1, "Illegal line in bfrange block in ToUnicode CMap"); | 208 | error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); |
199 | continue; | 209 | continue; |
200 | } | 210 | } |
201 | tok1[n1 - 1] = tok2[n2 - 1] = tok3[n3 - 1] = '\0'; | 211 | tok1[n1 - 1] = tok2[n2 - 1] = tok3[n3 - 1] = '\0'; |
202 | if (sscanf(tok1 + 1, "%x", &code1) != 1 || | 212 | if (sscanf(tok1 + 1, "%x", &code1) != 1 || |
203 | sscanf(tok2 + 1, "%x", &code2) != 1) { | 213 | sscanf(tok2 + 1, "%x", &code2) != 1) { |
204 | error(-1, "Illegal line in bfrange block in ToUnicode CMap"); | 214 | error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); |
205 | continue; | 215 | continue; |
206 | } | 216 | } |
207 | if (code2 >= mapLen) { | 217 | if (code2 >= mapLen) { |
208 | oldLen = mapLen; | 218 | oldLen = mapLen; |
209 | mapLen = (code2 + 256) & ~255; | 219 | mapLen = (code2 + 256) & ~255; |
210 | map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode)); | 220 | map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode)); |
211 | for (i = oldLen; i < mapLen; ++i) { | 221 | for (i = oldLen; i < mapLen; ++i) { |
212 | map[i] = 0; | 222 | map[i] = 0; |
213 | } | 223 | } |
214 | } | 224 | } |
215 | if (n3 == 6) { | 225 | if (n3 == 6) { |
216 | if (sscanf(tok3 + 1, "%x", &u) != 1) { | 226 | if (sscanf(tok3 + 1, "%x", &u) != 1) { |
217 | error(-1, "Illegal line in bfrange block in ToUnicode CMap"); | 227 | error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); |
218 | continue; | 228 | continue; |
219 | } | 229 | } |
220 | for (; code1 <= code2; ++code1) { | 230 | for (; code1 <= code2; ++code1) { |
221 | map[code1] = u++; | 231 | map[code1] = u++; |
222 | } | 232 | } |
223 | } else { | 233 | } else { |
@@ -231,40 +241,26 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *), | |||
231 | sMap[sMapLen].c = code1; | 241 | sMap[sMapLen].c = code1; |
232 | sMap[sMapLen].len = (n3 - 2) / 4; | 242 | sMap[sMapLen].len = (n3 - 2) / 4; |
233 | for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) { | 243 | for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) { |
234 | strncpy(uHex, tok3 + 1 + j*4, 4); | 244 | strncpy(uHex, tok3 + 1 + j*4, 4); |
235 | uHex[4] = '\0'; | 245 | uHex[4] = '\0'; |
236 | if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) { | 246 | if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) { |
237 | error(-1, "Illegal line in bfrange block in ToUnicode CMap"); | 247 | error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); |
238 | } | 248 | } |
239 | } | 249 | } |
240 | sMap[sMapLen].u[sMap[sMapLen].len - 1] += i; | 250 | sMap[sMapLen].u[sMap[sMapLen].len - 1] += i; |
241 | ++sMapLen; | 251 | ++sMapLen; |
242 | } | 252 | } |
243 | } | 253 | } |
244 | } else { | ||
245 | error(-1, "Illegal bfrange block in ToUnicode CMap"); | ||
246 | } | 254 | } |
247 | } else if (tok2 && !strcmp(tok2, "usecmap")) { | 255 | pst->getToken(tok1, sizeof(tok1), &n1); |
248 | if (tok1[0] == '/') { | 256 | } else { |
249 | name = new GString(tok1 + 1); | 257 | strcpy(tok1, tok2); |
250 | if ((f = globalParams->findToUnicodeFile(name))) { | ||
251 | parseCMap1((char *(*)(char *, int, void *))&getLine, f, nBits); | ||
252 | fclose(f); | ||
253 | } else { | ||
254 | error(-1, "Couldn't find ToUnicode CMap file for '%s'", | ||
255 | name->getCString()); | ||
256 | } | ||
257 | delete name; | ||
258 | } | ||
259 | } else if (tok2 && !strcmp(tok2, "beginbfchar")) { | ||
260 | inBFChar = gTrue; | ||
261 | } else if (tok2 && !strcmp(tok2, "beginbfrange")) { | ||
262 | inBFRange = gTrue; | ||
263 | } | 258 | } |
264 | } | 259 | } |
260 | delete pst; | ||
265 | } | 261 | } |
266 | 262 | ||
267 | CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) { | 263 | CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) { |
268 | CharCode i; | 264 | CharCode i; |
269 | 265 | ||
270 | collection = collectionA; | 266 | collection = collectionA; |
diff --git a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h index c811d72..06916c8 100644 --- a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h +++ b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h | |||
@@ -1,13 +1,13 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // CharCodeToUnicode.h | 3 | // CharCodeToUnicode.h |
4 | // | 4 | // |
5 | // Mapping from character codes to Unicode. | 5 | // Mapping from character codes to Unicode. |
6 | // | 6 | // |
7 | // Copyright 2001 Derek B. Noonburg | 7 | // Copyright 2001-2002 Glyph & Cog, LLC |
8 | // | 8 | // |
9 | //======================================================================== | 9 | //======================================================================== |
10 | 10 | ||
11 | #ifndef CHARCODETOUNICODE_H | 11 | #ifndef CHARCODETOUNICODE_H |
12 | #define CHARCODETOUNICODE_H | 12 | #define CHARCODETOUNICODE_H |
13 | 13 | ||
@@ -47,14 +47,13 @@ public: | |||
47 | 47 | ||
48 | // Map a CharCode to Unicode. | 48 | // Map a CharCode to Unicode. |
49 | int mapToUnicode(CharCode c, Unicode *u, int size); | 49 | int mapToUnicode(CharCode c, Unicode *u, int size); |
50 | 50 | ||
51 | private: | 51 | private: |
52 | 52 | ||
53 | void parseCMap1(char *(*getLineFunc)(char *, int, void *), | 53 | void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits); |
54 | void *data, int nBits); | ||
55 | CharCodeToUnicode(GString *collectionA); | 54 | CharCodeToUnicode(GString *collectionA); |
56 | CharCodeToUnicode(GString *collectionA, Unicode *mapA, | 55 | CharCodeToUnicode(GString *collectionA, Unicode *mapA, |
57 | CharCode mapLenA, GBool copyMap, | 56 | CharCode mapLenA, GBool copyMap, |
58 | CharCodeToUnicodeString *sMapA, int sMapLenA); | 57 | CharCodeToUnicodeString *sMapA, int sMapLenA); |
59 | 58 | ||
60 | GString *collection; | 59 | GString *collection; |
diff --git a/noncore/unsupported/qpdf/xpdf/CharTypes.h b/noncore/unsupported/qpdf/xpdf/CharTypes.h index 8938be5..bae2f26 100644 --- a/noncore/unsupported/qpdf/xpdf/CharTypes.h +++ b/noncore/unsupported/qpdf/xpdf/CharTypes.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // CharTypes.h | 3 | // CharTypes.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef CHARTYPES_H | 9 | #ifndef CHARTYPES_H |
10 | #define CHARTYPES_H | 10 | #define CHARTYPES_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Decrypt.cc b/noncore/unsupported/qpdf/xpdf/Decrypt.cc index 2def802..8de4091 100644 --- a/noncore/unsupported/qpdf/xpdf/Decrypt.cc +++ b/noncore/unsupported/qpdf/xpdf/Decrypt.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Decrypt.cc | 3 | // Decrypt.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/Decrypt.h b/noncore/unsupported/qpdf/xpdf/Decrypt.h index 1bdb2b7..52afb2f 100644 --- a/noncore/unsupported/qpdf/xpdf/Decrypt.h +++ b/noncore/unsupported/qpdf/xpdf/Decrypt.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Decrypt.h | 3 | // Decrypt.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef DECRYPT_H | 9 | #ifndef DECRYPT_H |
10 | #define DECRYPT_H | 10 | #define DECRYPT_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Dict.cc b/noncore/unsupported/qpdf/xpdf/Dict.cc index 1a49ca5..5eb077e 100644 --- a/noncore/unsupported/qpdf/xpdf/Dict.cc +++ b/noncore/unsupported/qpdf/xpdf/Dict.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Dict.cc | 3 | // Dict.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/Dict.h b/noncore/unsupported/qpdf/xpdf/Dict.h index c4f1ea5..b994514 100644 --- a/noncore/unsupported/qpdf/xpdf/Dict.h +++ b/noncore/unsupported/qpdf/xpdf/Dict.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Dict.h | 3 | // Dict.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef DICT_H | 9 | #ifndef DICT_H |
10 | #define DICT_H | 10 | #define DICT_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h b/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h index 048e25d..8e73486 100644 --- a/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h +++ b/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h | |||
@@ -1,20 +1,20 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // DisplayFontTable.h | 3 | // DisplayFontTable.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | static struct { | 9 | static struct { |
10 | char *name; | 10 | char *name; |
11 | char *xlfd; | 11 | char *xlfd; |
12 | char *encoding; | 12 | char *encoding; |
13 | } displayFontTab[] = { | 13 | } displayFontTab[] = { |
14 | #if _NO_USE_FOR_QPE | 14 | #if 0 |
15 | {"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 15 | {"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
16 | {"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 16 | {"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
17 | {"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 17 | {"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
18 | {"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 18 | {"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
19 | {"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 19 | {"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
20 | {"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 20 | {"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
@@ -24,8 +24,8 @@ static struct { | |||
24 | {"Times-Bold", "-*-times-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 24 | {"Times-Bold", "-*-times-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
25 | {"Times-BoldItalic", "-*-times-bold-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 25 | {"Times-BoldItalic", "-*-times-bold-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
26 | {"Times-Italic", "-*-times-medium-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 26 | {"Times-Italic", "-*-times-medium-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
27 | {"Times-Roman", "-*-times-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 27 | {"Times-Roman", "-*-times-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
28 | {"ZapfDingbats", "-*-zapfdingbats-medium-r-normal-*-%s-*-*-*-*-*-*-*", "ZapfDingbats"}, | 28 | {"ZapfDingbats", "-*-zapfdingbats-medium-r-normal-*-%s-*-*-*-*-*-*-*", "ZapfDingbats"}, |
29 | #endif | 29 | #endif |
30 | {NULL} | 30 | {NULL,0,0} |
31 | }; | 31 | }; |
diff --git a/noncore/unsupported/qpdf/xpdf/Error.cc b/noncore/unsupported/qpdf/xpdf/Error.cc index 8763846..3eae5c9 100644 --- a/noncore/unsupported/qpdf/xpdf/Error.cc +++ b/noncore/unsupported/qpdf/xpdf/Error.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Error.cc | 3 | // Error.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/Error.h b/noncore/unsupported/qpdf/xpdf/Error.h index 151e961..77801c5 100644 --- a/noncore/unsupported/qpdf/xpdf/Error.h +++ b/noncore/unsupported/qpdf/xpdf/Error.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Error.h | 3 | // Error.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef ERROR_H | 9 | #ifndef ERROR_H |
10 | #define ERROR_H | 10 | #define ERROR_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/ErrorCodes.h b/noncore/unsupported/qpdf/xpdf/ErrorCodes.h new file mode 100644 index 0000000..4e0d38a --- a/dev/null +++ b/noncore/unsupported/qpdf/xpdf/ErrorCodes.h | |||
@@ -0,0 +1,24 @@ | |||
1 | //======================================================================== | ||
2 | // | ||
3 | // ErrorCodes.h | ||
4 | // | ||
5 | // Copyright 2002 Glyph & Cog, LLC | ||
6 | // | ||
7 | //======================================================================== | ||
8 | |||
9 | #ifndef ERRORCODES_H | ||
10 | #define ERRORCODES_H | ||
11 | |||
12 | #define errNone 0// no error | ||
13 | |||
14 | #define errOpenFile 1// couldn't open the PDF file | ||
15 | |||
16 | #define errBadCatalog 2// couldn't read the page catalog | ||
17 | |||
18 | #define errDamaged 3// PDF file was damaged and couldn't be | ||
19 | // repaired | ||
20 | |||
21 | #define errEncrypted 4// file was encrypted and password was | ||
22 | // incorrect or not supplied | ||
23 | |||
24 | #endif | ||
diff --git a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc index 12a1a27..bd5f9cf 100644 --- a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc +++ b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // FontEncodingTables.cc | 3 | // FontEncodingTables.cc |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #include <aconf.h> | 9 | #include <aconf.h> |
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include "FontEncodingTables.h" | 11 | #include "FontEncodingTables.h" |
diff --git a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h index 4646a43..deee0a8 100644 --- a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h +++ b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // FontEncodingTables.h | 3 | // FontEncodingTables.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef FONTENCODINGTABLES_H | 9 | #ifndef FONTENCODINGTABLES_H |
10 | #define FONTENCODINGTABLES_H | 10 | #define FONTENCODINGTABLES_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Function.cc b/noncore/unsupported/qpdf/xpdf/Function.cc index 815cc89..ebf3718 100644 --- a/noncore/unsupported/qpdf/xpdf/Function.cc +++ b/noncore/unsupported/qpdf/xpdf/Function.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Function.cc | 3 | // Function.cc |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -412,33 +412,34 @@ void SampledFunction::transform(fouble *in, fouble *out) { | |||
412 | ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { | 412 | ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { |
413 | Object obj1, obj2; | 413 | Object obj1, obj2; |
414 | GBool hasN; | 414 | GBool hasN; |
415 | int i; | 415 | int i; |
416 | 416 | ||
417 | ok = gFalse; | 417 | ok = gFalse; |
418 | hasN = gFalse; | ||
419 | 418 | ||
420 | //----- initialize the generic stuff | 419 | //----- initialize the generic stuff |
421 | if (!init(dict)) { | 420 | if (!init(dict)) { |
422 | goto err1; | 421 | goto err1; |
423 | } | 422 | } |
424 | if (m != 1) { | 423 | if (m != 1) { |
425 | error(-1, "Exponential function with more than one input"); | 424 | error(-1, "Exponential function with more than one input"); |
426 | goto err1; | 425 | goto err1; |
427 | } | 426 | } |
427 | hasN = hasRange; | ||
428 | 428 | ||
429 | //----- default values | 429 | //----- default values |
430 | for (i = 0; i < funcMaxOutputs; ++i) { | 430 | for (i = 0; i < funcMaxOutputs; ++i) { |
431 | c0[i] = 0; | 431 | c0[i] = 0; |
432 | c1[i] = 1; | 432 | c1[i] = 1; |
433 | } | 433 | } |
434 | 434 | ||
435 | //----- C0 | 435 | //----- C0 |
436 | if (dict->lookup("C0", &obj1)->isArray()) { | 436 | if (dict->lookup("C0", &obj1)->isArray()) { |
437 | if (!hasN) { | 437 | if (!hasN) { |
438 | n = obj1.arrayGetLength(); | 438 | n = obj1.arrayGetLength(); |
439 | hasN = gTrue; | ||
439 | } else if (obj1.arrayGetLength() != n) { | 440 | } else if (obj1.arrayGetLength() != n) { |
440 | error(-1, "Function's C0 array is wrong length"); | 441 | error(-1, "Function's C0 array is wrong length"); |
441 | goto err2; | 442 | goto err2; |
442 | } | 443 | } |
443 | for (i = 0; i < n; ++i) { | 444 | for (i = 0; i < n; ++i) { |
444 | obj1.arrayGet(i, &obj2); | 445 | obj1.arrayGet(i, &obj2); |
@@ -453,12 +454,13 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { | |||
453 | obj1.free(); | 454 | obj1.free(); |
454 | 455 | ||
455 | //----- C1 | 456 | //----- C1 |
456 | if (dict->lookup("C1", &obj1)->isArray()) { | 457 | if (dict->lookup("C1", &obj1)->isArray()) { |
457 | if (!hasN) { | 458 | if (!hasN) { |
458 | n = obj1.arrayGetLength(); | 459 | n = obj1.arrayGetLength(); |
460 | hasN = gTrue; | ||
459 | } else if (obj1.arrayGetLength() != n) { | 461 | } else if (obj1.arrayGetLength() != n) { |
460 | error(-1, "Function's C1 array is wrong length"); | 462 | error(-1, "Function's C1 array is wrong length"); |
461 | goto err2; | 463 | goto err2; |
462 | } | 464 | } |
463 | for (i = 0; i < n; ++i) { | 465 | for (i = 0; i < n; ++i) { |
464 | obj1.arrayGet(i, &obj2); | 466 | obj1.arrayGet(i, &obj2); |
@@ -477,12 +479,19 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { | |||
477 | error(-1, "Function has missing or invalid N"); | 479 | error(-1, "Function has missing or invalid N"); |
478 | goto err2; | 480 | goto err2; |
479 | } | 481 | } |
480 | e = obj1.getNum(); | 482 | e = obj1.getNum(); |
481 | obj1.free(); | 483 | obj1.free(); |
482 | 484 | ||
485 | // this isn't supposed to happen, but I've run into (broken) PDF | ||
486 | // files where it does | ||
487 | if (!hasN) { | ||
488 | error(-1, "Exponential function does not define number of output values"); | ||
489 | n = 1; | ||
490 | } | ||
491 | |||
483 | ok = gTrue; | 492 | ok = gTrue; |
484 | return; | 493 | return; |
485 | 494 | ||
486 | err3: | 495 | err3: |
487 | obj2.free(); | 496 | obj2.free(); |
488 | err2: | 497 | err2: |
diff --git a/noncore/unsupported/qpdf/xpdf/Function.h b/noncore/unsupported/qpdf/xpdf/Function.h index a223359..deb4630 100644 --- a/noncore/unsupported/qpdf/xpdf/Function.h +++ b/noncore/unsupported/qpdf/xpdf/Function.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Function.h | 3 | // Function.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef FUNCTION_H | 9 | #ifndef FUNCTION_H |
10 | #define FUNCTION_H | 10 | #define FUNCTION_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Gfx.cc b/noncore/unsupported/qpdf/xpdf/Gfx.cc index c19971c..17d613e 100644 --- a/noncore/unsupported/qpdf/xpdf/Gfx.cc +++ b/noncore/unsupported/qpdf/xpdf/Gfx.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Gfx.cc | 3 | // Gfx.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -27,22 +27,33 @@ | |||
27 | #include "GfxState.h" | 27 | #include "GfxState.h" |
28 | #include "OutputDev.h" | 28 | #include "OutputDev.h" |
29 | #include "Page.h" | 29 | #include "Page.h" |
30 | #include "Error.h" | 30 | #include "Error.h" |
31 | #include "Gfx.h" | 31 | #include "Gfx.h" |
32 | 32 | ||
33 | // the MSVC math.h doesn't define this | ||
34 | #ifndef M_PI | ||
35 | #define M_PI 3.14159265358979323846 | ||
36 | #endif | ||
37 | |||
33 | //------------------------------------------------------------------------ | 38 | //------------------------------------------------------------------------ |
34 | // constants | 39 | // constants |
35 | //------------------------------------------------------------------------ | 40 | //------------------------------------------------------------------------ |
36 | 41 | ||
37 | // Max number of splits along the t axis for an axial shading fill. | 42 | // Max number of splits along the t axis for an axial shading fill. |
38 | #define axialMaxSplits 256 | 43 | #define axialMaxSplits 256 |
39 | 44 | ||
40 | // Max delta allowed in any color component for an axial shading fill. | 45 | // Max delta allowed in any color component for an axial shading fill. |
41 | #define axialColorDelta (1 / 256.0) | 46 | #define axialColorDelta (1 / 256.0) |
42 | 47 | ||
48 | // Max number of splits along the t axis for a radial shading fill. | ||
49 | #define radialMaxSplits 256 | ||
50 | |||
51 | // Max delta allowed in any color component for a radial shading fill. | ||
52 | #define radialColorDelta (1 / 256.0) | ||
53 | |||
43 | //------------------------------------------------------------------------ | 54 | //------------------------------------------------------------------------ |
44 | // Operator table | 55 | // Operator table |
45 | //------------------------------------------------------------------------ | 56 | //------------------------------------------------------------------------ |
46 | 57 | ||
47 | Operator Gfx::opTab[] = { | 58 | Operator Gfx::opTab[] = { |
48 | {"\"", 3, {tchkNum, tchkNum, tchkString}, | 59 | {"\"", 3, {tchkNum, tchkNum, tchkString}, |
@@ -371,12 +382,13 @@ GBool GfxResources::lookupGState(char *name, Object *obj) { | |||
371 | Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, | 382 | Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, |
372 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, | 383 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, |
373 | GBool printCommandsA) { | 384 | GBool printCommandsA) { |
374 | int i; | 385 | int i; |
375 | 386 | ||
376 | xref = xrefA; | 387 | xref = xrefA; |
388 | subPage = gFalse; | ||
377 | printCommands = printCommandsA; | 389 | printCommands = printCommandsA; |
378 | 390 | ||
379 | // start the resource stack | 391 | // start the resource stack |
380 | res = new GfxResources(xref, resDict, NULL); | 392 | res = new GfxResources(xref, resDict, NULL); |
381 | 393 | ||
382 | // initialize | 394 | // initialize |
@@ -402,27 +414,60 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, | |||
402 | state->clip(); | 414 | state->clip(); |
403 | out->clip(state); | 415 | out->clip(state); |
404 | state->clearPath(); | 416 | state->clearPath(); |
405 | } | 417 | } |
406 | } | 418 | } |
407 | 419 | ||
408 | Gfx::~Gfx() { | 420 | Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, |
409 | GfxResources *resPtr; | 421 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox) { |
422 | int i; | ||
410 | 423 | ||
424 | xref = xrefA; | ||
425 | subPage = gTrue; | ||
426 | printCommands = gFalse; | ||
427 | |||
428 | // start the resource stack | ||
429 | res = new GfxResources(xref, resDict, NULL); | ||
430 | |||
431 | // initialize | ||
432 | out = outA; | ||
433 | state = new GfxState(72, box, 0, gFalse); | ||
434 | fontChanged = gFalse; | ||
435 | clip = clipNone; | ||
436 | ignoreUndef = 0; | ||
437 | for (i = 0; i < 6; ++i) { | ||
438 | baseMatrix[i] = state->getCTM()[i]; | ||
439 | } | ||
440 | |||
441 | // set crop box | ||
442 | if (crop) { | ||
443 | state->moveTo(cropBox->x1, cropBox->y1); | ||
444 | state->lineTo(cropBox->x2, cropBox->y1); | ||
445 | state->lineTo(cropBox->x2, cropBox->y2); | ||
446 | state->lineTo(cropBox->x1, cropBox->y2); | ||
447 | state->closePath(); | ||
448 | state->clip(); | ||
449 | out->clip(state); | ||
450 | state->clearPath(); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | Gfx::~Gfx() { | ||
411 | while (state->hasSaves()) { | 455 | while (state->hasSaves()) { |
412 | state = state->restore(); | 456 | state = state->restore(); |
413 | out->restoreState(state); | 457 | out->restoreState(state); |
414 | } | 458 | } |
415 | out->endPage(); | 459 | if (!subPage) { |
460 | out->endPage(); | ||
461 | } | ||
416 | while (res) { | 462 | while (res) { |
417 | resPtr = res->getNext(); | 463 | popResources(); |
418 | delete res; | ||
419 | res = resPtr; | ||
420 | } | 464 | } |
421 | if (state) | 465 | if (state) { |
422 | delete state; | 466 | delete state; |
467 | } | ||
423 | } | 468 | } |
424 | 469 | ||
425 | void Gfx::display(Object *obj, GBool topLevel) { | 470 | void Gfx::display(Object *obj, GBool topLevel) { |
426 | Object obj2; | 471 | Object obj2; |
427 | int i; | 472 | int i; |
428 | 473 | ||
@@ -446,17 +491,17 @@ void Gfx::display(Object *obj, GBool topLevel) { | |||
446 | parser = NULL; | 491 | parser = NULL; |
447 | } | 492 | } |
448 | 493 | ||
449 | void Gfx::go(GBool topLevel) { | 494 | void Gfx::go(GBool topLevel) { |
450 | Object obj; | 495 | Object obj; |
451 | Object args[maxArgs]; | 496 | Object args[maxArgs]; |
452 | int numCmds, numArgs; | 497 | int numArgs; |
453 | int i; | 498 | int i; |
454 | 499 | ||
455 | // scan a sequence of objects | 500 | // scan a sequence of objects |
456 | numCmds = 0; | 501 | updateLevel = 0; |
457 | numArgs = 0; | 502 | numArgs = 0; |
458 | parser->getObj(&obj); | 503 | parser->getObj(&obj); |
459 | while (!obj.isEOF()) { | 504 | while (!obj.isEOF()) { |
460 | 505 | ||
461 | // got a command - execute it | 506 | // got a command - execute it |
462 | if (obj.isCmd()) { | 507 | if (obj.isCmd()) { |
@@ -473,15 +518,15 @@ void Gfx::go(GBool topLevel) { | |||
473 | obj.free(); | 518 | obj.free(); |
474 | for (i = 0; i < numArgs; ++i) | 519 | for (i = 0; i < numArgs; ++i) |
475 | args[i].free(); | 520 | args[i].free(); |
476 | numArgs = 0; | 521 | numArgs = 0; |
477 | 522 | ||
478 | // periodically update display | 523 | // periodically update display |
479 | if (++numCmds == 200) { | 524 | if (++updateLevel >= 20000) { |
480 | out->dump(); | 525 | out->dump(); |
481 | numCmds = 0; | 526 | updateLevel = 0; |
482 | } | 527 | } |
483 | 528 | ||
484 | // got an argument - save it | 529 | // got an argument - save it |
485 | } else if (numArgs < maxArgs) { | 530 | } else if (numArgs < maxArgs) { |
486 | args[numArgs++] = obj; | 531 | args[numArgs++] = obj; |
487 | 532 | ||
@@ -516,13 +561,13 @@ void Gfx::go(GBool topLevel) { | |||
516 | } | 561 | } |
517 | for (i = 0; i < numArgs; ++i) | 562 | for (i = 0; i < numArgs; ++i) |
518 | args[i].free(); | 563 | args[i].free(); |
519 | } | 564 | } |
520 | 565 | ||
521 | // update display | 566 | // update display |
522 | if (topLevel && numCmds > 0) { | 567 | if (topLevel && updateLevel > 0) { |
523 | out->dump(); | 568 | out->dump(); |
524 | } | 569 | } |
525 | } | 570 | } |
526 | 571 | ||
527 | void Gfx::execOp(Object *cmd, Object args[], int numArgs) { | 572 | void Gfx::execOp(Object *cmd, Object args[], int numArgs) { |
528 | Operator *op; | 573 | Operator *op; |
@@ -1135,13 +1180,13 @@ void Gfx::doPatternFill(GBool eoFill) { | |||
1135 | GfxTilingPattern *tPat; | 1180 | GfxTilingPattern *tPat; |
1136 | GfxColorSpace *cs; | 1181 | GfxColorSpace *cs; |
1137 | fouble xMin, yMin, xMax, yMax, x, y, x1, y1; | 1182 | fouble xMin, yMin, xMax, yMax, x, y, x1, y1; |
1138 | fouble cxMin, cyMin, cxMax, cyMax; | 1183 | fouble cxMin, cyMin, cxMax, cyMax; |
1139 | int xi0, yi0, xi1, yi1, xi, yi; | 1184 | int xi0, yi0, xi1, yi1, xi, yi; |
1140 | fouble *ctm, *btm, *ptm; | 1185 | fouble *ctm, *btm, *ptm; |
1141 | fouble m[6], ictm[6], m1[6], im[6], imb[6]; | 1186 | fouble m[6], ictm[6], m1[6], imb[6]; |
1142 | fouble det; | 1187 | fouble det; |
1143 | fouble xstep, ystep; | 1188 | fouble xstep, ystep; |
1144 | int i; | 1189 | int i; |
1145 | 1190 | ||
1146 | // this is a bit of a kludge -- patterns can be really slow, so we | 1191 | // this is a bit of a kludge -- patterns can be really slow, so we |
1147 | // skip them if we're only doing text extraction, since they almost | 1192 | // skip them if we're only doing text extraction, since they almost |
@@ -1186,21 +1231,12 @@ void Gfx::doPatternFill(GBool eoFill) { | |||
1186 | m[1] = m1[0] * ictm[1] + m1[1] * ictm[3]; | 1231 | m[1] = m1[0] * ictm[1] + m1[1] * ictm[3]; |
1187 | m[2] = m1[2] * ictm[0] + m1[3] * ictm[2]; | 1232 | m[2] = m1[2] * ictm[0] + m1[3] * ictm[2]; |
1188 | m[3] = m1[2] * ictm[1] + m1[3] * ictm[3]; | 1233 | m[3] = m1[2] * ictm[1] + m1[3] * ictm[3]; |
1189 | m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4]; | 1234 | m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4]; |
1190 | m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5]; | 1235 | m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5]; |
1191 | 1236 | ||
1192 | // construct a (current space) -> (pattern space) transform matrix | ||
1193 | det = 1 / (m[0] * m[3] - m[1] * m[2]); | ||
1194 | im[0] = m[3] * det; | ||
1195 | im[1] = -m[1] * det; | ||
1196 | im[2] = -m[2] * det; | ||
1197 | im[3] = m[0] * det; | ||
1198 | im[4] = (m[2] * m[5] - m[3] * m[4]) * det; | ||
1199 | im[5] = (m[1] * m[4] - m[0] * m[5]) * det; | ||
1200 | |||
1201 | // construct a (base space) -> (pattern space) transform matrix | 1237 | // construct a (base space) -> (pattern space) transform matrix |
1202 | det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]); | 1238 | det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]); |
1203 | imb[0] = m1[3] * det; | 1239 | imb[0] = m1[3] * det; |
1204 | imb[1] = -m1[1] * det; | 1240 | imb[1] = -m1[1] * det; |
1205 | imb[2] = -m1[2] * det; | 1241 | imb[2] = -m1[2] * det; |
1206 | imb[3] = m1[0] * det; | 1242 | imb[3] = m1[0] * det; |
@@ -1328,86 +1364,40 @@ void Gfx::opShFill(Object args[], int numArgs) { | |||
1328 | 1364 | ||
1329 | // do shading type-specific operations | 1365 | // do shading type-specific operations |
1330 | switch (shading->getType()) { | 1366 | switch (shading->getType()) { |
1331 | case 2: | 1367 | case 2: |
1332 | doAxialShFill((GfxAxialShading *)shading); | 1368 | doAxialShFill((GfxAxialShading *)shading); |
1333 | break; | 1369 | break; |
1370 | case 3: | ||
1371 | doRadialShFill((GfxRadialShading *)shading); | ||
1372 | break; | ||
1334 | } | 1373 | } |
1335 | 1374 | ||
1336 | // restore graphics state | 1375 | // restore graphics state |
1337 | state = state->restore(); | 1376 | state = state->restore(); |
1338 | out->restoreState(state); | 1377 | out->restoreState(state); |
1339 | 1378 | ||
1340 | delete shading; | 1379 | delete shading; |
1341 | } | 1380 | } |
1342 | 1381 | ||
1343 | void Gfx::doAxialShFill(GfxAxialShading *shading) { | 1382 | void Gfx::doAxialShFill(GfxAxialShading *shading) { |
1344 | fouble xMin, yMin, xMax, yMax; | 1383 | fouble xMin, yMin, xMax, yMax; |
1345 | fouble x0, y0, x1, y1; | 1384 | fouble x0, y0, x1, y1; |
1346 | fouble det; | ||
1347 | fouble *ctm; | ||
1348 | fouble ictm[6]; | ||
1349 | fouble dx, dy, mul; | 1385 | fouble dx, dy, mul; |
1350 | fouble tMin, tMax, t, tx, ty; | 1386 | fouble tMin, tMax, t, tx, ty; |
1351 | fouble s[4], sMin, sMax, tmp; | 1387 | fouble s[4], sMin, sMax, tmp; |
1352 | fouble ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1; | 1388 | fouble ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1; |
1353 | fouble t0, t1, tt; | 1389 | fouble t0, t1, tt; |
1354 | fouble ta[axialMaxSplits + 1]; | 1390 | fouble ta[axialMaxSplits + 1]; |
1355 | int next[axialMaxSplits + 1]; | 1391 | int next[axialMaxSplits + 1]; |
1356 | GfxColor color0, color1; | 1392 | GfxColor color0, color1; |
1357 | int nComps; | 1393 | int nComps; |
1358 | int i, j, k, kk; | 1394 | int i, j, k, kk; |
1359 | 1395 | ||
1360 | // get clip region bbox and transform to current user space | 1396 | // get the clip region bbox |
1361 | state->getClipBBox(&x0, &y0, &x1, &y1); | 1397 | state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); |
1362 | ctm = state->getCTM(); | ||
1363 | det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); | ||
1364 | ictm[0] = ctm[3] * det; | ||
1365 | ictm[1] = -ctm[1] * det; | ||
1366 | ictm[2] = -ctm[2] * det; | ||
1367 | ictm[3] = ctm[0] * det; | ||
1368 | ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; | ||
1369 | ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; | ||
1370 | xMin = xMax = x0 * ictm[0] + y0 * ictm[2] + ictm[4]; | ||
1371 | yMin = yMax = x0 * ictm[1] + y0 * ictm[3] + ictm[5]; | ||
1372 | tx = x0 * ictm[0] + y1 * ictm[2] + ictm[4]; | ||
1373 | ty = x0 * ictm[1] + y1 * ictm[3] + ictm[5]; | ||
1374 | if (tx < xMin) { | ||
1375 | xMin = tx; | ||
1376 | } else if (tx > xMax) { | ||
1377 | xMax = tx; | ||
1378 | } | ||
1379 | if (ty < yMin) { | ||
1380 | yMin = ty; | ||
1381 | } else if (ty > yMax) { | ||
1382 | yMax = ty; | ||
1383 | } | ||
1384 | tx = x1 * ictm[0] + y0 * ictm[2] + ictm[4]; | ||
1385 | ty = x1 * ictm[1] + y0 * ictm[3] + ictm[5]; | ||
1386 | if (tx < xMin) { | ||
1387 | xMin = tx; | ||
1388 | } else if (tx > xMax) { | ||
1389 | xMax = tx; | ||
1390 | } | ||
1391 | if (ty < yMin) { | ||
1392 | yMin = ty; | ||
1393 | } else if (ty > yMax) { | ||
1394 | yMax = ty; | ||
1395 | } | ||
1396 | tx = x1 * ictm[0] + y1 * ictm[2] + ictm[4]; | ||
1397 | ty = x1 * ictm[1] + y1 * ictm[3] + ictm[5]; | ||
1398 | if (tx < xMin) { | ||
1399 | xMin = tx; | ||
1400 | } else if (tx > xMax) { | ||
1401 | xMax = tx; | ||
1402 | } | ||
1403 | if (ty < yMin) { | ||
1404 | yMin = ty; | ||
1405 | } else if (ty > yMax) { | ||
1406 | yMax = ty; | ||
1407 | } | ||
1408 | 1398 | ||
1409 | // compute min and max t values, based on the four corners of the | 1399 | // compute min and max t values, based on the four corners of the |
1410 | // clip region bbox | 1400 | // clip region bbox |
1411 | shading->getCoords(&x0, &y0, &x1, &y1); | 1401 | shading->getCoords(&x0, &y0, &x1, &y1); |
1412 | dx = x1 - x0; | 1402 | dx = x1 - x0; |
1413 | dy = y1 - y0; | 1403 | dy = y1 - y0; |
@@ -1616,12 +1606,208 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) { | |||
1616 | vy0 = vy1; | 1606 | vy0 = vy1; |
1617 | color0 = color1; | 1607 | color0 = color1; |
1618 | i = next[i]; | 1608 | i = next[i]; |
1619 | } | 1609 | } |
1620 | } | 1610 | } |
1621 | 1611 | ||
1612 | void Gfx::doRadialShFill(GfxRadialShading *shading) { | ||
1613 | fouble sMin, sMax, xMin, yMin, xMax, yMax; | ||
1614 | fouble x0, y0, r0, x1, y1, r1, t0, t1; | ||
1615 | int nComps; | ||
1616 | GfxColor colorA, colorB; | ||
1617 | fouble xa, ya, xb, yb, ra, rb; | ||
1618 | fouble ta, tb, sa, sb; | ||
1619 | int ia, ib, k, n; | ||
1620 | fouble *ctm; | ||
1621 | fouble angle, t; | ||
1622 | |||
1623 | // get the shading info | ||
1624 | shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1); | ||
1625 | t0 = shading->getDomain0(); | ||
1626 | t1 = shading->getDomain1(); | ||
1627 | nComps = shading->getColorSpace()->getNComps(); | ||
1628 | |||
1629 | // compute the (possibly extended) s range | ||
1630 | sMin = 0; | ||
1631 | sMax = 1; | ||
1632 | if (shading->getExtend0()) { | ||
1633 | if (r0 < r1) { | ||
1634 | // extend the smaller end | ||
1635 | sMin = -r0 / (r1 - r0); | ||
1636 | } else { | ||
1637 | // extend the larger end | ||
1638 | //~ this computes the diagonal of the bounding box -- we should | ||
1639 | //~ really compute the intersection of the moving/expanding | ||
1640 | //~ circles with each of the four corners and look for the max | ||
1641 | //~ radius | ||
1642 | state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); | ||
1643 | sMin = (sqrt((xMax - xMin) * (xMax - xMin) + | ||
1644 | (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0); | ||
1645 | if (sMin > 0) { | ||
1646 | sMin = 0; | ||
1647 | } else if (sMin < -20) { | ||
1648 | // sanity check | ||
1649 | sMin = -20; | ||
1650 | } | ||
1651 | } | ||
1652 | } | ||
1653 | if (shading->getExtend1()) { | ||
1654 | if (r1 < r0) { | ||
1655 | // extend the smaller end | ||
1656 | sMax = -r0 / (r1 - r0); | ||
1657 | } else if (r1 > r0) { | ||
1658 | // extend the larger end | ||
1659 | state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); | ||
1660 | sMax = (sqrt((xMax - xMin) * (xMax - xMin) + | ||
1661 | (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0); | ||
1662 | if (sMax < 1) { | ||
1663 | sMin = 1; | ||
1664 | } else if (sMax > 20) { | ||
1665 | // sanity check | ||
1666 | sMax = 20; | ||
1667 | } | ||
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | // compute the number of steps into which circles must be divided to | ||
1672 | // achieve a curve flatness of 0.1 pixel in device space for the | ||
1673 | // largest circle (note that "device space" is 72 dpi when generating | ||
1674 | // PostScript, hence the relatively small 0.1 pixel accuracy) | ||
1675 | ctm = state->getCTM(); | ||
1676 | t = fabs(ctm[0]); | ||
1677 | if (fabs(ctm[1]) > t) { | ||
1678 | t = fabs(ctm[1]); | ||
1679 | } | ||
1680 | if (fabs(ctm[2]) > t) { | ||
1681 | t = fabs(ctm[2]); | ||
1682 | } | ||
1683 | if (fabs(ctm[3]) > t) { | ||
1684 | t = fabs(ctm[3]); | ||
1685 | } | ||
1686 | if (r0 > r1) { | ||
1687 | t *= r0; | ||
1688 | } else { | ||
1689 | t *= r1; | ||
1690 | } | ||
1691 | if (t < 1) { | ||
1692 | n = 3; | ||
1693 | } else { | ||
1694 | n = (int)(M_PI / acos(1 - 0.1 / t)); | ||
1695 | if (n < 3) { | ||
1696 | n = 3; | ||
1697 | } else if (n > 200) { | ||
1698 | n = 200; | ||
1699 | } | ||
1700 | } | ||
1701 | |||
1702 | // Traverse the t axis and do the shading. | ||
1703 | // | ||
1704 | // This generates and fills a series of rings. Each ring is defined | ||
1705 | // by two circles: | ||
1706 | // sa, ta, xa, ya, ra, colorA | ||
1707 | // sb, tb, xb, yb, rb, colorB | ||
1708 | // | ||
1709 | // The s/t axis is divided into radialMaxSplits parts; these parts | ||
1710 | // are combined as much as possible while respecting the | ||
1711 | // radialColorDelta parameter. | ||
1712 | |||
1713 | // setup for the start circle | ||
1714 | ia = 0; | ||
1715 | sa = sMin; | ||
1716 | ta = t0 + sa * (t1 - t0); | ||
1717 | xa = x0 + sa * (x1 - x0); | ||
1718 | ya = y0 + sa * (y1 - y0); | ||
1719 | ra = r0 + sa * (r1 - r0); | ||
1720 | if (ta < t0) { | ||
1721 | shading->getColor(t0, &colorA); | ||
1722 | } else if (ta > t1) { | ||
1723 | shading->getColor(t1, &colorA); | ||
1724 | } else { | ||
1725 | shading->getColor(ta, &colorA); | ||
1726 | } | ||
1727 | |||
1728 | while (ia < radialMaxSplits) { | ||
1729 | |||
1730 | // go as far along the t axis (toward t1) as we can, such that the | ||
1731 | // color difference is within the tolerance (radialColorDelta) -- | ||
1732 | // this uses bisection (between the current value, t, and t1), | ||
1733 | // limited to radialMaxSplits points along the t axis | ||
1734 | ib = radialMaxSplits; | ||
1735 | sb = sMin + ((fouble)ib / (fouble)radialMaxSplits) * (sMax - sMin); | ||
1736 | tb = t0 + sb * (t1 - t0); | ||
1737 | if (tb < t0) { | ||
1738 | shading->getColor(t0, &colorB); | ||
1739 | } else if (tb > t1) { | ||
1740 | shading->getColor(t1, &colorB); | ||
1741 | } else { | ||
1742 | shading->getColor(tb, &colorB); | ||
1743 | } | ||
1744 | while (ib - ia > 1) { | ||
1745 | for (k = 0; k < nComps; ++k) { | ||
1746 | if (fabs(colorB.c[k] - colorA.c[k]) > radialColorDelta) { | ||
1747 | break; | ||
1748 | } | ||
1749 | } | ||
1750 | if (k == nComps) { | ||
1751 | break; | ||
1752 | } | ||
1753 | ib = (ia + ib) / 2; | ||
1754 | sb = sMin + ((fouble)ib / (fouble)radialMaxSplits) * (sMax - sMin); | ||
1755 | tb = t0 + sb * (t1 - t0); | ||
1756 | if (tb < t0) { | ||
1757 | shading->getColor(t0, &colorB); | ||
1758 | } else if (tb > t1) { | ||
1759 | shading->getColor(t1, &colorB); | ||
1760 | } else { | ||
1761 | shading->getColor(tb, &colorB); | ||
1762 | } | ||
1763 | } | ||
1764 | |||
1765 | // compute center and radius of the circle | ||
1766 | xb = x0 + sb * (x1 - x0); | ||
1767 | yb = y0 + sb * (y1 - y0); | ||
1768 | rb = r0 + sb * (r1 - r0); | ||
1769 | |||
1770 | // use the average of the colors at the two circles | ||
1771 | for (k = 0; k < nComps; ++k) { | ||
1772 | colorA.c[k] = 0.5 * (colorA.c[k] + colorB.c[k]); | ||
1773 | } | ||
1774 | state->setFillColor(&colorA); | ||
1775 | out->updateFillColor(state); | ||
1776 | |||
1777 | // construct path for first circle | ||
1778 | state->moveTo(xa + ra, ya); | ||
1779 | for (k = 1; k < n; ++k) { | ||
1780 | angle = ((fouble)k / (fouble)n) * 2 * M_PI; | ||
1781 | state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle)); | ||
1782 | } | ||
1783 | state->closePath(); | ||
1784 | |||
1785 | // construct and append path for second circle | ||
1786 | state->moveTo(xb + rb, yb); | ||
1787 | for (k = 1; k < n; ++k) { | ||
1788 | angle = ((fouble)k / (fouble)n) * 2 * M_PI; | ||
1789 | state->lineTo(xb + rb * cos(angle), yb + rb * sin(angle)); | ||
1790 | } | ||
1791 | state->closePath(); | ||
1792 | |||
1793 | // fill the ring | ||
1794 | out->eoFill(state); | ||
1795 | state->clearPath(); | ||
1796 | |||
1797 | // step to the next value of t | ||
1798 | ia = ib; | ||
1799 | sa = sb; | ||
1800 | ta = tb; | ||
1801 | xa = xb; | ||
1802 | ya = yb; | ||
1803 | ra = rb; | ||
1804 | colorA = colorB; | ||
1805 | } | ||
1806 | } | ||
1807 | |||
1622 | void Gfx::doEndPath() { | 1808 | void Gfx::doEndPath() { |
1623 | if (state->isPath() && clip != clipNone) { | 1809 | if (state->isPath() && clip != clipNone) { |
1624 | state->clip(); | 1810 | state->clip(); |
1625 | if (clip == clipNormal) { | 1811 | if (clip == clipNormal) { |
1626 | out->clip(state); | 1812 | out->clip(state); |
1627 | } else { | 1813 | } else { |
@@ -1797,60 +1983,68 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) { | |||
1797 | doShowText(args[2].getString()); | 1983 | doShowText(args[2].getString()); |
1798 | } | 1984 | } |
1799 | 1985 | ||
1800 | void Gfx::opShowSpaceText(Object args[], int numArgs) { | 1986 | void Gfx::opShowSpaceText(Object args[], int numArgs) { |
1801 | Array *a; | 1987 | Array *a; |
1802 | Object obj; | 1988 | Object obj; |
1989 | int wMode; | ||
1803 | int i; | 1990 | int i; |
1804 | 1991 | ||
1805 | if (!state->getFont()) { | 1992 | if (!state->getFont()) { |
1806 | error(getPos(), "No font in show/space"); | 1993 | error(getPos(), "No font in show/space"); |
1807 | return; | 1994 | return; |
1808 | } | 1995 | } |
1996 | wMode = state->getFont()->getWMode(); | ||
1809 | a = args[0].getArray(); | 1997 | a = args[0].getArray(); |
1810 | for (i = 0; i < a->getLength(); ++i) { | 1998 | for (i = 0; i < a->getLength(); ++i) { |
1811 | a->get(i, &obj); | 1999 | a->get(i, &obj); |
1812 | if (obj.isNum()) { | 2000 | if (obj.isNum()) { |
1813 | state->textShift(-obj.getNum() * 0.001 * state->getFontSize()); | 2001 | if (wMode) { |
2002 | state->textShift(0, -obj.getNum() * 0.001 * state->getFontSize()); | ||
2003 | } else { | ||
2004 | state->textShift(-obj.getNum() * 0.001 * state->getFontSize(), 0); | ||
2005 | } | ||
1814 | out->updateTextShift(state, obj.getNum()); | 2006 | out->updateTextShift(state, obj.getNum()); |
1815 | } else if (obj.isString()) { | 2007 | } else if (obj.isString()) { |
1816 | doShowText(obj.getString()); | 2008 | doShowText(obj.getString()); |
1817 | } else { | 2009 | } else { |
1818 | error(getPos(), "Element of show/space array must be number or string"); | 2010 | error(getPos(), "Element of show/space array must be number or string"); |
1819 | } | 2011 | } |
1820 | obj.free(); | 2012 | obj.free(); |
1821 | } | 2013 | } |
1822 | } | 2014 | } |
1823 | 2015 | ||
1824 | void Gfx::doShowText(GString *s) { | 2016 | void Gfx::doShowText(GString *s) { |
1825 | GfxFont *font; | 2017 | GfxFont *font; |
2018 | int wMode; | ||
1826 | fouble riseX, riseY; | 2019 | fouble riseX, riseY; |
1827 | CharCode code; | 2020 | CharCode code; |
1828 | Unicode u[8]; | 2021 | Unicode u[8]; |
1829 | fouble dx, dy, dx2, dy2, tdx, tdy; | 2022 | fouble x, y, dx, dy, dx2, dy2, curX, curY, tdx, tdy; |
1830 | fouble originX, originY, tOriginX, tOriginY; | 2023 | fouble originX, originY, tOriginX, tOriginY; |
2024 | fouble oldCTM[6], newCTM[6]; | ||
2025 | fouble *mat; | ||
2026 | Object charProc; | ||
2027 | Dict *resDict; | ||
2028 | Parser *oldParser; | ||
1831 | char *p; | 2029 | char *p; |
1832 | int len, n, uLen, nChars, nSpaces; | 2030 | int len, n, uLen, nChars, nSpaces, i; |
1833 | 2031 | ||
1834 | if (fontChanged) { | 2032 | if (fontChanged) { |
1835 | out->updateFont(state); | 2033 | out->updateFont(state); |
1836 | fontChanged = gFalse; | 2034 | fontChanged = gFalse; |
1837 | } | 2035 | } |
1838 | font = state->getFont(); | 2036 | font = state->getFont(); |
2037 | wMode = font->getWMode(); | ||
1839 | 2038 | ||
1840 | #if 0 //~type3 | 2039 | if (out->useDrawChar()) { |
1841 | fouble x, y; | ||
1842 | fouble oldCTM[6], newCTM[6]; | ||
1843 | fouble *mat; | ||
1844 | Object charProc; | ||
1845 | Parser *oldParser; | ||
1846 | int i; | ||
1847 | |||
1848 | //~ also check out->renderType3() | ||
1849 | if (font->getType() == fontType3) { | ||
1850 | out->beginString(state, s); | 2040 | out->beginString(state, s); |
2041 | } | ||
2042 | |||
2043 | // handle a Type 3 char | ||
2044 | if (font->getType() == fontType3 && out->interpretType3Chars()) { | ||
1851 | mat = state->getCTM(); | 2045 | mat = state->getCTM(); |
1852 | for (i = 0; i < 6; ++i) { | 2046 | for (i = 0; i < 6; ++i) { |
1853 | oldCTM[i] = mat[i]; | 2047 | oldCTM[i] = mat[i]; |
1854 | } | 2048 | } |
1855 | mat = state->getTextMat(); | 2049 | mat = state->getTextMat(); |
1856 | newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2]; | 2050 | newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2]; |
@@ -1864,77 +2058,93 @@ void Gfx::doShowText(GString *s) { | |||
1864 | newCTM[3] = mat[2] * newCTM[1] + mat[3] * newCTM[3]; | 2058 | newCTM[3] = mat[2] * newCTM[1] + mat[3] * newCTM[3]; |
1865 | newCTM[0] *= state->getFontSize(); | 2059 | newCTM[0] *= state->getFontSize(); |
1866 | newCTM[3] *= state->getFontSize(); | 2060 | newCTM[3] *= state->getFontSize(); |
1867 | newCTM[0] *= state->getHorizScaling(); | 2061 | newCTM[0] *= state->getHorizScaling(); |
1868 | newCTM[2] *= state->getHorizScaling(); | 2062 | newCTM[2] *= state->getHorizScaling(); |
1869 | state->textTransformDelta(0, state->getRise(), &riseX, &riseY); | 2063 | state->textTransformDelta(0, state->getRise(), &riseX, &riseY); |
2064 | curX = state->getCurX(); | ||
2065 | curY = state->getCurY(); | ||
1870 | oldParser = parser; | 2066 | oldParser = parser; |
1871 | p = s->getCString(); | 2067 | p = s->getCString(); |
1872 | len = s->getLength(); | 2068 | len = s->getLength(); |
1873 | while (len > 0) { | 2069 | while (len > 0) { |
1874 | n = font->getNextChar(p, len, &code, | 2070 | n = font->getNextChar(p, len, &code, |
1875 | u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, | 2071 | u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, |
1876 | &dx, &dy, &originX, &originY); | 2072 | &dx, &dy, &originX, &originY); |
1877 | state->transform(state->getCurX() + riseX, state->getCurY() + riseY, | ||
1878 | &x, &y); | ||
1879 | out->saveState(state); | ||
1880 | state = state->save(); | ||
1881 | state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y); | ||
1882 | //~ out->updateCTM(???) | ||
1883 | ((Gfx8BitFont *)font)->getCharProc(code, &charProc); | ||
1884 | if (charProc.isStream()) { | ||
1885 | display(&charProc, gFalse); | ||
1886 | } else { | ||
1887 | error(getPos(), "Missing or bad Type3 CharProc entry"); | ||
1888 | } | ||
1889 | state = state->restore(); | ||
1890 | out->restoreState(state); | ||
1891 | charProc.free(); | ||
1892 | dx = dx * state->getFontSize() + state->getCharSpace(); | 2073 | dx = dx * state->getFontSize() + state->getCharSpace(); |
1893 | if (n == 1 && *p == ' ') { | 2074 | if (n == 1 && *p == ' ') { |
1894 | dx += state->getWordSpace(); | 2075 | dx += state->getWordSpace(); |
1895 | } | 2076 | } |
1896 | dx *= state->getHorizScaling(); | 2077 | dx *= state->getHorizScaling(); |
1897 | dy *= state->getFontSize(); | 2078 | dy *= state->getFontSize(); |
1898 | state->textTransformDelta(dx, dy, &tdx, &tdy); | 2079 | state->textTransformDelta(dx, dy, &tdx, &tdy); |
1899 | state->shift(tdx, tdy); | 2080 | state->transform(curX + riseX, curY + riseY, &x, &y); |
2081 | out->saveState(state); | ||
2082 | state = state->save(); | ||
2083 | state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y); | ||
2084 | //~ out->updateCTM(???) | ||
2085 | if (!out->beginType3Char(state, code, u, uLen)) { | ||
2086 | ((Gfx8BitFont *)font)->getCharProc(code, &charProc); | ||
2087 | if ((resDict = ((Gfx8BitFont *)font)->getResources())) { | ||
2088 | pushResources(resDict); | ||
2089 | } | ||
2090 | if (charProc.isStream()) { | ||
2091 | display(&charProc, gFalse); | ||
2092 | } else { | ||
2093 | error(getPos(), "Missing or bad Type3 CharProc entry"); | ||
2094 | } | ||
2095 | out->endType3Char(state); | ||
2096 | if (resDict) { | ||
2097 | popResources(); | ||
2098 | } | ||
2099 | charProc.free(); | ||
2100 | } | ||
2101 | state = state->restore(); | ||
2102 | out->restoreState(state); | ||
2103 | // GfxState::restore() does *not* restore the current position, | ||
2104 | // so we track it here with (curX, curY) | ||
2105 | curX += tdx; | ||
2106 | curY += tdy; | ||
2107 | state->moveTo(curX, curY); | ||
1900 | p += n; | 2108 | p += n; |
1901 | len -= n; | 2109 | len -= n; |
1902 | } | 2110 | } |
1903 | parser = oldParser; | 2111 | parser = oldParser; |
1904 | out->endString(state); | ||
1905 | return; | ||
1906 | } | ||
1907 | #endif | ||
1908 | 2112 | ||
1909 | if (out->useDrawChar()) { | 2113 | } else if (out->useDrawChar()) { |
1910 | state->textTransformDelta(0, state->getRise(), &riseX, &riseY); | 2114 | state->textTransformDelta(0, state->getRise(), &riseX, &riseY); |
1911 | out->beginString(state, s); | ||
1912 | p = s->getCString(); | 2115 | p = s->getCString(); |
1913 | len = s->getLength(); | 2116 | len = s->getLength(); |
1914 | while (len > 0) { | 2117 | while (len > 0) { |
1915 | n = font->getNextChar(p, len, &code, | 2118 | n = font->getNextChar(p, len, &code, |
1916 | u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, | 2119 | u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, |
1917 | &dx, &dy, &originX, &originY); | 2120 | &dx, &dy, &originX, &originY); |
1918 | dx = dx * state->getFontSize() + state->getCharSpace(); | 2121 | if (wMode) { |
1919 | if (n == 1 && *p == ' ') { | 2122 | dx *= state->getFontSize(); |
1920 | dx += state->getWordSpace(); | 2123 | dy = dy * state->getFontSize() + state->getCharSpace(); |
2124 | if (n == 1 && *p == ' ') { | ||
2125 | dy += state->getWordSpace(); | ||
2126 | } | ||
2127 | } else { | ||
2128 | dx = dx * state->getFontSize() + state->getCharSpace(); | ||
2129 | if (n == 1 && *p == ' ') { | ||
2130 | dx += state->getWordSpace(); | ||
2131 | } | ||
2132 | dx *= state->getHorizScaling(); | ||
2133 | dy *= state->getFontSize(); | ||
1921 | } | 2134 | } |
1922 | dx *= state->getHorizScaling(); | ||
1923 | dy *= state->getFontSize(); | ||
1924 | state->textTransformDelta(dx, dy, &tdx, &tdy); | 2135 | state->textTransformDelta(dx, dy, &tdx, &tdy); |
1925 | originX *= state->getFontSize(); | 2136 | originX *= state->getFontSize(); |
1926 | originY *= state->getFontSize(); | 2137 | originY *= state->getFontSize(); |
1927 | state->textTransformDelta(originX, originY, &tOriginX, &tOriginY); | 2138 | state->textTransformDelta(originX, originY, &tOriginX, &tOriginY); |
1928 | out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY, | 2139 | out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY, |
1929 | tdx, tdy, tOriginX, tOriginY, code, u, uLen); | 2140 | tdx, tdy, tOriginX, tOriginY, code, u, uLen); |
1930 | state->shift(tdx, tdy); | 2141 | state->shift(tdx, tdy); |
1931 | p += n; | 2142 | p += n; |
1932 | len -= n; | 2143 | len -= n; |
1933 | } | 2144 | } |
1934 | out->endString(state); | ||
1935 | 2145 | ||
1936 | } else { | 2146 | } else { |
1937 | dx = dy = 0; | 2147 | dx = dy = 0; |
1938 | p = s->getCString(); | 2148 | p = s->getCString(); |
1939 | len = s->getLength(); | 2149 | len = s->getLength(); |
1940 | nChars = nSpaces = 0; | 2150 | nChars = nSpaces = 0; |
@@ -1948,29 +2158,42 @@ void Gfx::doShowText(GString *s) { | |||
1948 | ++nSpaces; | 2158 | ++nSpaces; |
1949 | } | 2159 | } |
1950 | ++nChars; | 2160 | ++nChars; |
1951 | p += n; | 2161 | p += n; |
1952 | len -= n; | 2162 | len -= n; |
1953 | } | 2163 | } |
1954 | dx = dx * state->getFontSize() | 2164 | if (wMode) { |
1955 | + nChars * state->getCharSpace() | 2165 | dx *= state->getFontSize(); |
1956 | + nSpaces * state->getWordSpace(); | 2166 | dy = dy * state->getFontSize() |
1957 | dx *= state->getHorizScaling(); | 2167 | + nChars * state->getCharSpace() |
1958 | dy *= state->getFontSize(); | 2168 | + nSpaces * state->getWordSpace(); |
2169 | } else { | ||
2170 | dx = dx * state->getFontSize() | ||
2171 | + nChars * state->getCharSpace() | ||
2172 | + nSpaces * state->getWordSpace(); | ||
2173 | dx *= state->getHorizScaling(); | ||
2174 | dy *= state->getFontSize(); | ||
2175 | } | ||
1959 | state->textTransformDelta(dx, dy, &tdx, &tdy); | 2176 | state->textTransformDelta(dx, dy, &tdx, &tdy); |
1960 | out->drawString(state, s); | 2177 | out->drawString(state, s); |
1961 | state->shift(tdx, tdy); | 2178 | state->shift(tdx, tdy); |
1962 | } | 2179 | } |
2180 | |||
2181 | if (out->useDrawChar()) { | ||
2182 | out->endString(state); | ||
2183 | } | ||
2184 | |||
2185 | updateLevel += 10 * s->getLength(); | ||
1963 | } | 2186 | } |
1964 | 2187 | ||
1965 | //------------------------------------------------------------------------ | 2188 | //------------------------------------------------------------------------ |
1966 | // XObject operators | 2189 | // XObject operators |
1967 | //------------------------------------------------------------------------ | 2190 | //------------------------------------------------------------------------ |
1968 | 2191 | ||
1969 | void Gfx::opXObject(Object args[], int numArgs) { | 2192 | void Gfx::opXObject(Object args[], int numArgs) { |
1970 | Object obj1, obj2, refObj; | 2193 | Object obj1, obj2, obj3, refObj; |
1971 | #if OPI_SUPPORT | 2194 | #if OPI_SUPPORT |
1972 | Object opiDict; | 2195 | Object opiDict; |
1973 | #endif | 2196 | #endif |
1974 | 2197 | ||
1975 | if (!res->lookupXObject(args[0].getName(), &obj1)) { | 2198 | if (!res->lookupXObject(args[0].getName(), &obj1)) { |
1976 | return; | 2199 | return; |
@@ -1990,12 +2213,16 @@ void Gfx::opXObject(Object args[], int numArgs) { | |||
1990 | if (obj2.isName("Image")) { | 2213 | if (obj2.isName("Image")) { |
1991 | res->lookupXObjectNF(args[0].getName(), &refObj); | 2214 | res->lookupXObjectNF(args[0].getName(), &refObj); |
1992 | doImage(&refObj, obj1.getStream(), gFalse); | 2215 | doImage(&refObj, obj1.getStream(), gFalse); |
1993 | refObj.free(); | 2216 | refObj.free(); |
1994 | } else if (obj2.isName("Form")) { | 2217 | } else if (obj2.isName("Form")) { |
1995 | doForm(&obj1); | 2218 | doForm(&obj1); |
2219 | } else if (obj2.isName("PS")) { | ||
2220 | obj1.streamGetDict()->lookup("Level1", &obj3); | ||
2221 | out->psXObject(obj1.getStream(), | ||
2222 | obj3.isStream() ? obj3.getStream() : (Stream *)NULL); | ||
1996 | } else if (obj2.isName()) { | 2223 | } else if (obj2.isName()) { |
1997 | error(getPos(), "Unknown XObject subtype '%s'", obj2.getName()); | 2224 | error(getPos(), "Unknown XObject subtype '%s'", obj2.getName()); |
1998 | } else { | 2225 | } else { |
1999 | error(getPos(), "XObject subtype is missing or wrong type"); | 2226 | error(getPos(), "XObject subtype is missing or wrong type"); |
2000 | } | 2227 | } |
2001 | obj2.free(); | 2228 | obj2.free(); |
@@ -2145,12 +2372,17 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { | |||
2145 | haveMask ? maskColors : (int *)NULL, inlineImg); | 2372 | haveMask ? maskColors : (int *)NULL, inlineImg); |
2146 | delete colorMap; | 2373 | delete colorMap; |
2147 | 2374 | ||
2148 | maskObj.free(); | 2375 | maskObj.free(); |
2149 | } | 2376 | } |
2150 | 2377 | ||
2378 | if ((i = width * height) > 1000) { | ||
2379 | i = 1000; | ||
2380 | } | ||
2381 | updateLevel += i; | ||
2382 | |||
2151 | return; | 2383 | return; |
2152 | 2384 | ||
2153 | err2: | 2385 | err2: |
2154 | obj1.free(); | 2386 | obj1.free(); |
2155 | err1: | 2387 | err1: |
2156 | error(getPos(), "Bad image parameters"); | 2388 | error(getPos(), "Bad image parameters"); |
@@ -2212,25 +2444,28 @@ void Gfx::doForm(Object *str) { | |||
2212 | // draw it | 2444 | // draw it |
2213 | doForm1(str, resDict, m, bbox); | 2445 | doForm1(str, resDict, m, bbox); |
2214 | 2446 | ||
2215 | resObj.free(); | 2447 | resObj.free(); |
2216 | } | 2448 | } |
2217 | 2449 | ||
2218 | void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin, | 2450 | void Gfx::doAnnot(Object *str, fouble xMin, fouble yMin, |
2219 | fouble xMax, fouble yMax) { | 2451 | fouble xMax, fouble yMax) { |
2220 | Dict *dict, *resDict; | 2452 | Dict *dict, *resDict; |
2221 | Object matrixObj, bboxObj, resObj; | 2453 | Object matrixObj, bboxObj, resObj; |
2222 | Object obj1; | 2454 | Object obj1; |
2223 | fouble m[6], bbox[6]; | 2455 | fouble m[6], bbox[6], ictm[6]; |
2224 | fouble sx, sy; | 2456 | fouble *ctm; |
2457 | fouble formX0, formY0, formX1, formY1; | ||
2458 | fouble annotX0, annotY0, annotX1, annotY1; | ||
2459 | fouble det, x, y, sx, sy; | ||
2225 | int i; | 2460 | int i; |
2226 | 2461 | ||
2227 | // get stream dict | 2462 | // get stream dict |
2228 | dict = str->streamGetDict(); | 2463 | dict = str->streamGetDict(); |
2229 | 2464 | ||
2230 | // get bounding box | 2465 | // get the form bounding box |
2231 | dict->lookup("BBox", &bboxObj); | 2466 | dict->lookup("BBox", &bboxObj); |
2232 | if (!bboxObj.isArray()) { | 2467 | if (!bboxObj.isArray()) { |
2233 | bboxObj.free(); | 2468 | bboxObj.free(); |
2234 | error(getPos(), "Bad form bounding box"); | 2469 | error(getPos(), "Bad form bounding box"); |
2235 | return; | 2470 | return; |
2236 | } | 2471 | } |
@@ -2238,13 +2473,13 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin, | |||
2238 | bboxObj.arrayGet(i, &obj1); | 2473 | bboxObj.arrayGet(i, &obj1); |
2239 | bbox[i] = obj1.getNum(); | 2474 | bbox[i] = obj1.getNum(); |
2240 | obj1.free(); | 2475 | obj1.free(); |
2241 | } | 2476 | } |
2242 | bboxObj.free(); | 2477 | bboxObj.free(); |
2243 | 2478 | ||
2244 | // get matrix | 2479 | // get the form matrix |
2245 | dict->lookup("Matrix", &matrixObj); | 2480 | dict->lookup("Matrix", &matrixObj); |
2246 | if (matrixObj.isArray()) { | 2481 | if (matrixObj.isArray()) { |
2247 | for (i = 0; i < 6; ++i) { | 2482 | for (i = 0; i < 6; ++i) { |
2248 | matrixObj.arrayGet(i, &obj1); | 2483 | matrixObj.arrayGet(i, &obj1); |
2249 | m[i] = obj1.getNum(); | 2484 | m[i] = obj1.getNum(); |
2250 | obj1.free(); | 2485 | obj1.free(); |
@@ -2253,22 +2488,70 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin, | |||
2253 | m[0] = 1; m[1] = 0; | 2488 | m[0] = 1; m[1] = 0; |
2254 | m[2] = 0; m[3] = 1; | 2489 | m[2] = 0; m[3] = 1; |
2255 | m[4] = 0; m[5] = 0; | 2490 | m[4] = 0; m[5] = 0; |
2256 | } | 2491 | } |
2257 | matrixObj.free(); | 2492 | matrixObj.free(); |
2258 | 2493 | ||
2259 | // scale form bbox to widget rectangle | 2494 | // transform the form bbox from form space to user space |
2260 | sx = fabs((xMax - xMin) / (bbox[2] - bbox[0])); | 2495 | formX0 = bbox[0] * m[0] + bbox[1] * m[2] + m[4]; |
2261 | sy = fabs((yMax - yMin) / (bbox[3] - bbox[1])); | 2496 | formY0 = bbox[0] * m[1] + bbox[1] * m[3] + m[5]; |
2262 | m[0] *= sx; m[1] *= sy; | 2497 | formX1 = bbox[2] * m[0] + bbox[3] * m[2] + m[4]; |
2263 | m[2] *= sx; m[3] *= sy; | 2498 | formY1 = bbox[2] * m[1] + bbox[3] * m[3] + m[5]; |
2264 | m[4] *= sx; m[5] *= sy; | 2499 | |
2500 | // transform the annotation bbox from default user space to user | ||
2501 | // space: (bbox * baseMatrix) * iCTM | ||
2502 | ctm = state->getCTM(); | ||
2503 | det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); | ||
2504 | ictm[0] = ctm[3] * det; | ||
2505 | ictm[1] = -ctm[1] * det; | ||
2506 | ictm[2] = -ctm[2] * det; | ||
2507 | ictm[3] = ctm[0] * det; | ||
2508 | ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; | ||
2509 | ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; | ||
2510 | x = baseMatrix[0] * xMin + baseMatrix[2] * yMin + baseMatrix[4]; | ||
2511 | y = baseMatrix[1] * xMin + baseMatrix[3] * yMin + baseMatrix[5]; | ||
2512 | annotX0 = ictm[0] * x + ictm[2] * y + ictm[4]; | ||
2513 | annotY0 = ictm[1] * x + ictm[3] * y + ictm[5]; | ||
2514 | x = baseMatrix[0] * xMax + baseMatrix[2] * yMax + baseMatrix[4]; | ||
2515 | y = baseMatrix[1] * xMax + baseMatrix[3] * yMax + baseMatrix[5]; | ||
2516 | annotX1 = ictm[0] * x + ictm[2] * y + ictm[4]; | ||
2517 | annotY1 = ictm[1] * x + ictm[3] * y + ictm[5]; | ||
2518 | |||
2519 | // swap min/max coords | ||
2520 | if (formX0 > formX1) { | ||
2521 | x = formX0; formX0 = formX1; formX1 = x; | ||
2522 | } | ||
2523 | if (formY0 > formY1) { | ||
2524 | y = formY0; formY0 = formY1; formY1 = y; | ||
2525 | } | ||
2526 | if (annotX0 > annotX1) { | ||
2527 | x = annotX0; annotX0 = annotX1; annotX1 = x; | ||
2528 | } | ||
2529 | if (annotY0 > annotY1) { | ||
2530 | y = annotY0; annotY0 = annotY1; annotY1 = y; | ||
2531 | } | ||
2265 | 2532 | ||
2266 | // translate to widget rectangle | 2533 | // scale the form to fit the annotation bbox |
2267 | m[4] += xMin; | 2534 | if (formX1 == formX0) { |
2268 | m[5] += yMin; | 2535 | // this shouldn't happen |
2536 | sx = 1; | ||
2537 | } else { | ||
2538 | sx = (annotX1 - annotX0) / (formX1 - formX0); | ||
2539 | } | ||
2540 | if (formY1 == formY0) { | ||
2541 | // this shouldn't happen | ||
2542 | sy = 1; | ||
2543 | } else { | ||
2544 | sy = (annotY1 - annotY0) / (formY1 - formY0); | ||
2545 | } | ||
2546 | m[0] *= sx; | ||
2547 | m[2] *= sx; | ||
2548 | m[4] = (m[4] - formX0) * sx + annotX0; | ||
2549 | m[1] *= sy; | ||
2550 | m[3] *= sy; | ||
2551 | m[5] = (m[5] - formY0) * sy + annotY0; | ||
2269 | 2552 | ||
2270 | // get resources | 2553 | // get resources |
2271 | dict->lookup("Resources", &resObj); | 2554 | dict->lookup("Resources", &resObj); |
2272 | resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; | 2555 | resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; |
2273 | 2556 | ||
2274 | // draw it | 2557 | // draw it |
@@ -2278,17 +2561,16 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin, | |||
2278 | bboxObj.free(); | 2561 | bboxObj.free(); |
2279 | } | 2562 | } |
2280 | 2563 | ||
2281 | void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) { | 2564 | void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) { |
2282 | Parser *oldParser; | 2565 | Parser *oldParser; |
2283 | fouble oldBaseMatrix[6]; | 2566 | fouble oldBaseMatrix[6]; |
2284 | GfxResources *resPtr; | ||
2285 | int i; | 2567 | int i; |
2286 | 2568 | ||
2287 | // push new resources on stack | 2569 | // push new resources on stack |
2288 | res = new GfxResources(xref, resDict, res); | 2570 | pushResources(resDict); |
2289 | 2571 | ||
2290 | // save current graphics state | 2572 | // save current graphics state |
2291 | out->saveState(state); | 2573 | out->saveState(state); |
2292 | state = state->save(); | 2574 | state = state->save(); |
2293 | 2575 | ||
2294 | // save current parser | 2576 | // save current parser |
@@ -2329,17 +2611,27 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) { | |||
2329 | 2611 | ||
2330 | // restore graphics state | 2612 | // restore graphics state |
2331 | state = state->restore(); | 2613 | state = state->restore(); |
2332 | out->restoreState(state); | 2614 | out->restoreState(state); |
2333 | 2615 | ||
2334 | // pop resource stack | 2616 | // pop resource stack |
2617 | popResources(); | ||
2618 | |||
2619 | return; | ||
2620 | } | ||
2621 | |||
2622 | void Gfx::pushResources(Dict *resDict) { | ||
2623 | res = new GfxResources(xref, resDict, res); | ||
2624 | } | ||
2625 | |||
2626 | void Gfx::popResources() { | ||
2627 | GfxResources *resPtr; | ||
2628 | |||
2335 | resPtr = res->getNext(); | 2629 | resPtr = res->getNext(); |
2336 | delete res; | 2630 | delete res; |
2337 | res = resPtr; | 2631 | res = resPtr; |
2338 | |||
2339 | return; | ||
2340 | } | 2632 | } |
2341 | 2633 | ||
2342 | //------------------------------------------------------------------------ | 2634 | //------------------------------------------------------------------------ |
2343 | // in-line image operators | 2635 | // in-line image operators |
2344 | //------------------------------------------------------------------------ | 2636 | //------------------------------------------------------------------------ |
2345 | 2637 | ||
@@ -2375,25 +2667,30 @@ Stream *Gfx::buildImageStream() { | |||
2375 | dict.initDict(xref); | 2667 | dict.initDict(xref); |
2376 | parser->getObj(&obj); | 2668 | parser->getObj(&obj); |
2377 | while (!obj.isCmd("ID") && !obj.isEOF()) { | 2669 | while (!obj.isCmd("ID") && !obj.isEOF()) { |
2378 | if (!obj.isName()) { | 2670 | if (!obj.isName()) { |
2379 | error(getPos(), "Inline image dictionary key must be a name object"); | 2671 | error(getPos(), "Inline image dictionary key must be a name object"); |
2380 | obj.free(); | 2672 | obj.free(); |
2381 | parser->getObj(&obj); | ||
2382 | } else { | 2673 | } else { |
2383 | key = copyString(obj.getName()); | 2674 | key = copyString(obj.getName()); |
2384 | obj.free(); | 2675 | obj.free(); |
2385 | parser->getObj(&obj); | 2676 | parser->getObj(&obj); |
2386 | if (obj.isEOF() || obj.isError()) | 2677 | if (obj.isEOF() || obj.isError()) { |
2678 | gfree(key); | ||
2387 | break; | 2679 | break; |
2680 | } | ||
2388 | dict.dictAdd(key, &obj); | 2681 | dict.dictAdd(key, &obj); |
2389 | } | 2682 | } |
2390 | parser->getObj(&obj); | 2683 | parser->getObj(&obj); |
2391 | } | 2684 | } |
2392 | if (obj.isEOF()) | 2685 | if (obj.isEOF()) { |
2393 | error(getPos(), "End of file in inline image"); | 2686 | error(getPos(), "End of file in inline image"); |
2687 | obj.free(); | ||
2688 | dict.free(); | ||
2689 | return NULL; | ||
2690 | } | ||
2394 | obj.free(); | 2691 | obj.free(); |
2395 | 2692 | ||
2396 | // make stream | 2693 | // make stream |
2397 | str = new EmbedStream(parser->getStream(), &dict); | 2694 | str = new EmbedStream(parser->getStream(), &dict); |
2398 | str = str->addFilters(&dict); | 2695 | str = str->addFilters(&dict); |
2399 | 2696 | ||
@@ -2410,17 +2707,19 @@ void Gfx::opEndImage(Object args[], int numArgs) { | |||
2410 | 2707 | ||
2411 | //------------------------------------------------------------------------ | 2708 | //------------------------------------------------------------------------ |
2412 | // type 3 font operators | 2709 | // type 3 font operators |
2413 | //------------------------------------------------------------------------ | 2710 | //------------------------------------------------------------------------ |
2414 | 2711 | ||
2415 | void Gfx::opSetCharWidth(Object args[], int numArgs) { | 2712 | void Gfx::opSetCharWidth(Object args[], int numArgs) { |
2416 | error(getPos(), "Encountered 'd0' operator in content stream"); | 2713 | out->type3D0(state, args[0].getNum(), args[1].getNum()); |
2417 | } | 2714 | } |
2418 | 2715 | ||
2419 | void Gfx::opSetCacheDevice(Object args[], int numArgs) { | 2716 | void Gfx::opSetCacheDevice(Object args[], int numArgs) { |
2420 | error(getPos(), "Encountered 'd1' operator in content stream"); | 2717 | out->type3D1(state, args[0].getNum(), args[1].getNum(), |
2718 | args[2].getNum(), args[3].getNum(), | ||
2719 | args[4].getNum(), args[5].getNum()); | ||
2421 | } | 2720 | } |
2422 | 2721 | ||
2423 | //------------------------------------------------------------------------ | 2722 | //------------------------------------------------------------------------ |
2424 | // compatibility operators | 2723 | // compatibility operators |
2425 | //------------------------------------------------------------------------ | 2724 | //------------------------------------------------------------------------ |
2426 | 2725 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Gfx.h b/noncore/unsupported/qpdf/xpdf/Gfx.h index be5f2c2..2ecfb24 100644 --- a/noncore/unsupported/qpdf/xpdf/Gfx.h +++ b/noncore/unsupported/qpdf/xpdf/Gfx.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Gfx.h | 3 | // Gfx.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef GFX_H | 9 | #ifndef GFX_H |
10 | #define GFX_H | 10 | #define GFX_H |
11 | 11 | ||
@@ -24,12 +24,13 @@ class Dict; | |||
24 | class OutputDev; | 24 | class OutputDev; |
25 | class GfxFontDict; | 25 | class GfxFontDict; |
26 | class GfxFont; | 26 | class GfxFont; |
27 | class GfxPattern; | 27 | class GfxPattern; |
28 | class GfxShading; | 28 | class GfxShading; |
29 | class GfxAxialShading; | 29 | class GfxAxialShading; |
30 | class GfxRadialShading; | ||
30 | class GfxState; | 31 | class GfxState; |
31 | class Gfx; | 32 | class Gfx; |
32 | struct PDFRectangle; | 33 | struct PDFRectangle; |
33 | 34 | ||
34 | //------------------------------------------------------------------------ | 35 | //------------------------------------------------------------------------ |
35 | // Gfx | 36 | // Gfx |
@@ -94,27 +95,37 @@ public: | |||
94 | 95 | ||
95 | // Constructor for regular output. | 96 | // Constructor for regular output. |
96 | Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, | 97 | Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, |
97 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, | 98 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, |
98 | GBool printCommandsA); | 99 | GBool printCommandsA); |
99 | 100 | ||
100 | // Destructor. | 101 | // Constructor for a sub-page object. |
102 | Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, | ||
103 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox); | ||
104 | |||
101 | ~Gfx(); | 105 | ~Gfx(); |
102 | 106 | ||
103 | // Interpret a stream or array of streams. | 107 | // Interpret a stream or array of streams. |
104 | void display(Object *obj, GBool topLevel = gTrue); | 108 | void display(Object *obj, GBool topLevel = gTrue); |
105 | 109 | ||
106 | void doWidgetForm(Object *str, fouble xMin, fouble yMin, | 110 | // Display an annotation, given its appearance (a Form XObject) and |
107 | fouble xMax, fouble yMax); | 111 | // bounding box (in default user space). |
112 | void doAnnot(Object *str, fouble xMin, fouble yMin, | ||
113 | fouble xMax, fouble yMax); | ||
114 | |||
115 | void pushResources(Dict *resDict); | ||
116 | void popResources(); | ||
108 | 117 | ||
109 | private: | 118 | private: |
110 | 119 | ||
111 | XRef *xref; // the xref table for this PDF file | 120 | XRef *xref; // the xref table for this PDF file |
112 | OutputDev *out; // output device | 121 | OutputDev *out; // output device |
122 | GBool subPage; // is this a sub-page object? | ||
113 | GBool printCommands; // print the drawing commands (for debugging) | 123 | GBool printCommands; // print the drawing commands (for debugging) |
114 | GfxResources *res; // resource stack | 124 | GfxResources *res; // resource stack |
125 | int updateLevel; | ||
115 | 126 | ||
116 | GfxState *state; // current graphics state | 127 | GfxState *state; // current graphics state |
117 | GBool fontChanged; // set if font or text matrix has changed | 128 | GBool fontChanged; // set if font or text matrix has changed |
118 | GfxClipType clip; // do a clip? | 129 | GfxClipType clip; // do a clip? |
119 | int ignoreUndef; // current BX/EX nesting level | 130 | int ignoreUndef; // current BX/EX nesting level |
120 | fouble baseMatrix[6]; // default matrix for most recent | 131 | fouble baseMatrix[6]; // default matrix for most recent |
@@ -176,12 +187,13 @@ private: | |||
176 | void opCloseFillStroke(Object args[], int numArgs); | 187 | void opCloseFillStroke(Object args[], int numArgs); |
177 | void opEOFillStroke(Object args[], int numArgs); | 188 | void opEOFillStroke(Object args[], int numArgs); |
178 | void opCloseEOFillStroke(Object args[], int numArgs); | 189 | void opCloseEOFillStroke(Object args[], int numArgs); |
179 | void doPatternFill(GBool eoFill); | 190 | void doPatternFill(GBool eoFill); |
180 | void opShFill(Object args[], int numArgs); | 191 | void opShFill(Object args[], int numArgs); |
181 | void doAxialShFill(GfxAxialShading *shading); | 192 | void doAxialShFill(GfxAxialShading *shading); |
193 | void doRadialShFill(GfxRadialShading *shading); | ||
182 | void doEndPath(); | 194 | void doEndPath(); |
183 | 195 | ||
184 | // path clipping operators | 196 | // path clipping operators |
185 | void opClip(Object args[], int numArgs); | 197 | void opClip(Object args[], int numArgs); |
186 | void opEOClip(Object args[], int numArgs); | 198 | void opEOClip(Object args[], int numArgs); |
187 | 199 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/GfxFont.cc b/noncore/unsupported/qpdf/xpdf/GfxFont.cc index 518f97b..8d722d6 100644 --- a/noncore/unsupported/qpdf/xpdf/GfxFont.cc +++ b/noncore/unsupported/qpdf/xpdf/GfxFont.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // GfxFont.cc | 3 | // GfxFont.cc |
4 | // | 4 | // |
5 | // Copyright 1996-2001 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -451,19 +451,30 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
451 | } | 451 | } |
452 | obj2.free(); | 452 | obj2.free(); |
453 | } | 453 | } |
454 | } | 454 | } |
455 | obj1.free(); | 455 | obj1.free(); |
456 | 456 | ||
457 | // get Type3 font definition | 457 | // get Type 3 bounding box, font definition, and resources |
458 | if (type == fontType3) { | 458 | if (type == fontType3) { |
459 | fontDict->lookup("CharProcs", &charProcs); | 459 | if (fontDict->lookup("FontBBox", &obj1)->isArray()) { |
460 | if (!charProcs.isDict()) { | 460 | for (i = 0; i < 4 && i < obj1.arrayGetLength(); ++i) { |
461 | if (obj1.arrayGet(i, &obj2)->isNum()) { | ||
462 | fontBBox[i] = obj2.getNum(); | ||
463 | } | ||
464 | obj2.free(); | ||
465 | } | ||
466 | } | ||
467 | obj1.free(); | ||
468 | if (!fontDict->lookup("CharProcs", &charProcs)->isDict()) { | ||
461 | error(-1, "Missing or invalid CharProcs dictionary in Type 3 font"); | 469 | error(-1, "Missing or invalid CharProcs dictionary in Type 3 font"); |
462 | charProcs.free(); | 470 | charProcs.free(); |
463 | } | 471 | } |
472 | if (!fontDict->lookup("Resources", &resources)->isDict()) { | ||
473 | resources.free(); | ||
474 | } | ||
464 | } | 475 | } |
465 | 476 | ||
466 | //----- build the font encoding ----- | 477 | //----- build the font encoding ----- |
467 | 478 | ||
468 | // Encodings start with a base encoding, which can come from | 479 | // Encodings start with a base encoding, which can come from |
469 | // (in order of priority): | 480 | // (in order of priority): |
@@ -510,29 +521,34 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
510 | } else if (obj1.isName("StandardEncoding")) { | 521 | } else if (obj1.isName("StandardEncoding")) { |
511 | hasEncoding = gTrue; | 522 | hasEncoding = gTrue; |
512 | baseEnc = standardEncoding; | 523 | baseEnc = standardEncoding; |
513 | } | 524 | } |
514 | 525 | ||
515 | // check embedded or external font file for base encoding | 526 | // check embedded or external font file for base encoding |
527 | // (only for Type 1 fonts - trying to get an encoding out of a | ||
528 | // TrueType font is a losing proposition) | ||
516 | fontFile = NULL; | 529 | fontFile = NULL; |
517 | buf = NULL; | 530 | buf = NULL; |
518 | if ((type == fontType1 || type == fontType1C || type == fontTrueType) && | 531 | if ((type == fontType1 || type == fontType1C) && |
519 | (extFontFile || embFontID.num >= 0)) { | 532 | (extFontFile || embFontID.num >= 0)) { |
520 | if (extFontFile) { | 533 | if (extFontFile) { |
521 | buf = readExtFontFile(&len); | 534 | buf = readExtFontFile(&len); |
522 | } else { | 535 | } else { |
523 | buf = readEmbFontFile(xref, &len); | 536 | buf = readEmbFontFile(xref, &len); |
524 | } | 537 | } |
525 | if (buf) { | 538 | if (buf) { |
526 | #if 0 | 539 | #if 0 |
540 | if (type == fontType1C && !strncmp(buf, "%!", 2)) { | ||
541 | // various tools (including Adobe's) occasionally embed Type 1 | ||
542 | // fonts but label them Type 1C | ||
543 | type = fontType1; | ||
544 | } | ||
527 | if (type == fontType1) { | 545 | if (type == fontType1) { |
528 | fontFile = new Type1FontFile(buf, len); | 546 | fontFile = new Type1FontFile(buf, len); |
529 | } else if (type == fontType1C) { | ||
530 | fontFile = new Type1CFontFile(buf, len); | ||
531 | } else { | 547 | } else { |
532 | fontFile = new TrueTypeFontFile(buf, len); | 548 | fontFile = new Type1CFontFile(buf, len); |
533 | } | 549 | } |
534 | if (fontFile->getName()) { | 550 | if (fontFile->getName()) { |
535 | if (embFontName) { | 551 | if (embFontName) { |
536 | delete embFontName; | 552 | delete embFontName; |
537 | } | 553 | } |
538 | embFontName = new GString(fontFile->getName()); | 554 | embFontName = new GString(fontFile->getName()); |
@@ -566,12 +582,13 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
566 | } | 582 | } |
567 | 583 | ||
568 | // merge differences into encoding | 584 | // merge differences into encoding |
569 | if (obj1.isDict()) { | 585 | if (obj1.isDict()) { |
570 | obj1.dictLookup("Differences", &obj2); | 586 | obj1.dictLookup("Differences", &obj2); |
571 | if (obj2.isArray()) { | 587 | if (obj2.isArray()) { |
588 | hasEncoding = gTrue; | ||
572 | code = 0; | 589 | code = 0; |
573 | for (i = 0; i < obj2.arrayGetLength(); ++i) { | 590 | for (i = 0; i < obj2.arrayGetLength(); ++i) { |
574 | obj2.arrayGet(i, &obj3); | 591 | obj2.arrayGet(i, &obj3); |
575 | if (obj3.isInt()) { | 592 | if (obj3.isInt()) { |
576 | code = obj3.getInt(); | 593 | code = obj3.getInt(); |
577 | } else if (obj3.isName()) { | 594 | } else if (obj3.isName()) { |
@@ -633,14 +650,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
633 | } else { | 650 | } else { |
634 | toUnicode[code] = 0; | 651 | toUnicode[code] = 0; |
635 | } | 652 | } |
636 | } | 653 | } |
637 | 654 | ||
638 | // pass 2: try to fill in the missing chars, looking for names of | 655 | // pass 2: try to fill in the missing chars, looking for names of |
639 | // the form 'Axx', 'xx', 'Ann', or 'nn', where 'A' is any letter, | 656 | // the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B' |
640 | // 'xx' is two hex digits, and 'nn' is 2-4 decimal digits | 657 | // are any letters, 'xx' is two hex digits, and 'nn' is 2-4 |
658 | // decimal digits | ||
641 | if (missing && globalParams->getMapNumericCharNames()) { | 659 | if (missing && globalParams->getMapNumericCharNames()) { |
642 | for (code = 0; code < 256; ++code) { | 660 | for (code = 0; code < 256; ++code) { |
643 | if ((charName = enc[code]) && !toUnicode[code] && | 661 | if ((charName = enc[code]) && !toUnicode[code] && |
644 | strcmp(charName, ".notdef")) { | 662 | strcmp(charName, ".notdef")) { |
645 | n = strlen(charName); | 663 | n = strlen(charName); |
646 | code2 = -1; | 664 | code2 = -1; |
@@ -653,12 +671,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
653 | } else if (!hex && n >= 2 && n <= 4 && | 671 | } else if (!hex && n >= 2 && n <= 4 && |
654 | isdigit(charName[0]) && isdigit(charName[1])) { | 672 | isdigit(charName[0]) && isdigit(charName[1])) { |
655 | code2 = atoi(charName); | 673 | code2 = atoi(charName); |
656 | } else if (n >= 3 && n <= 5 && | 674 | } else if (n >= 3 && n <= 5 && |
657 | isdigit(charName[1]) && isdigit(charName[2])) { | 675 | isdigit(charName[1]) && isdigit(charName[2])) { |
658 | code2 = atoi(charName+1); | 676 | code2 = atoi(charName+1); |
677 | } else if (n >= 4 && n <= 6 && | ||
678 | isdigit(charName[2]) && isdigit(charName[3])) { | ||
679 | code2 = atoi(charName+2); | ||
659 | } | 680 | } |
660 | if (code2 >= 0 && code2 <= 0xff) { | 681 | if (code2 >= 0 && code2 <= 0xff) { |
661 | toUnicode[code] = (Unicode)code2; | 682 | toUnicode[code] = (Unicode)code2; |
662 | } | 683 | } |
663 | } | 684 | } |
664 | } | 685 | } |
@@ -681,16 +702,20 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
681 | fontDict->lookup("LastChar", &obj1); | 702 | fontDict->lookup("LastChar", &obj1); |
682 | lastChar = obj1.isInt() ? obj1.getInt() : 255; | 703 | lastChar = obj1.isInt() ? obj1.getInt() : 255; |
683 | obj1.free(); | 704 | obj1.free(); |
684 | mul = (type == fontType3) ? fontMat[0] : fouble(0.001); | 705 | mul = (type == fontType3) ? fontMat[0] : fouble(0.001); |
685 | fontDict->lookup("Widths", &obj1); | 706 | fontDict->lookup("Widths", &obj1); |
686 | if (obj1.isArray()) { | 707 | if (obj1.isArray()) { |
708 | flags |= fontFixedWidth; | ||
687 | for (code = firstChar; code <= lastChar; ++code) { | 709 | for (code = firstChar; code <= lastChar; ++code) { |
688 | obj1.arrayGet(code - firstChar, &obj2); | 710 | obj1.arrayGet(code - firstChar, &obj2); |
689 | if (obj2.isNum()) { | 711 | if (obj2.isNum()) { |
690 | widths[code] = obj2.getNum() * mul; | 712 | widths[code] = obj2.getNum() * mul; |
713 | if (widths[code] != widths[firstChar]) { | ||
714 | flags &= ~fontFixedWidth; | ||
715 | } | ||
691 | } | 716 | } |
692 | obj2.free(); | 717 | obj2.free(); |
693 | } | 718 | } |
694 | 719 | ||
695 | // use widths from built-in font | 720 | // use widths from built-in font |
696 | } else if (builtinFont) { | 721 | } else if (builtinFont) { |
@@ -749,12 +774,15 @@ Gfx8BitFont::~Gfx8BitFont() { | |||
749 | } | 774 | } |
750 | } | 775 | } |
751 | ctu->decRefCnt(); | 776 | ctu->decRefCnt(); |
752 | if (charProcs.isDict()) { | 777 | if (charProcs.isDict()) { |
753 | charProcs.free(); | 778 | charProcs.free(); |
754 | } | 779 | } |
780 | if (resources.isDict()) { | ||
781 | resources.free(); | ||
782 | } | ||
755 | } | 783 | } |
756 | 784 | ||
757 | int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, | 785 | int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, |
758 | Unicode *u, int uSize, int *uLen, | 786 | Unicode *u, int uSize, int *uLen, |
759 | fouble *dx, fouble *dy, fouble *ox, fouble *oy) { | 787 | fouble *dx, fouble *dy, fouble *ox, fouble *oy) { |
760 | CharCode c; | 788 | CharCode c; |
@@ -768,21 +796,29 @@ int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, | |||
768 | 796 | ||
769 | CharCodeToUnicode *Gfx8BitFont::getToUnicode() { | 797 | CharCodeToUnicode *Gfx8BitFont::getToUnicode() { |
770 | ctu->incRefCnt(); | 798 | ctu->incRefCnt(); |
771 | return ctu; | 799 | return ctu; |
772 | } | 800 | } |
773 | 801 | ||
802 | Dict *Gfx8BitFont::getCharProcs() { | ||
803 | return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL; | ||
804 | } | ||
805 | |||
774 | Object *Gfx8BitFont::getCharProc(int code, Object *proc) { | 806 | Object *Gfx8BitFont::getCharProc(int code, Object *proc) { |
775 | if (charProcs.isDict()) { | 807 | if (charProcs.isDict()) { |
776 | charProcs.dictLookup(enc[code], proc); | 808 | charProcs.dictLookup(enc[code], proc); |
777 | } else { | 809 | } else { |
778 | proc->initNull(); | 810 | proc->initNull(); |
779 | } | 811 | } |
780 | return proc; | 812 | return proc; |
781 | } | 813 | } |
782 | 814 | ||
815 | Dict *Gfx8BitFont::getResources() { | ||
816 | return resources.isDict() ? resources.getDict() : (Dict *)NULL; | ||
817 | } | ||
818 | |||
783 | //------------------------------------------------------------------------ | 819 | //------------------------------------------------------------------------ |
784 | // GfxCIDFont | 820 | // GfxCIDFont |
785 | //------------------------------------------------------------------------ | 821 | //------------------------------------------------------------------------ |
786 | 822 | ||
787 | static int cmpWidthExcep(const void *w1, const void *w2) { | 823 | static int cmpWidthExcep(const void *w1, const void *w2) { |
788 | return ((GfxFontCIDWidthExcep *)w1)->first - | 824 | return ((GfxFontCIDWidthExcep *)w1)->first - |
@@ -1183,12 +1219,16 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code, | |||
1183 | *ox = vx; | 1219 | *ox = vx; |
1184 | *oy = vy; | 1220 | *oy = vy; |
1185 | 1221 | ||
1186 | return n; | 1222 | return n; |
1187 | } | 1223 | } |
1188 | 1224 | ||
1225 | int GfxCIDFont::getWMode() { | ||
1226 | return cMap ? cMap->getWMode() : 0; | ||
1227 | } | ||
1228 | |||
1189 | CharCodeToUnicode *GfxCIDFont::getToUnicode() { | 1229 | CharCodeToUnicode *GfxCIDFont::getToUnicode() { |
1190 | ctu->incRefCnt(); | 1230 | ctu->incRefCnt(); |
1191 | return ctu; | 1231 | return ctu; |
1192 | } | 1232 | } |
1193 | 1233 | ||
1194 | GString *GfxCIDFont::getCollection() { | 1234 | GString *GfxCIDFont::getCollection() { |
@@ -1213,13 +1253,13 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) { | |||
1213 | obj1.getRef(), obj2.getDict()); | 1253 | obj1.getRef(), obj2.getDict()); |
1214 | if (fonts[i] && !fonts[i]->isOk()) { | 1254 | if (fonts[i] && !fonts[i]->isOk()) { |
1215 | delete fonts[i]; | 1255 | delete fonts[i]; |
1216 | fonts[i] = NULL; | 1256 | fonts[i] = NULL; |
1217 | } | 1257 | } |
1218 | } else { | 1258 | } else { |
1219 | error(-1, "font resource is not a dictionary"); | 1259 | error(-1, "font resource is not a dictionary reference"); |
1220 | fonts[i] = NULL; | 1260 | fonts[i] = NULL; |
1221 | } | 1261 | } |
1222 | obj1.free(); | 1262 | obj1.free(); |
1223 | obj2.free(); | 1263 | obj2.free(); |
1224 | } | 1264 | } |
1225 | } | 1265 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/GfxFont.h b/noncore/unsupported/qpdf/xpdf/GfxFont.h index b1aa952..8e9fe38 100644 --- a/noncore/unsupported/qpdf/xpdf/GfxFont.h +++ b/noncore/unsupported/qpdf/xpdf/GfxFont.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // GfxFont.h | 3 | // GfxFont.h |
4 | // | 4 | // |
5 | // Copyright 1996-2001 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef GFXFONT_H | 9 | #ifndef GFXFONT_H |
10 | #define GFXFONT_H | 10 | #define GFXFONT_H |
11 | 11 | ||
@@ -110,14 +110,13 @@ public: | |||
110 | // Returns false if there is no embedded font. | 110 | // Returns false if there is no embedded font. |
111 | GBool getEmbeddedFontID(Ref *embID) | 111 | GBool getEmbeddedFontID(Ref *embID) |
112 | { *embID = embFontID; return embFontID.num >= 0; } | 112 | { *embID = embFontID; return embFontID.num >= 0; } |
113 | 113 | ||
114 | // Get the PostScript font name for the embedded font. Returns | 114 | // Get the PostScript font name for the embedded font. Returns |
115 | // NULL if there is no embedded font. | 115 | // NULL if there is no embedded font. |
116 | char *getEmbeddedFontName() | 116 | GString *getEmbeddedFontName() { return embFontName; } |
117 | { return embFontName ? embFontName->getCString() : (char *)NULL; } | ||
118 | 117 | ||
119 | // Get the name of the external font file. Returns NULL if there | 118 | // Get the name of the external font file. Returns NULL if there |
120 | // is no external font file. | 119 | // is no external font file. |
121 | GString *getExtFontFile() { return extFontFile; } | 120 | GString *getExtFontFile() { return extFontFile; } |
122 | 121 | ||
123 | // Get font descriptor flags. | 122 | // Get font descriptor flags. |
@@ -134,12 +133,15 @@ public: | |||
134 | fouble *getFontBBox() { return fontBBox; } | 133 | fouble *getFontBBox() { return fontBBox; } |
135 | 134 | ||
136 | // Return the ascent and descent values. | 135 | // Return the ascent and descent values. |
137 | fouble getAscent() { return ascent; } | 136 | fouble getAscent() { return ascent; } |
138 | fouble getDescent() { return descent; } | 137 | fouble getDescent() { return descent; } |
139 | 138 | ||
139 | // Return the writing mode (0=horizontal, 1=vertical). | ||
140 | virtual int getWMode() { return 0; } | ||
141 | |||
140 | // Read an external or embedded font file into a buffer. | 142 | // Read an external or embedded font file into a buffer. |
141 | char *readExtFontFile(int *len); | 143 | char *readExtFontFile(int *len); |
142 | char *readEmbFontFile(XRef *xref, int *len); | 144 | char *readEmbFontFile(XRef *xref, int *len); |
143 | 145 | ||
144 | // Get the next char from a string <s> of <len> bytes, returning the | 146 | // Get the next char from a string <s> of <len> bytes, returning the |
145 | // char <code>, its Unicode mapping <u>, its displacement vector | 147 | // char <code>, its Unicode mapping <u>, its displacement vector |
@@ -152,24 +154,24 @@ public: | |||
152 | fouble *dx, fouble *dy, fouble *ox, fouble *oy) = 0; | 154 | fouble *dx, fouble *dy, fouble *ox, fouble *oy) = 0; |
153 | 155 | ||
154 | protected: | 156 | protected: |
155 | 157 | ||
156 | void readFontDescriptor(XRef *xref, Dict *fontDict); | 158 | void readFontDescriptor(XRef *xref, Dict *fontDict); |
157 | CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits); | 159 | CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits); |
158 | void GfxFont::findExtFontFile(); | 160 | void findExtFontFile(); |
159 | 161 | ||
160 | GString *tag; // PDF font tag | 162 | GString *tag; // PDF font tag |
161 | Ref id; // reference (used as unique ID) | 163 | Ref id; // reference (used as unique ID) |
162 | GString *name; // font name | 164 | GString *name; // font name |
163 | GfxFontType type; // type of font | 165 | GfxFontType type; // type of font |
164 | int flags; // font descriptor flags | 166 | int flags; // font descriptor flags |
165 | GString *embFontName; // name of embedded font | 167 | GString *embFontName; // name of embedded font |
166 | Ref embFontID; // ref to embedded font file stream | 168 | Ref embFontID; // ref to embedded font file stream |
167 | GString *extFontFile; // external font file name | 169 | GString *extFontFile; // external font file name |
168 | fouble fontMat[6]; // font matrix (Type 3 only) | 170 | fouble fontMat[6]; // font matrix (Type 3 only) |
169 | fouble fontBBox[4]; // font bounding box | 171 | fouble fontBBox[4]; // font bounding box (Type 3 only) |
170 | fouble missingWidth; // "default" width | 172 | fouble missingWidth; // "default" width |
171 | fouble ascent; // max height above baseline | 173 | fouble ascent; // max height above baseline |
172 | fouble descent; // max depth below baseline | 174 | fouble descent; // max depth below baseline |
173 | GBool ok; | 175 | GBool ok; |
174 | }; | 176 | }; |
175 | 177 | ||
@@ -201,24 +203,31 @@ public: | |||
201 | // Returns true if the PDF font specified an encoding. | 203 | // Returns true if the PDF font specified an encoding. |
202 | GBool getHasEncoding() { return hasEncoding; } | 204 | GBool getHasEncoding() { return hasEncoding; } |
203 | 205 | ||
204 | // Get width of a character or string. | 206 | // Get width of a character or string. |
205 | fouble getWidth(Guchar c) { return widths[c]; } | 207 | fouble getWidth(Guchar c) { return widths[c]; } |
206 | 208 | ||
209 | // Return the Type 3 CharProc dictionary, or NULL if none. | ||
210 | Dict *getCharProcs(); | ||
211 | |||
207 | // Return the Type 3 CharProc for the character associated with <code>. | 212 | // Return the Type 3 CharProc for the character associated with <code>. |
208 | Object *getCharProc(int code, Object *proc); | 213 | Object *getCharProc(int code, Object *proc); |
209 | 214 | ||
215 | // Return the Type 3 Resources dictionary, or NULL if none. | ||
216 | Dict *getResources(); | ||
217 | |||
210 | private: | 218 | private: |
211 | 219 | ||
212 | char *enc[256]; // char code --> char name | 220 | char *enc[256]; // char code --> char name |
213 | char encFree[256]; // boolean for each char name: if set, | 221 | char encFree[256]; // boolean for each char name: if set, |
214 | // the string is malloc'ed | 222 | // the string is malloc'ed |
215 | CharCodeToUnicode *ctu;// char code --> Unicode | 223 | CharCodeToUnicode *ctu;// char code --> Unicode |
216 | GBool hasEncoding; | 224 | GBool hasEncoding; |
217 | fouble widths[256]; // character widths | 225 | fouble widths[256]; // character widths |
218 | Object charProcs; // Type3 CharProcs dictionary | 226 | Object charProcs; // Type 3 CharProcs dictionary |
227 | Object resources; // Type 3 Resources dictionary | ||
219 | }; | 228 | }; |
220 | 229 | ||
221 | //------------------------------------------------------------------------ | 230 | //------------------------------------------------------------------------ |
222 | // GfxCIDFont | 231 | // GfxCIDFont |
223 | //------------------------------------------------------------------------ | 232 | //------------------------------------------------------------------------ |
224 | 233 | ||
@@ -233,12 +242,15 @@ public: | |||
233 | virtual GBool isCIDFont() { return gTrue; } | 242 | virtual GBool isCIDFont() { return gTrue; } |
234 | 243 | ||
235 | virtual int getNextChar(char *s, int len, CharCode *code, | 244 | virtual int getNextChar(char *s, int len, CharCode *code, |
236 | Unicode *u, int uSize, int *uLen, | 245 | Unicode *u, int uSize, int *uLen, |
237 | fouble *dx, fouble *dy, fouble *ox, fouble *oy); | 246 | fouble *dx, fouble *dy, fouble *ox, fouble *oy); |
238 | 247 | ||
248 | // Return the writing mode (0=horizontal, 1=vertical). | ||
249 | virtual int getWMode(); | ||
250 | |||
239 | // Return the Unicode map. | 251 | // Return the Unicode map. |
240 | CharCodeToUnicode *getToUnicode(); | 252 | CharCodeToUnicode *getToUnicode(); |
241 | 253 | ||
242 | // Get the collection name (<registry>-<ordering>). | 254 | // Get the collection name (<registry>-<ordering>). |
243 | GString *getCollection(); | 255 | GString *getCollection(); |
244 | 256 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/GfxState.cc b/noncore/unsupported/qpdf/xpdf/GfxState.cc index af4e0d4..befd45a 100644 --- a/noncore/unsupported/qpdf/xpdf/GfxState.cc +++ b/noncore/unsupported/qpdf/xpdf/GfxState.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // GfxState.cc | 3 | // GfxState.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -405,15 +405,28 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) { | |||
405 | - 0.299 * color->c[0] | 405 | - 0.299 * color->c[0] |
406 | - 0.587 * color->c[1] | 406 | - 0.587 * color->c[1] |
407 | - 0.114 * color->c[2]); | 407 | - 0.114 * color->c[2]); |
408 | } | 408 | } |
409 | 409 | ||
410 | void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { | 410 | void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { |
411 | rgb->r = clip01(1 - (color->c[0] + color->c[3])); | 411 | fouble c, m, y, aw, ac, am, ay, ar, ag, ab; |
412 | rgb->g = clip01(1 - (color->c[1] + color->c[3])); | 412 | |
413 | rgb->b = clip01(1 - (color->c[2] + color->c[3])); | 413 | c = clip01(color->c[0] + color->c[3]); |
414 | m = clip01(color->c[1] + color->c[3]); | ||
415 | y = clip01(color->c[2] + color->c[3]); | ||
416 | aw = (1-c) * (1-m) * (1-y); | ||
417 | ac = c * (1-m) * (1-y); | ||
418 | am = (1-c) * m * (1-y); | ||
419 | ay = (1-c) * (1-m) * y; | ||
420 | ar = (1-c) * m * y; | ||
421 | ag = c * (1-m) * y; | ||
422 | ab = c * m * (1-y); | ||
423 | rgb->r = clip01(aw + 0.9137*am + 0.9961*ay + 0.9882*ar); | ||
424 | rgb->g = clip01(aw + 0.6196*ac + ay + 0.5176*ag); | ||
425 | rgb->b = clip01(aw + 0.7804*ac + 0.5412*am + 0.0667*ar + 0.2118*ag + | ||
426 | 0.4863*ab); | ||
414 | } | 427 | } |
415 | 428 | ||
416 | void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { | 429 | void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { |
417 | cmyk->c = clip01(color->c[0]); | 430 | cmyk->c = clip01(color->c[0]); |
418 | cmyk->m = clip01(color->c[1]); | 431 | cmyk->m = clip01(color->c[1]); |
419 | cmyk->y = clip01(color->c[2]); | 432 | cmyk->y = clip01(color->c[2]); |
@@ -1265,16 +1278,12 @@ GfxShading *GfxShading::parse(Object *obj) { | |||
1265 | error(-1, "Invalid ShadingType in shading dictionary"); | 1278 | error(-1, "Invalid ShadingType in shading dictionary"); |
1266 | obj1.free(); | 1279 | obj1.free(); |
1267 | goto err1; | 1280 | goto err1; |
1268 | } | 1281 | } |
1269 | typeA = obj1.getInt(); | 1282 | typeA = obj1.getInt(); |
1270 | obj1.free(); | 1283 | obj1.free(); |
1271 | if (typeA != 2) { | ||
1272 | error(-1, "Unimplemented shading type %d", typeA); | ||
1273 | goto err1; | ||
1274 | } | ||
1275 | 1284 | ||
1276 | obj->dictLookup("ColorSpace", &obj1); | 1285 | obj->dictLookup("ColorSpace", &obj1); |
1277 | if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) { | 1286 | if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) { |
1278 | error(-1, "Bad color space in shading dictionary"); | 1287 | error(-1, "Bad color space in shading dictionary"); |
1279 | obj1.free(); | 1288 | obj1.free(); |
1280 | goto err1; | 1289 | goto err1; |
@@ -1314,13 +1323,23 @@ GfxShading *GfxShading::parse(Object *obj) { | |||
1314 | } else { | 1323 | } else { |
1315 | error(-1, "Bad BBox in shading dictionary"); | 1324 | error(-1, "Bad BBox in shading dictionary"); |
1316 | } | 1325 | } |
1317 | } | 1326 | } |
1318 | obj1.free(); | 1327 | obj1.free(); |
1319 | 1328 | ||
1320 | shading = GfxAxialShading::parse(obj->getDict()); | 1329 | switch (typeA) { |
1330 | case 2: | ||
1331 | shading = GfxAxialShading::parse(obj->getDict()); | ||
1332 | break; | ||
1333 | case 3: | ||
1334 | shading = GfxRadialShading::parse(obj->getDict()); | ||
1335 | break; | ||
1336 | default: | ||
1337 | error(-1, "Unimplemented shading type %d", typeA); | ||
1338 | goto err1; | ||
1339 | } | ||
1321 | 1340 | ||
1322 | if (shading) { | 1341 | if (shading) { |
1323 | shading->type = typeA; | 1342 | shading->type = typeA; |
1324 | shading->colorSpace = colorSpaceA; | 1343 | shading->colorSpace = colorSpaceA; |
1325 | shading->background = backgroundA; | 1344 | shading->background = backgroundA; |
1326 | shading->hasBackground = hasBackgroundA; | 1345 | shading->hasBackground = hasBackgroundA; |
@@ -1454,12 +1473,134 @@ void GfxAxialShading::getColor(fouble t, GfxColor *color) { | |||
1454 | for (i = 0; i < nFuncs; ++i) { | 1473 | for (i = 0; i < nFuncs; ++i) { |
1455 | funcs[i]->transform(&t, &color->c[i]); | 1474 | funcs[i]->transform(&t, &color->c[i]); |
1456 | } | 1475 | } |
1457 | } | 1476 | } |
1458 | 1477 | ||
1459 | //------------------------------------------------------------------------ | 1478 | //------------------------------------------------------------------------ |
1479 | // GfxRadialShading | ||
1480 | //------------------------------------------------------------------------ | ||
1481 | |||
1482 | GfxRadialShading::GfxRadialShading(fouble x0A, fouble y0A, fouble r0A, | ||
1483 | fouble x1A, fouble y1A, fouble r1A, | ||
1484 | fouble t0A, fouble t1A, | ||
1485 | Function **funcsA, int nFuncsA, | ||
1486 | GBool extend0A, GBool extend1A) { | ||
1487 | int i; | ||
1488 | |||
1489 | x0 = x0A; | ||
1490 | y0 = y0A; | ||
1491 | r0 = r0A; | ||
1492 | x1 = x1A; | ||
1493 | y1 = y1A; | ||
1494 | r1 = r1A; | ||
1495 | t0 = t0A; | ||
1496 | t1 = t1A; | ||
1497 | nFuncs = nFuncsA; | ||
1498 | for (i = 0; i < nFuncs; ++i) { | ||
1499 | funcs[i] = funcsA[i]; | ||
1500 | } | ||
1501 | extend0 = extend0A; | ||
1502 | extend1 = extend1A; | ||
1503 | } | ||
1504 | |||
1505 | GfxRadialShading::~GfxRadialShading() { | ||
1506 | int i; | ||
1507 | |||
1508 | for (i = 0; i < nFuncs; ++i) { | ||
1509 | delete funcs[i]; | ||
1510 | } | ||
1511 | } | ||
1512 | |||
1513 | GfxRadialShading *GfxRadialShading::parse(Dict *dict) { | ||
1514 | fouble x0A, y0A, r0A, x1A, y1A, r1A; | ||
1515 | fouble t0A, t1A; | ||
1516 | Function *funcsA[gfxColorMaxComps]; | ||
1517 | int nFuncsA; | ||
1518 | GBool extend0A, extend1A; | ||
1519 | Object obj1, obj2; | ||
1520 | int i; | ||
1521 | |||
1522 | x0A = y0A = r0A = x1A = y1A = r1A = 0; | ||
1523 | if (dict->lookup("Coords", &obj1)->isArray() && | ||
1524 | obj1.arrayGetLength() == 6) { | ||
1525 | x0A = obj1.arrayGet(0, &obj2)->getNum(); | ||
1526 | obj2.free(); | ||
1527 | y0A = obj1.arrayGet(1, &obj2)->getNum(); | ||
1528 | obj2.free(); | ||
1529 | r0A = obj1.arrayGet(2, &obj2)->getNum(); | ||
1530 | obj2.free(); | ||
1531 | x1A = obj1.arrayGet(3, &obj2)->getNum(); | ||
1532 | obj2.free(); | ||
1533 | y1A = obj1.arrayGet(4, &obj2)->getNum(); | ||
1534 | obj2.free(); | ||
1535 | r1A = obj1.arrayGet(5, &obj2)->getNum(); | ||
1536 | obj2.free(); | ||
1537 | } else { | ||
1538 | error(-1, "Missing or invalid Coords in shading dictionary"); | ||
1539 | goto err1; | ||
1540 | } | ||
1541 | obj1.free(); | ||
1542 | |||
1543 | t0A = 0; | ||
1544 | t1A = 1; | ||
1545 | if (dict->lookup("Domain", &obj1)->isArray() && | ||
1546 | obj1.arrayGetLength() == 2) { | ||
1547 | t0A = obj1.arrayGet(0, &obj2)->getNum(); | ||
1548 | obj2.free(); | ||
1549 | t1A = obj1.arrayGet(1, &obj2)->getNum(); | ||
1550 | obj2.free(); | ||
1551 | } | ||
1552 | obj1.free(); | ||
1553 | |||
1554 | dict->lookup("Function", &obj1); | ||
1555 | if (obj1.isArray()) { | ||
1556 | nFuncsA = obj1.arrayGetLength(); | ||
1557 | for (i = 0; i < nFuncsA; ++i) { | ||
1558 | obj1.arrayGet(i, &obj2); | ||
1559 | if (!(funcsA[i] = Function::parse(&obj2))) { | ||
1560 | obj1.free(); | ||
1561 | obj2.free(); | ||
1562 | goto err1; | ||
1563 | } | ||
1564 | obj2.free(); | ||
1565 | } | ||
1566 | } else { | ||
1567 | nFuncsA = 1; | ||
1568 | if (!(funcsA[0] = Function::parse(&obj1))) { | ||
1569 | obj1.free(); | ||
1570 | goto err1; | ||
1571 | } | ||
1572 | } | ||
1573 | obj1.free(); | ||
1574 | |||
1575 | extend0A = extend1A = gFalse; | ||
1576 | if (dict->lookup("Extend", &obj1)->isArray() && | ||
1577 | obj1.arrayGetLength() == 2) { | ||
1578 | extend0A = obj1.arrayGet(0, &obj2)->getBool(); | ||
1579 | obj2.free(); | ||
1580 | extend1A = obj1.arrayGet(1, &obj2)->getBool(); | ||
1581 | obj2.free(); | ||
1582 | } | ||
1583 | obj1.free(); | ||
1584 | |||
1585 | return new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A, | ||
1586 | funcsA, nFuncsA, extend0A, extend1A); | ||
1587 | |||
1588 | err1: | ||
1589 | return NULL; | ||
1590 | } | ||
1591 | |||
1592 | void GfxRadialShading::getColor(fouble t, GfxColor *color) { | ||
1593 | int i; | ||
1594 | |||
1595 | for (i = 0; i < nFuncs; ++i) { | ||
1596 | funcs[i]->transform(&t, &color->c[i]); | ||
1597 | } | ||
1598 | } | ||
1599 | |||
1600 | //------------------------------------------------------------------------ | ||
1460 | // GfxImageColorMap | 1601 | // GfxImageColorMap |
1461 | //------------------------------------------------------------------------ | 1602 | //------------------------------------------------------------------------ |
1462 | 1603 | ||
1463 | GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, | 1604 | GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, |
1464 | GfxColorSpace *colorSpaceA) { | 1605 | GfxColorSpace *colorSpaceA) { |
1465 | GfxIndexedColorSpace *indexedCS; | 1606 | GfxIndexedColorSpace *indexedCS; |
@@ -1915,12 +2056,73 @@ GfxState::GfxState(GfxState *state) { | |||
1915 | lineDash = (fouble *)gmalloc(lineDashLength * sizeof(fouble)); | 2056 | lineDash = (fouble *)gmalloc(lineDashLength * sizeof(fouble)); |
1916 | memcpy(lineDash, state->lineDash, lineDashLength * sizeof(fouble)); | 2057 | memcpy(lineDash, state->lineDash, lineDashLength * sizeof(fouble)); |
1917 | } | 2058 | } |
1918 | saved = NULL; | 2059 | saved = NULL; |
1919 | } | 2060 | } |
1920 | 2061 | ||
2062 | void GfxState::getUserClipBBox(fouble *xMin, fouble *yMin, | ||
2063 | fouble *xMax, fouble *yMax) { | ||
2064 | fouble ictm[6]; | ||
2065 | fouble xMin1, yMin1, xMax1, yMax1, det, tx, ty; | ||
2066 | |||
2067 | // invert the CTM | ||
2068 | det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); | ||
2069 | ictm[0] = ctm[3] * det; | ||
2070 | ictm[1] = -ctm[1] * det; | ||
2071 | ictm[2] = -ctm[2] * det; | ||
2072 | ictm[3] = ctm[0] * det; | ||
2073 | ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; | ||
2074 | ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; | ||
2075 | |||
2076 | // transform all four corners of the clip bbox; find the min and max | ||
2077 | // x and y values | ||
2078 | xMin1 = xMax1 = clipXMin * ictm[0] + clipYMin * ictm[2] + ictm[4]; | ||
2079 | yMin1 = yMax1 = clipXMin * ictm[1] + clipYMin * ictm[3] + ictm[5]; | ||
2080 | tx = clipXMin * ictm[0] + clipYMax * ictm[2] + ictm[4]; | ||
2081 | ty = clipXMin * ictm[1] + clipYMax * ictm[3] + ictm[5]; | ||
2082 | if (tx < xMin1) { | ||
2083 | xMin1 = tx; | ||
2084 | } else if (tx > xMax1) { | ||
2085 | xMax1 = tx; | ||
2086 | } | ||
2087 | if (ty < yMin1) { | ||
2088 | yMin1 = ty; | ||
2089 | } else if (ty > yMax1) { | ||
2090 | yMax1 = ty; | ||
2091 | } | ||
2092 | tx = clipXMax * ictm[0] + clipYMin * ictm[2] + ictm[4]; | ||
2093 | ty = clipXMax * ictm[1] + clipYMin * ictm[3] + ictm[5]; | ||
2094 | if (tx < xMin1) { | ||
2095 | xMin1 = tx; | ||
2096 | } else if (tx > xMax1) { | ||
2097 | xMax1 = tx; | ||
2098 | } | ||
2099 | if (ty < yMin1) { | ||
2100 | yMin1 = ty; | ||
2101 | } else if (ty > yMax1) { | ||
2102 | yMax1 = ty; | ||
2103 | } | ||
2104 | tx = clipXMax * ictm[0] + clipYMax * ictm[2] + ictm[4]; | ||
2105 | ty = clipXMax * ictm[1] + clipYMax * ictm[3] + ictm[5]; | ||
2106 | if (tx < xMin1) { | ||
2107 | xMin1 = tx; | ||
2108 | } else if (tx > xMax1) { | ||
2109 | xMax1 = tx; | ||
2110 | } | ||
2111 | if (ty < yMin1) { | ||
2112 | yMin1 = ty; | ||
2113 | } else if (ty > yMax1) { | ||
2114 | yMax1 = ty; | ||
2115 | } | ||
2116 | |||
2117 | *xMin = xMin1; | ||
2118 | *yMin = yMin1; | ||
2119 | *xMax = xMax1; | ||
2120 | *yMax = yMax1; | ||
2121 | } | ||
2122 | |||
1921 | fouble GfxState::transformWidth(fouble w) { | 2123 | fouble GfxState::transformWidth(fouble w) { |
1922 | fouble x, y; | 2124 | fouble x, y; |
1923 | 2125 | ||
1924 | x = ctm[0] + ctm[2]; | 2126 | x = ctm[0] + ctm[2]; |
1925 | y = ctm[1] + ctm[3]; | 2127 | y = ctm[1] + ctm[3]; |
1926 | return w * sqrt(0.5 * (x * x + y * y)); | 2128 | return w * sqrt(0.5 * (x * x + y * y)); |
@@ -1943,33 +2145,54 @@ void GfxState::getFontTransMat(fouble *m11, fouble *m12, | |||
1943 | *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize; | 2145 | *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize; |
1944 | *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize; | 2146 | *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize; |
1945 | } | 2147 | } |
1946 | 2148 | ||
1947 | void GfxState::setCTM(fouble a, fouble b, fouble c, | 2149 | void GfxState::setCTM(fouble a, fouble b, fouble c, |
1948 | fouble d, fouble e, fouble f) { | 2150 | fouble d, fouble e, fouble f) { |
2151 | int i; | ||
2152 | |||
1949 | ctm[0] = a; | 2153 | ctm[0] = a; |
1950 | ctm[1] = b; | 2154 | ctm[1] = b; |
1951 | ctm[2] = c; | 2155 | ctm[2] = c; |
1952 | ctm[3] = d; | 2156 | ctm[3] = d; |
1953 | ctm[4] = e; | 2157 | ctm[4] = e; |
1954 | ctm[5] = f; | 2158 | ctm[5] = f; |
2159 | |||
2160 | // avoid FP exceptions on badly messed up PDF files | ||
2161 | for (i = 0; i < 6; ++i) { | ||
2162 | if (ctm[i] > fouble(1e3)) { | ||
2163 | ctm[i] = fouble(1e3); | ||
2164 | } else if (ctm[i] < -fouble(1e3)) { | ||
2165 | ctm[i] = -fouble(1e3); | ||
2166 | } | ||
2167 | } | ||
1955 | } | 2168 | } |
1956 | 2169 | ||
1957 | void GfxState::concatCTM(fouble a, fouble b, fouble c, | 2170 | void GfxState::concatCTM(fouble a, fouble b, fouble c, |
1958 | fouble d, fouble e, fouble f) { | 2171 | fouble d, fouble e, fouble f) { |
1959 | fouble a1 = ctm[0]; | 2172 | fouble a1 = ctm[0]; |
1960 | fouble b1 = ctm[1]; | 2173 | fouble b1 = ctm[1]; |
1961 | fouble c1 = ctm[2]; | 2174 | fouble c1 = ctm[2]; |
1962 | fouble d1 = ctm[3]; | 2175 | fouble d1 = ctm[3]; |
2176 | int i; | ||
1963 | 2177 | ||
1964 | ctm[0] = a * a1 + b * c1; | 2178 | ctm[0] = a * a1 + b * c1; |
1965 | ctm[1] = a * b1 + b * d1; | 2179 | ctm[1] = a * b1 + b * d1; |
1966 | ctm[2] = c * a1 + d * c1; | 2180 | ctm[2] = c * a1 + d * c1; |
1967 | ctm[3] = c * b1 + d * d1; | 2181 | ctm[3] = c * b1 + d * d1; |
1968 | ctm[4] = e * a1 + f * c1 + ctm[4]; | 2182 | ctm[4] = e * a1 + f * c1 + ctm[4]; |
1969 | ctm[5] = e * b1 + f * d1 + ctm[5]; | 2183 | ctm[5] = e * b1 + f * d1 + ctm[5]; |
2184 | |||
2185 | // avoid FP exceptions on badly messed up PDF files | ||
2186 | for (i = 0; i < 6; ++i) { | ||
2187 | if (ctm[i] > fouble(1e3)) { | ||
2188 | ctm[i] = fouble(1e3); | ||
2189 | } else if (ctm[i] < -fouble(1e3)) { | ||
2190 | ctm[i] = -fouble(1e3); | ||
2191 | } | ||
2192 | } | ||
1970 | } | 2193 | } |
1971 | 2194 | ||
1972 | void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { | 2195 | void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { |
1973 | if (fillColorSpace) { | 2196 | if (fillColorSpace) { |
1974 | delete fillColorSpace; | 2197 | delete fillColorSpace; |
1975 | } | 2198 | } |
@@ -2048,16 +2271,16 @@ void GfxState::clip() { | |||
2048 | } | 2271 | } |
2049 | if (yMax < clipYMax) { | 2272 | if (yMax < clipYMax) { |
2050 | clipYMax = yMax; | 2273 | clipYMax = yMax; |
2051 | } | 2274 | } |
2052 | } | 2275 | } |
2053 | 2276 | ||
2054 | void GfxState::textShift(fouble tx) { | 2277 | void GfxState::textShift(fouble tx, fouble ty) { |
2055 | fouble dx, dy; | 2278 | fouble dx, dy; |
2056 | 2279 | ||
2057 | textTransformDelta(tx, 0, &dx, &dy); | 2280 | textTransformDelta(tx, ty, &dx, &dy); |
2058 | curX += dx; | 2281 | curX += dx; |
2059 | curY += dy; | 2282 | curY += dy; |
2060 | } | 2283 | } |
2061 | 2284 | ||
2062 | void GfxState::shift(fouble dx, fouble dy) { | 2285 | void GfxState::shift(fouble dx, fouble dy) { |
2063 | curX += dx; | 2286 | curX += dx; |
@@ -2092,6 +2315,7 @@ GfxState *GfxState::restore() { | |||
2092 | } else { | 2315 | } else { |
2093 | oldState = this; | 2316 | oldState = this; |
2094 | } | 2317 | } |
2095 | 2318 | ||
2096 | return oldState; | 2319 | return oldState; |
2097 | } | 2320 | } |
2321 | |||
diff --git a/noncore/unsupported/qpdf/xpdf/GfxState.h b/noncore/unsupported/qpdf/xpdf/GfxState.h index 7fe16ea..328f9a8 100644 --- a/noncore/unsupported/qpdf/xpdf/GfxState.h +++ b/noncore/unsupported/qpdf/xpdf/GfxState.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // GfxState.h | 3 | // GfxState.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef GFXSTATE_H | 9 | #ifndef GFXSTATE_H |
10 | #define GFXSTATE_H | 10 | #define GFXSTATE_H |
11 | 11 | ||
@@ -565,12 +565,46 @@ private: | |||
565 | Function *funcs[gfxColorMaxComps]; | 565 | Function *funcs[gfxColorMaxComps]; |
566 | int nFuncs; | 566 | int nFuncs; |
567 | GBool extend0, extend1; | 567 | GBool extend0, extend1; |
568 | }; | 568 | }; |
569 | 569 | ||
570 | //------------------------------------------------------------------------ | 570 | //------------------------------------------------------------------------ |
571 | // GfxRadialShading | ||
572 | //------------------------------------------------------------------------ | ||
573 | |||
574 | class GfxRadialShading: public GfxShading { | ||
575 | public: | ||
576 | |||
577 | GfxRadialShading(fouble x0A, fouble y0A, fouble r0A, | ||
578 | fouble x1A, fouble y1A, fouble r1A, | ||
579 | fouble t0A, fouble t1A, | ||
580 | Function **funcsA, int nFuncsA, | ||
581 | GBool extend0A, GBool extend1A); | ||
582 | virtual ~GfxRadialShading(); | ||
583 | |||
584 | static GfxRadialShading *parse(Dict *dict); | ||
585 | |||
586 | void getCoords(fouble *x0A, fouble *y0A, fouble *r0A, | ||
587 | fouble *x1A, fouble *y1A, fouble *r1A) | ||
588 | { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; } | ||
589 | fouble getDomain0() { return t0; } | ||
590 | fouble getDomain1() { return t1; } | ||
591 | void getColor(fouble t, GfxColor *color); | ||
592 | GBool getExtend0() { return extend0; } | ||
593 | GBool getExtend1() { return extend1; } | ||
594 | |||
595 | private: | ||
596 | |||
597 | fouble x0, y0, r0, x1, y1, r1; | ||
598 | fouble t0, t1; | ||
599 | Function *funcs[gfxColorMaxComps]; | ||
600 | int nFuncs; | ||
601 | GBool extend0, extend1; | ||
602 | }; | ||
603 | |||
604 | //------------------------------------------------------------------------ | ||
571 | // GfxImageColorMap | 605 | // GfxImageColorMap |
572 | //------------------------------------------------------------------------ | 606 | //------------------------------------------------------------------------ |
573 | 607 | ||
574 | class GfxImageColorMap { | 608 | class GfxImageColorMap { |
575 | public: | 609 | public: |
576 | 610 | ||
@@ -780,12 +814,13 @@ public: | |||
780 | int getRender() { return render; } | 814 | int getRender() { return render; } |
781 | GfxPath *getPath() { return path; } | 815 | GfxPath *getPath() { return path; } |
782 | fouble getCurX() { return curX; } | 816 | fouble getCurX() { return curX; } |
783 | fouble getCurY() { return curY; } | 817 | fouble getCurY() { return curY; } |
784 | void getClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax) | 818 | void getClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax) |
785 | { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; } | 819 | { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; } |
820 | void getUserClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax); | ||
786 | fouble getLineX() { return lineX; } | 821 | fouble getLineX() { return lineX; } |
787 | fouble getLineY() { return lineY; } | 822 | fouble getLineY() { return lineY; } |
788 | 823 | ||
789 | // Is there a current point/path? | 824 | // Is there a current point/path? |
790 | GBool isCurPt() { return path->isCurPt(); } | 825 | GBool isCurPt() { return path->isCurPt(); } |
791 | GBool isPath() { return path->isPath(); } | 826 | GBool isPath() { return path->isPath(); } |
@@ -862,13 +897,13 @@ public: | |||
862 | // Update clip region. | 897 | // Update clip region. |
863 | void clip(); | 898 | void clip(); |
864 | 899 | ||
865 | // Text position. | 900 | // Text position. |
866 | void textMoveTo(fouble tx, fouble ty) | 901 | void textMoveTo(fouble tx, fouble ty) |
867 | { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); } | 902 | { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); } |
868 | void textShift(fouble tx); | 903 | void textShift(fouble tx, fouble ty); |
869 | void shift(fouble dx, fouble dy); | 904 | void shift(fouble dx, fouble dy); |
870 | 905 | ||
871 | // Push/pop GfxState on/off stack. | 906 | // Push/pop GfxState on/off stack. |
872 | GfxState *save(); | 907 | GfxState *save(); |
873 | GfxState *restore(); | 908 | GfxState *restore(); |
874 | GBool hasSaves() { return saved != NULL; } | 909 | GBool hasSaves() { return saved != NULL; } |
diff --git a/noncore/unsupported/qpdf/xpdf/GlobalParams.cc b/noncore/unsupported/qpdf/xpdf/GlobalParams.cc index 8be58a3..0bc908e 100644 --- a/noncore/unsupported/qpdf/xpdf/GlobalParams.cc +++ b/noncore/unsupported/qpdf/xpdf/GlobalParams.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // GlobalParams.cc | 3 | // GlobalParams.cc |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -93,42 +93,45 @@ DisplayFontParam::~DisplayFontParam() { | |||
93 | } | 93 | } |
94 | 94 | ||
95 | //------------------------------------------------------------------------ | 95 | //------------------------------------------------------------------------ |
96 | // PSFontParam | 96 | // PSFontParam |
97 | //------------------------------------------------------------------------ | 97 | //------------------------------------------------------------------------ |
98 | 98 | ||
99 | PSFontParam::PSFontParam(GString *pdfFontNameA, GString *psFontNameA) { | 99 | PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA, |
100 | GString *psFontNameA, GString *encodingA) { | ||
100 | pdfFontName = pdfFontNameA; | 101 | pdfFontName = pdfFontNameA; |
102 | wMode = wModeA; | ||
101 | psFontName = psFontNameA; | 103 | psFontName = psFontNameA; |
104 | encoding = encodingA; | ||
102 | } | 105 | } |
103 | 106 | ||
104 | PSFontParam::~PSFontParam() { | 107 | PSFontParam::~PSFontParam() { |
105 | delete pdfFontName; | 108 | delete pdfFontName; |
106 | delete psFontName; | 109 | delete psFontName; |
110 | if (encoding) { | ||
111 | delete encoding; | ||
112 | } | ||
107 | } | 113 | } |
108 | 114 | ||
109 | //------------------------------------------------------------------------ | 115 | //------------------------------------------------------------------------ |
110 | // parsing | 116 | // parsing |
111 | //------------------------------------------------------------------------ | 117 | //------------------------------------------------------------------------ |
112 | 118 | ||
113 | GlobalParams::GlobalParams(char *cfgFileName) { | 119 | GlobalParams::GlobalParams(char *cfgFileName) { |
114 | UnicodeMap *map; | 120 | UnicodeMap *map; |
115 | DisplayFontParam *dfp; | 121 | DisplayFontParam *dfp; |
116 | GString *fileName; | 122 | GString *fileName; |
117 | FILE *f; | 123 | FILE *f; |
118 | char buf[512]; | ||
119 | int line; | ||
120 | GList *tokens; | ||
121 | GString *cmd; | ||
122 | char *p1, *p2; | ||
123 | int i; | 124 | int i; |
124 | 125 | ||
125 | initBuiltinFontTables(); | 126 | initBuiltinFontTables(); |
126 | 127 | ||
128 | // scan the encoding in reverse because we want the lowest-numbered | ||
129 | // index for each char name ('space' is encoded twice) | ||
127 | macRomanReverseMap = new NameToCharCode(); | 130 | macRomanReverseMap = new NameToCharCode(); |
128 | for (i = 0; i < 256; ++i) { | 131 | for (i = 255; i >= 0; --i) { |
129 | if (macRomanEncoding[i]) { | 132 | if (macRomanEncoding[i]) { |
130 | macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i); | 133 | macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i); |
131 | } | 134 | } |
132 | } | 135 | } |
133 | 136 | ||
134 | nameToUnicode = new NameToCharCode(); | 137 | nameToUnicode = new NameToCharCode(); |
@@ -136,12 +139,13 @@ GlobalParams::GlobalParams(char *cfgFileName) { | |||
136 | residentUnicodeMaps = new GHash(); | 139 | residentUnicodeMaps = new GHash(); |
137 | unicodeMaps = new GHash(gTrue); | 140 | unicodeMaps = new GHash(gTrue); |
138 | cMapDirs = new GHash(gTrue); | 141 | cMapDirs = new GHash(gTrue); |
139 | toUnicodeDirs = new GList(); | 142 | toUnicodeDirs = new GList(); |
140 | displayFonts = new GHash(); | 143 | displayFonts = new GHash(); |
141 | displayCIDFonts = new GHash(); | 144 | displayCIDFonts = new GHash(); |
145 | displayNamedCIDFonts = new GHash(); | ||
142 | #if HAVE_PAPER_H | 146 | #if HAVE_PAPER_H |
143 | const struct paper *paperType; | 147 | const struct paper *paperType; |
144 | paperinit(); | 148 | paperinit(); |
145 | paperType = paperinfo(systempapername()); | 149 | paperType = paperinfo(systempapername()); |
146 | psPaperWidth = (int)paperpswidth(paperType); | 150 | psPaperWidth = (int)paperpswidth(paperType); |
147 | psPaperHeight = (int)paperpsheight(paperType); | 151 | psPaperHeight = (int)paperpsheight(paperType); |
@@ -151,24 +155,30 @@ GlobalParams::GlobalParams(char *cfgFileName) { | |||
151 | psPaperHeight = defPaperHeight; | 155 | psPaperHeight = defPaperHeight; |
152 | #endif | 156 | #endif |
153 | psDuplex = gFalse; | 157 | psDuplex = gFalse; |
154 | psLevel = psLevel2; | 158 | psLevel = psLevel2; |
155 | psFile = NULL; | 159 | psFile = NULL; |
156 | psFonts = new GHash(); | 160 | psFonts = new GHash(); |
161 | psNamedFonts16 = new GList(); | ||
162 | psFonts16 = new GList(); | ||
157 | psEmbedType1 = gTrue; | 163 | psEmbedType1 = gTrue; |
158 | psEmbedTrueType = gTrue; | 164 | psEmbedTrueType = gTrue; |
165 | psEmbedCIDPostScript = gTrue; | ||
166 | psEmbedCIDTrueType = gTrue; | ||
159 | psOPI = gFalse; | 167 | psOPI = gFalse; |
168 | psASCIIHex = gFalse; | ||
160 | textEncoding = new GString("Latin1"); | 169 | textEncoding = new GString("Latin1"); |
161 | #if defined(WIN32) | 170 | #if defined(WIN32) |
162 | textEOL = eolDOS; | 171 | textEOL = eolDOS; |
163 | #elif defined(MACOS) | 172 | #elif defined(MACOS) |
164 | textEOL = eolMac; | 173 | textEOL = eolMac; |
165 | #else | 174 | #else |
166 | textEOL = eolUnix; | 175 | textEOL = eolUnix; |
167 | #endif | 176 | #endif |
168 | fontDirs = new GList(); | 177 | fontDirs = new GList(); |
178 | initialZoom = new GString("1"); | ||
169 | t1libControl = fontRastAALow; | 179 | t1libControl = fontRastAALow; |
170 | freetypeControl = fontRastAALow; | 180 | freetypeControl = fontRastAALow; |
171 | urlCommand = NULL; | 181 | urlCommand = NULL; |
172 | mapNumericCharNames = gTrue; | 182 | mapNumericCharNames = gTrue; |
173 | errQuiet = gFalse; | 183 | errQuiet = gFalse; |
174 | 184 | ||
@@ -190,12 +200,14 @@ GlobalParams::GlobalParams(char *cfgFileName) { | |||
190 | residentUnicodeMaps->add(map->getEncodingName(), map); | 200 | residentUnicodeMaps->add(map->getEncodingName(), map); |
191 | map = new UnicodeMap("ZapfDingbats", zapfDingbatsUnicodeMapRanges, | 201 | map = new UnicodeMap("ZapfDingbats", zapfDingbatsUnicodeMapRanges, |
192 | zapfDingbatsUnicodeMapLen); | 202 | zapfDingbatsUnicodeMapLen); |
193 | residentUnicodeMaps->add(map->getEncodingName(), map); | 203 | residentUnicodeMaps->add(map->getEncodingName(), map); |
194 | map = new UnicodeMap("UTF-8", &mapUTF8); | 204 | map = new UnicodeMap("UTF-8", &mapUTF8); |
195 | residentUnicodeMaps->add(map->getEncodingName(), map); | 205 | residentUnicodeMaps->add(map->getEncodingName(), map); |
206 | map = new UnicodeMap("UCS-2", &mapUCS2); | ||
207 | residentUnicodeMaps->add(map->getEncodingName(), map); | ||
196 | 208 | ||
197 | // default displayFonts table | 209 | // default displayFonts table |
198 | for (i = 0; displayFontTab[i].name; ++i) { | 210 | for (i = 0; displayFontTab[i].name; ++i) { |
199 | dfp = new DisplayFontParam(displayFontTab[i].name, | 211 | dfp = new DisplayFontParam(displayFontTab[i].name, |
200 | displayFontTab[i].xlfd, | 212 | displayFontTab[i].xlfd, |
201 | displayFontTab[i].encoding); | 213 | displayFontTab[i].encoding); |
@@ -216,12 +228,13 @@ GlobalParams::GlobalParams(char *cfgFileName) { | |||
216 | if (!(f = fopen(fileName->getCString(), "r"))) { | 228 | if (!(f = fopen(fileName->getCString(), "r"))) { |
217 | delete fileName; | 229 | delete fileName; |
218 | } | 230 | } |
219 | } | 231 | } |
220 | if (!f) { | 232 | if (!f) { |
221 | #if defined(WIN32) && !defined(__CYGWIN32__) | 233 | #if defined(WIN32) && !defined(__CYGWIN32__) |
234 | char buf[512]; | ||
222 | i = GetModuleFileName(NULL, buf, sizeof(buf)); | 235 | i = GetModuleFileName(NULL, buf, sizeof(buf)); |
223 | if (i <= 0 || i >= sizeof(buf)) { | 236 | if (i <= 0 || i >= sizeof(buf)) { |
224 | // error or path too long for buffer - just use the current dir | 237 | // error or path too long for buffer - just use the current dir |
225 | buf[i] = '\0'; | 238 | buf[i] = '\0'; |
226 | } | 239 | } |
227 | fileName = grabPath(buf); | 240 | fileName = grabPath(buf); |
@@ -231,104 +244,147 @@ GlobalParams::GlobalParams(char *cfgFileName) { | |||
231 | #endif | 244 | #endif |
232 | if (!(f = fopen(fileName->getCString(), "r"))) { | 245 | if (!(f = fopen(fileName->getCString(), "r"))) { |
233 | delete fileName; | 246 | delete fileName; |
234 | } | 247 | } |
235 | } | 248 | } |
236 | if (f) { | 249 | if (f) { |
237 | line = 1; | 250 | parseFile(fileName, f); |
238 | while (fgets(buf, sizeof(buf) - 1, f)) { | 251 | delete fileName; |
239 | 252 | } | |
240 | // break the line into tokens | 253 | } |
241 | tokens = new GList(); | 254 | |
242 | p1 = buf; | 255 | void GlobalParams::parseFile(GString *fileName, FILE *f) { |
243 | while (*p1) { | 256 | int line; |
244 | for (; *p1 && isspace(*p1); ++p1) ; | 257 | GList *tokens; |
245 | if (!*p1) { | 258 | GString *cmd, *incFile; |
246 | break; | 259 | char *p1, *p2; |
247 | } | 260 | char buf[512]; |
248 | if (*p1 == '"' || *p1 == '\'') { | 261 | FILE *f2; |
249 | for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ; | 262 | |
250 | ++p1; | 263 | line = 1; |
251 | } else { | 264 | while (fgets(buf, sizeof(buf) - 1, f)) { |
252 | for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ; | 265 | |
253 | } | 266 | // break the line into tokens |
254 | tokens->append(new GString(p1, p2 - p1)); | 267 | tokens = new GList(); |
255 | p1 = p2 + 1; | 268 | p1 = buf; |
269 | while (*p1) { | ||
270 | for (; *p1 && isspace(*p1); ++p1) ; | ||
271 | if (!*p1) { | ||
272 | break; | ||
273 | } | ||
274 | if (*p1 == '"' || *p1 == '\'') { | ||
275 | for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ; | ||
276 | ++p1; | ||
277 | } else { | ||
278 | for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ; | ||
256 | } | 279 | } |
280 | tokens->append(new GString(p1, p2 - p1)); | ||
281 | p1 = p2 + 1; | ||
282 | } | ||
257 | 283 | ||
258 | if (tokens->getLength() > 0 && | 284 | if (tokens->getLength() > 0 && |
259 | ((GString *)tokens->get(0))->getChar(0) != '#') { | 285 | ((GString *)tokens->get(0))->getChar(0) != '#') { |
260 | cmd = (GString *)tokens->get(0); | 286 | cmd = (GString *)tokens->get(0); |
261 | if (!cmd->cmp("nameToUnicode")) { | 287 | if (!cmd->cmp("include")) { |
262 | parseNameToUnicode(tokens, fileName, line); | 288 | if (tokens->getLength() == 2) { |
263 | } else if (!cmd->cmp("cidToUnicode")) { | 289 | incFile = (GString *)tokens->get(1); |
264 | parseCIDToUnicode(tokens, fileName, line); | 290 | if ((f2 = fopen(incFile->getCString(), "r"))) { |
265 | } else if (!cmd->cmp("unicodeMap")) { | 291 | parseFile(incFile, f2); |
266 | parseUnicodeMap(tokens, fileName, line); | 292 | fclose(f2); |
267 | } else if (!cmd->cmp("cMapDir")) { | 293 | } else { |
268 | parseCMapDir(tokens, fileName, line); | 294 | error(-1, "Couldn't find included config file: '%s' (%s:%d)", |
269 | } else if (!cmd->cmp("toUnicodeDir")) { | 295 | incFile->getCString(), fileName->getCString(), line); |
270 | parseToUnicodeDir(tokens, fileName, line); | 296 | } |
271 | } else if (!cmd->cmp("displayFontX")) { | ||
272 | parseDisplayFont(tokens, gFalse, displayFontX, fileName, line); | ||
273 | } else if (!cmd->cmp("displayFontT1")) { | ||
274 | parseDisplayFont(tokens, gFalse, displayFontT1, fileName, line); | ||
275 | } else if (!cmd->cmp("displayFontTT")) { | ||
276 | parseDisplayFont(tokens, gFalse, displayFontTT, fileName, line); | ||
277 | } else if (!cmd->cmp("displayCIDFontX")) { | ||
278 | parseDisplayFont(tokens, gTrue, displayFontX, fileName, line); | ||
279 | } else if (!cmd->cmp("psFile")) { | ||
280 | parsePSFile(tokens, fileName, line); | ||
281 | } else if (!cmd->cmp("psFont")) { | ||
282 | parsePSFont(tokens, fileName, line); | ||
283 | } else if (!cmd->cmp("psPaperSize")) { | ||
284 | parsePSPaperSize(tokens, fileName, line); | ||
285 | } else if (!cmd->cmp("psDuplex")) { | ||
286 | parseYesNo("psDuplex", &psDuplex, tokens, fileName, line); | ||
287 | } else if (!cmd->cmp("psLevel")) { | ||
288 | parsePSLevel(tokens, fileName, line); | ||
289 | } else if (!cmd->cmp("psEmbedType1")) { | ||
290 | parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line); | ||
291 | } else if (!cmd->cmp("psEmbedTrueType")) { | ||
292 | parseYesNo("psEmbedTrueType", &psEmbedTrueType, | ||
293 | tokens, fileName, line); | ||
294 | } else if (!cmd->cmp("psOPI")) { | ||
295 | parseYesNo("psOPI", &psOPI, tokens, fileName, line); | ||
296 | } else if (!cmd->cmp("textEncoding")) { | ||
297 | parseTextEncoding(tokens, fileName, line); | ||
298 | } else if (!cmd->cmp("textEOL")) { | ||
299 | parseTextEOL(tokens, fileName, line); | ||
300 | } else if (!cmd->cmp("fontDir")) { | ||
301 | parseFontDir(tokens, fileName, line); | ||
302 | } else if (!cmd->cmp("t1libControl")) { | ||
303 | parseFontRastControl("t1libControl", &t1libControl, | ||
304 | tokens, fileName, line); | ||
305 | } else if (!cmd->cmp("freetypeControl")) { | ||
306 | parseFontRastControl("freetypeControl", &freetypeControl, | ||
307 | tokens, fileName, line); | ||
308 | } else if (!cmd->cmp("urlCommand")) { | ||
309 | parseURLCommand(tokens, fileName, line); | ||
310 | } else if (!cmd->cmp("mapNumericCharNames")) { | ||
311 | parseYesNo("mapNumericCharNames", &mapNumericCharNames, | ||
312 | tokens, fileName, line); | ||
313 | } else if (!cmd->cmp("errQuiet")) { | ||
314 | parseYesNo("errQuiet", &errQuiet, tokens, fileName, line); | ||
315 | } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) { | ||
316 | error(-1, "Unknown config file command"); | ||
317 | error(-1, "-- the config file format has changed since Xpdf 0.9x"); | ||
318 | } else { | 297 | } else { |
319 | error(-1, "Unknown config file command '%s' (%s:%d)", | 298 | error(-1, "Bad 'include' config file command (%s:%d)", |
320 | cmd->getCString(), fileName->getCString(), line); | 299 | fileName->getCString(), line); |
321 | } | 300 | } |
301 | } else if (!cmd->cmp("nameToUnicode")) { | ||
302 | parseNameToUnicode(tokens, fileName, line); | ||
303 | } else if (!cmd->cmp("cidToUnicode")) { | ||
304 | parseCIDToUnicode(tokens, fileName, line); | ||
305 | } else if (!cmd->cmp("unicodeMap")) { | ||
306 | parseUnicodeMap(tokens, fileName, line); | ||
307 | } else if (!cmd->cmp("cMapDir")) { | ||
308 | parseCMapDir(tokens, fileName, line); | ||
309 | } else if (!cmd->cmp("toUnicodeDir")) { | ||
310 | parseToUnicodeDir(tokens, fileName, line); | ||
311 | } else if (!cmd->cmp("displayFontX")) { | ||
312 | parseDisplayFont(tokens, displayFonts, displayFontX, fileName, line); | ||
313 | } else if (!cmd->cmp("displayFontT1")) { | ||
314 | parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line); | ||
315 | } else if (!cmd->cmp("displayFontTT")) { | ||
316 | parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line); | ||
317 | } else if (!cmd->cmp("displayCIDFontX")) { | ||
318 | parseDisplayFont(tokens, displayCIDFonts, | ||
319 | displayFontX, fileName, line); | ||
320 | } else if (!cmd->cmp("displayNamedCIDFontX")) { | ||
321 | parseDisplayFont(tokens, displayNamedCIDFonts, | ||
322 | displayFontX, fileName, line); | ||
323 | } else if (!cmd->cmp("psFile")) { | ||
324 | parsePSFile(tokens, fileName, line); | ||
325 | } else if (!cmd->cmp("psFont")) { | ||
326 | parsePSFont(tokens, fileName, line); | ||
327 | } else if (!cmd->cmp("psNamedFont16")) { | ||
328 | parsePSFont16("psNamedFont16", psNamedFonts16, | ||
329 | tokens, fileName, line); | ||
330 | } else if (!cmd->cmp("psFont16")) { | ||
331 | parsePSFont16("psFont16", psFonts16, tokens, fileName, line); | ||
332 | } else if (!cmd->cmp("psPaperSize")) { | ||
333 | parsePSPaperSize(tokens, fileName, line); | ||
334 | } else if (!cmd->cmp("psDuplex")) { | ||
335 | parseYesNo("psDuplex", &psDuplex, tokens, fileName, line); | ||
336 | } else if (!cmd->cmp("psLevel")) { | ||
337 | parsePSLevel(tokens, fileName, line); | ||
338 | } else if (!cmd->cmp("psEmbedType1Fonts")) { | ||
339 | parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line); | ||
340 | } else if (!cmd->cmp("psEmbedTrueTypeFonts")) { | ||
341 | parseYesNo("psEmbedTrueType", &psEmbedTrueType, | ||
342 | tokens, fileName, line); | ||
343 | } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) { | ||
344 | parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript, | ||
345 | tokens, fileName, line); | ||
346 | } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) { | ||
347 | parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType, | ||
348 | tokens, fileName, line); | ||
349 | } else if (!cmd->cmp("psOPI")) { | ||
350 | parseYesNo("psOPI", &psOPI, tokens, fileName, line); | ||
351 | } else if (!cmd->cmp("psASCIIHex")) { | ||
352 | parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line); | ||
353 | } else if (!cmd->cmp("textEncoding")) { | ||
354 | parseTextEncoding(tokens, fileName, line); | ||
355 | } else if (!cmd->cmp("textEOL")) { | ||
356 | parseTextEOL(tokens, fileName, line); | ||
357 | } else if (!cmd->cmp("fontDir")) { | ||
358 | parseFontDir(tokens, fileName, line); | ||
359 | } else if (!cmd->cmp("initialZoom")) { | ||
360 | parseInitialZoom(tokens, fileName, line); | ||
361 | } else if (!cmd->cmp("t1libControl")) { | ||
362 | parseFontRastControl("t1libControl", &t1libControl, | ||
363 | tokens, fileName, line); | ||
364 | } else if (!cmd->cmp("freetypeControl")) { | ||
365 | parseFontRastControl("freetypeControl", &freetypeControl, | ||
366 | tokens, fileName, line); | ||
367 | } else if (!cmd->cmp("urlCommand")) { | ||
368 | parseURLCommand(tokens, fileName, line); | ||
369 | } else if (!cmd->cmp("mapNumericCharNames")) { | ||
370 | parseYesNo("mapNumericCharNames", &mapNumericCharNames, | ||
371 | tokens, fileName, line); | ||
372 | } else if (!cmd->cmp("errQuiet")) { | ||
373 | parseYesNo("errQuiet", &errQuiet, tokens, fileName, line); | ||
374 | } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) { | ||
375 | error(-1, "Unknown config file command"); | ||
376 | error(-1, "-- the config file format has changed since Xpdf 0.9x"); | ||
377 | } else { | ||
378 | error(-1, "Unknown config file command '%s' (%s:%d)", | ||
379 | cmd->getCString(), fileName->getCString(), line); | ||
322 | } | 380 | } |
323 | |||
324 | deleteGList(tokens, GString); | ||
325 | ++line; | ||
326 | } | 381 | } |
327 | 382 | ||
328 | delete fileName; | 383 | deleteGList(tokens, GString); |
384 | ++line; | ||
329 | } | 385 | } |
330 | } | 386 | } |
331 | 387 | ||
332 | void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName, | 388 | void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName, |
333 | int line) { | 389 | int line) { |
334 | GString *name; | 390 | GString *name; |
@@ -423,13 +479,13 @@ void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName, | |||
423 | fileName->getCString(), line); | 479 | fileName->getCString(), line); |
424 | return; | 480 | return; |
425 | } | 481 | } |
426 | toUnicodeDirs->append(((GString *)tokens->get(1))->copy()); | 482 | toUnicodeDirs->append(((GString *)tokens->get(1))->copy()); |
427 | } | 483 | } |
428 | 484 | ||
429 | void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID, | 485 | void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash, |
430 | DisplayFontParamKind kind, | 486 | DisplayFontParamKind kind, |
431 | GString *fileName, int line) { | 487 | GString *fileName, int line) { |
432 | DisplayFontParam *param, *old; | 488 | DisplayFontParam *param, *old; |
433 | 489 | ||
434 | if (tokens->getLength() < 2) { | 490 | if (tokens->getLength() < 2) { |
435 | goto err1; | 491 | goto err1; |
@@ -455,29 +511,22 @@ void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID, | |||
455 | goto err2; | 511 | goto err2; |
456 | } | 512 | } |
457 | param->tt.fileName = ((GString *)tokens->get(2))->copy(); | 513 | param->tt.fileName = ((GString *)tokens->get(2))->copy(); |
458 | break; | 514 | break; |
459 | } | 515 | } |
460 | 516 | ||
461 | if (isCID) { | 517 | if ((old = (DisplayFontParam *)fontHash->remove(param->name))) { |
462 | if ((old = (DisplayFontParam *)displayCIDFonts->remove(param->name))) { | 518 | delete old; |
463 | delete old; | ||
464 | } | ||
465 | displayCIDFonts->add(param->name, param); | ||
466 | } else { | ||
467 | if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) { | ||
468 | delete old; | ||
469 | } | ||
470 | displayFonts->add(param->name, param); | ||
471 | } | 519 | } |
520 | fontHash->add(param->name, param); | ||
472 | return; | 521 | return; |
473 | 522 | ||
474 | err2: | 523 | err2: |
475 | delete param; | 524 | delete param; |
476 | err1: | 525 | err1: |
477 | error(-1, "Bad 'displayFont...' config file command (%s:%d)", | 526 | error(-1, "Bad 'display*Font*' config file command (%s:%d)", |
478 | fileName->getCString(), line); | 527 | fileName->getCString(), line); |
479 | } | 528 | } |
480 | 529 | ||
481 | void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName, | 530 | void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName, |
482 | int line) { | 531 | int line) { |
483 | GString *tok; | 532 | GString *tok; |
@@ -513,12 +562,16 @@ void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) { | |||
513 | } else if (!tok->cmp("level1sep")) { | 562 | } else if (!tok->cmp("level1sep")) { |
514 | psLevel = psLevel1Sep; | 563 | psLevel = psLevel1Sep; |
515 | } else if (!tok->cmp("level2")) { | 564 | } else if (!tok->cmp("level2")) { |
516 | psLevel = psLevel2; | 565 | psLevel = psLevel2; |
517 | } else if (!tok->cmp("level2sep")) { | 566 | } else if (!tok->cmp("level2sep")) { |
518 | psLevel = psLevel2Sep; | 567 | psLevel = psLevel2Sep; |
568 | } else if (!tok->cmp("level3")) { | ||
569 | psLevel = psLevel3; | ||
570 | } else if (!tok->cmp("level3Sep")) { | ||
571 | psLevel = psLevel3Sep; | ||
519 | } else { | 572 | } else { |
520 | error(-1, "Bad 'psLevel' config file command (%s:%d)", | 573 | error(-1, "Bad 'psLevel' config file command (%s:%d)", |
521 | fileName->getCString(), line); | 574 | fileName->getCString(), line); |
522 | } | 575 | } |
523 | } | 576 | } |
524 | 577 | ||
@@ -539,17 +592,45 @@ void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) { | |||
539 | 592 | ||
540 | if (tokens->getLength() != 3) { | 593 | if (tokens->getLength() != 3) { |
541 | error(-1, "Bad 'psFont' config file command (%s:%d)", | 594 | error(-1, "Bad 'psFont' config file command (%s:%d)", |
542 | fileName->getCString(), line); | 595 | fileName->getCString(), line); |
543 | return; | 596 | return; |
544 | } | 597 | } |
545 | param = new PSFontParam(((GString *)tokens->get(1))->copy(), | 598 | param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0, |
546 | ((GString *)tokens->get(2))->copy()); | 599 | ((GString *)tokens->get(2))->copy(), NULL); |
547 | psFonts->add(param->pdfFontName, param); | 600 | psFonts->add(param->pdfFontName, param); |
548 | } | 601 | } |
549 | 602 | ||
603 | void GlobalParams::parsePSFont16(char *cmdName, GList *fontList, | ||
604 | GList *tokens, GString *fileName, int line) { | ||
605 | PSFontParam *param; | ||
606 | int wMode; | ||
607 | GString *tok; | ||
608 | |||
609 | if (tokens->getLength() != 5) { | ||
610 | error(-1, "Bad '%s' config file command (%s:%d)", | ||
611 | cmdName, fileName->getCString(), line); | ||
612 | return; | ||
613 | } | ||
614 | tok = (GString *)tokens->get(2); | ||
615 | if (!tok->cmp("H")) { | ||
616 | wMode = 0; | ||
617 | } else if (!tok->cmp("V")) { | ||
618 | wMode = 1; | ||
619 | } else { | ||
620 | error(-1, "Bad '%s' config file command (%s:%d)", | ||
621 | cmdName, fileName->getCString(), line); | ||
622 | return; | ||
623 | } | ||
624 | param = new PSFontParam(((GString *)tokens->get(1))->copy(), | ||
625 | wMode, | ||
626 | ((GString *)tokens->get(3))->copy(), | ||
627 | ((GString *)tokens->get(4))->copy()); | ||
628 | fontList->append(param); | ||
629 | } | ||
630 | |||
550 | void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName, | 631 | void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName, |
551 | int line) { | 632 | int line) { |
552 | if (tokens->getLength() != 2) { | 633 | if (tokens->getLength() != 2) { |
553 | error(-1, "Bad 'textEncoding' config file command (%s:%d)", | 634 | error(-1, "Bad 'textEncoding' config file command (%s:%d)", |
554 | fileName->getCString(), line); | 635 | fileName->getCString(), line); |
555 | return; | 636 | return; |
@@ -585,23 +666,21 @@ void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) { | |||
585 | fileName->getCString(), line); | 666 | fileName->getCString(), line); |
586 | return; | 667 | return; |
587 | } | 668 | } |
588 | fontDirs->append(((GString *)tokens->get(1))->copy()); | 669 | fontDirs->append(((GString *)tokens->get(1))->copy()); |
589 | } | 670 | } |
590 | 671 | ||
591 | void GlobalParams::parseURLCommand(GList *tokens, GString *fileName, | 672 | void GlobalParams::parseInitialZoom(GList *tokens, |
592 | int line) { | 673 | GString *fileName, int line) { |
593 | if (tokens->getLength() != 2) { | 674 | if (tokens->getLength() != 2) { |
594 | error(-1, "Bad 'urlCommand' config file command (%s:%d)", | 675 | error(-1, "Bad 'initialZoom' config file command (%s:%d)", |
595 | fileName->getCString(), line); | 676 | fileName->getCString(), line); |
596 | return; | 677 | return; |
597 | } | 678 | } |
598 | if (urlCommand) { | 679 | delete initialZoom; |
599 | delete urlCommand; | 680 | initialZoom = ((GString *)tokens->get(1))->copy(); |
600 | } | ||
601 | urlCommand = ((GString *)tokens->get(1))->copy(); | ||
602 | } | 681 | } |
603 | 682 | ||
604 | void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val, | 683 | void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val, |
605 | GList *tokens, GString *fileName, | 684 | GList *tokens, GString *fileName, |
606 | int line) { | 685 | int line) { |
607 | GString *tok; | 686 | GString *tok; |
@@ -615,12 +694,25 @@ void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val, | |||
615 | if (!setFontRastControl(val, tok->getCString())) { | 694 | if (!setFontRastControl(val, tok->getCString())) { |
616 | error(-1, "Bad '%s' config file command (%s:%d)", | 695 | error(-1, "Bad '%s' config file command (%s:%d)", |
617 | cmdName, fileName->getCString(), line); | 696 | cmdName, fileName->getCString(), line); |
618 | } | 697 | } |
619 | } | 698 | } |
620 | 699 | ||
700 | void GlobalParams::parseURLCommand(GList *tokens, GString *fileName, | ||
701 | int line) { | ||
702 | if (tokens->getLength() != 2) { | ||
703 | error(-1, "Bad 'urlCommand' config file command (%s:%d)", | ||
704 | fileName->getCString(), line); | ||
705 | return; | ||
706 | } | ||
707 | if (urlCommand) { | ||
708 | delete urlCommand; | ||
709 | } | ||
710 | urlCommand = ((GString *)tokens->get(1))->copy(); | ||
711 | } | ||
712 | |||
621 | void GlobalParams::parseYesNo(char *cmdName, GBool *flag, | 713 | void GlobalParams::parseYesNo(char *cmdName, GBool *flag, |
622 | GList *tokens, GString *fileName, int line) { | 714 | GList *tokens, GString *fileName, int line) { |
623 | GString *tok; | 715 | GString *tok; |
624 | 716 | ||
625 | if (tokens->getLength() != 2) { | 717 | if (tokens->getLength() != 2) { |
626 | error(-1, "Bad '%s' config file command (%s:%d)", | 718 | error(-1, "Bad '%s' config file command (%s:%d)", |
@@ -651,18 +743,22 @@ GlobalParams::~GlobalParams() { | |||
651 | deleteGHash(cidToUnicodes, GString); | 743 | deleteGHash(cidToUnicodes, GString); |
652 | deleteGHash(residentUnicodeMaps, UnicodeMap); | 744 | deleteGHash(residentUnicodeMaps, UnicodeMap); |
653 | deleteGHash(unicodeMaps, GString); | 745 | deleteGHash(unicodeMaps, GString); |
654 | deleteGList(toUnicodeDirs, GString); | 746 | deleteGList(toUnicodeDirs, GString); |
655 | deleteGHash(displayFonts, DisplayFontParam); | 747 | deleteGHash(displayFonts, DisplayFontParam); |
656 | deleteGHash(displayCIDFonts, DisplayFontParam); | 748 | deleteGHash(displayCIDFonts, DisplayFontParam); |
749 | deleteGHash(displayNamedCIDFonts, DisplayFontParam); | ||
657 | if (psFile) { | 750 | if (psFile) { |
658 | delete psFile; | 751 | delete psFile; |
659 | } | 752 | } |
660 | deleteGHash(psFonts, PSFontParam); | 753 | deleteGHash(psFonts, PSFontParam); |
754 | deleteGList(psNamedFonts16, PSFontParam); | ||
755 | deleteGList(psFonts16, PSFontParam); | ||
661 | delete textEncoding; | 756 | delete textEncoding; |
662 | deleteGList(fontDirs, GString); | 757 | deleteGList(fontDirs, GString); |
758 | delete initialZoom; | ||
663 | if (urlCommand) { | 759 | if (urlCommand) { |
664 | delete urlCommand; | 760 | delete urlCommand; |
665 | } | 761 | } |
666 | 762 | ||
667 | cMapDirs->startIter(&iter); | 763 | cMapDirs->startIter(&iter); |
668 | while (cMapDirs->getNext(&iter, &key, (void **)&list)) { | 764 | while (cMapDirs->getNext(&iter, &key, (void **)&list)) { |
@@ -749,20 +845,56 @@ FILE *GlobalParams::findToUnicodeFile(GString *name) { | |||
749 | } | 845 | } |
750 | 846 | ||
751 | DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) { | 847 | DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) { |
752 | return (DisplayFontParam *)displayFonts->lookup(fontName); | 848 | return (DisplayFontParam *)displayFonts->lookup(fontName); |
753 | } | 849 | } |
754 | 850 | ||
755 | DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *collection) { | 851 | DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName, |
756 | return (DisplayFontParam *)displayCIDFonts->lookup(collection); | 852 | GString *collection) { |
853 | DisplayFontParam *dfp; | ||
854 | |||
855 | if (!fontName || | ||
856 | !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) { | ||
857 | dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection); | ||
858 | } | ||
859 | return dfp; | ||
757 | } | 860 | } |
758 | 861 | ||
759 | PSFontParam *GlobalParams::getPSFont(GString *fontName) { | 862 | PSFontParam *GlobalParams::getPSFont(GString *fontName) { |
760 | return (PSFontParam *)psFonts->lookup(fontName); | 863 | return (PSFontParam *)psFonts->lookup(fontName); |
761 | } | 864 | } |
762 | 865 | ||
866 | PSFontParam *GlobalParams::getPSFont16(GString *fontName, | ||
867 | GString *collection, int wMode) { | ||
868 | PSFontParam *p; | ||
869 | int i; | ||
870 | |||
871 | p = NULL; | ||
872 | if (fontName) { | ||
873 | for (i = 0; i < psNamedFonts16->getLength(); ++i) { | ||
874 | p = (PSFontParam *)psNamedFonts16->get(i); | ||
875 | if (!p->pdfFontName->cmp(fontName) && | ||
876 | p->wMode == wMode) { | ||
877 | break; | ||
878 | } | ||
879 | p = NULL; | ||
880 | } | ||
881 | } | ||
882 | if (!p && collection) { | ||
883 | for (i = 0; i < psFonts16->getLength(); ++i) { | ||
884 | p = (PSFontParam *)psFonts16->get(i); | ||
885 | if (!p->pdfFontName->cmp(collection) && | ||
886 | p->wMode == wMode) { | ||
887 | break; | ||
888 | } | ||
889 | p = NULL; | ||
890 | } | ||
891 | } | ||
892 | return p; | ||
893 | } | ||
894 | |||
763 | GString *GlobalParams::findFontFile(GString *fontName, | 895 | GString *GlobalParams::findFontFile(GString *fontName, |
764 | char *ext1, char *ext2) { | 896 | char *ext1, char *ext2) { |
765 | GString *dir, *fileName; | 897 | GString *dir, *fileName; |
766 | FILE *f; | 898 | FILE *f; |
767 | int i; | 899 | int i; |
768 | 900 | ||
@@ -863,16 +995,28 @@ void GlobalParams::setPSEmbedType1(GBool embed) { | |||
863 | } | 995 | } |
864 | 996 | ||
865 | void GlobalParams::setPSEmbedTrueType(GBool embed) { | 997 | void GlobalParams::setPSEmbedTrueType(GBool embed) { |
866 | psEmbedTrueType = embed; | 998 | psEmbedTrueType = embed; |
867 | } | 999 | } |
868 | 1000 | ||
1001 | void GlobalParams::setPSEmbedCIDPostScript(GBool embed) { | ||
1002 | psEmbedCIDPostScript = embed; | ||
1003 | } | ||
1004 | |||
1005 | void GlobalParams::setPSEmbedCIDTrueType(GBool embed) { | ||
1006 | psEmbedCIDTrueType = embed; | ||
1007 | } | ||
1008 | |||
869 | void GlobalParams::setPSOPI(GBool opi) { | 1009 | void GlobalParams::setPSOPI(GBool opi) { |
870 | psOPI = opi; | 1010 | psOPI = opi; |
871 | } | 1011 | } |
872 | 1012 | ||
1013 | void GlobalParams::setPSASCIIHex(GBool hex) { | ||
1014 | psASCIIHex = hex; | ||
1015 | } | ||
1016 | |||
873 | void GlobalParams::setTextEncoding(char *encodingName) { | 1017 | void GlobalParams::setTextEncoding(char *encodingName) { |
874 | delete textEncoding; | 1018 | delete textEncoding; |
875 | textEncoding = new GString(encodingName); | 1019 | textEncoding = new GString(encodingName); |
876 | } | 1020 | } |
877 | 1021 | ||
878 | GBool GlobalParams::setTextEOL(char *s) { | 1022 | GBool GlobalParams::setTextEOL(char *s) { |
@@ -885,12 +1029,17 @@ GBool GlobalParams::setTextEOL(char *s) { | |||
885 | } else { | 1029 | } else { |
886 | return gFalse; | 1030 | return gFalse; |
887 | } | 1031 | } |
888 | return gTrue; | 1032 | return gTrue; |
889 | } | 1033 | } |
890 | 1034 | ||
1035 | void GlobalParams::setInitialZoom(char *s) { | ||
1036 | delete initialZoom; | ||
1037 | initialZoom = new GString(s); | ||
1038 | } | ||
1039 | |||
891 | GBool GlobalParams::setT1libControl(char *s) { | 1040 | GBool GlobalParams::setT1libControl(char *s) { |
892 | return setFontRastControl(&t1libControl, s); | 1041 | return setFontRastControl(&t1libControl, s); |
893 | } | 1042 | } |
894 | 1043 | ||
895 | GBool GlobalParams::setFreeTypeControl(char *s) { | 1044 | GBool GlobalParams::setFreeTypeControl(char *s) { |
896 | return setFontRastControl(&freetypeControl, s); | 1045 | return setFontRastControl(&freetypeControl, s); |
diff --git a/noncore/unsupported/qpdf/xpdf/GlobalParams.h b/noncore/unsupported/qpdf/xpdf/GlobalParams.h index ecbb5fc..b651110 100644 --- a/noncore/unsupported/qpdf/xpdf/GlobalParams.h +++ b/noncore/unsupported/qpdf/xpdf/GlobalParams.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // GlobalParams.h | 3 | // GlobalParams.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef GLOBALPARAMS_H | 9 | #ifndef GLOBALPARAMS_H |
10 | #define GLOBALPARAMS_H | 10 | #define GLOBALPARAMS_H |
11 | 11 | ||
@@ -42,14 +42,15 @@ enum DisplayFontParamKind { | |||
42 | displayFontTT | 42 | displayFontTT |
43 | }; | 43 | }; |
44 | 44 | ||
45 | class DisplayFontParam { | 45 | class DisplayFontParam { |
46 | public: | 46 | public: |
47 | 47 | ||
48 | GString *name; // font name for 8-bit fonts; | 48 | GString *name; // font name for 8-bit fonts and named |
49 | // collection name for CID fonts | 49 | // CID fonts; collection name for |
50 | // generic CID fonts | ||
50 | DisplayFontParamKind kind; | 51 | DisplayFontParamKind kind; |
51 | union { | 52 | union { |
52 | struct { | 53 | struct { |
53 | GString *xlfd; | 54 | GString *xlfd; |
54 | GString *encoding; | 55 | GString *encoding; |
55 | } x; | 56 | } x; |
@@ -76,26 +77,34 @@ enum FontRastControl { | |||
76 | 77 | ||
77 | //------------------------------------------------------------------------ | 78 | //------------------------------------------------------------------------ |
78 | 79 | ||
79 | class PSFontParam { | 80 | class PSFontParam { |
80 | public: | 81 | public: |
81 | 82 | ||
82 | GString *pdfFontName; | 83 | GString *pdfFontName; // PDF font name for 8-bit fonts and |
83 | GString *psFontName; | 84 | // named 16-bit fonts; char collection |
85 | // name for generic 16-bit fonts | ||
86 | int wMode; // writing mode (0=horiz, 1=vert) for | ||
87 | // 16-bit fonts | ||
88 | GString *psFontName; // PostScript font name | ||
89 | GString *encoding; // encoding, for 16-bit fonts only | ||
84 | 90 | ||
85 | PSFontParam(GString *pdfFontNameA, GString *psFontNameA); | 91 | PSFontParam(GString *pdfFontNameA, int wModeA, |
92 | GString *psFontNameA, GString *encodingA); | ||
86 | ~PSFontParam(); | 93 | ~PSFontParam(); |
87 | }; | 94 | }; |
88 | 95 | ||
89 | //------------------------------------------------------------------------ | 96 | //------------------------------------------------------------------------ |
90 | 97 | ||
91 | enum PSLevel { | 98 | enum PSLevel { |
92 | psLevel1, | 99 | psLevel1, |
93 | psLevel1Sep, | 100 | psLevel1Sep, |
94 | psLevel2, | 101 | psLevel2, |
95 | psLevel2Sep | 102 | psLevel2Sep, |
103 | psLevel3, | ||
104 | psLevel3Sep | ||
96 | }; | 105 | }; |
97 | 106 | ||
98 | //------------------------------------------------------------------------ | 107 | //------------------------------------------------------------------------ |
99 | 108 | ||
100 | enum EndOfLineKind { | 109 | enum EndOfLineKind { |
101 | eolUnix, // LF | 110 | eolUnix, // LF |
@@ -122,25 +131,30 @@ public: | |||
122 | FILE *getCIDToUnicodeFile(GString *collection); | 131 | FILE *getCIDToUnicodeFile(GString *collection); |
123 | UnicodeMap *getResidentUnicodeMap(GString *encodingName); | 132 | UnicodeMap *getResidentUnicodeMap(GString *encodingName); |
124 | FILE *getUnicodeMapFile(GString *encodingName); | 133 | FILE *getUnicodeMapFile(GString *encodingName); |
125 | FILE *findCMapFile(GString *collection, GString *cMapName); | 134 | FILE *findCMapFile(GString *collection, GString *cMapName); |
126 | FILE *findToUnicodeFile(GString *name); | 135 | FILE *findToUnicodeFile(GString *name); |
127 | DisplayFontParam *getDisplayFont(GString *fontName); | 136 | DisplayFontParam *getDisplayFont(GString *fontName); |
128 | DisplayFontParam *getDisplayCIDFont(GString *collection); | 137 | DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection); |
129 | GString *getPSFile() { return psFile; } | 138 | GString *getPSFile() { return psFile; } |
130 | int getPSPaperWidth() { return psPaperWidth; } | 139 | int getPSPaperWidth() { return psPaperWidth; } |
131 | int getPSPaperHeight() { return psPaperHeight; } | 140 | int getPSPaperHeight() { return psPaperHeight; } |
132 | GBool getPSDuplex() { return psDuplex; } | 141 | GBool getPSDuplex() { return psDuplex; } |
133 | PSLevel getPSLevel() { return psLevel; } | 142 | PSLevel getPSLevel() { return psLevel; } |
134 | PSFontParam *getPSFont(GString *fontName); | 143 | PSFontParam *getPSFont(GString *fontName); |
144 | PSFontParam *getPSFont16(GString *fontName, GString *collection, int wMode); | ||
135 | GBool getPSEmbedType1() { return psEmbedType1; } | 145 | GBool getPSEmbedType1() { return psEmbedType1; } |
136 | GBool getPSEmbedTrueType() { return psEmbedTrueType; } | 146 | GBool getPSEmbedTrueType() { return psEmbedTrueType; } |
147 | GBool getPSEmbedCIDPostScript() { return psEmbedCIDPostScript; } | ||
148 | GBool getPSEmbedCIDTrueType() { return psEmbedCIDTrueType; } | ||
137 | GBool getPSOPI() { return psOPI; } | 149 | GBool getPSOPI() { return psOPI; } |
150 | GBool getPSASCIIHex() { return psASCIIHex; } | ||
138 | GString *getTextEncodingName() { return textEncoding; } | 151 | GString *getTextEncodingName() { return textEncoding; } |
139 | EndOfLineKind getTextEOL() { return textEOL; } | 152 | EndOfLineKind getTextEOL() { return textEOL; } |
140 | GString *findFontFile(GString *fontName, char *ext1, char *ext2); | 153 | GString *findFontFile(GString *fontName, char *ext1, char *ext2); |
154 | GString *getInitialZoom() { return initialZoom; } | ||
141 | FontRastControl getT1libControl() { return t1libControl; } | 155 | FontRastControl getT1libControl() { return t1libControl; } |
142 | FontRastControl getFreeTypeControl() { return freetypeControl; } | 156 | FontRastControl getFreeTypeControl() { return freetypeControl; } |
143 | GString *getURLCommand() { return urlCommand; } | 157 | GString *getURLCommand() { return urlCommand; } |
144 | GBool getMapNumericCharNames() { return mapNumericCharNames; } | 158 | GBool getMapNumericCharNames() { return mapNumericCharNames; } |
145 | GBool getErrQuiet() { return errQuiet; } | 159 | GBool getErrQuiet() { return errQuiet; } |
146 | 160 | ||
@@ -156,35 +170,44 @@ public: | |||
156 | void setPSPaperWidth(int width); | 170 | void setPSPaperWidth(int width); |
157 | void setPSPaperHeight(int height); | 171 | void setPSPaperHeight(int height); |
158 | void setPSDuplex(GBool duplex); | 172 | void setPSDuplex(GBool duplex); |
159 | void setPSLevel(PSLevel level); | 173 | void setPSLevel(PSLevel level); |
160 | void setPSEmbedType1(GBool embed); | 174 | void setPSEmbedType1(GBool embed); |
161 | void setPSEmbedTrueType(GBool embed); | 175 | void setPSEmbedTrueType(GBool embed); |
176 | void setPSEmbedCIDPostScript(GBool embed); | ||
177 | void setPSEmbedCIDTrueType(GBool embed); | ||
162 | void setPSOPI(GBool opi); | 178 | void setPSOPI(GBool opi); |
179 | void setPSASCIIHex(GBool hex); | ||
163 | void setTextEncoding(char *encodingName); | 180 | void setTextEncoding(char *encodingName); |
164 | GBool setTextEOL(char *s); | 181 | GBool setTextEOL(char *s); |
182 | void setInitialZoom(char *s); | ||
165 | GBool setT1libControl(char *s); | 183 | GBool setT1libControl(char *s); |
166 | GBool setFreeTypeControl(char *s); | 184 | GBool setFreeTypeControl(char *s); |
167 | void setErrQuiet(GBool errQuietA); | 185 | void setErrQuiet(GBool errQuietA); |
168 | 186 | ||
169 | private: | 187 | private: |
170 | 188 | ||
189 | void parseFile(GString *fileName, FILE *f); | ||
171 | void parseNameToUnicode(GList *tokens, GString *fileName, int line); | 190 | void parseNameToUnicode(GList *tokens, GString *fileName, int line); |
172 | void parseCIDToUnicode(GList *tokens, GString *fileName, int line); | 191 | void parseCIDToUnicode(GList *tokens, GString *fileName, int line); |
173 | void parseUnicodeMap(GList *tokens, GString *fileName, int line); | 192 | void parseUnicodeMap(GList *tokens, GString *fileName, int line); |
174 | void parseCMapDir(GList *tokens, GString *fileName, int line); | 193 | void parseCMapDir(GList *tokens, GString *fileName, int line); |
175 | void parseToUnicodeDir(GList *tokens, GString *fileName, int line); | 194 | void parseToUnicodeDir(GList *tokens, GString *fileName, int line); |
176 | void parseDisplayFont(GList *tokens, GBool isCID, DisplayFontParamKind kind, | 195 | void parseDisplayFont(GList *tokens, GHash *fontHash, |
196 | DisplayFontParamKind kind, | ||
177 | GString *fileName, int line); | 197 | GString *fileName, int line); |
178 | void parsePSFile(GList *tokens, GString *fileName, int line); | 198 | void parsePSFile(GList *tokens, GString *fileName, int line); |
179 | void parsePSPaperSize(GList *tokens, GString *fileName, int line); | 199 | void parsePSPaperSize(GList *tokens, GString *fileName, int line); |
180 | void parsePSLevel(GList *tokens, GString *fileName, int line); | 200 | void parsePSLevel(GList *tokens, GString *fileName, int line); |
181 | void parsePSFont(GList *tokens, GString *fileName, int line); | 201 | void parsePSFont(GList *tokens, GString *fileName, int line); |
202 | void parsePSFont16(char *cmdName, GList *fontList, | ||
203 | GList *tokens, GString *fileName, int line); | ||
182 | void parseTextEncoding(GList *tokens, GString *fileName, int line); | 204 | void parseTextEncoding(GList *tokens, GString *fileName, int line); |
183 | void parseTextEOL(GList *tokens, GString *fileName, int line); | 205 | void parseTextEOL(GList *tokens, GString *fileName, int line); |
184 | void parseFontDir(GList *tokens, GString *fileName, int line); | 206 | void parseFontDir(GList *tokens, GString *fileName, int line); |
207 | void parseInitialZoom(GList *tokens, GString *fileName, int line); | ||
185 | void parseFontRastControl(char *cmdName, FontRastControl *val, | 208 | void parseFontRastControl(char *cmdName, FontRastControl *val, |
186 | GList *tokens, GString *fileName, int line); | 209 | GList *tokens, GString *fileName, int line); |
187 | void parseURLCommand(GList *tokens, GString *fileName, int line); | 210 | void parseURLCommand(GList *tokens, GString *fileName, int line); |
188 | void parseYesNo(char *cmdName, GBool *flag, | 211 | void parseYesNo(char *cmdName, GBool *flag, |
189 | GList *tokens, GString *fileName, int line); | 212 | GList *tokens, GString *fileName, int line); |
190 | GBool setFontRastControl(FontRastControl *val, char *s); | 213 | GBool setFontRastControl(FontRastControl *val, char *s); |
@@ -209,27 +232,35 @@ private: | |||
209 | // name [GList[GString]] | 232 | // name [GList[GString]] |
210 | GList *toUnicodeDirs; // list of ToUnicode CMap dirs [GString] | 233 | GList *toUnicodeDirs; // list of ToUnicode CMap dirs [GString] |
211 | GHash *displayFonts; // display font info, indexed by font name | 234 | GHash *displayFonts; // display font info, indexed by font name |
212 | // [DisplayFontParam] | 235 | // [DisplayFontParam] |
213 | GHash *displayCIDFonts;// display CID font info, indexed by | 236 | GHash *displayCIDFonts;// display CID font info, indexed by |
214 | // collection [DisplayFontParam] | 237 | // collection [DisplayFontParam] |
238 | GHash *displayNamedCIDFonts;// display CID font info, indexed by | ||
239 | // font name [DisplayFontParam] | ||
215 | GString *psFile; // PostScript file or command (for xpdf) | 240 | GString *psFile; // PostScript file or command (for xpdf) |
216 | int psPaperWidth; // paper size, in PostScript points, for | 241 | int psPaperWidth; // paper size, in PostScript points, for |
217 | int psPaperHeight; // PostScript output | 242 | int psPaperHeight; // PostScript output |
218 | GBool psDuplex; // enable duplexing in PostScript? | 243 | GBool psDuplex; // enable duplexing in PostScript? |
219 | PSLevel psLevel; // PostScript level to generate | 244 | PSLevel psLevel; // PostScript level to generate |
220 | GHash *psFonts; // PostScript font info, indexed by PDF | 245 | GHash *psFonts; // PostScript font info, indexed by PDF |
221 | // font name [PSFontParam] | 246 | // font name [PSFontParam] |
247 | GList *psNamedFonts16;// named 16-bit fonts [PSFontParam] | ||
248 | GList *psFonts16; // generic 16-bit fonts [PSFontParam] | ||
222 | GBool psEmbedType1; // embed Type 1 fonts? | 249 | GBool psEmbedType1; // embed Type 1 fonts? |
223 | GBool psEmbedTrueType;// embed TrueType fonts? | 250 | GBool psEmbedTrueType;// embed TrueType fonts? |
251 | GBool psEmbedCIDPostScript;// embed CID PostScript fonts? | ||
252 | GBool psEmbedCIDTrueType;// embed CID TrueType fonts? | ||
224 | GBool psOPI; // generate PostScript OPI comments? | 253 | GBool psOPI; // generate PostScript OPI comments? |
254 | GBool psASCIIHex; // use ASCIIHex instead of ASCII85? | ||
225 | GString *textEncoding;// encoding (unicodeMap) to use for text | 255 | GString *textEncoding;// encoding (unicodeMap) to use for text |
226 | // output | 256 | // output |
227 | EndOfLineKind textEOL;// type of EOL marker to use for text | 257 | EndOfLineKind textEOL;// type of EOL marker to use for text |
228 | // output | 258 | // output |
229 | GList *fontDirs; // list of font dirs [GString] | 259 | GList *fontDirs; // list of font dirs [GString] |
260 | GString *initialZoom; // initial zoom level | ||
230 | FontRastControl t1libControl;// t1lib rasterization mode | 261 | FontRastControl t1libControl;// t1lib rasterization mode |
231 | FontRastControl // FreeType rasterization mode | 262 | FontRastControl // FreeType rasterization mode |
232 | freetypeControl; | 263 | freetypeControl; |
233 | GString *urlCommand; // command executed for URL links | 264 | GString *urlCommand; // command executed for URL links |
234 | GBool mapNumericCharNames;// map numeric char names (from font subsets)? | 265 | GBool mapNumericCharNames;// map numeric char names (from font subsets)? |
235 | GBool errQuiet; // suppress error messages? | 266 | GBool errQuiet; // suppress error messages? |
diff --git a/noncore/unsupported/qpdf/xpdf/Lexer.cc b/noncore/unsupported/qpdf/xpdf/Lexer.cc index fff4bcb..a258950 100644 --- a/noncore/unsupported/qpdf/xpdf/Lexer.cc +++ b/noncore/unsupported/qpdf/xpdf/Lexer.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Lexer.cc | 3 | // Lexer.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/Lexer.h b/noncore/unsupported/qpdf/xpdf/Lexer.h index 5edbeda..8a01ab2 100644 --- a/noncore/unsupported/qpdf/xpdf/Lexer.h +++ b/noncore/unsupported/qpdf/xpdf/Lexer.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Lexer.h | 3 | // Lexer.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef LEXER_H | 9 | #ifndef LEXER_H |
10 | #define LEXER_H | 10 | #define LEXER_H |
11 | 11 | ||
@@ -48,19 +48,20 @@ public: | |||
48 | void skipChar() { getChar(); } | 48 | void skipChar() { getChar(); } |
49 | 49 | ||
50 | // Get stream. | 50 | // Get stream. |
51 | Stream *getStream() | 51 | Stream *getStream() |
52 | { return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); } | 52 | { return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); } |
53 | 53 | ||
54 | // Get current position in file. | 54 | // Get current position in file. This is only used for error |
55 | // messages, so it returns an int instead of a Guint. | ||
55 | int getPos() | 56 | int getPos() |
56 | { return curStr.isNone() ? -1 : curStr.streamGetPos(); } | 57 | { return curStr.isNone() ? -1 : (int)curStr.streamGetPos(); } |
57 | 58 | ||
58 | // Set position in file. | 59 | // Set position in file. |
59 | void setPos(int pos) | 60 | void setPos(Guint pos, int dir = 0) |
60 | { if (!curStr.isNone()) curStr.streamSetPos(pos); } | 61 | { if (!curStr.isNone()) curStr.streamSetPos(pos, dir); } |
61 | 62 | ||
62 | private: | 63 | private: |
63 | 64 | ||
64 | int getChar(); | 65 | int getChar(); |
65 | int lookChar(); | 66 | int lookChar(); |
66 | 67 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Link.cc b/noncore/unsupported/qpdf/xpdf/Link.cc index 79a5f6e..c25ec43 100644 --- a/noncore/unsupported/qpdf/xpdf/Link.cc +++ b/noncore/unsupported/qpdf/xpdf/Link.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Link.cc | 3 | // Link.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -26,37 +26,33 @@ | |||
26 | static GString *getFileSpecName(Object *fileSpecObj); | 26 | static GString *getFileSpecName(Object *fileSpecObj); |
27 | 27 | ||
28 | //------------------------------------------------------------------------ | 28 | //------------------------------------------------------------------------ |
29 | // LinkDest | 29 | // LinkDest |
30 | //------------------------------------------------------------------------ | 30 | //------------------------------------------------------------------------ |
31 | 31 | ||
32 | LinkDest::LinkDest(Array *a, GBool pageIsRefA) { | 32 | LinkDest::LinkDest(Array *a) { |
33 | Object obj1, obj2; | 33 | Object obj1, obj2; |
34 | 34 | ||
35 | // initialize fields | 35 | // initialize fields |
36 | pageIsRef = pageIsRefA; | ||
37 | left = bottom = right = top = zoom = 0; | 36 | left = bottom = right = top = zoom = 0; |
38 | ok = gFalse; | 37 | ok = gFalse; |
39 | 38 | ||
40 | // get page | 39 | // get page |
41 | if (pageIsRef) { | 40 | a->getNF(0, &obj1); |
42 | if (!a->getNF(0, &obj1)->isRef()) { | 41 | if (obj1.isInt()) { |
43 | error(-1, "Bad annotation destination"); | 42 | pageNum = obj1.getInt() + 1; |
44 | goto err2; | 43 | pageIsRef = gFalse; |
45 | } | 44 | } else if (obj1.isRef()) { |
46 | pageRef.num = obj1.getRefNum(); | 45 | pageRef.num = obj1.getRefNum(); |
47 | pageRef.gen = obj1.getRefGen(); | 46 | pageRef.gen = obj1.getRefGen(); |
48 | obj1.free(); | 47 | pageIsRef = gTrue; |
49 | } else { | 48 | } else { |
50 | if (!a->get(0, &obj1)->isInt()) { | 49 | error(-1, "Bad annotation destination"); |
51 | error(-1, "Bad annotation destination"); | 50 | goto err2; |
52 | goto err2; | ||
53 | } | ||
54 | pageNum = obj1.getInt() + 1; | ||
55 | obj1.free(); | ||
56 | } | 51 | } |
52 | obj1.free(); | ||
57 | 53 | ||
58 | // get destination type | 54 | // get destination type |
59 | a->get(1, &obj1); | 55 | a->get(1, &obj1); |
60 | 56 | ||
61 | // XYZ link | 57 | // XYZ link |
62 | if (obj1.isName("XYZ")) { | 58 | if (obj1.isName("XYZ")) { |
@@ -218,13 +214,13 @@ LinkGoTo::LinkGoTo(Object *destObj) { | |||
218 | namedDest = new GString(destObj->getName()); | 214 | namedDest = new GString(destObj->getName()); |
219 | } else if (destObj->isString()) { | 215 | } else if (destObj->isString()) { |
220 | namedDest = destObj->getString()->copy(); | 216 | namedDest = destObj->getString()->copy(); |
221 | 217 | ||
222 | // destination dictionary | 218 | // destination dictionary |
223 | } else if (destObj->isArray()) { | 219 | } else if (destObj->isArray()) { |
224 | dest = new LinkDest(destObj->getArray(), gTrue); | 220 | dest = new LinkDest(destObj->getArray()); |
225 | if (!dest->isOk()) { | 221 | if (!dest->isOk()) { |
226 | delete dest; | 222 | delete dest; |
227 | dest = NULL; | 223 | dest = NULL; |
228 | } | 224 | } |
229 | 225 | ||
230 | // error | 226 | // error |
@@ -256,13 +252,13 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) { | |||
256 | namedDest = new GString(destObj->getName()); | 252 | namedDest = new GString(destObj->getName()); |
257 | } else if (destObj->isString()) { | 253 | } else if (destObj->isString()) { |
258 | namedDest = destObj->getString()->copy(); | 254 | namedDest = destObj->getString()->copy(); |
259 | 255 | ||
260 | // destination dictionary | 256 | // destination dictionary |
261 | } else if (destObj->isArray()) { | 257 | } else if (destObj->isArray()) { |
262 | dest = new LinkDest(destObj->getArray(), gFalse); | 258 | dest = new LinkDest(destObj->getArray()); |
263 | if (!dest->isOk()) { | 259 | if (!dest->isOk()) { |
264 | delete dest; | 260 | delete dest; |
265 | dest = NULL; | 261 | dest = NULL; |
266 | } | 262 | } |
267 | 263 | ||
268 | // error | 264 | // error |
@@ -443,13 +439,13 @@ Link::Link(Dict *dict, GString *baseURI) { | |||
443 | t = y1; | 439 | t = y1; |
444 | y1 = y2; | 440 | y1 = y2; |
445 | y2 = t; | 441 | y2 = t; |
446 | } | 442 | } |
447 | 443 | ||
448 | // get border | 444 | // get border |
449 | borderW = 0; | 445 | borderW = 1; |
450 | if (!dict->lookup("Border", &obj1)->isNull()) { | 446 | if (!dict->lookup("Border", &obj1)->isNull()) { |
451 | if (obj1.isArray() && obj1.arrayGetLength() >= 3) { | 447 | if (obj1.isArray() && obj1.arrayGetLength() >= 3) { |
452 | if (obj1.arrayGet(2, &obj2)->isNum()) { | 448 | if (obj1.arrayGet(2, &obj2)->isNum()) { |
453 | borderW = obj2.getNum(); | 449 | borderW = obj2.getNum(); |
454 | } else { | 450 | } else { |
455 | error(-1, "Bad annotation border"); | 451 | error(-1, "Bad annotation border"); |
@@ -579,13 +575,13 @@ Links::~Links() { | |||
579 | gfree(links); | 575 | gfree(links); |
580 | } | 576 | } |
581 | 577 | ||
582 | LinkAction *Links::find(fouble x, fouble y) { | 578 | LinkAction *Links::find(fouble x, fouble y) { |
583 | int i; | 579 | int i; |
584 | 580 | ||
585 | for (i = 0; i < numLinks; ++i) { | 581 | for (i = numLinks - 1; i >= 0; --i) { |
586 | if (links[i]->inRect(x, y)) { | 582 | if (links[i]->inRect(x, y)) { |
587 | return links[i]->getAction(); | 583 | return links[i]->getAction(); |
588 | } | 584 | } |
589 | } | 585 | } |
590 | return NULL; | 586 | return NULL; |
591 | } | 587 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/Link.h b/noncore/unsupported/qpdf/xpdf/Link.h index 0ad4581..7b5ba86 100644 --- a/noncore/unsupported/qpdf/xpdf/Link.h +++ b/noncore/unsupported/qpdf/xpdf/Link.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Link.h | 3 | // Link.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef LINK_H | 9 | #ifndef LINK_H |
10 | #define LINK_H | 10 | #define LINK_H |
11 | 11 | ||
@@ -60,16 +60,14 @@ enum LinkDestKind { | |||
60 | destFitBV | 60 | destFitBV |
61 | }; | 61 | }; |
62 | 62 | ||
63 | class LinkDest { | 63 | class LinkDest { |
64 | public: | 64 | public: |
65 | 65 | ||
66 | // Build a LinkDest from the array. If <pageIsRef> is true, the | 66 | // Build a LinkDest from the array. |
67 | // page is specified by an object reference; otherwise the page is | 67 | LinkDest(Array *a); |
68 | // specified by a (zero-relative) page number. | ||
69 | LinkDest(Array *a, GBool pageIsRef1); | ||
70 | 68 | ||
71 | // Copy a LinkDest. | 69 | // Copy a LinkDest. |
72 | LinkDest *copy() { return new LinkDest(this); } | 70 | LinkDest *copy() { return new LinkDest(this); } |
73 | 71 | ||
74 | // Was the LinkDest created successfully? | 72 | // Was the LinkDest created successfully? |
75 | GBool isOk() { return ok; } | 73 | GBool isOk() { return ok; } |
diff --git a/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc b/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc index 06be2f4..b9cde77 100644 --- a/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc +++ b/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // NameToCharCode.cc | 3 | // NameToCharCode.cc |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/NameToCharCode.h b/noncore/unsupported/qpdf/xpdf/NameToCharCode.h index 9f9b1c3..22e41b6 100644 --- a/noncore/unsupported/qpdf/xpdf/NameToCharCode.h +++ b/noncore/unsupported/qpdf/xpdf/NameToCharCode.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // NameToCharCode.h | 3 | // NameToCharCode.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef NAMETOCHARCODE_H | 9 | #ifndef NAMETOCHARCODE_H |
10 | #define NAMETOCHARCODE_H | 10 | #define NAMETOCHARCODE_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h b/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h index 7ca635e..432fafb 100644 --- a/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h +++ b/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // NameToUnicodeTable.h | 3 | // NameToUnicodeTable.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | static struct { | 9 | static struct { |
10 | Unicode u; | 10 | Unicode u; |
11 | char *name; | 11 | char *name; |
diff --git a/noncore/unsupported/qpdf/xpdf/Object.cc b/noncore/unsupported/qpdf/xpdf/Object.cc index 5ecade3..6d92c6a 100644 --- a/noncore/unsupported/qpdf/xpdf/Object.cc +++ b/noncore/unsupported/qpdf/xpdf/Object.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Object.cc | 3 | // Object.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/Object.h b/noncore/unsupported/qpdf/xpdf/Object.h index 000ffa0..7a67a7d 100644 --- a/noncore/unsupported/qpdf/xpdf/Object.h +++ b/noncore/unsupported/qpdf/xpdf/Object.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Object.h | 3 | // Object.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef OBJECT_H | 9 | #ifndef OBJECT_H |
10 | #define OBJECT_H | 10 | #define OBJECT_H |
11 | 11 | ||
@@ -173,14 +173,14 @@ public: | |||
173 | GBool streamIs(char *dictType); | 173 | GBool streamIs(char *dictType); |
174 | void streamReset(); | 174 | void streamReset(); |
175 | void streamClose(); | 175 | void streamClose(); |
176 | int streamGetChar(); | 176 | int streamGetChar(); |
177 | int streamLookChar(); | 177 | int streamLookChar(); |
178 | char *streamGetLine(char *buf, int size); | 178 | char *streamGetLine(char *buf, int size); |
179 | int streamGetPos(); | 179 | Guint streamGetPos(); |
180 | void streamSetPos(int pos); | 180 | void streamSetPos(Guint pos, int dir = 0); |
181 | Dict *streamGetDict(); | 181 | Dict *streamGetDict(); |
182 | 182 | ||
183 | // Output. | 183 | // Output. |
184 | char *getTypeName(); | 184 | char *getTypeName(); |
185 | void print(FILE *f = stdout); | 185 | void print(FILE *f = stdout); |
186 | 186 | ||
@@ -284,16 +284,16 @@ inline int Object::streamGetChar() | |||
284 | inline int Object::streamLookChar() | 284 | inline int Object::streamLookChar() |
285 | { return stream->lookChar(); } | 285 | { return stream->lookChar(); } |
286 | 286 | ||
287 | inline char *Object::streamGetLine(char *buf, int size) | 287 | inline char *Object::streamGetLine(char *buf, int size) |
288 | { return stream->getLine(buf, size); } | 288 | { return stream->getLine(buf, size); } |
289 | 289 | ||
290 | inline int Object::streamGetPos() | 290 | inline Guint Object::streamGetPos() |
291 | { return stream->getPos(); } | 291 | { return stream->getPos(); } |
292 | 292 | ||
293 | inline void Object::streamSetPos(int pos) | 293 | inline void Object::streamSetPos(Guint pos, int dir) |
294 | { stream->setPos(pos); } | 294 | { stream->setPos(pos, dir); } |
295 | 295 | ||
296 | inline Dict *Object::streamGetDict() | 296 | inline Dict *Object::streamGetDict() |
297 | { return stream->getDict(); } | 297 | { return stream->getDict(); } |
298 | 298 | ||
299 | #endif | 299 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/OutputDev.cc b/noncore/unsupported/qpdf/xpdf/OutputDev.cc index 3c02835..1004f0f 100644 --- a/noncore/unsupported/qpdf/xpdf/OutputDev.cc +++ b/noncore/unsupported/qpdf/xpdf/OutputDev.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // OutputDev.cc | 3 | // OutputDev.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -56,12 +56,17 @@ void OutputDev::updateAll(GfxState *state) { | |||
56 | updateLineWidth(state); | 56 | updateLineWidth(state); |
57 | updateFillColor(state); | 57 | updateFillColor(state); |
58 | updateStrokeColor(state); | 58 | updateStrokeColor(state); |
59 | updateFont(state); | 59 | updateFont(state); |
60 | } | 60 | } |
61 | 61 | ||
62 | GBool OutputDev::beginType3Char(GfxState *state, | ||
63 | CharCode code, Unicode *u, int uLen) { | ||
64 | return gFalse; | ||
65 | } | ||
66 | |||
62 | void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, | 67 | void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, |
63 | int width, int height, GBool invert, | 68 | int width, int height, GBool invert, |
64 | GBool inlineImg) { | 69 | GBool inlineImg) { |
65 | int i, j; | 70 | int i, j; |
66 | 71 | ||
67 | if (inlineImg) { | 72 | if (inlineImg) { |
diff --git a/noncore/unsupported/qpdf/xpdf/OutputDev.h b/noncore/unsupported/qpdf/xpdf/OutputDev.h index 04cbace..398c035 100644 --- a/noncore/unsupported/qpdf/xpdf/OutputDev.h +++ b/noncore/unsupported/qpdf/xpdf/OutputDev.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // OutputDev.h | 3 | // OutputDev.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef OUTPUTDEV_H | 9 | #ifndef OUTPUTDEV_H |
10 | #define OUTPUTDEV_H | 10 | #define OUTPUTDEV_H |
11 | 11 | ||
@@ -43,12 +43,16 @@ public: | |||
43 | // (Upside-down means (0,0) is the top left corner of the page.) | 43 | // (Upside-down means (0,0) is the top left corner of the page.) |
44 | virtual GBool upsideDown() = 0; | 44 | virtual GBool upsideDown() = 0; |
45 | 45 | ||
46 | // Does this device use drawChar() or drawString()? | 46 | // Does this device use drawChar() or drawString()? |
47 | virtual GBool useDrawChar() = 0; | 47 | virtual GBool useDrawChar() = 0; |
48 | 48 | ||
49 | // Does this device use beginType3Char/endType3Char? Otherwise, | ||
50 | // text in Type 3 fonts will be drawn with drawChar/drawString. | ||
51 | virtual GBool interpretType3Chars() = 0; | ||
52 | |||
49 | // Does this device need non-text content? | 53 | // Does this device need non-text content? |
50 | virtual GBool needNonText() { return gTrue; } | 54 | virtual GBool needNonText() { return gTrue; } |
51 | 55 | ||
52 | //----- initialization and control | 56 | //----- initialization and control |
53 | 57 | ||
54 | // Set default transform matrix. | 58 | // Set default transform matrix. |
@@ -116,12 +120,15 @@ public: | |||
116 | virtual void endString(GfxState *state) {} | 120 | virtual void endString(GfxState *state) {} |
117 | virtual void drawChar(GfxState *state, fouble x, fouble y, | 121 | virtual void drawChar(GfxState *state, fouble x, fouble y, |
118 | fouble dx, fouble dy, | 122 | fouble dx, fouble dy, |
119 | fouble originX, fouble originY, | 123 | fouble originX, fouble originY, |
120 | CharCode code, Unicode *u, int uLen) {} | 124 | CharCode code, Unicode *u, int uLen) {} |
121 | virtual void drawString(GfxState *state, GString *s) {} | 125 | virtual void drawString(GfxState *state, GString *s) {} |
126 | virtual GBool beginType3Char(GfxState *state, | ||
127 | CharCode code, Unicode *u, int uLen); | ||
128 | virtual void endType3Char(GfxState *state) {} | ||
122 | 129 | ||
123 | //----- image drawing | 130 | //----- image drawing |
124 | virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, | 131 | virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, |
125 | int width, int height, GBool invert, | 132 | int width, int height, GBool invert, |
126 | GBool inlineImg); | 133 | GBool inlineImg); |
127 | virtual void drawImage(GfxState *state, Object *ref, Stream *str, | 134 | virtual void drawImage(GfxState *state, Object *ref, Stream *str, |
@@ -131,12 +138,20 @@ public: | |||
131 | #if OPI_SUPPORT | 138 | #if OPI_SUPPORT |
132 | //----- OPI functions | 139 | //----- OPI functions |
133 | virtual void opiBegin(GfxState *state, Dict *opiDict); | 140 | virtual void opiBegin(GfxState *state, Dict *opiDict); |
134 | virtual void opiEnd(GfxState *state, Dict *opiDict); | 141 | virtual void opiEnd(GfxState *state, Dict *opiDict); |
135 | #endif | 142 | #endif |
136 | 143 | ||
144 | //----- Type 3 font operators | ||
145 | virtual void type3D0(GfxState *state, fouble wx, fouble wy) {} | ||
146 | virtual void type3D1(GfxState *state, fouble wx, fouble wy, | ||
147 | fouble llx, fouble lly, fouble urx, fouble ury) {} | ||
148 | |||
149 | //----- PostScript XObjects | ||
150 | virtual void psXObject(Stream *psStream, Stream *level1Stream) {} | ||
151 | |||
137 | private: | 152 | private: |
138 | 153 | ||
139 | fouble defCTM[6]; // default coordinate transform matrix | 154 | fouble defCTM[6]; // default coordinate transform matrix |
140 | fouble defICTM[6]; // inverse of default CTM | 155 | fouble defICTM[6]; // inverse of default CTM |
141 | }; | 156 | }; |
142 | 157 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/PDFDoc.cc b/noncore/unsupported/qpdf/xpdf/PDFDoc.cc index 4bbe9b7..97dfa55 100644 --- a/noncore/unsupported/qpdf/xpdf/PDFDoc.cc +++ b/noncore/unsupported/qpdf/xpdf/PDFDoc.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // PDFDoc.cc | 3 | // PDFDoc.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -21,12 +21,13 @@ | |||
21 | #include "Catalog.h" | 21 | #include "Catalog.h" |
22 | #include "Stream.h" | 22 | #include "Stream.h" |
23 | #include "XRef.h" | 23 | #include "XRef.h" |
24 | #include "Link.h" | 24 | #include "Link.h" |
25 | #include "OutputDev.h" | 25 | #include "OutputDev.h" |
26 | #include "Error.h" | 26 | #include "Error.h" |
27 | #include "ErrorCodes.h" | ||
27 | #include "Lexer.h" | 28 | #include "Lexer.h" |
28 | #include "Parser.h" | 29 | #include "Parser.h" |
29 | #include "PDFDoc.h" | 30 | #include "PDFDoc.h" |
30 | 31 | ||
31 | //------------------------------------------------------------------------ | 32 | //------------------------------------------------------------------------ |
32 | 33 | ||
@@ -40,12 +41,13 @@ | |||
40 | PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword, | 41 | PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword, |
41 | GString *userPassword, GBool printCommandsA) { | 42 | GString *userPassword, GBool printCommandsA) { |
42 | Object obj; | 43 | Object obj; |
43 | GString *fileName2; | 44 | GString *fileName2; |
44 | 45 | ||
45 | ok = gFalse; | 46 | ok = gFalse; |
47 | errCode = errNone; | ||
46 | 48 | ||
47 | file = NULL; | 49 | file = NULL; |
48 | str = NULL; | 50 | str = NULL; |
49 | xref = NULL; | 51 | xref = NULL; |
50 | catalog = NULL; | 52 | catalog = NULL; |
51 | links = NULL; | 53 | links = NULL; |
@@ -54,40 +56,43 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword, | |||
54 | // try to open file | 56 | // try to open file |
55 | fileName = fileNameA; | 57 | fileName = fileNameA; |
56 | fileName2 = NULL; | 58 | fileName2 = NULL; |
57 | #ifdef VMS | 59 | #ifdef VMS |
58 | if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) { | 60 | if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) { |
59 | error(-1, "Couldn't open file '%s'", fileName->getCString()); | 61 | error(-1, "Couldn't open file '%s'", fileName->getCString()); |
62 | errCode = errOpenFile; | ||
60 | return; | 63 | return; |
61 | } | 64 | } |
62 | #else | 65 | #else |
63 | if (!(file = fopen(fileName->getCString(), "rb"))) { | 66 | if (!(file = fopen(fileName->getCString(), "rb"))) { |
64 | fileName2 = fileName->copy(); | 67 | fileName2 = fileName->copy(); |
65 | fileName2->lowerCase(); | 68 | fileName2->lowerCase(); |
66 | if (!(file = fopen(fileName2->getCString(), "rb"))) { | 69 | if (!(file = fopen(fileName2->getCString(), "rb"))) { |
67 | fileName2->upperCase(); | 70 | fileName2->upperCase(); |
68 | if (!(file = fopen(fileName2->getCString(), "rb"))) { | 71 | if (!(file = fopen(fileName2->getCString(), "rb"))) { |
69 | error(-1, "Couldn't open file '%s'", fileName->getCString()); | 72 | error(-1, "Couldn't open file '%s'", fileName->getCString()); |
70 | delete fileName2; | 73 | delete fileName2; |
74 | errCode = errOpenFile; | ||
71 | return; | 75 | return; |
72 | } | 76 | } |
73 | } | 77 | } |
74 | delete fileName2; | 78 | delete fileName2; |
75 | } | 79 | } |
76 | #endif | 80 | #endif |
77 | 81 | ||
78 | // create stream | 82 | // create stream |
79 | obj.initNull(); | 83 | obj.initNull(); |
80 | str = new FileStream(file, 0, -1, &obj); | 84 | str = new FileStream(file, 0, gFalse, 0, &obj); |
81 | 85 | ||
82 | ok = setup(ownerPassword, userPassword); | 86 | ok = setup(ownerPassword, userPassword); |
83 | } | 87 | } |
84 | 88 | ||
85 | PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword, | 89 | PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword, |
86 | GString *userPassword, GBool printCommandsA) { | 90 | GString *userPassword, GBool printCommandsA) { |
87 | ok = gFalse; | 91 | ok = gFalse; |
92 | errCode = errNone; | ||
88 | fileName = NULL; | 93 | fileName = NULL; |
89 | file = NULL; | 94 | file = NULL; |
90 | str = strA; | 95 | str = strA; |
91 | xref = NULL; | 96 | xref = NULL; |
92 | catalog = NULL; | 97 | catalog = NULL; |
93 | links = NULL; | 98 | links = NULL; |
@@ -100,19 +105,21 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) { | |||
100 | checkHeader(); | 105 | checkHeader(); |
101 | 106 | ||
102 | // read xref table | 107 | // read xref table |
103 | xref = new XRef(str, ownerPassword, userPassword); | 108 | xref = new XRef(str, ownerPassword, userPassword); |
104 | if (!xref->isOk()) { | 109 | if (!xref->isOk()) { |
105 | error(-1, "Couldn't read xref table"); | 110 | error(-1, "Couldn't read xref table"); |
111 | errCode = xref->getErrorCode(); | ||
106 | return gFalse; | 112 | return gFalse; |
107 | } | 113 | } |
108 | 114 | ||
109 | // read catalog | 115 | // read catalog |
110 | catalog = new Catalog(xref, printCommands); | 116 | catalog = new Catalog(xref, printCommands); |
111 | if (!catalog->isOk()) { | 117 | if (!catalog->isOk()) { |
112 | error(-1, "Couldn't read page catalog"); | 118 | error(-1, "Couldn't read page catalog"); |
119 | errCode = errBadCatalog; | ||
113 | return gFalse; | 120 | return gFalse; |
114 | } | 121 | } |
115 | 122 | ||
116 | // done | 123 | // done |
117 | return gTrue; | 124 | return gTrue; |
118 | } | 125 | } |
@@ -201,14 +208,15 @@ GBool PDFDoc::isLinearized() { | |||
201 | Parser *parser; | 208 | Parser *parser; |
202 | Object obj1, obj2, obj3, obj4, obj5; | 209 | Object obj1, obj2, obj3, obj4, obj5; |
203 | GBool lin; | 210 | GBool lin; |
204 | 211 | ||
205 | lin = gFalse; | 212 | lin = gFalse; |
206 | obj1.initNull(); | 213 | obj1.initNull(); |
207 | parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), | 214 | parser = new Parser(xref, |
208 | -1, &obj1))); | 215 | new Lexer(xref, |
216 | str->makeSubStream(str->getStart(), gFalse, 0, &obj1))); | ||
209 | parser->getObj(&obj1); | 217 | parser->getObj(&obj1); |
210 | parser->getObj(&obj2); | 218 | parser->getObj(&obj2); |
211 | parser->getObj(&obj3); | 219 | parser->getObj(&obj3); |
212 | parser->getObj(&obj4); | 220 | parser->getObj(&obj4); |
213 | if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && | 221 | if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && |
214 | obj4.isDict()) { | 222 | obj4.isDict()) { |
diff --git a/noncore/unsupported/qpdf/xpdf/PDFDoc.h b/noncore/unsupported/qpdf/xpdf/PDFDoc.h index 592095e..3157683 100644 --- a/noncore/unsupported/qpdf/xpdf/PDFDoc.h +++ b/noncore/unsupported/qpdf/xpdf/PDFDoc.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // PDFDoc.h | 3 | // PDFDoc.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef PDFDOC_H | 9 | #ifndef PDFDOC_H |
10 | #define PDFDOC_H | 10 | #define PDFDOC_H |
11 | 11 | ||
@@ -39,12 +39,15 @@ public: | |||
39 | GString *userPassword = NULL, GBool printCommandsA = gFalse); | 39 | GString *userPassword = NULL, GBool printCommandsA = gFalse); |
40 | ~PDFDoc(); | 40 | ~PDFDoc(); |
41 | 41 | ||
42 | // Was PDF document successfully opened? | 42 | // Was PDF document successfully opened? |
43 | GBool isOk() { return ok; } | 43 | GBool isOk() { return ok; } |
44 | 44 | ||
45 | // Get the error code (if isOk() returns false). | ||
46 | int getErrorCode() { return errCode; } | ||
47 | |||
45 | // Get file name. | 48 | // Get file name. |
46 | GString *getFileName() { return fileName; } | 49 | GString *getFileName() { return fileName; } |
47 | 50 | ||
48 | // Get the xref table. | 51 | // Get the xref table. |
49 | XRef *getXRef() { return xref; } | 52 | XRef *getXRef() { return xref; } |
50 | 53 | ||
@@ -134,9 +137,10 @@ private: | |||
134 | XRef *xref; | 137 | XRef *xref; |
135 | Catalog *catalog; | 138 | Catalog *catalog; |
136 | Links *links; | 139 | Links *links; |
137 | GBool printCommands; | 140 | GBool printCommands; |
138 | 141 | ||
139 | GBool ok; | 142 | GBool ok; |
143 | int errCode; | ||
140 | }; | 144 | }; |
141 | 145 | ||
142 | #endif | 146 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc b/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc new file mode 100644 index 0000000..8d654bd --- a/dev/null +++ b/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc | |||
@@ -0,0 +1,133 @@ | |||
1 | //======================================================================== | ||
2 | // | ||
3 | // PSTokenizer.cc | ||
4 | // | ||
5 | // Copyright 2002 Glyph & Cog, LLC | ||
6 | // | ||
7 | //======================================================================== | ||
8 | |||
9 | #ifdef __GNUC__ | ||
10 | #pragma implementation | ||
11 | #endif | ||
12 | |||
13 | #include <stdio.h> | ||
14 | #include <stdlib.h> | ||
15 | #include "PSTokenizer.h" | ||
16 | |||
17 | //------------------------------------------------------------------------ | ||
18 | |||
19 | // A '1' in this array means the character is white space. A '1' or | ||
20 | // '2' means the character ends a name or command. | ||
21 | static char specialChars[256] = { | ||
22 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x | ||
23 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x | ||
24 | 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x | ||
25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x | ||
26 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x | ||
27 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x | ||
28 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x | ||
29 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x | ||
30 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x | ||
31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x | ||
32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax | ||
33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx | ||
34 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx | ||
35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx | ||
36 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex | ||
37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx | ||
38 | }; | ||
39 | |||
40 | //------------------------------------------------------------------------ | ||
41 | |||
42 | PSTokenizer::PSTokenizer(int (*getCharFuncA)(void *), void *dataA) { | ||
43 | getCharFunc = getCharFuncA; | ||
44 | data = dataA; | ||
45 | charBuf = -1; | ||
46 | } | ||
47 | |||
48 | PSTokenizer::~PSTokenizer() { | ||
49 | } | ||
50 | |||
51 | GBool PSTokenizer::getToken(char *buf, int size, int *length) { | ||
52 | GBool comment, backslash; | ||
53 | int c; | ||
54 | int i; | ||
55 | |||
56 | // skip whitespace and comments | ||
57 | comment = gFalse; | ||
58 | while (1) { | ||
59 | if ((c = getChar()) == EOF) { | ||
60 | buf[0] = '\0'; | ||
61 | *length = 0; | ||
62 | return gFalse; | ||
63 | } | ||
64 | if (comment) { | ||
65 | if (c == '\x0a' || c == '\x0d') { | ||
66 | comment = gFalse; | ||
67 | } | ||
68 | } else if (c == '%') { | ||
69 | comment = gTrue; | ||
70 | } else if (specialChars[c] != 1) { | ||
71 | break; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | // read a token | ||
76 | i = 0; | ||
77 | buf[i++] = c; | ||
78 | if (c == '(') { | ||
79 | backslash = gFalse; | ||
80 | while ((c = lookChar()) != EOF) { | ||
81 | if (i < size - 1) { | ||
82 | buf[i++] = c; | ||
83 | } | ||
84 | getChar(); | ||
85 | if (c == '\\') { | ||
86 | backslash = gTrue; | ||
87 | } else if (!backslash && c == ')') { | ||
88 | break; | ||
89 | } else { | ||
90 | backslash = gFalse; | ||
91 | } | ||
92 | } | ||
93 | } else if (c == '<') { | ||
94 | while ((c = lookChar()) != EOF) { | ||
95 | getChar(); | ||
96 | if (i < size - 1) { | ||
97 | buf[i++] = c; | ||
98 | } | ||
99 | if (c == '>') { | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | } else if (c != '[' && c != ']') { | ||
104 | while ((c = lookChar()) != EOF && !specialChars[c]) { | ||
105 | getChar(); | ||
106 | if (i < size - 1) { | ||
107 | buf[i++] = c; | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | buf[i] = '\0'; | ||
112 | *length = i; | ||
113 | |||
114 | return gTrue; | ||
115 | } | ||
116 | |||
117 | int PSTokenizer::lookChar() { | ||
118 | if (charBuf < 0) { | ||
119 | charBuf = (*getCharFunc)(data); | ||
120 | } | ||
121 | return charBuf; | ||
122 | } | ||
123 | |||
124 | int PSTokenizer::getChar() { | ||
125 | int c; | ||
126 | |||
127 | if (charBuf < 0) { | ||
128 | charBuf = (*getCharFunc)(data); | ||
129 | } | ||
130 | c = charBuf; | ||
131 | charBuf = -1; | ||
132 | return c; | ||
133 | } | ||
diff --git a/noncore/unsupported/qpdf/xpdf/PSTokenizer.h b/noncore/unsupported/qpdf/xpdf/PSTokenizer.h new file mode 100644 index 0000000..1053c67 --- a/dev/null +++ b/noncore/unsupported/qpdf/xpdf/PSTokenizer.h | |||
@@ -0,0 +1,39 @@ | |||
1 | //======================================================================== | ||
2 | // | ||
3 | // PSTokenizer.h | ||
4 | // | ||
5 | // Copyright 2002 Glyph & Cog, LLC | ||
6 | // | ||
7 | //======================================================================== | ||
8 | |||
9 | #ifndef PSTOKENIZER_H | ||
10 | #define PSTOKENIZER_H | ||
11 | |||
12 | #ifdef __GNUC__ | ||
13 | #pragma interface | ||
14 | #endif | ||
15 | |||
16 | #include "gtypes.h" | ||
17 | |||
18 | //------------------------------------------------------------------------ | ||
19 | |||
20 | class PSTokenizer { | ||
21 | public: | ||
22 | |||
23 | PSTokenizer(int (*getCharFuncA)(void *), void *dataA); | ||
24 | ~PSTokenizer(); | ||
25 | |||
26 | // Get the next PostScript token. Returns false at end-of-stream. | ||
27 | GBool getToken(char *buf, int size, int *length); | ||
28 | |||
29 | private: | ||
30 | |||
31 | int lookChar(); | ||
32 | int getChar(); | ||
33 | |||
34 | int (*getCharFunc)(void *); | ||
35 | void *data; | ||
36 | int charBuf; | ||
37 | }; | ||
38 | |||
39 | #endif | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Page.cc b/noncore/unsupported/qpdf/xpdf/Page.cc index 17c4481..9cc08c4 100644 --- a/noncore/unsupported/qpdf/xpdf/Page.cc +++ b/noncore/unsupported/qpdf/xpdf/Page.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Page.cc | 3 | // Page.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -17,13 +17,13 @@ | |||
17 | #include "Dict.h" | 17 | #include "Dict.h" |
18 | #include "XRef.h" | 18 | #include "XRef.h" |
19 | #include "Link.h" | 19 | #include "Link.h" |
20 | #include "OutputDev.h" | 20 | #include "OutputDev.h" |
21 | #ifndef PDF_PARSER_ONLY | 21 | #ifndef PDF_PARSER_ONLY |
22 | #include "Gfx.h" | 22 | #include "Gfx.h" |
23 | #include "FormWidget.h" | 23 | #include "Annot.h" |
24 | #endif | 24 | #endif |
25 | #include "Error.h" | 25 | #include "Error.h" |
26 | #include "Page.h" | 26 | #include "Page.h" |
27 | 27 | ||
28 | //------------------------------------------------------------------------ | 28 | //------------------------------------------------------------------------ |
29 | // PageAttrs | 29 | // PageAttrs |
@@ -90,22 +90,36 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) { | |||
90 | rotate += 360; | 90 | rotate += 360; |
91 | } | 91 | } |
92 | while (rotate >= 360) { | 92 | while (rotate >= 360) { |
93 | rotate -= 360; | 93 | rotate -= 360; |
94 | } | 94 | } |
95 | 95 | ||
96 | // misc attributes | ||
97 | dict->lookup("LastModified", &lastModified); | ||
98 | dict->lookup("BoxColorInfo", &boxColorInfo); | ||
99 | dict->lookup("Group", &group); | ||
100 | dict->lookup("Metadata", &metadata); | ||
101 | dict->lookup("PieceInfo", &pieceInfo); | ||
102 | dict->lookup("SeparationInfo", &separationInfo); | ||
103 | |||
96 | // resource dictionary | 104 | // resource dictionary |
97 | dict->lookup("Resources", &obj1); | 105 | dict->lookup("Resources", &obj1); |
98 | if (obj1.isDict()) { | 106 | if (obj1.isDict()) { |
99 | resources.free(); | 107 | resources.free(); |
100 | obj1.copy(&resources); | 108 | obj1.copy(&resources); |
101 | } | 109 | } |
102 | obj1.free(); | 110 | obj1.free(); |
103 | } | 111 | } |
104 | 112 | ||
105 | PageAttrs::~PageAttrs() { | 113 | PageAttrs::~PageAttrs() { |
114 | lastModified.free(); | ||
115 | boxColorInfo.free(); | ||
116 | group.free(); | ||
117 | metadata.free(); | ||
118 | pieceInfo.free(); | ||
119 | separationInfo.free(); | ||
106 | resources.free(); | 120 | resources.free(); |
107 | } | 121 | } |
108 | 122 | ||
109 | GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) { | 123 | GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) { |
110 | PDFRectangle tmp; | 124 | PDFRectangle tmp; |
111 | Object obj1, obj2; | 125 | Object obj1, obj2; |
@@ -206,13 +220,13 @@ void Page::display(OutputDev *out, fouble dpi, int rotate, | |||
206 | #ifndef PDF_PARSER_ONLY | 220 | #ifndef PDF_PARSER_ONLY |
207 | PDFRectangle *box, *cropBox; | 221 | PDFRectangle *box, *cropBox; |
208 | Gfx *gfx; | 222 | Gfx *gfx; |
209 | Object obj; | 223 | Object obj; |
210 | Link *link; | 224 | Link *link; |
211 | int i; | 225 | int i; |
212 | FormWidgets *formWidgets; | 226 | Annots *annotList; |
213 | 227 | ||
214 | box = getBox(); | 228 | box = getBox(); |
215 | cropBox = getCropBox(); | 229 | cropBox = getCropBox(); |
216 | 230 | ||
217 | if (printCommands) { | 231 | if (printCommands) { |
218 | printf("***** MediaBox = ll:%g,%g ur:%g,%g\n", | 232 | printf("***** MediaBox = ll:%g,%g ur:%g,%g\n", |
@@ -244,24 +258,24 @@ void Page::display(OutputDev *out, fouble dpi, int rotate, | |||
244 | link = links->getLink(i); | 258 | link = links->getLink(i); |
245 | out->drawLink(link, catalog); | 259 | out->drawLink(link, catalog); |
246 | } | 260 | } |
247 | out->dump(); | 261 | out->dump(); |
248 | } | 262 | } |
249 | 263 | ||
250 | // draw AcroForm widgets | 264 | // draw non-link annotations |
251 | //~ need to reset CTM ??? | 265 | //~ need to reset CTM ??? |
252 | formWidgets = new FormWidgets(xref, annots.fetch(xref, &obj)); | 266 | annotList = new Annots(xref, annots.fetch(xref, &obj)); |
253 | obj.free(); | 267 | obj.free(); |
254 | if (printCommands && formWidgets->getNumWidgets() > 0) { | 268 | if (annotList->getNumAnnots() > 0) { |
255 | printf("***** AcroForm widgets\n"); | 269 | if (printCommands) { |
256 | } | 270 | printf("***** Annotations\n"); |
257 | for (i = 0; i < formWidgets->getNumWidgets(); ++i) { | 271 | } |
258 | formWidgets->getWidget(i)->draw(gfx); | 272 | for (i = 0; i < annotList->getNumAnnots(); ++i) { |
259 | } | 273 | annotList->getAnnot(i)->draw(gfx); |
260 | if (formWidgets->getNumWidgets() > 0) { | 274 | } |
261 | out->dump(); | 275 | out->dump(); |
262 | } | 276 | } |
263 | delete formWidgets; | 277 | delete annotList; |
264 | 278 | ||
265 | delete gfx; | 279 | delete gfx; |
266 | #endif | 280 | #endif |
267 | } | 281 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/Page.h b/noncore/unsupported/qpdf/xpdf/Page.h index 203878f..57e802a 100644 --- a/noncore/unsupported/qpdf/xpdf/Page.h +++ b/noncore/unsupported/qpdf/xpdf/Page.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Page.h | 3 | // Page.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef PAGE_H | 9 | #ifndef PAGE_H |
10 | #define PAGE_H | 10 | #define PAGE_H |
11 | 11 | ||
@@ -48,12 +48,26 @@ public: | |||
48 | PDFRectangle *getCropBox() { return &cropBox; } | 48 | PDFRectangle *getCropBox() { return &cropBox; } |
49 | GBool isCropped() { return haveCropBox; } | 49 | GBool isCropped() { return haveCropBox; } |
50 | PDFRectangle *getBleedBox() { return &bleedBox; } | 50 | PDFRectangle *getBleedBox() { return &bleedBox; } |
51 | PDFRectangle *getTrimBox() { return &trimBox; } | 51 | PDFRectangle *getTrimBox() { return &trimBox; } |
52 | PDFRectangle *getArtBox() { return &artBox; } | 52 | PDFRectangle *getArtBox() { return &artBox; } |
53 | int getRotate() { return rotate; } | 53 | int getRotate() { return rotate; } |
54 | GString *getLastModified() | ||
55 | { return lastModified.isString() | ||
56 | ? lastModified.getString() : (GString *)NULL; } | ||
57 | Dict *getBoxColorInfo() | ||
58 | { return boxColorInfo.isDict() ? boxColorInfo.getDict() : (Dict *)NULL; } | ||
59 | Dict *getGroup() | ||
60 | { return group.isDict() ? group.getDict() : (Dict *)NULL; } | ||
61 | Stream *getMetadata() | ||
62 | { return metadata.isStream() ? metadata.getStream() : (Stream *)NULL; } | ||
63 | Dict *getPieceInfo() | ||
64 | { return pieceInfo.isDict() ? pieceInfo.getDict() : (Dict *)NULL; } | ||
65 | Dict *getSeparationInfo() | ||
66 | { return separationInfo.isDict() | ||
67 | ? separationInfo.getDict() : (Dict *)NULL; } | ||
54 | Dict *getResourceDict() | 68 | Dict *getResourceDict() |
55 | { return resources.isDict() ? resources.getDict() : (Dict *)NULL; } | 69 | { return resources.isDict() ? resources.getDict() : (Dict *)NULL; } |
56 | 70 | ||
57 | private: | 71 | private: |
58 | 72 | ||
59 | GBool readBox(Dict *dict, char *key, PDFRectangle *box); | 73 | GBool readBox(Dict *dict, char *key, PDFRectangle *box); |
@@ -63,12 +77,18 @@ private: | |||
63 | GBool haveCropBox; | 77 | GBool haveCropBox; |
64 | GBool limitToCropBox; | 78 | GBool limitToCropBox; |
65 | PDFRectangle bleedBox; | 79 | PDFRectangle bleedBox; |
66 | PDFRectangle trimBox; | 80 | PDFRectangle trimBox; |
67 | PDFRectangle artBox; | 81 | PDFRectangle artBox; |
68 | int rotate; | 82 | int rotate; |
83 | Object lastModified; | ||
84 | Object boxColorInfo; | ||
85 | Object group; | ||
86 | Object metadata; | ||
87 | Object pieceInfo; | ||
88 | Object separationInfo; | ||
69 | Object resources; | 89 | Object resources; |
70 | }; | 90 | }; |
71 | 91 | ||
72 | //------------------------------------------------------------------------ | 92 | //------------------------------------------------------------------------ |
73 | // Page | 93 | // Page |
74 | //------------------------------------------------------------------------ | 94 | //------------------------------------------------------------------------ |
@@ -94,12 +114,18 @@ public: | |||
94 | fouble getWidth() { return attrs->getBox()->x2 - attrs->getBox()->x1; } | 114 | fouble getWidth() { return attrs->getBox()->x2 - attrs->getBox()->x1; } |
95 | fouble getHeight() { return attrs->getBox()->y2 - attrs->getBox()->y1; } | 115 | fouble getHeight() { return attrs->getBox()->y2 - attrs->getBox()->y1; } |
96 | PDFRectangle *getBleedBox() { return attrs->getBleedBox(); } | 116 | PDFRectangle *getBleedBox() { return attrs->getBleedBox(); } |
97 | PDFRectangle *getTrimBox() { return attrs->getTrimBox(); } | 117 | PDFRectangle *getTrimBox() { return attrs->getTrimBox(); } |
98 | PDFRectangle *getArtBox() { return attrs->getArtBox(); } | 118 | PDFRectangle *getArtBox() { return attrs->getArtBox(); } |
99 | int getRotate() { return attrs->getRotate(); } | 119 | int getRotate() { return attrs->getRotate(); } |
120 | GString *getLastModified() { return attrs->getLastModified(); } | ||
121 | Dict *getBoxColorInfo() { return attrs->getBoxColorInfo(); } | ||
122 | Dict *getGroup() { return attrs->getGroup(); } | ||
123 | Stream *getMetadata() { return attrs->getMetadata(); } | ||
124 | Dict *getPieceInfo() { return attrs->getPieceInfo(); } | ||
125 | Dict *getSeparationInfo() { return attrs->getSeparationInfo(); } | ||
100 | 126 | ||
101 | // Get resource dictionary. | 127 | // Get resource dictionary. |
102 | Dict *getResourceDict() { return attrs->getResourceDict(); } | 128 | Dict *getResourceDict() { return attrs->getResourceDict(); } |
103 | 129 | ||
104 | // Get annotations array. | 130 | // Get annotations array. |
105 | Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); } | 131 | Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); } |
diff --git a/noncore/unsupported/qpdf/xpdf/Parser.cc b/noncore/unsupported/qpdf/xpdf/Parser.cc index a98753d..4df53c9 100644 --- a/noncore/unsupported/qpdf/xpdf/Parser.cc +++ b/noncore/unsupported/qpdf/xpdf/Parser.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Parser.cc | 3 | // Parser.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -152,36 +152,37 @@ Object *Parser::getObj(Object *obj) { | |||
152 | return obj; | 152 | return obj; |
153 | } | 153 | } |
154 | 154 | ||
155 | Stream *Parser::makeStream(Object *dict) { | 155 | Stream *Parser::makeStream(Object *dict) { |
156 | Object obj; | 156 | Object obj; |
157 | Stream *str; | 157 | Stream *str; |
158 | int pos, endPos, length; | 158 | Guint pos, endPos, length; |
159 | 159 | ||
160 | // get stream start position | 160 | // get stream start position |
161 | lexer->skipToNextLine(); | 161 | lexer->skipToNextLine(); |
162 | pos = lexer->getPos(); | 162 | pos = lexer->getPos(); |
163 | 163 | ||
164 | // get length | 164 | // get length |
165 | dict->dictLookup("Length", &obj); | 165 | dict->dictLookup("Length", &obj); |
166 | if (obj.isInt()) { | 166 | if (obj.isInt()) { |
167 | length = obj.getInt(); | 167 | length = (Guint)obj.getInt(); |
168 | obj.free(); | 168 | obj.free(); |
169 | } else { | 169 | } else { |
170 | error(getPos(), "Bad 'Length' attribute in stream"); | 170 | error(getPos(), "Bad 'Length' attribute in stream"); |
171 | obj.free(); | 171 | obj.free(); |
172 | return NULL; | 172 | return NULL; |
173 | } | 173 | } |
174 | 174 | ||
175 | // check for length in damaged file | 175 | // check for length in damaged file |
176 | if ((endPos = xref->getStreamEnd(pos)) >= 0) { | 176 | if (xref->getStreamEnd(pos, &endPos)) { |
177 | length = endPos - pos; | 177 | length = endPos - pos; |
178 | } | 178 | } |
179 | 179 | ||
180 | // make base stream | 180 | // make base stream |
181 | str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict); | 181 | str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue, |
182 | length, dict); | ||
182 | 183 | ||
183 | // get filters | 184 | // get filters |
184 | str = str->addFilters(dict); | 185 | str = str->addFilters(dict); |
185 | 186 | ||
186 | // skip over stream data | 187 | // skip over stream data |
187 | lexer->setPos(pos + length); | 188 | lexer->setPos(pos + length); |
diff --git a/noncore/unsupported/qpdf/xpdf/Parser.h b/noncore/unsupported/qpdf/xpdf/Parser.h index 463d998..c11475b 100644 --- a/noncore/unsupported/qpdf/xpdf/Parser.h +++ b/noncore/unsupported/qpdf/xpdf/Parser.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Parser.h | 3 | // Parser.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef PARSER_H | 9 | #ifndef PARSER_H |
10 | #define PARSER_H | 10 | #define PARSER_H |
11 | 11 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h b/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h index 1af8742..f5a77b0 100644 --- a/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h +++ b/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h | |||
@@ -1,13 +1,13 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Stream-CCITT.h | 3 | // Stream-CCITT.h |
4 | // | 4 | // |
5 | // Tables for CCITT Fax decoding. | 5 | // Tables for CCITT Fax decoding. |
6 | // | 6 | // |
7 | // Copyright 1996 Derek B. Noonburg | 7 | // Copyright 1996-2002 Glyph & Cog, LLC |
8 | // | 8 | // |
9 | //======================================================================== | 9 | //======================================================================== |
10 | 10 | ||
11 | struct CCITTCode { | 11 | struct CCITTCode { |
12 | short bits; | 12 | short bits; |
13 | short n; | 13 | short n; |
diff --git a/noncore/unsupported/qpdf/xpdf/Stream.cc b/noncore/unsupported/qpdf/xpdf/Stream.cc index 18490d4..c558478 100644 --- a/noncore/unsupported/qpdf/xpdf/Stream.cc +++ b/noncore/unsupported/qpdf/xpdf/Stream.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Stream.cc | 3 | // Stream.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -300,13 +300,13 @@ FilterStream::~FilterStream() { | |||
300 | } | 300 | } |
301 | 301 | ||
302 | void FilterStream::close() { | 302 | void FilterStream::close() { |
303 | str->close(); | 303 | str->close(); |
304 | } | 304 | } |
305 | 305 | ||
306 | void FilterStream::setPos(int pos) { | 306 | void FilterStream::setPos(Guint pos, int dir) { |
307 | error(-1, "Internal: called setPos() on FilterStream"); | 307 | error(-1, "Internal: called setPos() on FilterStream"); |
308 | } | 308 | } |
309 | 309 | ||
310 | //------------------------------------------------------------------------ | 310 | //------------------------------------------------------------------------ |
311 | // ImageStream | 311 | // ImageStream |
312 | //------------------------------------------------------------------------ | 312 | //------------------------------------------------------------------------ |
@@ -551,60 +551,74 @@ GBool StreamPredictor::getNextLine() { | |||
551 | } | 551 | } |
552 | 552 | ||
553 | //------------------------------------------------------------------------ | 553 | //------------------------------------------------------------------------ |
554 | // FileStream | 554 | // FileStream |
555 | //------------------------------------------------------------------------ | 555 | //------------------------------------------------------------------------ |
556 | 556 | ||
557 | FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA): | 557 | FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA, |
558 | Guint lengthA, Object *dictA): | ||
558 | BaseStream(dictA) { | 559 | BaseStream(dictA) { |
559 | f = fA; | 560 | f = fA; |
560 | start = startA; | 561 | start = startA; |
562 | limited = limitedA; | ||
561 | length = lengthA; | 563 | length = lengthA; |
562 | bufPtr = bufEnd = buf; | 564 | bufPtr = bufEnd = buf; |
563 | bufPos = start; | 565 | bufPos = start; |
564 | savePos = -1; | 566 | savePos = 0; |
567 | saved = gFalse; | ||
565 | } | 568 | } |
566 | 569 | ||
567 | FileStream::~FileStream() { | 570 | FileStream::~FileStream() { |
568 | close(); | 571 | close(); |
569 | } | 572 | } |
570 | 573 | ||
571 | Stream *FileStream::makeSubStream(int startA, int lengthA, Object *dictA) { | 574 | Stream *FileStream::makeSubStream(Guint startA, GBool limitedA, |
572 | return new FileStream(f, startA, lengthA, dictA); | 575 | Guint lengthA, Object *dictA) { |
576 | return new FileStream(f, startA, limitedA, lengthA, dictA); | ||
573 | } | 577 | } |
574 | 578 | ||
575 | void FileStream::reset() { | 579 | void FileStream::reset() { |
576 | savePos = (int)ftell(f); | 580 | #if HAVE_FSEEK64 |
581 | savePos = (Guint)ftell64(f); | ||
582 | fseek64(f, start, SEEK_SET); | ||
583 | #else | ||
584 | savePos = (Guint)ftell(f); | ||
577 | fseek(f, start, SEEK_SET); | 585 | fseek(f, start, SEEK_SET); |
586 | #endif | ||
587 | saved = gTrue; | ||
578 | bufPtr = bufEnd = buf; | 588 | bufPtr = bufEnd = buf; |
579 | bufPos = start; | 589 | bufPos = start; |
580 | #ifndef NO_DECRYPTION | 590 | #ifndef NO_DECRYPTION |
581 | if (decrypt) | 591 | if (decrypt) |
582 | decrypt->reset(); | 592 | decrypt->reset(); |
583 | #endif | 593 | #endif |
584 | } | 594 | } |
585 | 595 | ||
586 | void FileStream::close() { | 596 | void FileStream::close() { |
587 | if (savePos >= 0) { | 597 | if (saved) { |
598 | #if HAVE_FSEEK64 | ||
599 | fseek64(f, savePos, SEEK_SET); | ||
600 | #else | ||
588 | fseek(f, savePos, SEEK_SET); | 601 | fseek(f, savePos, SEEK_SET); |
589 | savePos = -1; | 602 | #endif |
603 | saved = gFalse; | ||
590 | } | 604 | } |
591 | } | 605 | } |
592 | 606 | ||
593 | GBool FileStream::fillBuf() { | 607 | GBool FileStream::fillBuf() { |
594 | int n; | 608 | int n; |
595 | #ifndef NO_DECRYPTION | 609 | #ifndef NO_DECRYPTION |
596 | char *p; | 610 | char *p; |
597 | #endif | 611 | #endif |
598 | 612 | ||
599 | bufPos += bufEnd - buf; | 613 | bufPos += bufEnd - buf; |
600 | bufPtr = bufEnd = buf; | 614 | bufPtr = bufEnd = buf; |
601 | if (length >= 0 && bufPos >= start + length) { | 615 | if (limited && bufPos >= start + length) { |
602 | return gFalse; | 616 | return gFalse; |
603 | } | 617 | } |
604 | if (length >= 0 && bufPos + fileStreamBufSize > start + length) { | 618 | if (limited && bufPos + fileStreamBufSize > start + length) { |
605 | n = start + length - bufPos; | 619 | n = start + length - bufPos; |
606 | } else { | 620 | } else { |
607 | n = fileStreamBufSize; | 621 | n = fileStreamBufSize; |
608 | } | 622 | } |
609 | n = fread(buf, 1, n, f); | 623 | n = fread(buf, 1, n, f); |
610 | bufEnd = buf + n; | 624 | bufEnd = buf + n; |
@@ -618,66 +632,165 @@ GBool FileStream::fillBuf() { | |||
618 | } | 632 | } |
619 | } | 633 | } |
620 | #endif | 634 | #endif |
621 | return gTrue; | 635 | return gTrue; |
622 | } | 636 | } |
623 | 637 | ||
624 | void FileStream::setPos(int pos) { | 638 | void FileStream::setPos(Guint pos, int dir) { |
625 | long size; | 639 | Guint size; |
626 | 640 | ||
627 | if (pos >= 0) { | 641 | if (dir >= 0) { |
642 | #if HAVE_FSEEK64 | ||
643 | fseek64(f, pos, SEEK_SET); | ||
644 | #else | ||
628 | fseek(f, pos, SEEK_SET); | 645 | fseek(f, pos, SEEK_SET); |
646 | #endif | ||
629 | bufPos = pos; | 647 | bufPos = pos; |
630 | } else { | 648 | } else { |
649 | #if HAVE_FSEEK64 | ||
650 | fseek64(f, 0, SEEK_END); | ||
651 | size = (Guint)ftell64(f); | ||
652 | #else | ||
631 | fseek(f, 0, SEEK_END); | 653 | fseek(f, 0, SEEK_END); |
632 | size = ftell(f); | 654 | size = (Guint)ftell(f); |
633 | if (pos < -size) | 655 | #endif |
634 | pos = (int)(-size); | 656 | if (pos > size) |
657 | pos = (Guint)size; | ||
635 | #ifdef __CYGWIN32__ | 658 | #ifdef __CYGWIN32__ |
636 | //~ work around a bug in cygwin's implementation of fseek | 659 | //~ work around a bug in cygwin's implementation of fseek |
637 | rewind(f); | 660 | rewind(f); |
638 | #endif | 661 | #endif |
639 | fseek(f, pos, SEEK_END); | 662 | #if HAVE_FSEEK64 |
640 | bufPos = (int)ftell(f); | 663 | fseek64(f, -(int)pos, SEEK_END); |
664 | bufPos = (Guint)ftell64(f); | ||
665 | #else | ||
666 | fseek(f, -(int)pos, SEEK_END); | ||
667 | bufPos = (Guint)ftell(f); | ||
668 | #endif | ||
641 | } | 669 | } |
642 | bufPtr = bufEnd = buf; | 670 | bufPtr = bufEnd = buf; |
643 | } | 671 | } |
644 | 672 | ||
645 | void FileStream::moveStart(int delta) { | 673 | void FileStream::moveStart(int delta) { |
646 | start += delta; | 674 | start += delta; |
647 | bufPtr = bufEnd = buf; | 675 | bufPtr = bufEnd = buf; |
648 | bufPos = start; | 676 | bufPos = start; |
649 | } | 677 | } |
650 | 678 | ||
651 | //------------------------------------------------------------------------ | 679 | //------------------------------------------------------------------------ |
680 | // MemStream | ||
681 | //------------------------------------------------------------------------ | ||
682 | |||
683 | MemStream::MemStream(char *bufA, Guint lengthA, Object *dictA): | ||
684 | BaseStream(dictA) { | ||
685 | buf = bufA; | ||
686 | needFree = gFalse; | ||
687 | length = lengthA; | ||
688 | bufEnd = buf + length; | ||
689 | bufPtr = buf; | ||
690 | } | ||
691 | |||
692 | MemStream::~MemStream() { | ||
693 | if (needFree) { | ||
694 | gfree(buf); | ||
695 | } | ||
696 | } | ||
697 | |||
698 | Stream *MemStream::makeSubStream(Guint start, GBool limited, | ||
699 | Guint lengthA, Object *dictA) { | ||
700 | Guint newLength; | ||
701 | |||
702 | if (!limited || start + lengthA > length) { | ||
703 | newLength = length - start; | ||
704 | } else { | ||
705 | newLength = lengthA; | ||
706 | } | ||
707 | return new MemStream(buf + start, newLength, dictA); | ||
708 | } | ||
709 | |||
710 | void MemStream::reset() { | ||
711 | bufPtr = buf; | ||
712 | #ifndef NO_DECRYPTION | ||
713 | if (decrypt) { | ||
714 | decrypt->reset(); | ||
715 | } | ||
716 | #endif | ||
717 | } | ||
718 | |||
719 | void MemStream::close() { | ||
720 | } | ||
721 | |||
722 | void MemStream::setPos(Guint pos, int dir) { | ||
723 | if (dir >= 0) { | ||
724 | if (pos > length) { | ||
725 | bufPtr = bufEnd; | ||
726 | } else { | ||
727 | bufPtr = buf + pos; | ||
728 | } | ||
729 | } else { | ||
730 | if (pos > length) { | ||
731 | bufPtr = buf; | ||
732 | } else { | ||
733 | bufPtr = bufEnd - pos; | ||
734 | } | ||
735 | } | ||
736 | } | ||
737 | |||
738 | void MemStream::moveStart(int delta) { | ||
739 | buf += delta; | ||
740 | bufPtr = buf; | ||
741 | } | ||
742 | |||
743 | #ifndef NO_DECRYPTION | ||
744 | void MemStream::doDecryption(Guchar *fileKey, int keyLength, | ||
745 | int objNum, int objGen) { | ||
746 | char *newBuf; | ||
747 | char *p, *q; | ||
748 | |||
749 | this->BaseStream::doDecryption(fileKey, keyLength, objNum, objGen); | ||
750 | if (decrypt) { | ||
751 | newBuf = (char *)gmalloc(bufEnd - buf); | ||
752 | for (p = buf, q = newBuf; p < bufEnd; ++p, ++q) { | ||
753 | *q = (char)decrypt->decryptByte((Guchar)*p); | ||
754 | } | ||
755 | bufEnd = newBuf + (bufEnd - buf); | ||
756 | bufPtr = newBuf + (bufPtr - buf); | ||
757 | buf = newBuf; | ||
758 | needFree = gTrue; | ||
759 | } | ||
760 | } | ||
761 | #endif | ||
762 | |||
763 | //------------------------------------------------------------------------ | ||
652 | // EmbedStream | 764 | // EmbedStream |
653 | //------------------------------------------------------------------------ | 765 | //------------------------------------------------------------------------ |
654 | 766 | ||
655 | EmbedStream::EmbedStream(Stream *strA, Object *dictA): | 767 | EmbedStream::EmbedStream(Stream *strA, Object *dictA): |
656 | BaseStream(dictA) { | 768 | BaseStream(dictA) { |
657 | str = strA; | 769 | str = strA; |
658 | } | 770 | } |
659 | 771 | ||
660 | EmbedStream::~EmbedStream() { | 772 | EmbedStream::~EmbedStream() { |
661 | } | 773 | } |
662 | 774 | ||
663 | Stream *EmbedStream::makeSubStream(int start, int length, Object *dictA) { | 775 | Stream *EmbedStream::makeSubStream(Guint start, GBool limited, |
776 | Guint length, Object *dictA) { | ||
664 | error(-1, "Internal: called makeSubStream() on EmbedStream"); | 777 | error(-1, "Internal: called makeSubStream() on EmbedStream"); |
665 | return NULL; | 778 | return NULL; |
666 | } | 779 | } |
667 | 780 | ||
668 | void EmbedStream::setPos(int pos) { | 781 | void EmbedStream::setPos(Guint pos, int dir) { |
669 | error(-1, "Internal: called setPos() on EmbedStream"); | 782 | error(-1, "Internal: called setPos() on EmbedStream"); |
670 | } | 783 | } |
671 | 784 | ||
672 | int EmbedStream::getStart() { | 785 | Guint EmbedStream::getStart() { |
673 | error(-1, "Internal: called getStart() on EmbedStream"); | 786 | error(-1, "Internal: called getStart() on EmbedStream"); |
674 | return 0; | 787 | return 0; |
675 | } | 788 | } |
676 | 789 | ||
677 | void EmbedStream::moveStart(int start) { | 790 | void EmbedStream::moveStart(int delta) { |
678 | error(-1, "Internal: called moveStart() on EmbedStream"); | 791 | error(-1, "Internal: called moveStart() on EmbedStream"); |
679 | } | 792 | } |
680 | 793 | ||
681 | //------------------------------------------------------------------------ | 794 | //------------------------------------------------------------------------ |
682 | // ASCIIHexStream | 795 | // ASCIIHexStream |
683 | //------------------------------------------------------------------------ | 796 | //------------------------------------------------------------------------ |
@@ -956,17 +1069,13 @@ void LZWStream::reset() { | |||
956 | error(getPos(), "Couldn't popen '%s'", zCmd->getCString()); | 1069 | error(getPos(), "Couldn't popen '%s'", zCmd->getCString()); |
957 | unlink(zName->getCString()); | 1070 | unlink(zName->getCString()); |
958 | delete zName; | 1071 | delete zName; |
959 | return; | 1072 | return; |
960 | } | 1073 | } |
961 | #else // HAVE_POPEN | 1074 | #else // HAVE_POPEN |
962 | #ifdef VMS | 1075 | if (!executeCommand(zCmd->getCString())) { |
963 | if (!system(zCmd->getCString())) { | ||
964 | #else | ||
965 | if (system(zCmd->getCString())) { | ||
966 | #endif | ||
967 | error(getPos(), "Couldn't execute '%s'", zCmd->getCString()); | 1076 | error(getPos(), "Couldn't execute '%s'", zCmd->getCString()); |
968 | unlink(zName->getCString()); | 1077 | unlink(zName->getCString()); |
969 | delete zName; | 1078 | delete zName; |
970 | return; | 1079 | return; |
971 | } | 1080 | } |
972 | zName->del(zName->getLength() - 2, 2); | 1081 | zName->del(zName->getLength() - 2, 2); |
@@ -3284,12 +3393,62 @@ int FixedLengthEncoder::lookChar() { | |||
3284 | if (length >= 0 && count >= length) | 3393 | if (length >= 0 && count >= length) |
3285 | return EOF; | 3394 | return EOF; |
3286 | return str->getChar(); | 3395 | return str->getChar(); |
3287 | } | 3396 | } |
3288 | 3397 | ||
3289 | //------------------------------------------------------------------------ | 3398 | //------------------------------------------------------------------------ |
3399 | // ASCIIHexEncoder | ||
3400 | //------------------------------------------------------------------------ | ||
3401 | |||
3402 | ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA): | ||
3403 | FilterStream(strA) { | ||
3404 | bufPtr = bufEnd = buf; | ||
3405 | lineLen = 0; | ||
3406 | eof = gFalse; | ||
3407 | } | ||
3408 | |||
3409 | ASCIIHexEncoder::~ASCIIHexEncoder() { | ||
3410 | if (str->isEncoder()) { | ||
3411 | delete str; | ||
3412 | } | ||
3413 | } | ||
3414 | |||
3415 | void ASCIIHexEncoder::reset() { | ||
3416 | str->reset(); | ||
3417 | bufPtr = bufEnd = buf; | ||
3418 | lineLen = 0; | ||
3419 | eof = gFalse; | ||
3420 | } | ||
3421 | |||
3422 | void ASCIIHexEncoder::close() { | ||
3423 | } | ||
3424 | |||
3425 | GBool ASCIIHexEncoder::fillBuf() { | ||
3426 | static char *hex = "0123456789abcdef"; | ||
3427 | int c; | ||
3428 | |||
3429 | if (eof) { | ||
3430 | return gFalse; | ||
3431 | } | ||
3432 | bufPtr = bufEnd = buf; | ||
3433 | if ((c = str->getChar()) == EOF) { | ||
3434 | *bufEnd++ = '>'; | ||
3435 | eof = gTrue; | ||
3436 | } else { | ||
3437 | if (lineLen >= 64) { | ||
3438 | *bufEnd++ = '\n'; | ||
3439 | lineLen = 0; | ||
3440 | } | ||
3441 | *bufEnd++ = hex[(c >> 4) & 0x0f]; | ||
3442 | *bufEnd++ = hex[c & 0x0f]; | ||
3443 | lineLen += 2; | ||
3444 | } | ||
3445 | return gTrue; | ||
3446 | } | ||
3447 | |||
3448 | //------------------------------------------------------------------------ | ||
3290 | // ASCII85Encoder | 3449 | // ASCII85Encoder |
3291 | //------------------------------------------------------------------------ | 3450 | //------------------------------------------------------------------------ |
3292 | 3451 | ||
3293 | ASCII85Encoder::ASCII85Encoder(Stream *strA): | 3452 | ASCII85Encoder::ASCII85Encoder(Stream *strA): |
3294 | FilterStream(strA) { | 3453 | FilterStream(strA) { |
3295 | bufPtr = bufEnd = buf; | 3454 | bufPtr = bufEnd = buf; |
diff --git a/noncore/unsupported/qpdf/xpdf/Stream.h b/noncore/unsupported/qpdf/xpdf/Stream.h index 1f9c561..3319dcc 100644 --- a/noncore/unsupported/qpdf/xpdf/Stream.h +++ b/noncore/unsupported/qpdf/xpdf/Stream.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // Stream.h | 3 | // Stream.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef STREAM_H | 9 | #ifndef STREAM_H |
10 | #define STREAM_H | 10 | #define STREAM_H |
11 | 11 | ||
@@ -75,14 +75,16 @@ public: | |||
75 | // Get next line from stream. | 75 | // Get next line from stream. |
76 | virtual char *getLine(char *buf, int size); | 76 | virtual char *getLine(char *buf, int size); |
77 | 77 | ||
78 | // Get current position in file. | 78 | // Get current position in file. |
79 | virtual int getPos() = 0; | 79 | virtual int getPos() = 0; |
80 | 80 | ||
81 | // Go to a position in the stream. | 81 | // Go to a position in the stream. If <dir> is negative, the |
82 | virtual void setPos(int pos) = 0; | 82 | // position is from the end of the file; otherwise the position is |
83 | // from the start of the file. | ||
84 | virtual void setPos(Guint pos, int dir = 0) = 0; | ||
83 | 85 | ||
84 | // Get PostScript command for the filter(s). | 86 | // Get PostScript command for the filter(s). |
85 | virtual GString *getPSFilter(char *indent); | 87 | virtual GString *getPSFilter(char *indent); |
86 | 88 | ||
87 | // Does this stream type potentially contain non-printable chars? | 89 | // Does this stream type potentially contain non-printable chars? |
88 | virtual GBool isBinary(GBool last = gTrue) = 0; | 90 | virtual GBool isBinary(GBool last = gTrue) = 0; |
@@ -115,24 +117,26 @@ private: | |||
115 | 117 | ||
116 | class BaseStream: public Stream { | 118 | class BaseStream: public Stream { |
117 | public: | 119 | public: |
118 | 120 | ||
119 | BaseStream(Object *dictA); | 121 | BaseStream(Object *dictA); |
120 | virtual ~BaseStream(); | 122 | virtual ~BaseStream(); |
121 | virtual Stream *makeSubStream(int start, int length, Object *dict) = 0; | 123 | virtual Stream *makeSubStream(Guint start, GBool limited, |
122 | virtual void setPos(int pos) = 0; | 124 | Guint length, Object *dict) = 0; |
125 | virtual void setPos(Guint pos, int dir = 0) = 0; | ||
123 | virtual BaseStream *getBaseStream() { return this; } | 126 | virtual BaseStream *getBaseStream() { return this; } |
124 | virtual Dict *getDict() { return dict.getDict(); } | 127 | virtual Dict *getDict() { return dict.getDict(); } |
125 | 128 | ||
126 | // Get/set position of first byte of stream within the file. | 129 | // Get/set position of first byte of stream within the file. |
127 | virtual int getStart() = 0; | 130 | virtual Guint getStart() = 0; |
128 | virtual void moveStart(int delta) = 0; | 131 | virtual void moveStart(int delta) = 0; |
129 | 132 | ||
130 | #ifndef NO_DECRYPTION | 133 | #ifndef NO_DECRYPTION |
131 | // Set decryption for this stream. | 134 | // Set decryption for this stream. |
132 | void doDecryption(Guchar *fileKey, int keyLength, int objNum, int objGen); | 135 | virtual void doDecryption(Guchar *fileKey, int keyLength, |
136 | int objNum, int objGen); | ||
133 | #endif | 137 | #endif |
134 | 138 | ||
135 | #ifndef NO_DECRYPTION | 139 | #ifndef NO_DECRYPTION |
136 | protected: | 140 | protected: |
137 | 141 | ||
138 | Decrypt *decrypt; | 142 | Decrypt *decrypt; |
@@ -153,13 +157,13 @@ class FilterStream: public Stream { | |||
153 | public: | 157 | public: |
154 | 158 | ||
155 | FilterStream(Stream *strA); | 159 | FilterStream(Stream *strA); |
156 | virtual ~FilterStream(); | 160 | virtual ~FilterStream(); |
157 | virtual void close(); | 161 | virtual void close(); |
158 | virtual int getPos() { return str->getPos(); } | 162 | virtual int getPos() { return str->getPos(); } |
159 | virtual void setPos(int pos); | 163 | virtual void setPos(Guint pos, int dir = 0); |
160 | virtual BaseStream *getBaseStream() { return str->getBaseStream(); } | 164 | virtual BaseStream *getBaseStream() { return str->getBaseStream(); } |
161 | virtual Dict *getDict() { return str->getDict(); } | 165 | virtual Dict *getDict() { return str->getDict(); } |
162 | 166 | ||
163 | protected: | 167 | protected: |
164 | 168 | ||
165 | Stream *str; | 169 | Stream *str; |
@@ -239,40 +243,81 @@ private: | |||
239 | 243 | ||
240 | #define fileStreamBufSize 256 | 244 | #define fileStreamBufSize 256 |
241 | 245 | ||
242 | class FileStream: public BaseStream { | 246 | class FileStream: public BaseStream { |
243 | public: | 247 | public: |
244 | 248 | ||
245 | FileStream(FILE *fA, int startA, int lengthA, Object *dictA); | 249 | FileStream(FILE *fA, Guint startA, GBool limitedA, |
250 | Guint lengthA, Object *dictA); | ||
246 | virtual ~FileStream(); | 251 | virtual ~FileStream(); |
247 | virtual Stream *makeSubStream(int startA, int lengthA, Object *dictA); | 252 | virtual Stream *makeSubStream(Guint startA, GBool limitedA, |
253 | Guint lengthA, Object *dictA); | ||
248 | virtual StreamKind getKind() { return strFile; } | 254 | virtual StreamKind getKind() { return strFile; } |
249 | virtual void reset(); | 255 | virtual void reset(); |
250 | virtual void close(); | 256 | virtual void close(); |
251 | virtual int getChar() | 257 | virtual int getChar() |
252 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } | 258 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } |
253 | virtual int lookChar() | 259 | virtual int lookChar() |
254 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } | 260 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } |
255 | virtual int getPos() { return bufPos + (bufPtr - buf); } | 261 | virtual int getPos() { return bufPos + (bufPtr - buf); } |
256 | virtual void setPos(int pos); | 262 | virtual void setPos(Guint pos, int dir = 0); |
257 | virtual GBool isBinary(GBool last = gTrue) { return last; } | 263 | virtual GBool isBinary(GBool last = gTrue) { return last; } |
258 | virtual int getStart() { return start; } | 264 | virtual Guint getStart() { return start; } |
259 | virtual void moveStart(int delta); | 265 | virtual void moveStart(int delta); |
260 | 266 | ||
261 | private: | 267 | private: |
262 | 268 | ||
263 | GBool fillBuf(); | 269 | GBool fillBuf(); |
264 | 270 | ||
265 | FILE *f; | 271 | FILE *f; |
266 | int start; | 272 | Guint start; |
267 | int length; | 273 | GBool limited; |
274 | Guint length; | ||
268 | char buf[fileStreamBufSize]; | 275 | char buf[fileStreamBufSize]; |
269 | char *bufPtr; | 276 | char *bufPtr; |
270 | char *bufEnd; | 277 | char *bufEnd; |
271 | int bufPos; | 278 | Guint bufPos; |
272 | int savePos; | 279 | int savePos; |
280 | GBool saved; | ||
281 | }; | ||
282 | |||
283 | //------------------------------------------------------------------------ | ||
284 | // MemStream | ||
285 | //------------------------------------------------------------------------ | ||
286 | |||
287 | class MemStream: public BaseStream { | ||
288 | public: | ||
289 | |||
290 | MemStream(char *bufA, Guint lengthA, Object *dictA); | ||
291 | virtual ~MemStream(); | ||
292 | virtual Stream *makeSubStream(Guint start, GBool limited, | ||
293 | Guint lengthA, Object *dictA); | ||
294 | virtual StreamKind getKind() { return strWeird; } | ||
295 | virtual void reset(); | ||
296 | virtual void close(); | ||
297 | virtual int getChar() | ||
298 | { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; } | ||
299 | virtual int lookChar() | ||
300 | { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; } | ||
301 | virtual int getPos() { return bufPtr - buf; } | ||
302 | virtual void setPos(Guint pos, int dir = 0); | ||
303 | virtual GBool isBinary(GBool last = gTrue) { return last; } | ||
304 | virtual Guint getStart() { return 0; } | ||
305 | virtual void moveStart(int delta); | ||
306 | #ifndef NO_DECRYPTION | ||
307 | virtual void doDecryption(Guchar *fileKey, int keyLength, | ||
308 | int objNum, int objGen); | ||
309 | #endif | ||
310 | |||
311 | private: | ||
312 | |||
313 | char *buf; | ||
314 | Guint length; | ||
315 | GBool needFree; | ||
316 | char *bufEnd; | ||
317 | char *bufPtr; | ||
273 | }; | 318 | }; |
274 | 319 | ||
275 | //------------------------------------------------------------------------ | 320 | //------------------------------------------------------------------------ |
276 | // EmbedStream | 321 | // EmbedStream |
277 | // | 322 | // |
278 | // This is a special stream type used for embedded streams (inline | 323 | // This is a special stream type used for embedded streams (inline |
@@ -284,21 +329,22 @@ private: | |||
284 | 329 | ||
285 | class EmbedStream: public BaseStream { | 330 | class EmbedStream: public BaseStream { |
286 | public: | 331 | public: |
287 | 332 | ||
288 | EmbedStream(Stream *strA, Object *dictA); | 333 | EmbedStream(Stream *strA, Object *dictA); |
289 | virtual ~EmbedStream(); | 334 | virtual ~EmbedStream(); |
290 | virtual Stream *makeSubStream(int start, int length, Object *dictA); | 335 | virtual Stream *makeSubStream(Guint start, GBool limited, |
336 | Guint length, Object *dictA); | ||
291 | virtual StreamKind getKind() { return str->getKind(); } | 337 | virtual StreamKind getKind() { return str->getKind(); } |
292 | virtual void reset() {} | 338 | virtual void reset() {} |
293 | virtual int getChar() { return str->getChar(); } | 339 | virtual int getChar() { return str->getChar(); } |
294 | virtual int lookChar() { return str->lookChar(); } | 340 | virtual int lookChar() { return str->lookChar(); } |
295 | virtual int getPos() { return str->getPos(); } | 341 | virtual int getPos() { return str->getPos(); } |
296 | virtual void setPos(int pos); | 342 | virtual void setPos(Guint pos, int dir = 0); |
297 | virtual GBool isBinary(GBool last = gTrue) { return last; } | 343 | virtual GBool isBinary(GBool last = gTrue) { return last; } |
298 | virtual int getStart(); | 344 | virtual Guint getStart(); |
299 | virtual void moveStart(int delta); | 345 | virtual void moveStart(int delta); |
300 | 346 | ||
301 | private: | 347 | private: |
302 | 348 | ||
303 | Stream *str; | 349 | Stream *str; |
304 | }; | 350 | }; |
@@ -656,12 +702,43 @@ private: | |||
656 | 702 | ||
657 | int length; | 703 | int length; |
658 | int count; | 704 | int count; |
659 | }; | 705 | }; |
660 | 706 | ||
661 | //------------------------------------------------------------------------ | 707 | //------------------------------------------------------------------------ |
708 | // ASCIIHexEncoder | ||
709 | //------------------------------------------------------------------------ | ||
710 | |||
711 | class ASCIIHexEncoder: public FilterStream { | ||
712 | public: | ||
713 | |||
714 | ASCIIHexEncoder(Stream *strA); | ||
715 | virtual ~ASCIIHexEncoder(); | ||
716 | virtual StreamKind getKind() { return strWeird; } | ||
717 | virtual void reset(); | ||
718 | virtual void close(); | ||
719 | virtual int getChar() | ||
720 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } | ||
721 | virtual int lookChar() | ||
722 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } | ||
723 | virtual GString *getPSFilter(char *indent) { return NULL; } | ||
724 | virtual GBool isBinary(GBool last = gTrue) { return gFalse; } | ||
725 | virtual GBool isEncoder() { return gTrue; } | ||
726 | |||
727 | private: | ||
728 | |||
729 | char buf[4]; | ||
730 | char *bufPtr; | ||
731 | char *bufEnd; | ||
732 | int lineLen; | ||
733 | GBool eof; | ||
734 | |||
735 | GBool fillBuf(); | ||
736 | }; | ||
737 | |||
738 | //------------------------------------------------------------------------ | ||
662 | // ASCII85Encoder | 739 | // ASCII85Encoder |
663 | //------------------------------------------------------------------------ | 740 | //------------------------------------------------------------------------ |
664 | 741 | ||
665 | class ASCII85Encoder: public FilterStream { | 742 | class ASCII85Encoder: public FilterStream { |
666 | public: | 743 | public: |
667 | 744 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc b/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc index aa9366a..d3b0137 100644 --- a/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc +++ b/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // TextOutputDev.cc | 3 | // TextOutputDev.cc |
4 | // | 4 | // |
5 | // Copyright 1997 Derek B. Noonburg | 5 | // Copyright 1997-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -45,12 +45,18 @@ TextString::TextString(GfxState *state, fouble fontSize) { | |||
45 | } else { | 45 | } else { |
46 | // this means that the PDF file draws text without a current font, | 46 | // this means that the PDF file draws text without a current font, |
47 | // which should never happen | 47 | // which should never happen |
48 | yMin = y - 0.95 * fontSize; | 48 | yMin = y - 0.95 * fontSize; |
49 | yMax = y + 0.35 * fontSize; | 49 | yMax = y + 0.35 * fontSize; |
50 | } | 50 | } |
51 | if (yMin == yMax) { | ||
52 | // this is a sanity check for a case that shouldn't happen -- but | ||
53 | // if it does happen, we want to avoid dividing by zero later | ||
54 | yMin = y; | ||
55 | yMax = y + 1; | ||
56 | } | ||
51 | col = 0; | 57 | col = 0; |
52 | text = NULL; | 58 | text = NULL; |
53 | xRight = NULL; | 59 | xRight = NULL; |
54 | len = size = 0; | 60 | len = size = 0; |
55 | yxNext = NULL; | 61 | yxNext = NULL; |
56 | xyNext = NULL; | 62 | xyNext = NULL; |
@@ -96,12 +102,13 @@ TextPage::~TextPage() { | |||
96 | 102 | ||
97 | void TextPage::updateFont(GfxState *state) { | 103 | void TextPage::updateFont(GfxState *state) { |
98 | GfxFont *font; | 104 | GfxFont *font; |
99 | fouble *fm; | 105 | fouble *fm; |
100 | char *name; | 106 | char *name; |
101 | int code; | 107 | int code; |
108 | fouble w; | ||
102 | 109 | ||
103 | // adjust the font size | 110 | // adjust the font size |
104 | fontSize = state->getTransformedFontSize(); | 111 | fontSize = state->getTransformedFontSize(); |
105 | if ((font = state->getFont()) && font->getType() == fontType3) { | 112 | if ((font = state->getFont()) && font->getType() == fontType3) { |
106 | // This is a hack which makes it possible to deal with some Type 3 | 113 | // This is a hack which makes it possible to deal with some Type 3 |
107 | // fonts. The problem is that it's impossible to know what the | 114 | // fonts. The problem is that it's impossible to know what the |
@@ -113,14 +120,17 @@ void TextPage::updateFont(GfxState *state) { | |||
113 | if ((name = ((Gfx8BitFont *)font)->getCharName(code)) && | 120 | if ((name = ((Gfx8BitFont *)font)->getCharName(code)) && |
114 | name[0] == 'm' && name[1] == '\0') { | 121 | name[0] == 'm' && name[1] == '\0') { |
115 | break; | 122 | break; |
116 | } | 123 | } |
117 | } | 124 | } |
118 | if (code < 256) { | 125 | if (code < 256) { |
119 | // 600 is a generic average 'm' width -- yes, this is a hack | 126 | w = ((Gfx8BitFont *)font)->getWidth(code); |
120 | fontSize *= ((Gfx8BitFont *)font)->getWidth(code) / 0.6; | 127 | if (w != 0) { |
128 | // 600 is a generic average 'm' width -- yes, this is a hack | ||
129 | fontSize *= w / 0.6; | ||
130 | } | ||
121 | } | 131 | } |
122 | fm = font->getFontMatrix(); | 132 | fm = font->getFontMatrix(); |
123 | if (fm[0] != 0) { | 133 | if (fm[0] != 0) { |
124 | fontSize *= fabs(fm[3] / fm[0]); | 134 | fontSize *= fabs(fm[3] / fm[0]); |
125 | } | 135 | } |
126 | } | 136 | } |
@@ -151,14 +161,16 @@ void TextPage::addChar(GfxState *state, fouble x, fouble y, | |||
151 | } | 161 | } |
152 | state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(), | 162 | state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(), |
153 | 0, &dx2, &dy2); | 163 | 0, &dx2, &dy2); |
154 | dx -= dx2; | 164 | dx -= dx2; |
155 | dy -= dy2; | 165 | dy -= dy2; |
156 | state->transformDelta(dx, dy, &w1, &h1); | 166 | state->transformDelta(dx, dy, &w1, &h1); |
157 | w1 /= uLen; | 167 | if (uLen != 0) { |
158 | h1 /= uLen; | 168 | w1 /= uLen; |
169 | h1 /= uLen; | ||
170 | } | ||
159 | for (i = 0; i < uLen; ++i) { | 171 | for (i = 0; i < uLen; ++i) { |
160 | curStr->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, u[i]); | 172 | curStr->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, u[i]); |
161 | } | 173 | } |
162 | } | 174 | } |
163 | 175 | ||
164 | void TextPage::endString() { | 176 | void TextPage::endString() { |
@@ -426,13 +438,13 @@ GString *TextPage::getText(fouble xMin, fouble yMin, | |||
426 | s->append(eol, eolLen); | 438 | s->append(eol, eolLen); |
427 | } | 439 | } |
428 | uMap->decRefCnt(); | 440 | uMap->decRefCnt(); |
429 | return s; | 441 | return s; |
430 | } | 442 | } |
431 | 443 | ||
432 | void TextPage::dump(FILE *f) { | 444 | void TextPage::dump(void *outputStream, TextOutputFunc outputFunc) { |
433 | UnicodeMap *uMap; | 445 | UnicodeMap *uMap; |
434 | char space[8], eol[16], eop[8], buf[8]; | 446 | char space[8], eol[16], eop[8], buf[8]; |
435 | int spaceLen, eolLen, eopLen, n; | 447 | int spaceLen, eolLen, eopLen, n; |
436 | TextString *str1, *str2, *str3; | 448 | TextString *str1, *str2, *str3; |
437 | fouble yMin, yMax; | 449 | fouble yMin, yMax; |
438 | int col1, col2, d, i; | 450 | int col1, col2, d, i; |
@@ -495,43 +507,43 @@ void TextPage::dump(FILE *f) { | |||
495 | } | 507 | } |
496 | } | 508 | } |
497 | str1->col = col1; | 509 | str1->col = col1; |
498 | } | 510 | } |
499 | 511 | ||
500 | #if 0 //~ for debugging | 512 | #if 0 //~ for debugging |
501 | fprintf(f, "~~~~~~~~~~\n"); | 513 | fprintf((FILE *)outputStream, "~~~~~~~~~~\n"); |
502 | for (str1 = yxStrings; str1; str1 = str1->yxNext) { | 514 | for (str1 = yxStrings; str1; str1 = str1->yxNext) { |
503 | fprintf(f, "(%4d,%4d) - (%4d,%4d) [%3d] '", | 515 | fprintf((FILE *)outputStream, "(%4d,%4d) - (%4d,%4d) [%3d] '", |
504 | (int)str1->xMin, (int)str1->yMin, | 516 | (int)str1->xMin, (int)str1->yMin, |
505 | (int)str1->xMax, (int)str1->yMax, str1->col); | 517 | (int)str1->xMax, (int)str1->yMax, str1->col); |
506 | for (i = 0; i < str1->len; ++i) { | 518 | for (i = 0; i < str1->len; ++i) { |
507 | fputc(str1->text[i] & 0xff, stdout); | 519 | fputc(str1->text[i] & 0xff, stdout); |
508 | } | 520 | } |
509 | printf("'\n"); | 521 | printf("'\n"); |
510 | } | 522 | } |
511 | fprintf(f, "~~~~~~~~~~\n"); | 523 | fprintf((FILE *)outputStream, "~~~~~~~~~~\n"); |
512 | #endif | 524 | #endif |
513 | 525 | ||
514 | // output | 526 | // output |
515 | col1 = 0; | 527 | col1 = 0; |
516 | yMax = yxStrings ? yxStrings->yMax : fouble(0); | 528 | yMax = yxStrings ? yxStrings->yMax : fouble(0); |
517 | for (str1 = yxStrings; str1; str1 = str1->yxNext) { | 529 | for (str1 = yxStrings; str1; str1 = str1->yxNext) { |
518 | 530 | ||
519 | // line this string up with the correct column | 531 | // line this string up with the correct column |
520 | if (rawOrder && col1 == 0) { | 532 | if (rawOrder && col1 == 0) { |
521 | col1 = str1->col; | 533 | col1 = str1->col; |
522 | } else { | 534 | } else { |
523 | for (; col1 < str1->col; ++col1) { | 535 | for (; col1 < str1->col; ++col1) { |
524 | fwrite(space, 1, spaceLen, f); | 536 | (*outputFunc)(outputStream, space, spaceLen); |
525 | } | 537 | } |
526 | } | 538 | } |
527 | 539 | ||
528 | // print the string | 540 | // print the string |
529 | for (i = 0; i < str1->len; ++i) { | 541 | for (i = 0; i < str1->len; ++i) { |
530 | if ((n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf))) > 0) { | 542 | if ((n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf))) > 0) { |
531 | fwrite(buf, 1, n, f); | 543 | (*outputFunc)(outputStream, buf, n); |
532 | } | 544 | } |
533 | } | 545 | } |
534 | 546 | ||
535 | // increment column | 547 | // increment column |
536 | col1 += str1->len; | 548 | col1 += str1->len; |
537 | 549 | ||
@@ -544,13 +556,13 @@ void TextPage::dump(FILE *f) { | |||
544 | if (!(str1->yxNext && | 556 | if (!(str1->yxNext && |
545 | !(rawOrder && str1->yxNext->yMax < str1->yMin) && | 557 | !(rawOrder && str1->yxNext->yMax < str1->yMin) && |
546 | str1->yxNext->yMin < 0.2*str1->yMin + 0.8*str1->yMax && | 558 | str1->yxNext->yMin < 0.2*str1->yMin + 0.8*str1->yMax && |
547 | str1->yxNext->xMin >= str1->xMax)) { | 559 | str1->yxNext->xMin >= str1->xMax)) { |
548 | 560 | ||
549 | // print a return | 561 | // print a return |
550 | fwrite(eol, 1, eolLen, f); | 562 | (*outputFunc)(outputStream, eol, eolLen); |
551 | 563 | ||
552 | // print extra vertical space if necessary | 564 | // print extra vertical space if necessary |
553 | if (str1->yxNext) { | 565 | if (str1->yxNext) { |
554 | 566 | ||
555 | // find yMin for next line | 567 | // find yMin for next line |
556 | yMin = str1->yxNext->yMin; | 568 | yMin = str1->yxNext->yMin; |
@@ -570,26 +582,26 @@ void TextPage::dump(FILE *f) { | |||
570 | if (rawOrder && d > 2) { | 582 | if (rawOrder && d > 2) { |
571 | d = 2; | 583 | d = 2; |
572 | } else if (!rawOrder && d > 5) { | 584 | } else if (!rawOrder && d > 5) { |
573 | d = 5; | 585 | d = 5; |
574 | } | 586 | } |
575 | for (; d > 0; --d) { | 587 | for (; d > 0; --d) { |
576 | fwrite(eol, 1, eolLen, f); | 588 | (*outputFunc)(outputStream, eol, eolLen); |
577 | } | 589 | } |
578 | } | 590 | } |
579 | 591 | ||
580 | // set up for next line | 592 | // set up for next line |
581 | col1 = 0; | 593 | col1 = 0; |
582 | yMax = str1->yxNext ? str1->yxNext->yMax : fouble(0); | 594 | yMax = str1->yxNext ? str1->yxNext->yMax : fouble(0); |
583 | } | 595 | } |
584 | } | 596 | } |
585 | 597 | ||
586 | // end of page | 598 | // end of page |
587 | fwrite(eol, 1, eolLen, f); | 599 | (*outputFunc)(outputStream, eol, eolLen); |
588 | fwrite(eop, 1, eopLen, f); | 600 | (*outputFunc)(outputStream, eop, eopLen); |
589 | fwrite(eol, 1, eolLen, f); | 601 | (*outputFunc)(outputStream, eol, eolLen); |
590 | 602 | ||
591 | uMap->decRefCnt(); | 603 | uMap->decRefCnt(); |
592 | } | 604 | } |
593 | 605 | ||
594 | void TextPage::clear() { | 606 | void TextPage::clear() { |
595 | TextString *p1, *p2; | 607 | TextString *p1, *p2; |
@@ -608,57 +620,72 @@ void TextPage::clear() { | |||
608 | } | 620 | } |
609 | 621 | ||
610 | //------------------------------------------------------------------------ | 622 | //------------------------------------------------------------------------ |
611 | // TextOutputDev | 623 | // TextOutputDev |
612 | //------------------------------------------------------------------------ | 624 | //------------------------------------------------------------------------ |
613 | 625 | ||
626 | static void outputToFile(void *stream, char *text, int len) { | ||
627 | fwrite(text, 1, len, (FILE *)stream); | ||
628 | } | ||
629 | |||
614 | TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) { | 630 | TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) { |
615 | text = NULL; | 631 | text = NULL; |
616 | rawOrder = rawOrderA; | 632 | rawOrder = rawOrderA; |
617 | ok = gTrue; | 633 | ok = gTrue; |
618 | 634 | ||
619 | // open file | 635 | // open file |
620 | needClose = gFalse; | 636 | needClose = gFalse; |
621 | if (fileName) { | 637 | if (fileName) { |
622 | if (!strcmp(fileName, "-")) { | 638 | if (!strcmp(fileName, "-")) { |
623 | f = stdout; | 639 | outputStream = stdout; |
624 | } else if ((f = fopen(fileName, append ? "a" : "w"))) { | 640 | } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) { |
625 | needClose = gTrue; | 641 | needClose = gTrue; |
626 | } else { | 642 | } else { |
627 | error(-1, "Couldn't open text file '%s'", fileName); | 643 | error(-1, "Couldn't open text file '%s'", fileName); |
628 | ok = gFalse; | 644 | ok = gFalse; |
629 | return; | 645 | return; |
630 | } | 646 | } |
647 | outputFunc = &outputToFile; | ||
631 | } else { | 648 | } else { |
632 | f = NULL; | 649 | outputStream = NULL; |
633 | } | 650 | } |
634 | 651 | ||
635 | // set up text object | 652 | // set up text object |
636 | text = new TextPage(rawOrder); | 653 | text = new TextPage(rawOrder); |
637 | } | 654 | } |
638 | 655 | ||
656 | TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream, | ||
657 | GBool rawOrderA) { | ||
658 | outputFunc = func; | ||
659 | outputStream = stream; | ||
660 | needClose = gFalse; | ||
661 | rawOrder = rawOrderA; | ||
662 | text = new TextPage(rawOrder); | ||
663 | ok = gTrue; | ||
664 | } | ||
665 | |||
639 | TextOutputDev::~TextOutputDev() { | 666 | TextOutputDev::~TextOutputDev() { |
640 | if (needClose) { | 667 | if (needClose) { |
641 | #ifdef MACOS | 668 | #ifdef MACOS |
642 | ICS_MapRefNumAndAssign((short)f->handle); | 669 | ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle); |
643 | #endif | 670 | #endif |
644 | fclose(f); | 671 | fclose((FILE *)outputStream); |
645 | } | 672 | } |
646 | if (text) { | 673 | if (text) { |
647 | delete text; | 674 | delete text; |
648 | } | 675 | } |
649 | } | 676 | } |
650 | 677 | ||
651 | void TextOutputDev::startPage(int pageNum, GfxState *state) { | 678 | void TextOutputDev::startPage(int pageNum, GfxState *state) { |
652 | text->clear(); | 679 | text->clear(); |
653 | } | 680 | } |
654 | 681 | ||
655 | void TextOutputDev::endPage() { | 682 | void TextOutputDev::endPage() { |
656 | text->coalesce(); | 683 | text->coalesce(); |
657 | if (f) { | 684 | if (outputStream) { |
658 | text->dump(f); | 685 | text->dump(outputStream, outputFunc); |
659 | } | 686 | } |
660 | } | 687 | } |
661 | 688 | ||
662 | void TextOutputDev::updateFont(GfxState *state) { | 689 | void TextOutputDev::updateFont(GfxState *state) { |
663 | text->updateFont(state); | 690 | text->updateFont(state); |
664 | } | 691 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/TextOutputDev.h b/noncore/unsupported/qpdf/xpdf/TextOutputDev.h index 4c71e5e..f0f238e 100644 --- a/noncore/unsupported/qpdf/xpdf/TextOutputDev.h +++ b/noncore/unsupported/qpdf/xpdf/TextOutputDev.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // TextOutputDev.h | 3 | // TextOutputDev.h |
4 | // | 4 | // |
5 | // Copyright 1997 Derek B. Noonburg | 5 | // Copyright 1997-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef TEXTOUTPUTDEV_H | 9 | #ifndef TEXTOUTPUTDEV_H |
10 | #define TEXTOUTPUTDEV_H | 10 | #define TEXTOUTPUTDEV_H |
11 | 11 | ||
@@ -19,12 +19,16 @@ | |||
19 | #include "OutputDev.h" | 19 | #include "OutputDev.h" |
20 | 20 | ||
21 | class GfxState; | 21 | class GfxState; |
22 | class GString; | 22 | class GString; |
23 | 23 | ||
24 | //------------------------------------------------------------------------ | 24 | //------------------------------------------------------------------------ |
25 | |||
26 | typedef void (*TextOutputFunc)(void *stream, char *text, int len); | ||
27 | |||
28 | //------------------------------------------------------------------------ | ||
25 | // TextString | 29 | // TextString |
26 | //------------------------------------------------------------------------ | 30 | //------------------------------------------------------------------------ |
27 | 31 | ||
28 | class TextString { | 32 | class TextString { |
29 | public: | 33 | public: |
30 | 34 | ||
@@ -94,13 +98,13 @@ public: | |||
94 | 98 | ||
95 | // Get the text which is inside the specified rectangle. | 99 | // Get the text which is inside the specified rectangle. |
96 | GString *getText(fouble xMin, fouble yMin, | 100 | GString *getText(fouble xMin, fouble yMin, |
97 | fouble xMax, fouble yMax); | 101 | fouble xMax, fouble yMax); |
98 | 102 | ||
99 | // Dump contents of page to a file. | 103 | // Dump contents of page to a file. |
100 | void dump(FILE *f); | 104 | void dump(void *outputStream, TextOutputFunc outputFunc); |
101 | 105 | ||
102 | // Clear the page. | 106 | // Clear the page. |
103 | void clear(); | 107 | void clear(); |
104 | 108 | ||
105 | private: | 109 | private: |
106 | 110 | ||
@@ -125,12 +129,16 @@ public: | |||
125 | 129 | ||
126 | // Open a text output file. If <fileName> is NULL, no file is | 130 | // Open a text output file. If <fileName> is NULL, no file is |
127 | // written (this is useful, e.g., for searching text). If | 131 | // written (this is useful, e.g., for searching text). If |
128 | // <rawOrder> is true, the text is kept in content stream order. | 132 | // <rawOrder> is true, the text is kept in content stream order. |
129 | TextOutputDev(char *fileName, GBool rawOrderA, GBool append); | 133 | TextOutputDev(char *fileName, GBool rawOrderA, GBool append); |
130 | 134 | ||
135 | // Create a TextOutputDev which will write to a generic stream. If | ||
136 | // <rawOrder> is true, the text is kept in content stream order. | ||
137 | TextOutputDev(TextOutputFunc func, void *stream, GBool rawOrderA); | ||
138 | |||
131 | // Destructor. | 139 | // Destructor. |
132 | virtual ~TextOutputDev(); | 140 | virtual ~TextOutputDev(); |
133 | 141 | ||
134 | // Check if file was successfully created. | 142 | // Check if file was successfully created. |
135 | virtual GBool isOk() { return ok; } | 143 | virtual GBool isOk() { return ok; } |
136 | 144 | ||
@@ -140,12 +148,16 @@ public: | |||
140 | // (Upside-down means (0,0) is the top left corner of the page.) | 148 | // (Upside-down means (0,0) is the top left corner of the page.) |
141 | virtual GBool upsideDown() { return gTrue; } | 149 | virtual GBool upsideDown() { return gTrue; } |
142 | 150 | ||
143 | // Does this device use drawChar() or drawString()? | 151 | // Does this device use drawChar() or drawString()? |
144 | virtual GBool useDrawChar() { return gTrue; } | 152 | virtual GBool useDrawChar() { return gTrue; } |
145 | 153 | ||
154 | // Does this device use beginType3Char/endType3Char? Otherwise, | ||
155 | // text in Type 3 fonts will be drawn with drawChar/drawString. | ||
156 | virtual GBool interpretType3Chars() { return gFalse; } | ||
157 | |||
146 | // Does this device need non-text content? | 158 | // Does this device need non-text content? |
147 | virtual GBool needNonText() { return gFalse; } | 159 | virtual GBool needNonText() { return gFalse; } |
148 | 160 | ||
149 | //----- initialization and control | 161 | //----- initialization and control |
150 | 162 | ||
151 | // Start a page. | 163 | // Start a page. |
@@ -176,14 +188,16 @@ public: | |||
176 | GBool top, GBool bottom, | 188 | GBool top, GBool bottom, |
177 | fouble *xMin, fouble *yMin, | 189 | fouble *xMin, fouble *yMin, |
178 | fouble *xMax, fouble *yMax); | 190 | fouble *xMax, fouble *yMax); |
179 | 191 | ||
180 | private: | 192 | private: |
181 | 193 | ||
182 | FILE *f; // text file | 194 | TextOutputFunc outputFunc;// output function |
183 | GBool needClose; // need to close the file? | 195 | void *outputStream; // output stream |
196 | GBool needClose; // need to close the output file? | ||
197 | // (only if outputStream is a FILE*) | ||
184 | TextPage *text; // text for the current page | 198 | TextPage *text; // text for the current page |
185 | GBool rawOrder; // keep text in content stream order | 199 | GBool rawOrder; // keep text in content stream order |
186 | GBool ok; // set up ok? | 200 | GBool ok; // set up ok? |
187 | }; | 201 | }; |
188 | 202 | ||
189 | #endif | 203 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc b/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc index ab823b1..75f23d2 100644 --- a/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc +++ b/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // UnicodeMap.cc | 3 | // UnicodeMap.cc |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMap.h b/noncore/unsupported/qpdf/xpdf/UnicodeMap.h index 4d982c8..274c447 100644 --- a/noncore/unsupported/qpdf/xpdf/UnicodeMap.h +++ b/noncore/unsupported/qpdf/xpdf/UnicodeMap.h | |||
@@ -1,13 +1,13 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // UnicodeMap.h | 3 | // UnicodeMap.h |
4 | // | 4 | // |
5 | // Mapping from Unicode to an encoding. | 5 | // Mapping from Unicode to an encoding. |
6 | // | 6 | // |
7 | // Copyright 2001 Derek B. Noonburg | 7 | // Copyright 2001-2002 Glyph & Cog, LLC |
8 | // | 8 | // |
9 | //======================================================================== | 9 | //======================================================================== |
10 | 10 | ||
11 | #ifndef UNICODEMAP_H | 11 | #ifndef UNICODEMAP_H |
12 | #define UNICODEMAP_H | 12 | #define UNICODEMAP_H |
13 | 13 | ||
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h b/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h index 6fcd44e..51dee98 100644 --- a/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h +++ b/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h | |||
@@ -1,21 +1,23 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // UnicodeMapTables.h | 3 | // UnicodeMapTables.h |
4 | // | 4 | // |
5 | // Copyright 2001 Derek B. Noonburg | 5 | // Copyright 2001-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | static UnicodeMapRange latin1UnicodeMapRanges[] = { | 9 | static UnicodeMapRange latin1UnicodeMapRanges[] = { |
10 | { 0x000a, 0x000a, 0x0a, 1 }, | 10 | { 0x000a, 0x000a, 0x0a, 1 }, |
11 | { 0x000c, 0x000d, 0x0c, 1 }, | 11 | { 0x000c, 0x000d, 0x0c, 1 }, |
12 | { 0x0020, 0x007e, 0x20, 1 }, | 12 | { 0x0020, 0x007e, 0x20, 1 }, |
13 | { 0x00a0, 0x00a0, 0x20, 1 }, | 13 | { 0x00a0, 0x00a0, 0x20, 1 }, |
14 | { 0x00a1, 0x00ac, 0xa1, 1 }, | 14 | { 0x00a1, 0x00ac, 0xa1, 1 }, |
15 | { 0x00ae, 0x00ff, 0xae, 1 }, | 15 | { 0x00ae, 0x00ff, 0xae, 1 }, |
16 | { 0x010c, 0x010c, 0x43, 1 }, | ||
17 | { 0x010d, 0x010d, 0x63, 1 }, | ||
16 | { 0x0131, 0x0131, 0x69, 1 }, | 18 | { 0x0131, 0x0131, 0x69, 1 }, |
17 | { 0x0141, 0x0141, 0x4c, 1 }, | 19 | { 0x0141, 0x0141, 0x4c, 1 }, |
18 | { 0x0142, 0x0142, 0x6c, 1 }, | 20 | { 0x0142, 0x0142, 0x6c, 1 }, |
19 | { 0x0152, 0x0152, 0x4f45, 2 }, | 21 | { 0x0152, 0x0152, 0x4f45, 2 }, |
20 | { 0x0153, 0x0153, 0x6f65, 2 }, | 22 | { 0x0153, 0x0153, 0x6f65, 2 }, |
21 | { 0x0160, 0x0160, 0x53, 1 }, | 23 | { 0x0160, 0x0160, 0x53, 1 }, |
@@ -38,12 +40,29 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = { | |||
38 | { 0x2026, 0x2026, 0x2e2e2e, 3 }, | 40 | { 0x2026, 0x2026, 0x2e2e2e, 3 }, |
39 | { 0x2039, 0x2039, 0x3c, 1 }, | 41 | { 0x2039, 0x2039, 0x3c, 1 }, |
40 | { 0x203a, 0x203a, 0x3e, 1 }, | 42 | { 0x203a, 0x203a, 0x3e, 1 }, |
41 | { 0x2044, 0x2044, 0x2f, 1 }, | 43 | { 0x2044, 0x2044, 0x2f, 1 }, |
42 | { 0x2122, 0x2122, 0x544d, 2 }, | 44 | { 0x2122, 0x2122, 0x544d, 2 }, |
43 | { 0x2212, 0x2212, 0x2d, 1 }, | 45 | { 0x2212, 0x2212, 0x2d, 1 }, |
46 | { 0xf6f9, 0xf6f9, 0x4c, 1 }, | ||
47 | { 0xf6fa, 0xf6fa, 0x4f45, 2 }, | ||
48 | { 0xf6fc, 0xf6fc, 0xb0, 1 }, | ||
49 | { 0xf6fd, 0xf6fd, 0x53, 1 }, | ||
50 | { 0xf6fe, 0xf6fe, 0x7e, 1 }, | ||
51 | { 0xf6ff, 0xf6ff, 0x5a, 1 }, | ||
52 | { 0xf721, 0xf721, 0x21, 1 }, | ||
53 | { 0xf724, 0xf724, 0x24, 1 }, | ||
54 | { 0xf726, 0xf726, 0x26, 1 }, | ||
55 | { 0xf730, 0xf739, 0x30, 1 }, | ||
56 | { 0xf73f, 0xf73f, 0x3f, 1 }, | ||
57 | { 0xf761, 0xf77a, 0x41, 1 }, | ||
58 | { 0xf7a1, 0xf7a2, 0xa1, 1 }, | ||
59 | { 0xf7bf, 0xf7bf, 0xbf, 1 }, | ||
60 | { 0xf7e0, 0xf7f6, 0xc0, 1 }, | ||
61 | { 0xf7f8, 0xf7fe, 0xd8, 1 }, | ||
62 | { 0xf7ff, 0xf7ff, 0x59, 1 }, | ||
44 | { 0xfb00, 0xfb00, 0x6666, 2 }, | 63 | { 0xfb00, 0xfb00, 0x6666, 2 }, |
45 | { 0xfb01, 0xfb01, 0x6669, 2 }, | 64 | { 0xfb01, 0xfb01, 0x6669, 2 }, |
46 | { 0xfb02, 0xfb02, 0x666c, 2 }, | 65 | { 0xfb02, 0xfb02, 0x666c, 2 }, |
47 | { 0xfb03, 0xfb03, 0x666669, 3 }, | 66 | { 0xfb03, 0xfb03, 0x666669, 3 }, |
48 | { 0xfb04, 0xfb04, 0x66666c, 3 } | 67 | { 0xfb04, 0xfb04, 0x66666c, 3 } |
49 | }; | 68 | }; |
@@ -132,12 +151,51 @@ static UnicodeMapRange ascii7UnicodeMapRanges[] = { | |||
132 | { 0x201c, 0x201c, 0x22, 1 }, | 151 | { 0x201c, 0x201c, 0x22, 1 }, |
133 | { 0x201d, 0x201d, 0x22, 1 }, | 152 | { 0x201d, 0x201d, 0x22, 1 }, |
134 | { 0x2022, 0x2022, 0x2a, 1 }, | 153 | { 0x2022, 0x2022, 0x2a, 1 }, |
135 | { 0x2026, 0x2026, 0x2e2e2e, 3 }, | 154 | { 0x2026, 0x2026, 0x2e2e2e, 3 }, |
136 | { 0x2122, 0x2122, 0x544d, 2 }, | 155 | { 0x2122, 0x2122, 0x544d, 2 }, |
137 | { 0x2212, 0x2212, 0x2d, 1 }, | 156 | { 0x2212, 0x2212, 0x2d, 1 }, |
157 | { 0xf6f9, 0xf6f9, 0x4c, 1 }, | ||
158 | { 0xf6fa, 0xf6fa, 0x4f45, 2 }, | ||
159 | { 0xf6fd, 0xf6fd, 0x53, 1 }, | ||
160 | { 0xf6fe, 0xf6fe, 0x7e, 1 }, | ||
161 | { 0xf6ff, 0xf6ff, 0x5a, 1 }, | ||
162 | { 0xf721, 0xf721, 0x21, 1 }, | ||
163 | { 0xf724, 0xf724, 0x24, 1 }, | ||
164 | { 0xf726, 0xf726, 0x26, 1 }, | ||
165 | { 0xf730, 0xf739, 0x30, 1 }, | ||
166 | { 0xf73f, 0xf73f, 0x3f, 1 }, | ||
167 | { 0xf761, 0xf77a, 0x41, 1 }, | ||
168 | { 0xf7e0, 0xf7e0, 0x41, 1 }, | ||
169 | { 0xf7e1, 0xf7e1, 0x41, 1 }, | ||
170 | { 0xf7e2, 0xf7e2, 0x41, 1 }, | ||
171 | { 0xf7e3, 0xf7e3, 0x41, 1 }, | ||
172 | { 0xf7e4, 0xf7e4, 0x41, 1 }, | ||
173 | { 0xf7e5, 0xf7e5, 0x41, 1 }, | ||
174 | { 0xf7e6, 0xf7e6, 0x4145, 2 }, | ||
175 | { 0xf7e7, 0xf7e7, 0x43, 1 }, | ||
176 | { 0xf7e8, 0xf7e8, 0x45, 1 }, | ||
177 | { 0xf7e9, 0xf7e9, 0x45, 1 }, | ||
178 | { 0xf7ea, 0xf7ea, 0x45, 1 }, | ||
179 | { 0xf7eb, 0xf7eb, 0x45, 1 }, | ||
180 | { 0xf7ec, 0xf7ec, 0x49, 1 }, | ||
181 | { 0xf7ed, 0xf7ed, 0x49, 1 }, | ||
182 | { 0xf7ee, 0xf7ee, 0x49, 1 }, | ||
183 | { 0xf7ef, 0xf7ef, 0x49, 1 }, | ||
184 | { 0xf7f1, 0xf7f2, 0x4e, 1 }, | ||
185 | { 0xf7f3, 0xf7f3, 0x4f, 1 }, | ||
186 | { 0xf7f4, 0xf7f4, 0x4f, 1 }, | ||
187 | { 0xf7f5, 0xf7f5, 0x4f, 1 }, | ||
188 | { 0xf7f6, 0xf7f6, 0x4f, 1 }, | ||
189 | { 0xf7f8, 0xf7f8, 0x4f, 1 }, | ||
190 | { 0xf7f9, 0xf7f9, 0x55, 1 }, | ||
191 | { 0xf7fa, 0xf7fa, 0x55, 1 }, | ||
192 | { 0xf7fb, 0xf7fb, 0x55, 1 }, | ||
193 | { 0xf7fc, 0xf7fc, 0x55, 1 }, | ||
194 | { 0xf7fd, 0xf7fd, 0x59, 1 }, | ||
195 | { 0xf7ff, 0xf7ff, 0x59, 1 }, | ||
138 | { 0xfb00, 0xfb00, 0x6666, 2 }, | 196 | { 0xfb00, 0xfb00, 0x6666, 2 }, |
139 | { 0xfb01, 0xfb01, 0x6669, 2 }, | 197 | { 0xfb01, 0xfb01, 0x6669, 2 }, |
140 | { 0xfb02, 0xfb02, 0x666c, 2 }, | 198 | { 0xfb02, 0xfb02, 0x666c, 2 }, |
141 | { 0xfb03, 0xfb03, 0x666669, 3 }, | 199 | { 0xfb03, 0xfb03, 0x666669, 3 }, |
142 | { 0xfb04, 0xfb04, 0x66666c, 3 } | 200 | { 0xfb04, 0xfb04, 0x66666c, 3 } |
143 | }; | 201 | }; |
diff --git a/noncore/unsupported/qpdf/xpdf/XRef.cc b/noncore/unsupported/qpdf/xpdf/XRef.cc index 5d526e9..0e1bbc9 100644 --- a/noncore/unsupported/qpdf/xpdf/XRef.cc +++ b/noncore/unsupported/qpdf/xpdf/XRef.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // XRef.cc | 3 | // XRef.cc |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -22,12 +22,13 @@ | |||
22 | #include "Parser.h" | 22 | #include "Parser.h" |
23 | #include "Dict.h" | 23 | #include "Dict.h" |
24 | #ifndef NO_DECRYPTION | 24 | #ifndef NO_DECRYPTION |
25 | #include "Decrypt.h" | 25 | #include "Decrypt.h" |
26 | #endif | 26 | #endif |
27 | #include "Error.h" | 27 | #include "Error.h" |
28 | #include "ErrorCodes.h" | ||
28 | #include "XRef.h" | 29 | #include "XRef.h" |
29 | 30 | ||
30 | //------------------------------------------------------------------------ | 31 | //------------------------------------------------------------------------ |
31 | 32 | ||
32 | #define xrefSearchSize 1024// read this many bytes at end of file | 33 | #define xrefSearchSize 1024// read this many bytes at end of file |
33 | // to look for 'startxref' | 34 | // to look for 'startxref' |
@@ -46,16 +47,17 @@ | |||
46 | 47 | ||
47 | //------------------------------------------------------------------------ | 48 | //------------------------------------------------------------------------ |
48 | // XRef | 49 | // XRef |
49 | //------------------------------------------------------------------------ | 50 | //------------------------------------------------------------------------ |
50 | 51 | ||
51 | XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { | 52 | XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { |
52 | int pos; | 53 | Guint pos; |
53 | int i; | 54 | int i; |
54 | 55 | ||
55 | ok = gTrue; | 56 | ok = gTrue; |
57 | errCode = errNone; | ||
56 | size = 0; | 58 | size = 0; |
57 | entries = NULL; | 59 | entries = NULL; |
58 | streamEnds = NULL; | 60 | streamEnds = NULL; |
59 | streamEndsLen = 0; | 61 | streamEndsLen = 0; |
60 | 62 | ||
61 | // read the trailer | 63 | // read the trailer |
@@ -64,31 +66,33 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { | |||
64 | pos = readTrailer(); | 66 | pos = readTrailer(); |
65 | 67 | ||
66 | // if there was a problem with the trailer, | 68 | // if there was a problem with the trailer, |
67 | // try to reconstruct the xref table | 69 | // try to reconstruct the xref table |
68 | if (pos == 0) { | 70 | if (pos == 0) { |
69 | if (!(ok = constructXRef())) { | 71 | if (!(ok = constructXRef())) { |
72 | errCode = errDamaged; | ||
70 | return; | 73 | return; |
71 | } | 74 | } |
72 | 75 | ||
73 | // trailer is ok - read the xref table | 76 | // trailer is ok - read the xref table |
74 | } else { | 77 | } else { |
75 | entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry)); | 78 | entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry)); |
76 | for (i = 0; i < size; ++i) { | 79 | for (i = 0; i < size; ++i) { |
77 | entries[i].offset = -1; | 80 | entries[i].offset = 0xffffffff; |
78 | entries[i].used = gFalse; | 81 | entries[i].used = gFalse; |
79 | } | 82 | } |
80 | while (readXRef(&pos)) ; | 83 | while (readXRef(&pos)) ; |
81 | 84 | ||
82 | // if there was a problem with the xref table, | 85 | // if there was a problem with the xref table, |
83 | // try to reconstruct it | 86 | // try to reconstruct it |
84 | if (!ok) { | 87 | if (!ok) { |
85 | gfree(entries); | 88 | gfree(entries); |
86 | size = 0; | 89 | size = 0; |
87 | entries = NULL; | 90 | entries = NULL; |
88 | if (!(ok = constructXRef())) { | 91 | if (!(ok = constructXRef())) { |
92 | errCode = errDamaged; | ||
89 | return; | 93 | return; |
90 | } | 94 | } |
91 | } | 95 | } |
92 | } | 96 | } |
93 | 97 | ||
94 | // now set the trailer dictionary's xref pointer so we can fetch | 98 | // now set the trailer dictionary's xref pointer so we can fetch |
@@ -98,12 +102,13 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { | |||
98 | // check for encryption | 102 | // check for encryption |
99 | #ifndef NO_DECRYPTION | 103 | #ifndef NO_DECRYPTION |
100 | encrypted = gFalse; | 104 | encrypted = gFalse; |
101 | #endif | 105 | #endif |
102 | if (checkEncrypted(ownerPassword, userPassword)) { | 106 | if (checkEncrypted(ownerPassword, userPassword)) { |
103 | ok = gFalse; | 107 | ok = gFalse; |
108 | errCode = errEncrypted; | ||
104 | return; | 109 | return; |
105 | } | 110 | } |
106 | } | 111 | } |
107 | 112 | ||
108 | XRef::~XRef() { | 113 | XRef::~XRef() { |
109 | gfree(entries); | 114 | gfree(entries); |
@@ -112,23 +117,24 @@ XRef::~XRef() { | |||
112 | gfree(streamEnds); | 117 | gfree(streamEnds); |
113 | } | 118 | } |
114 | } | 119 | } |
115 | 120 | ||
116 | // Read startxref position, xref table size, and root. Returns | 121 | // Read startxref position, xref table size, and root. Returns |
117 | // first xref position. | 122 | // first xref position. |
118 | int XRef::readTrailer() { | 123 | Guint XRef::readTrailer() { |
119 | Parser *parser; | 124 | Parser *parser; |
120 | Object obj; | 125 | Object obj; |
121 | char buf[xrefSearchSize+1]; | 126 | char buf[xrefSearchSize+1]; |
122 | int n, pos, pos1; | 127 | int n; |
128 | Guint pos, pos1; | ||
123 | char *p; | 129 | char *p; |
124 | int c; | 130 | int c; |
125 | int i; | 131 | int i; |
126 | 132 | ||
127 | // read last xrefSearchSize bytes | 133 | // read last xrefSearchSize bytes |
128 | str->setPos(-xrefSearchSize); | 134 | str->setPos(xrefSearchSize, -1); |
129 | for (n = 0; n < xrefSearchSize; ++n) { | 135 | for (n = 0; n < xrefSearchSize; ++n) { |
130 | if ((c = str->getChar()) == EOF) | 136 | if ((c = str->getChar()) == EOF) |
131 | break; | 137 | break; |
132 | buf[n] = c; | 138 | buf[n] = c; |
133 | } | 139 | } |
134 | buf[n] = '\0'; | 140 | buf[n] = '\0'; |
@@ -138,13 +144,13 @@ int XRef::readTrailer() { | |||
138 | if (!strncmp(&buf[i], "startxref", 9)) | 144 | if (!strncmp(&buf[i], "startxref", 9)) |
139 | break; | 145 | break; |
140 | } | 146 | } |
141 | if (i < 0) | 147 | if (i < 0) |
142 | return 0; | 148 | return 0; |
143 | for (p = &buf[i+9]; isspace(*p); ++p) ; | 149 | for (p = &buf[i+9]; isspace(*p); ++p) ; |
144 | pos = lastXRefPos = atoi(p); | 150 | pos = lastXRefPos = strToUnsigned(p); |
145 | 151 | ||
146 | // find trailer dict by looking after first xref table | 152 | // find trailer dict by looking after first xref table |
147 | // (NB: we can't just use the trailer dict at the end of the file -- | 153 | // (NB: we can't just use the trailer dict at the end of the file -- |
148 | // this won't work for linearized files.) | 154 | // this won't work for linearized files.) |
149 | str->setPos(start + pos); | 155 | str->setPos(start + pos); |
150 | for (i = 0; i < 4; ++i) | 156 | for (i = 0; i < 4; ++i) |
@@ -173,14 +179,15 @@ int XRef::readTrailer() { | |||
173 | pos1 += (p - buf) + n * 20; | 179 | pos1 += (p - buf) + n * 20; |
174 | } | 180 | } |
175 | pos1 += 7; | 181 | pos1 += 7; |
176 | 182 | ||
177 | // read trailer dict | 183 | // read trailer dict |
178 | obj.initNull(); | 184 | obj.initNull(); |
179 | parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(start + pos1, | 185 | parser = new Parser(NULL, |
180 | -1, &obj))); | 186 | new Lexer(NULL, |
187 | str->makeSubStream(start + pos1, gFalse, 0, &obj))); | ||
181 | parser->getObj(&trailerDict); | 188 | parser->getObj(&trailerDict); |
182 | if (trailerDict.isDict()) { | 189 | if (trailerDict.isDict()) { |
183 | trailerDict.dictLookupNF("Size", &obj); | 190 | trailerDict.dictLookupNF("Size", &obj); |
184 | if (obj.isInt()) | 191 | if (obj.isInt()) |
185 | size = obj.getInt(); | 192 | size = obj.getInt(); |
186 | else | 193 | else |
@@ -201,13 +208,13 @@ int XRef::readTrailer() { | |||
201 | 208 | ||
202 | // return first xref position | 209 | // return first xref position |
203 | return pos; | 210 | return pos; |
204 | } | 211 | } |
205 | 212 | ||
206 | // Read an xref table and the prev pointer from the trailer. | 213 | // Read an xref table and the prev pointer from the trailer. |
207 | GBool XRef::readXRef(int *pos) { | 214 | GBool XRef::readXRef(Guint *pos) { |
208 | Parser *parser; | 215 | Parser *parser; |
209 | Object obj, obj2; | 216 | Object obj, obj2; |
210 | char s[20]; | 217 | char s[20]; |
211 | GBool more; | 218 | GBool more; |
212 | int first, newSize, n, i, j; | 219 | int first, newSize, n, i, j; |
213 | int c; | 220 | int c; |
@@ -258,27 +265,27 @@ GBool XRef::readXRef(int *pos) { | |||
258 | // check for buggy PDF files with an incorrect (too small) xref | 265 | // check for buggy PDF files with an incorrect (too small) xref |
259 | // table size | 266 | // table size |
260 | if (first + n > size) { | 267 | if (first + n > size) { |
261 | newSize = size + 256; | 268 | newSize = size + 256; |
262 | entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); | 269 | entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); |
263 | for (i = size; i < newSize; ++i) { | 270 | for (i = size; i < newSize; ++i) { |
264 | entries[i].offset = -1; | 271 | entries[i].offset = 0xffffffff; |
265 | entries[i].used = gFalse; | 272 | entries[i].used = gFalse; |
266 | } | 273 | } |
267 | size = newSize; | 274 | size = newSize; |
268 | } | 275 | } |
269 | for (i = first; i < first + n; ++i) { | 276 | for (i = first; i < first + n; ++i) { |
270 | for (j = 0; j < 20; ++j) { | 277 | for (j = 0; j < 20; ++j) { |
271 | if ((c = str->getChar()) == EOF) { | 278 | if ((c = str->getChar()) == EOF) { |
272 | goto err2; | 279 | goto err2; |
273 | } | 280 | } |
274 | s[j] = (char)c; | 281 | s[j] = (char)c; |
275 | } | 282 | } |
276 | if (entries[i].offset < 0) { | 283 | if (entries[i].offset == 0xffffffff) { |
277 | s[10] = '\0'; | 284 | s[10] = '\0'; |
278 | entries[i].offset = atoi(s); | 285 | entries[i].offset = strToUnsigned(s); |
279 | s[16] = '\0'; | 286 | s[16] = '\0'; |
280 | entries[i].gen = atoi(&s[11]); | 287 | entries[i].gen = atoi(&s[11]); |
281 | if (s[17] == 'n') { | 288 | if (s[17] == 'n') { |
282 | entries[i].used = gTrue; | 289 | entries[i].used = gTrue; |
283 | } else if (s[17] == 'f') { | 290 | } else if (s[17] == 'f') { |
284 | entries[i].used = gFalse; | 291 | entries[i].used = gFalse; |
@@ -290,34 +297,35 @@ GBool XRef::readXRef(int *pos) { | |||
290 | // instead of 0. | 297 | // instead of 0. |
291 | if (i == 1 && first == 1 && | 298 | if (i == 1 && first == 1 && |
292 | entries[1].offset == 0 && entries[1].gen == 65535 && | 299 | entries[1].offset == 0 && entries[1].gen == 65535 && |
293 | !entries[1].used) { | 300 | !entries[1].used) { |
294 | i = first = 0; | 301 | i = first = 0; |
295 | entries[0] = entries[1]; | 302 | entries[0] = entries[1]; |
296 | entries[1].offset = -1; | 303 | entries[1].offset = 0xffffffff; |
297 | } | 304 | } |
298 | } | 305 | } |
299 | } | 306 | } |
300 | } | 307 | } |
301 | 308 | ||
302 | // read prev pointer from trailer dictionary | 309 | // read prev pointer from trailer dictionary |
303 | obj.initNull(); | 310 | obj.initNull(); |
304 | parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(str->getPos(), | 311 | parser = new Parser(NULL, |
305 | -1, &obj))); | 312 | new Lexer(NULL, |
313 | str->makeSubStream(str->getPos(), gFalse, 0, &obj))); | ||
306 | parser->getObj(&obj); | 314 | parser->getObj(&obj); |
307 | if (!obj.isCmd("trailer")) { | 315 | if (!obj.isCmd("trailer")) { |
308 | goto err1; | 316 | goto err1; |
309 | } | 317 | } |
310 | obj.free(); | 318 | obj.free(); |
311 | parser->getObj(&obj); | 319 | parser->getObj(&obj); |
312 | if (!obj.isDict()) { | 320 | if (!obj.isDict()) { |
313 | goto err1; | 321 | goto err1; |
314 | } | 322 | } |
315 | obj.getDict()->lookupNF("Prev", &obj2); | 323 | obj.getDict()->lookupNF("Prev", &obj2); |
316 | if (obj2.isInt()) { | 324 | if (obj2.isInt()) { |
317 | *pos = obj2.getInt(); | 325 | *pos = (Guint)obj2.getInt(); |
318 | more = gTrue; | 326 | more = gTrue; |
319 | } else { | 327 | } else { |
320 | more = gFalse; | 328 | more = gFalse; |
321 | } | 329 | } |
322 | obj.free(); | 330 | obj.free(); |
323 | obj2.free(); | 331 | obj2.free(); |
@@ -334,13 +342,13 @@ GBool XRef::readXRef(int *pos) { | |||
334 | 342 | ||
335 | // Attempt to construct an xref table for a damaged file. | 343 | // Attempt to construct an xref table for a damaged file. |
336 | GBool XRef::constructXRef() { | 344 | GBool XRef::constructXRef() { |
337 | Parser *parser; | 345 | Parser *parser; |
338 | Object obj; | 346 | Object obj; |
339 | char buf[256]; | 347 | char buf[256]; |
340 | int pos; | 348 | Guint pos; |
341 | int num, gen; | 349 | int num, gen; |
342 | int newSize; | 350 | int newSize; |
343 | int streamEndsSize; | 351 | int streamEndsSize; |
344 | char *p; | 352 | char *p; |
345 | int i; | 353 | int i; |
346 | GBool gotRoot; | 354 | GBool gotRoot; |
@@ -357,14 +365,15 @@ GBool XRef::constructXRef() { | |||
357 | } | 365 | } |
358 | p = buf; | 366 | p = buf; |
359 | 367 | ||
360 | // got trailer dictionary | 368 | // got trailer dictionary |
361 | if (!strncmp(p, "trailer", 7)) { | 369 | if (!strncmp(p, "trailer", 7)) { |
362 | obj.initNull(); | 370 | obj.initNull(); |
363 | parser = new Parser(NULL, new Lexer(NULL, | 371 | parser = new Parser(NULL, |
364 | str->makeSubStream(start + pos + 7, -1, &obj))); | 372 | new Lexer(NULL, |
373 | str->makeSubStream(start + pos + 7, gFalse, 0, &obj))); | ||
365 | if (!trailerDict.isNone()) | 374 | if (!trailerDict.isNone()) |
366 | trailerDict.free(); | 375 | trailerDict.free(); |
367 | parser->getObj(&trailerDict); | 376 | parser->getObj(&trailerDict); |
368 | if (trailerDict.isDict()) { | 377 | if (trailerDict.isDict()) { |
369 | trailerDict.dictLookupNF("Root", &obj); | 378 | trailerDict.dictLookupNF("Root", &obj); |
370 | if (obj.isRef()) { | 379 | if (obj.isRef()) { |
@@ -400,13 +409,13 @@ GBool XRef::constructXRef() { | |||
400 | if (!strncmp(p, "obj", 3)) { | 409 | if (!strncmp(p, "obj", 3)) { |
401 | if (num >= size) { | 410 | if (num >= size) { |
402 | newSize = (num + 1 + 255) & ~255; | 411 | newSize = (num + 1 + 255) & ~255; |
403 | entries = (XRefEntry *) | 412 | entries = (XRefEntry *) |
404 | grealloc(entries, newSize * sizeof(XRefEntry)); | 413 | grealloc(entries, newSize * sizeof(XRefEntry)); |
405 | for (i = size; i < newSize; ++i) { | 414 | for (i = size; i < newSize; ++i) { |
406 | entries[i].offset = -1; | 415 | entries[i].offset = 0xffffffff; |
407 | entries[i].used = gFalse; | 416 | entries[i].used = gFalse; |
408 | } | 417 | } |
409 | size = newSize; | 418 | size = newSize; |
410 | } | 419 | } |
411 | if (!entries[num].used || gen >= entries[num].gen) { | 420 | if (!entries[num].used || gen >= entries[num].gen) { |
412 | entries[num].offset = pos - start; | 421 | entries[num].offset = pos - start; |
@@ -418,13 +427,14 @@ GBool XRef::constructXRef() { | |||
418 | } | 427 | } |
419 | } | 428 | } |
420 | 429 | ||
421 | } else if (!strncmp(p, "endstream", 9)) { | 430 | } else if (!strncmp(p, "endstream", 9)) { |
422 | if (streamEndsLen == streamEndsSize) { | 431 | if (streamEndsLen == streamEndsSize) { |
423 | streamEndsSize += 64; | 432 | streamEndsSize += 64; |
424 | streamEnds = (int *)grealloc(streamEnds, streamEndsSize * sizeof(int)); | 433 | streamEnds = (Guint *)grealloc(streamEnds, |
434 | streamEndsSize * sizeof(int)); | ||
425 | } | 435 | } |
426 | streamEnds[streamEndsLen++] = pos; | 436 | streamEnds[streamEndsLen++] = pos; |
427 | } | 437 | } |
428 | } | 438 | } |
429 | 439 | ||
430 | if (gotRoot) | 440 | if (gotRoot) |
@@ -577,16 +587,17 @@ Object *XRef::fetch(int num, int gen, Object *obj) { | |||
577 | if (num < 0 || num >= size) { | 587 | if (num < 0 || num >= size) { |
578 | obj->initNull(); | 588 | obj->initNull(); |
579 | return obj; | 589 | return obj; |
580 | } | 590 | } |
581 | 591 | ||
582 | e = &entries[num]; | 592 | e = &entries[num]; |
583 | if (e->gen == gen && e->offset >= 0) { | 593 | if (e->gen == gen && e->offset != 0xffffffff) { |
584 | obj1.initNull(); | 594 | obj1.initNull(); |
585 | parser = new Parser(this, new Lexer(this, | 595 | parser = new Parser(this, |
586 | str->makeSubStream(start + e->offset, -1, &obj1))); | 596 | new Lexer(this, |
597 | str->makeSubStream(start + e->offset, gFalse, 0, &obj1))); | ||
587 | parser->getObj(&obj1); | 598 | parser->getObj(&obj1); |
588 | parser->getObj(&obj2); | 599 | parser->getObj(&obj2); |
589 | parser->getObj(&obj3); | 600 | parser->getObj(&obj3); |
590 | if (obj1.isInt() && obj1.getInt() == num && | 601 | if (obj1.isInt() && obj1.getInt() == num && |
591 | obj2.isInt() && obj2.getInt() == gen && | 602 | obj2.isInt() && obj2.getInt() == gen && |
592 | obj3.isCmd("obj")) { | 603 | obj3.isCmd("obj")) { |
@@ -615,18 +626,18 @@ Object *XRef::getDocInfo(Object *obj) { | |||
615 | 626 | ||
616 | // Added for the pdftex project. | 627 | // Added for the pdftex project. |
617 | Object *XRef::getDocInfoNF(Object *obj) { | 628 | Object *XRef::getDocInfoNF(Object *obj) { |
618 | return trailerDict.dictLookupNF("Info", obj); | 629 | return trailerDict.dictLookupNF("Info", obj); |
619 | } | 630 | } |
620 | 631 | ||
621 | int XRef::getStreamEnd(int streamStart) { | 632 | GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) { |
622 | int a, b, m; | 633 | int a, b, m; |
623 | 634 | ||
624 | if (streamEndsLen == 0 || | 635 | if (streamEndsLen == 0 || |
625 | streamStart > streamEnds[streamEndsLen - 1]) { | 636 | streamStart > streamEnds[streamEndsLen - 1]) { |
626 | return -1; | 637 | return gFalse; |
627 | } | 638 | } |
628 | 639 | ||
629 | a = -1; | 640 | a = -1; |
630 | b = streamEndsLen - 1; | 641 | b = streamEndsLen - 1; |
631 | // invariant: streamEnds[a] < streamStart <= streamEnds[b] | 642 | // invariant: streamEnds[a] < streamStart <= streamEnds[b] |
632 | while (b - a > 1) { | 643 | while (b - a > 1) { |
@@ -634,8 +645,21 @@ int XRef::getStreamEnd(int streamStart) { | |||
634 | if (streamStart <= streamEnds[m]) { | 645 | if (streamStart <= streamEnds[m]) { |
635 | b = m; | 646 | b = m; |
636 | } else { | 647 | } else { |
637 | a = m; | 648 | a = m; |
638 | } | 649 | } |
639 | } | 650 | } |
640 | return streamEnds[b]; | 651 | *streamEnd = streamEnds[b]; |
652 | return gTrue; | ||
653 | } | ||
654 | |||
655 | Guint XRef::strToUnsigned(char *s) { | ||
656 | Guint x; | ||
657 | char *p; | ||
658 | int i; | ||
659 | |||
660 | x = 0; | ||
661 | for (p = s, i = 0; *p && isdigit(*p) && i < 10; ++p, ++i) { | ||
662 | x = 10 * x + (*p - '0'); | ||
663 | } | ||
664 | return x; | ||
641 | } | 665 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/XRef.h b/noncore/unsupported/qpdf/xpdf/XRef.h index a44c495..7876fa6 100644 --- a/noncore/unsupported/qpdf/xpdf/XRef.h +++ b/noncore/unsupported/qpdf/xpdf/XRef.h | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // XRef.h | 3 | // XRef.h |
4 | // | 4 | // |
5 | // Copyright 1996 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef XREF_H | 9 | #ifndef XREF_H |
10 | #define XREF_H | 10 | #define XREF_H |
11 | 11 | ||
@@ -21,13 +21,13 @@ class Stream; | |||
21 | 21 | ||
22 | //------------------------------------------------------------------------ | 22 | //------------------------------------------------------------------------ |
23 | // XRef | 23 | // XRef |
24 | //------------------------------------------------------------------------ | 24 | //------------------------------------------------------------------------ |
25 | 25 | ||
26 | struct XRefEntry { | 26 | struct XRefEntry { |
27 | int offset; | 27 | Guint offset; |
28 | int gen; | 28 | int gen; |
29 | GBool used; | 29 | GBool used; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | class XRef { | 32 | class XRef { |
33 | public: | 33 | public: |
@@ -38,12 +38,15 @@ public: | |||
38 | // Destructor. | 38 | // Destructor. |
39 | ~XRef(); | 39 | ~XRef(); |
40 | 40 | ||
41 | // Is xref table valid? | 41 | // Is xref table valid? |
42 | GBool isOk() { return ok; } | 42 | GBool isOk() { return ok; } |
43 | 43 | ||
44 | // Get the error code (if isOk() returns false). | ||
45 | int getErrorCode() { return errCode; } | ||
46 | |||
44 | // Is the file encrypted? | 47 | // Is the file encrypted? |
45 | #ifndef NO_DECRYPTION | 48 | #ifndef NO_DECRYPTION |
46 | GBool isEncrypted() { return encrypted; } | 49 | GBool isEncrypted() { return encrypted; } |
47 | #else | 50 | #else |
48 | GBool isEncrypted() { return gFalse; } | 51 | GBool isEncrypted() { return gFalse; } |
49 | #endif | 52 | #endif |
@@ -65,47 +68,49 @@ public: | |||
65 | Object *getDocInfoNF(Object *obj); | 68 | Object *getDocInfoNF(Object *obj); |
66 | 69 | ||
67 | // Return the number of objects in the xref table. | 70 | // Return the number of objects in the xref table. |
68 | int getNumObjects() { return size; } | 71 | int getNumObjects() { return size; } |
69 | 72 | ||
70 | // Return the offset of the last xref table. | 73 | // Return the offset of the last xref table. |
71 | int getLastXRefPos() { return lastXRefPos; } | 74 | Guint getLastXRefPos() { return lastXRefPos; } |
72 | 75 | ||
73 | // Return the catalog object reference. | 76 | // Return the catalog object reference. |
74 | int getRootNum() { return rootNum; } | 77 | int getRootNum() { return rootNum; } |
75 | int getRootGen() { return rootGen; } | 78 | int getRootGen() { return rootGen; } |
76 | 79 | ||
77 | // Get end position for a stream in a damaged file. | 80 | // Get end position for a stream in a damaged file. |
78 | // Returns -1 if unknown or file is not damaged. | 81 | // Returns false if unknown or file is not damaged. |
79 | int getStreamEnd(int streamStart); | 82 | GBool getStreamEnd(Guint streamStart, Guint *streamEnd); |
80 | 83 | ||
81 | private: | 84 | private: |
82 | 85 | ||
83 | BaseStream *str; // input stream | 86 | BaseStream *str; // input stream |
84 | int start; // offset in file (to allow for garbage | 87 | Guint start; // offset in file (to allow for garbage |
85 | // at beginning of file) | 88 | // at beginning of file) |
86 | XRefEntry *entries; // xref entries | 89 | XRefEntry *entries; // xref entries |
87 | int size; // size of <entries> array | 90 | int size; // size of <entries> array |
88 | int rootNum, rootGen; // catalog dict | 91 | int rootNum, rootGen; // catalog dict |
89 | GBool ok; // true if xref table is valid | 92 | GBool ok; // true if xref table is valid |
93 | int errCode; // error code (if <ok> is false) | ||
90 | Object trailerDict; // trailer dictionary | 94 | Object trailerDict; // trailer dictionary |
91 | int lastXRefPos; // offset of last xref table | 95 | Guint lastXRefPos; // offset of last xref table |
92 | int *streamEnds; // 'endstream' positions - only used in | 96 | Guint *streamEnds; // 'endstream' positions - only used in |
93 | // damaged files | 97 | // damaged files |
94 | int streamEndsLen; // number of valid entries in streamEnds | 98 | int streamEndsLen; // number of valid entries in streamEnds |
95 | #ifndef NO_DECRYPTION | 99 | #ifndef NO_DECRYPTION |
96 | GBool encrypted; // true if file is encrypted | 100 | GBool encrypted; // true if file is encrypted |
97 | int encVersion; // encryption algorithm | 101 | int encVersion; // encryption algorithm |
98 | int encRevision; // security handler revision | 102 | int encRevision; // security handler revision |
99 | int keyLength; // length of key, in bytes | 103 | int keyLength; // length of key, in bytes |
100 | int permFlags; // permission bits | 104 | int permFlags; // permission bits |
101 | Guchar fileKey[16]; // file decryption key | 105 | Guchar fileKey[16]; // file decryption key |
102 | GBool ownerPasswordOk;// true if owner password is correct | 106 | GBool ownerPasswordOk;// true if owner password is correct |
103 | #endif | 107 | #endif |
104 | 108 | ||
105 | int readTrailer(); | 109 | Guint readTrailer(); |
106 | GBool readXRef(int *pos); | 110 | GBool readXRef(Guint *pos); |
107 | GBool constructXRef(); | 111 | GBool constructXRef(); |
108 | GBool checkEncrypted(GString *ownerPassword, GString *userPassword); | 112 | GBool checkEncrypted(GString *ownerPassword, GString *userPassword); |
113 | Guint strToUnsigned(char *s); | ||
109 | }; | 114 | }; |
110 | 115 | ||
111 | #endif | 116 | #endif |