summaryrefslogtreecommitdiff
path: root/noncore/unsupported/qpdf
authorsandman <sandman>2002-05-23 23:51:52 (UTC)
committer sandman <sandman>2002-05-23 23:51:52 (UTC)
commit2f3bb7b07f833273d966d41813e68bfe8b9d8d76 (patch) (unidiff)
tree00beb1bd9e7f4ba79e22334a0d258269b28f4564 /noncore/unsupported/qpdf
parent6e82b45dd416ceeba78765717b700e853c96a137 (diff)
downloadopie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.zip
opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.gz
opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.bz2
Port to xpdf 1.01
Diffstat (limited to 'noncore/unsupported/qpdf') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/unsupported/qpdf/QOutputDev.h7
-rw-r--r--noncore/unsupported/qpdf/README45
-rw-r--r--noncore/unsupported/qpdf/UTF8.h14
-rw-r--r--noncore/unsupported/qpdf/qpdf.cpp13
-rw-r--r--noncore/unsupported/qpdf/qpdf.h7
-rw-r--r--noncore/unsupported/qpdf/qpdf.pro5
-rw-r--r--noncore/unsupported/qpdf/xpdf/Annot.cc (renamed from noncore/unsupported/qpdf/xpdf/FormWidget.cc)53
-rw-r--r--noncore/unsupported/qpdf/xpdf/Annot.h (renamed from noncore/unsupported/qpdf/xpdf/FormWidget.h)40
-rw-r--r--noncore/unsupported/qpdf/xpdf/Array.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Array.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFont.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/CMap.cc104
-rw-r--r--noncore/unsupported/qpdf/xpdf/CMap.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Catalog.cc8
-rw-r--r--noncore/unsupported/qpdf/xpdf/Catalog.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc160
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h5
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharTypes.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Decrypt.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Decrypt.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Dict.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Dict.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/DisplayFontTable.h6
-rw-r--r--noncore/unsupported/qpdf/xpdf/Error.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Error.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/ErrorCodes.h24
-rw-r--r--noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/FontEncodingTables.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Function.cc13
-rw-r--r--noncore/unsupported/qpdf/xpdf/Function.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Gfx.cc589
-rw-r--r--noncore/unsupported/qpdf/xpdf/Gfx.h20
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxFont.cc62
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxFont.h24
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.cc246
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.h39
-rw-r--r--noncore/unsupported/qpdf/xpdf/GlobalParams.cc381
-rw-r--r--noncore/unsupported/qpdf/xpdf/GlobalParams.h49
-rw-r--r--noncore/unsupported/qpdf/xpdf/Lexer.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Lexer.h11
-rw-r--r--noncore/unsupported/qpdf/xpdf/Link.cc34
-rw-r--r--noncore/unsupported/qpdf/xpdf/Link.h8
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToCharCode.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToCharCode.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Object.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Object.h12
-rw-r--r--noncore/unsupported/qpdf/xpdf/OutputDev.cc7
-rw-r--r--noncore/unsupported/qpdf/xpdf/OutputDev.h17
-rw-r--r--noncore/unsupported/qpdf/xpdf/PDFDoc.cc16
-rw-r--r--noncore/unsupported/qpdf/xpdf/PDFDoc.h6
-rw-r--r--noncore/unsupported/qpdf/xpdf/PSTokenizer.cc133
-rw-r--r--noncore/unsupported/qpdf/xpdf/PSTokenizer.h39
-rw-r--r--noncore/unsupported/qpdf/xpdf/Page.cc40
-rw-r--r--noncore/unsupported/qpdf/xpdf/Page.h28
-rw-r--r--noncore/unsupported/qpdf/xpdf/Parser.cc11
-rw-r--r--noncore/unsupported/qpdf/xpdf/Parser.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream-CCITT.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream.cc215
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream.h113
-rw-r--r--noncore/unsupported/qpdf/xpdf/TextOutputDev.cc73
-rw-r--r--noncore/unsupported/qpdf/xpdf/TextOutputDev.h22
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMap.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMap.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h60
-rw-r--r--noncore/unsupported/qpdf/xpdf/XRef.cc80
-rw-r--r--noncore/unsupported/qpdf/xpdf/XRef.h25
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
@@ -79,6 +79,13 @@ public:
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.
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,7 +1,7 @@
1 1
2QPDF - a PDF viewer for the Qtopia environment 2QPDF - a PDF viewer for the Qtopia environment
3 3
4This tool is based on xpdf (currently 1.00). It uses the (mostly unmodified - 4This tool is based on xpdf (currently 1.01). It uses the (mostly unmodified -
5see below) xpdf PDF rendering engine. The Qtopia adaption was done with a new 5see below) xpdf PDF rendering engine. The Qtopia adaption was done with a new
6OutputDev which renders directly to a QPixmap via QPainter calls. 6OutputDev which renders directly to a QPixmap via QPainter calls.
7 7
@@ -20,12 +20,19 @@ Changes in 20020408:
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
23Changed in 20020413: 23Changes 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
29Changes in 20020417:
30 - Fixed crash in XPDF regarding 0-length strings.
31 - Fast sqrt, rint and fabs functions added.
32
33Changes in 20020524:
34 - Ported to xpdf 1.01
35
29 36
30Changes to xpdf: 37Changes 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
@@ -52,36 +59,20 @@ ToDo:
52 59
53 60
54Install: 61Install:
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
86Have fun ;) 77Have fun ;)
87 78
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
@@ -22,3 +22,17 @@ static int mapUTF8 ( Unicode u, char *buf, int bufSize )
22 else 22 else
23 return 0; 23 return 0;
24} 24}
25
26static 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
@@ -16,12 +16,12 @@
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>
@@ -37,6 +37,12 @@
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
41int main ( int argc, char **argv ) 47int main ( int argc, char **argv )
42{ 48{
@@ -81,7 +87,12 @@ QPdfDlg::QPdfDlg ( ) : QMainWindow ( )
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
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
@@ -5,12 +5,14 @@
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
9class QPEOutputDev; 10class QPEOutputDev;
10class PDFDoc; 11class PDFDoc;
11 12
12class DocLnk; 13class DocLnk;
13class FileSelector; 14class FileSelector;
15class OFileSelector;
14class QWidgetStack; 16class QWidgetStack;
15class QLineEdit; 17class QLineEdit;
16 18
@@ -68,7 +70,12 @@ protected:
68private: 70private:
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;
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
@@ -13,7 +13,7 @@ SOURCES = xpdf/Array.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 \
@@ -27,6 +27,7 @@ SOURCES = xpdf/Array.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 \
@@ -52,7 +53,7 @@ INCLUDEPATH += . \
52 ../goo \ 53 ../goo \
53 goo 54 goo
54 55
55LIBS += -L $(OPIEDIR)/lib -lqpe 56LIBS += -L $(OPIEDIR)/lib -lqpe -lopie
56 57
57DESTDIR = $(OPIEDIR)/bin 58DESTDIR = $(OPIEDIR)/bin
58TARGET = qpdf 59TARGET = qpdf
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,8 +1,8 @@
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
@@ -14,13 +14,13 @@
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
23FormWidget::FormWidget(XRef *xrefA, Dict *dict) { 23Annot::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
@@ -77,49 +77,48 @@ FormWidget::FormWidget(XRef *xrefA, Dict *dict) {
77 obj1.free(); 77 obj1.free();
78} 78}
79 79
80FormWidget::~FormWidget() { 80Annot::~Annot() {
81 appearance.free(); 81 appearance.free();
82} 82}
83 83
84void FormWidget::draw(Gfx *gfx) { 84void 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
97FormWidgets::FormWidgets(XRef *xref, Object *annots) { 97Annots::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();
@@ -129,11 +128,11 @@ FormWidgets::FormWidgets(XRef *xref, Object *annots) {
129 } 128 }
130} 129}
131 130
132FormWidgets::~FormWidgets() { 131Annots::~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,30 +1,32 @@
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
16class XRef; 18class XRef;
17class Gfx; 19class Gfx;
18 20
19//------------------------------------------------------------------------ 21//------------------------------------------------------------------------
20// FormWidget 22// Annot
21//------------------------------------------------------------------------ 23//------------------------------------------------------------------------
22 24
23class FormWidget { 25class Annot {
24public: 26public:
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);
@@ -37,31 +39,31 @@ private:
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
49class FormWidgets { 51class Annots {
50public: 52public:
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
61private: 63private:
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -20,6 +20,7 @@
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//------------------------------------------------------------------------
@@ -34,15 +35,20 @@ struct CMapVectorEntry {
34 35
35//------------------------------------------------------------------------ 36//------------------------------------------------------------------------
36 37
38static int getCharFromFile(void *data) {
39 return fgetc((FILE *)data);
40}
41
42//------------------------------------------------------------------------
43
37CMap *CMap::parse(CMapCache *cache, GString *collectionA, 44CMap *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
@@ -61,50 +67,64 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA,
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -146,7 +146,7 @@ GString *Catalog::readMetadata() {
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();
@@ -265,10 +265,10 @@ LinkDest *Catalog::findDest(GString *name) {
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();
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -18,6 +18,7 @@
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//------------------------------------------------------------------------
@@ -32,6 +33,26 @@ struct CharCodeToUnicodeString {
32 33
33//------------------------------------------------------------------------ 34//------------------------------------------------------------------------
34 35
36static 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
50static int getCharFromFile(void *data) {
51 return fgetc((FILE *)data);
52}
53
54//------------------------------------------------------------------------
55
35CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) { 56CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) {
36 FILE *f; 57 FILE *f;
37 Unicode *mapA; 58 Unicode *mapA;
@@ -75,47 +96,20 @@ 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
78static 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
103CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) { 99CharCodeToUnicode *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
114void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *), 109void 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;
@@ -126,28 +120,40 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
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) {
@@ -160,7 +166,7 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
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;
@@ -177,31 +183,35 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
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) {
@@ -214,7 +224,7 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
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) {
@@ -234,34 +244,20 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
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
267CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) { 263CharCodeToUnicode::CharCodeToUnicode(GString *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
@@ -4,7 +4,7 @@
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
@@ -50,8 +50,7 @@ public:
50 50
51private: 51private:
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,
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -11,7 +11,7 @@ static struct {
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"},
@@ -27,5 +27,5 @@ static struct {
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -415,7 +415,6 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
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)) {
@@ -425,6 +424,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
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) {
@@ -436,6 +436,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
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;
@@ -456,6 +457,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
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;
@@ -480,6 +482,13 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -30,6 +30,11 @@
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//------------------------------------------------------------------------
@@ -40,6 +45,12 @@
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//------------------------------------------------------------------------
@@ -374,6 +385,7 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
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
@@ -405,21 +417,54 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
405 } 417 }
406} 418}
407 419
408Gfx::~Gfx() { 420Gfx::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
454Gfx::~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
425void Gfx::display(Object *obj, GBool topLevel) { 470void Gfx::display(Object *obj, GBool topLevel) {
@@ -449,11 +494,11 @@ void Gfx::display(Object *obj, GBool topLevel) {
449void Gfx::go(GBool topLevel) { 494void 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()) {
@@ -476,9 +521,9 @@ void Gfx::go(GBool topLevel) {
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
@@ -519,7 +564,7 @@ void Gfx::go(GBool topLevel) {
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}
@@ -1138,7 +1183,7 @@ void Gfx::doPatternFill(GBool eoFill) {
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;
@@ -1189,15 +1234,6 @@ void Gfx::doPatternFill(GBool eoFill) {
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;
@@ -1331,6 +1367,9 @@ void Gfx::opShFill(Object args[], int numArgs) {
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
@@ -1343,9 +1382,6 @@ void Gfx::opShFill(Object args[], int numArgs) {
1343void Gfx::doAxialShFill(GfxAxialShading *shading) { 1382void 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;
@@ -1357,54 +1393,8 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
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
@@ -1619,6 +1609,202 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
1619 } 1609 }
1620} 1610}
1621 1611
1612void 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
1622void Gfx::doEndPath() { 1808void Gfx::doEndPath() {
1623 if (state->isPath() && clip != clipNone) { 1809 if (state->isPath() && clip != clipNone) {
1624 state->clip(); 1810 state->clip();
@@ -1800,17 +1986,23 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) {
1800void Gfx::opShowSpaceText(Object args[], int numArgs) { 1986void 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());
@@ -1823,31 +2015,33 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
1823 2015
1824void Gfx::doShowText(GString *s) { 2016void 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];
@@ -1867,6 +2061,8 @@ void Gfx::doShowText(GString *s) {
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();
@@ -1874,21 +2070,6 @@ void Gfx::doShowText(GString *s) {
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();
@@ -1896,31 +2077,61 @@ void Gfx::doShowText(GString *s) {
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();
@@ -1931,7 +2142,6 @@ void Gfx::doShowText(GString *s) {
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;
@@ -1951,15 +2161,28 @@ void Gfx::doShowText(GString *s) {
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//------------------------------------------------------------------------
@@ -1967,7 +2190,7 @@ void Gfx::doShowText(GString *s) {
1967//------------------------------------------------------------------------ 2190//------------------------------------------------------------------------
1968 2191
1969void Gfx::opXObject(Object args[], int numArgs) { 2192void 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
@@ -1993,6 +2216,10 @@ void Gfx::opXObject(Object args[], int numArgs) {
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 {
@@ -2148,6 +2375,11 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
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:
@@ -2215,19 +2447,22 @@ void Gfx::doForm(Object *str) {
2215 resObj.free(); 2447 resObj.free();
2216} 2448}
2217 2449
2218void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin, 2450void 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();
@@ -2241,7 +2476,7 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
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) {
@@ -2256,16 +2491,64 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
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);
@@ -2281,11 +2564,10 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
2281void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) { 2564void 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);
@@ -2332,11 +2614,21 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
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
2622void Gfx::pushResources(Dict *resDict) {
2623 res = new GfxResources(xref, resDict, res);
2624}
2625
2626void 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//------------------------------------------------------------------------
@@ -2378,19 +2670,24 @@ Stream *Gfx::buildImageStream() {
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
@@ -2413,11 +2710,13 @@ void Gfx::opEndImage(Object args[], int numArgs) {
2413//------------------------------------------------------------------------ 2710//------------------------------------------------------------------------
2414 2711
2415void Gfx::opSetCharWidth(Object args[], int numArgs) { 2712void 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
2419void Gfx::opSetCacheDevice(Object args[], int numArgs) { 2716void 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//------------------------------------------------------------------------
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
@@ -2,7 +2,7 @@
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
@@ -27,6 +27,7 @@ class GfxFont;
27class GfxPattern; 27class GfxPattern;
28class GfxShading; 28class GfxShading;
29class GfxAxialShading; 29class GfxAxialShading;
30class GfxRadialShading;
30class GfxState; 31class GfxState;
31class Gfx; 32class Gfx;
32struct PDFRectangle; 33struct PDFRectangle;
@@ -97,21 +98,31 @@ public:
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
109private: 118private:
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
@@ -179,6 +190,7 @@ private:
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
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
@@ -2,7 +2,7 @@
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
@@ -454,13 +454,24 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
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 -----
@@ -513,9 +524,11 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
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);
@@ -524,12 +537,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
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) {
@@ -569,6 +585,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
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);
@@ -636,8 +653,9 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
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] &&
@@ -656,6 +674,9 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
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;
@@ -684,10 +705,14 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
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 }
@@ -752,6 +777,9 @@ Gfx8BitFont::~Gfx8BitFont() {
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
757int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, 785int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,
@@ -771,6 +799,10 @@ CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
771 return ctu; 799 return ctu;
772} 800}
773 801
802Dict *Gfx8BitFont::getCharProcs() {
803 return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL;
804}
805
774Object *Gfx8BitFont::getCharProc(int code, Object *proc) { 806Object *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);
@@ -780,6 +812,10 @@ Object *Gfx8BitFont::getCharProc(int code, Object *proc) {
780 return proc; 812 return proc;
781} 813}
782 814
815Dict *Gfx8BitFont::getResources() {
816 return resources.isDict() ? resources.getDict() : (Dict *)NULL;
817}
818
783//------------------------------------------------------------------------ 819//------------------------------------------------------------------------
784// GfxCIDFont 820// GfxCIDFont
785//------------------------------------------------------------------------ 821//------------------------------------------------------------------------
@@ -1186,6 +1222,10 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
1186 return n; 1222 return n;
1187} 1223}
1188 1224
1225int GfxCIDFont::getWMode() {
1226 return cMap ? cMap->getWMode() : 0;
1227}
1228
1189CharCodeToUnicode *GfxCIDFont::getToUnicode() { 1229CharCodeToUnicode *GfxCIDFont::getToUnicode() {
1190 ctu->incRefCnt(); 1230 ctu->incRefCnt();
1191 return ctu; 1231 return ctu;
@@ -1216,7 +1256,7 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
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();
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
@@ -2,7 +2,7 @@
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
@@ -113,8 +113,7 @@ public:
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.
@@ -137,6 +136,9 @@ public:
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);
@@ -155,7 +157,7 @@ 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)
@@ -166,7 +168,7 @@ protected:
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
@@ -204,9 +206,15 @@ public:
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
210private: 218private:
211 219
212 char *enc[256]; // char code --> char name 220 char *enc[256]; // char code --> char name
@@ -215,7 +223,8 @@ private:
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//------------------------------------------------------------------------
@@ -236,6 +245,9 @@ public:
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
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
@@ -2,7 +2,7 @@
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
@@ -408,9 +408,22 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) {
408} 408}
409 409
410void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { 410void 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
416void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { 429void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
@@ -1268,10 +1281,6 @@ GfxShading *GfxShading::parse(Object *obj) {
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))) {
@@ -1317,7 +1326,17 @@ GfxShading *GfxShading::parse(Object *obj) {
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;
@@ -1457,6 +1476,128 @@ void GfxAxialShading::getColor(fouble t, GfxColor *color) {
1457} 1476}
1458 1477
1459//------------------------------------------------------------------------ 1478//------------------------------------------------------------------------
1479// GfxRadialShading
1480//------------------------------------------------------------------------
1481
1482GfxRadialShading::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
1505GfxRadialShading::~GfxRadialShading() {
1506 int i;
1507
1508 for (i = 0; i < nFuncs; ++i) {
1509 delete funcs[i];
1510 }
1511}
1512
1513GfxRadialShading *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
1592void 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
@@ -1918,6 +2059,67 @@ GfxState::GfxState(GfxState *state) {
1918 saved = NULL; 2059 saved = NULL;
1919} 2060}
1920 2061
2062void 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
1921fouble GfxState::transformWidth(fouble w) { 2123fouble GfxState::transformWidth(fouble w) {
1922 fouble x, y; 2124 fouble x, y;
1923 2125
@@ -1946,12 +2148,23 @@ void GfxState::getFontTransMat(fouble *m11, fouble *m12,
1946 2148
1947void GfxState::setCTM(fouble a, fouble b, fouble c, 2149void 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
1957void GfxState::concatCTM(fouble a, fouble b, fouble c, 2170void GfxState::concatCTM(fouble a, fouble b, fouble c,
@@ -1960,6 +2173,7 @@ void GfxState::concatCTM(fouble a, fouble b, fouble c,
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;
@@ -1967,6 +2181,15 @@ void GfxState::concatCTM(fouble a, fouble b, fouble c,
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
1972void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { 2195void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
@@ -2051,10 +2274,10 @@ void GfxState::clip() {
2051 } 2274 }
2052} 2275}
2053 2276
2054void GfxState::textShift(fouble tx) { 2277void 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}
@@ -2095,3 +2318,4 @@ GfxState *GfxState::restore() {
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
@@ -2,7 +2,7 @@
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
@@ -568,6 +568,40 @@ private:
568}; 568};
569 569
570//------------------------------------------------------------------------ 570//------------------------------------------------------------------------
571// GfxRadialShading
572//------------------------------------------------------------------------
573
574class GfxRadialShading: public GfxShading {
575public:
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
595private:
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
@@ -783,6 +817,7 @@ public:
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
@@ -865,7 +900,7 @@ public:
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.
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
@@ -2,7 +2,7 @@
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
@@ -96,14 +96,20 @@ DisplayFontParam::~DisplayFontParam() {
96// PSFontParam 96// PSFontParam
97//------------------------------------------------------------------------ 97//------------------------------------------------------------------------
98 98
99PSFontParam::PSFontParam(GString *pdfFontNameA, GString *psFontNameA) { 99PSFontParam::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
104PSFontParam::~PSFontParam() { 107PSFontParam::~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//------------------------------------------------------------------------
@@ -115,17 +121,14 @@ GlobalParams::GlobalParams(char *cfgFileName) {
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 }
@@ -139,6 +142,7 @@ GlobalParams::GlobalParams(char *cfgFileName) {
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();
@@ -154,9 +158,14 @@ GlobalParams::GlobalParams(char *cfgFileName) {
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;
@@ -166,6 +175,7 @@ GlobalParams::GlobalParams(char *cfgFileName) {
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;
@@ -193,6 +203,8 @@ GlobalParams::GlobalParams(char *cfgFileName) {
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) {
@@ -219,6 +231,7 @@ GlobalParams::GlobalParams(char *cfgFileName) {
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
@@ -234,98 +247,141 @@ GlobalParams::GlobalParams(char *cfgFileName) {
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; 255void 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
@@ -426,7 +482,7 @@ void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
426 toUnicodeDirs->append(((GString *)tokens->get(1))->copy()); 482 toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
427} 483}
428 484
429void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID, 485void 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;
@@ -458,23 +514,16 @@ void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
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
@@ -516,6 +565,10 @@ void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
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);
@@ -542,11 +595,39 @@ void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
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
603void 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
550void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName, 631void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
551 int line) { 632 int line) {
552 if (tokens->getLength() != 2) { 633 if (tokens->getLength() != 2) {
@@ -588,17 +669,15 @@ void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
588 fontDirs->append(((GString *)tokens->get(1))->copy()); 669 fontDirs->append(((GString *)tokens->get(1))->copy());
589} 670}
590 671
591void GlobalParams::parseURLCommand(GList *tokens, GString *fileName, 672void 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
604void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val, 683void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val,
@@ -618,6 +697,19 @@ void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val,
618 } 697 }
619} 698}
620 699
700void 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
621void GlobalParams::parseYesNo(char *cmdName, GBool *flag, 713void 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;
@@ -654,12 +746,16 @@ GlobalParams::~GlobalParams() {
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 }
@@ -752,14 +848,50 @@ DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
752 return (DisplayFontParam *)displayFonts->lookup(fontName); 848 return (DisplayFontParam *)displayFonts->lookup(fontName);
753} 849}
754 850
755DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *collection) { 851DisplayFontParam *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
759PSFontParam *GlobalParams::getPSFont(GString *fontName) { 862PSFontParam *GlobalParams::getPSFont(GString *fontName) {
760 return (PSFontParam *)psFonts->lookup(fontName); 863 return (PSFontParam *)psFonts->lookup(fontName);
761} 864}
762 865
866PSFontParam *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
763GString *GlobalParams::findFontFile(GString *fontName, 895GString *GlobalParams::findFontFile(GString *fontName,
764 char *ext1, char *ext2) { 896 char *ext1, char *ext2) {
765 GString *dir, *fileName; 897 GString *dir, *fileName;
@@ -866,10 +998,22 @@ void GlobalParams::setPSEmbedTrueType(GBool embed) {
866 psEmbedTrueType = embed; 998 psEmbedTrueType = embed;
867} 999}
868 1000
1001void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1002 psEmbedCIDPostScript = embed;
1003}
1004
1005void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1006 psEmbedCIDTrueType = embed;
1007}
1008
869void GlobalParams::setPSOPI(GBool opi) { 1009void GlobalParams::setPSOPI(GBool opi) {
870 psOPI = opi; 1010 psOPI = opi;
871} 1011}
872 1012
1013void GlobalParams::setPSASCIIHex(GBool hex) {
1014 psASCIIHex = hex;
1015}
1016
873void GlobalParams::setTextEncoding(char *encodingName) { 1017void GlobalParams::setTextEncoding(char *encodingName) {
874 delete textEncoding; 1018 delete textEncoding;
875 textEncoding = new GString(encodingName); 1019 textEncoding = new GString(encodingName);
@@ -888,6 +1032,11 @@ GBool GlobalParams::setTextEOL(char *s) {
888 return gTrue; 1032 return gTrue;
889} 1033}
890 1034
1035void GlobalParams::setInitialZoom(char *s) {
1036 delete initialZoom;
1037 initialZoom = new GString(s);
1038}
1039
891GBool GlobalParams::setT1libControl(char *s) { 1040GBool GlobalParams::setT1libControl(char *s) {
892 return setFontRastControl(&t1libControl, s); 1041 return setFontRastControl(&t1libControl, s);
893} 1042}
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
@@ -2,7 +2,7 @@
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
@@ -45,8 +45,9 @@ enum DisplayFontParamKind {
45class DisplayFontParam { 45class DisplayFontParam {
46public: 46public:
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 {
@@ -79,10 +80,16 @@ enum FontRastControl {
79class PSFontParam { 80class PSFontParam {
80public: 81public:
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
@@ -92,7 +99,9 @@ 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//------------------------------------------------------------------------
@@ -125,19 +134,24 @@ public:
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; }
@@ -159,29 +173,38 @@ public:
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
169private: 187private:
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);
@@ -212,6 +235,8 @@ private:
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
@@ -219,14 +244,20 @@ private:
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;
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -51,13 +51,14 @@ public:
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
62private: 63private:
63 64
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
@@ -2,7 +2,7 @@
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
@@ -29,31 +29,27 @@ static GString *getFileSpecName(Object *fileSpecObj);
29// LinkDest 29// LinkDest
30//------------------------------------------------------------------------ 30//------------------------------------------------------------------------
31 31
32LinkDest::LinkDest(Array *a, GBool pageIsRefA) { 32LinkDest::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);
@@ -221,7 +217,7 @@ LinkGoTo::LinkGoTo(Object *destObj) {
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;
@@ -259,7 +255,7 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
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;
@@ -446,7 +442,7 @@ Link::Link(Dict *dict, GString *baseURI) {
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()) {
@@ -582,7 +578,7 @@ Links::~Links() {
582LinkAction *Links::find(fouble x, fouble y) { 578LinkAction *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 }
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
@@ -2,7 +2,7 @@
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
@@ -63,10 +63,8 @@ enum LinkDestKind {
63class LinkDest { 63class LinkDest {
64public: 64public:
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); }
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -176,8 +176,8 @@ public:
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.
@@ -287,11 +287,11 @@ inline int Object::streamLookChar()
287inline char *Object::streamGetLine(char *buf, int size) 287inline char *Object::streamGetLine(char *buf, int size)
288 { return stream->getLine(buf, size); } 288 { return stream->getLine(buf, size); }
289 289
290inline int Object::streamGetPos() 290inline Guint Object::streamGetPos()
291 { return stream->getPos(); } 291 { return stream->getPos(); }
292 292
293inline void Object::streamSetPos(int pos) 293inline void Object::streamSetPos(Guint pos, int dir)
294 { stream->setPos(pos); } 294 { stream->setPos(pos, dir); }
295 295
296inline Dict *Object::streamGetDict() 296inline Dict *Object::streamGetDict()
297 { return stream->getDict(); } 297 { return stream->getDict(); }
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
@@ -2,7 +2,7 @@
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
@@ -59,6 +59,11 @@ void OutputDev::updateAll(GfxState *state) {
59 updateFont(state); 59 updateFont(state);
60} 60}
61 61
62GBool OutputDev::beginType3Char(GfxState *state,
63 CharCode code, Unicode *u, int uLen) {
64 return gFalse;
65}
66
62void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, 67void 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) {
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
@@ -2,7 +2,7 @@
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
@@ -46,6 +46,10 @@ public:
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
@@ -119,6 +123,9 @@ public:
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,
@@ -134,6 +141,14 @@ public:
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
137private: 152private:
138 153
139 fouble defCTM[6]; // default coordinate transform matrix 154 fouble defCTM[6]; // default coordinate transform matrix
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
@@ -2,7 +2,7 @@
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
@@ -24,6 +24,7 @@
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"
@@ -43,6 +44,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
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;
@@ -57,6 +59,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
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
@@ -68,6 +71,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
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 }
@@ -77,7 +81,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
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}
@@ -85,6 +89,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
85PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword, 89PDFDoc::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;
@@ -103,6 +108,7 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
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
@@ -110,6 +116,7 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
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
@@ -204,8 +211,9 @@ GBool PDFDoc::isLinearized() {
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);
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
@@ -2,7 +2,7 @@
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
@@ -42,6 +42,9 @@ public:
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
@@ -137,6 +140,7 @@ private:
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.
21static 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
42PSTokenizer::PSTokenizer(int (*getCharFuncA)(void *), void *dataA) {
43 getCharFunc = getCharFuncA;
44 data = dataA;
45 charBuf = -1;
46}
47
48PSTokenizer::~PSTokenizer() {
49}
50
51GBool 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
117int PSTokenizer::lookChar() {
118 if (charBuf < 0) {
119 charBuf = (*getCharFunc)(data);
120 }
121 return charBuf;
122}
123
124int 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
20class PSTokenizer {
21public:
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
29private:
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
@@ -2,7 +2,7 @@
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
@@ -20,7 +20,7 @@
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"
@@ -93,6 +93,14 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
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()) {
@@ -103,6 +111,12 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
103} 111}
104 112
105PageAttrs::~PageAttrs() { 113PageAttrs::~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
@@ -209,7 +223,7 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
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();
@@ -247,20 +261,20 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
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
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
@@ -2,7 +2,7 @@
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
@@ -51,6 +51,20 @@ public:
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
@@ -66,6 +80,12 @@ private:
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
@@ -97,6 +117,12 @@ public:
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(); }
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
@@ -2,7 +2,7 @@
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
@@ -155,7 +155,7 @@ Object *Parser::getObj(Object *obj) {
155Stream *Parser::makeStream(Object *dict) { 155Stream *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();
@@ -164,7 +164,7 @@ Stream *Parser::makeStream(Object *dict) {
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");
@@ -173,12 +173,13 @@ Stream *Parser::makeStream(Object *dict) {
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);
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
@@ -2,7 +2,7 @@
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
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
@@ -4,7 +4,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -303,7 +303,7 @@ void FilterStream::close() {
303 str->close(); 303 str->close();
304} 304}
305 305
306void FilterStream::setPos(int pos) { 306void 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
@@ -554,27 +554,37 @@ GBool StreamPredictor::getNextLine() {
554// FileStream 554// FileStream
555//------------------------------------------------------------------------ 555//------------------------------------------------------------------------
556 556
557FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA): 557FileStream::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
567FileStream::~FileStream() { 570FileStream::~FileStream() {
568 close(); 571 close();
569} 572}
570 573
571Stream *FileStream::makeSubStream(int startA, int lengthA, Object *dictA) { 574Stream *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
575void FileStream::reset() { 579void 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
@@ -584,9 +594,13 @@ void FileStream::reset() {
584} 594}
585 595
586void FileStream::close() { 596void 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
@@ -598,10 +612,10 @@ GBool FileStream::fillBuf() {
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;
@@ -621,23 +635,37 @@ GBool FileStream::fillBuf() {
621 return gTrue; 635 return gTrue;
622} 636}
623 637
624void FileStream::setPos(int pos) { 638void 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}
@@ -649,6 +677,90 @@ void FileStream::moveStart(int delta) {
649} 677}
650 678
651//------------------------------------------------------------------------ 679//------------------------------------------------------------------------
680// MemStream
681//------------------------------------------------------------------------
682
683MemStream::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
692MemStream::~MemStream() {
693 if (needFree) {
694 gfree(buf);
695 }
696}
697
698Stream *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
710void MemStream::reset() {
711 bufPtr = buf;
712#ifndef NO_DECRYPTION
713 if (decrypt) {
714 decrypt->reset();
715 }
716#endif
717}
718
719void MemStream::close() {
720}
721
722void 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
738void MemStream::moveStart(int delta) {
739 buf += delta;
740 bufPtr = buf;
741}
742
743#ifndef NO_DECRYPTION
744void 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
@@ -660,21 +772,22 @@ EmbedStream::EmbedStream(Stream *strA, Object *dictA):
660EmbedStream::~EmbedStream() { 772EmbedStream::~EmbedStream() {
661} 773}
662 774
663Stream *EmbedStream::makeSubStream(int start, int length, Object *dictA) { 775Stream *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
668void EmbedStream::setPos(int pos) { 781void 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
672int EmbedStream::getStart() { 785Guint 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
677void EmbedStream::moveStart(int start) { 790void EmbedStream::moveStart(int delta) {
678 error(-1, "Internal: called moveStart() on EmbedStream"); 791 error(-1, "Internal: called moveStart() on EmbedStream");
679} 792}
680 793
@@ -959,11 +1072,7 @@ void LZWStream::reset() {
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;
@@ -3287,6 +3396,56 @@ int FixedLengthEncoder::lookChar() {
3287} 3396}
3288 3397
3289//------------------------------------------------------------------------ 3398//------------------------------------------------------------------------
3399// ASCIIHexEncoder
3400//------------------------------------------------------------------------
3401
3402ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA):
3403 FilterStream(strA) {
3404 bufPtr = bufEnd = buf;
3405 lineLen = 0;
3406 eof = gFalse;
3407}
3408
3409ASCIIHexEncoder::~ASCIIHexEncoder() {
3410 if (str->isEncoder()) {
3411 delete str;
3412 }
3413}
3414
3415void ASCIIHexEncoder::reset() {
3416 str->reset();
3417 bufPtr = bufEnd = buf;
3418 lineLen = 0;
3419 eof = gFalse;
3420}
3421
3422void ASCIIHexEncoder::close() {
3423}
3424
3425GBool 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
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
@@ -2,7 +2,7 @@
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
@@ -78,8 +78,10 @@ public:
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);
@@ -118,18 +120,20 @@ 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
@@ -156,7 +160,7 @@ public:
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
@@ -242,9 +246,11 @@ private:
242class FileStream: public BaseStream { 246class FileStream: public BaseStream {
243public: 247public:
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();
@@ -253,9 +259,9 @@ public:
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
261private: 267private:
@@ -263,13 +269,52 @@ private:
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
287class MemStream: public BaseStream {
288public:
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
311private:
312
313 char *buf;
314 Guint length;
315 GBool needFree;
316 char *bufEnd;
317 char *bufPtr;
273}; 318};
274 319
275//------------------------------------------------------------------------ 320//------------------------------------------------------------------------
@@ -287,15 +332,16 @@ 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
301private: 347private:
@@ -659,6 +705,37 @@ private:
659}; 705};
660 706
661//------------------------------------------------------------------------ 707//------------------------------------------------------------------------
708// ASCIIHexEncoder
709//------------------------------------------------------------------------
710
711class ASCIIHexEncoder: public FilterStream {
712public:
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
727private:
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
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
@@ -2,7 +2,7 @@
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
@@ -48,6 +48,12 @@ TextString::TextString(GfxState *state, fouble fontSize) {
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;
@@ -99,6 +105,7 @@ void TextPage::updateFont(GfxState *state) {
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();
@@ -116,8 +123,11 @@ void TextPage::updateFont(GfxState *state) {
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) {
@@ -154,8 +164,10 @@ void TextPage::addChar(GfxState *state, fouble x, fouble y,
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 }
@@ -429,7 +441,7 @@ GString *TextPage::getText(fouble xMin, fouble yMin,
429 return s; 441 return s;
430} 442}
431 443
432void TextPage::dump(FILE *f) { 444void 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;
@@ -498,9 +510,9 @@ void TextPage::dump(FILE *f) {
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) {
@@ -508,7 +520,7 @@ void TextPage::dump(FILE *f) {
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
@@ -521,14 +533,14 @@ void TextPage::dump(FILE *f) {
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
@@ -547,7 +559,7 @@ void TextPage::dump(FILE *f) {
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) {
@@ -573,7 +585,7 @@ void TextPage::dump(FILE *f) {
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
@@ -584,9 +596,9 @@ void TextPage::dump(FILE *f) {
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}
@@ -611,6 +623,10 @@ void TextPage::clear() {
611// TextOutputDev 623// TextOutputDev
612//------------------------------------------------------------------------ 624//------------------------------------------------------------------------
613 625
626static void outputToFile(void *stream, char *text, int len) {
627 fwrite(text, 1, len, (FILE *)stream);
628}
629
614TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) { 630TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) {
615 text = NULL; 631 text = NULL;
616 rawOrder = rawOrderA; 632 rawOrder = rawOrderA;
@@ -620,28 +636,39 @@ TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) {
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
656TextOutputDev::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
639TextOutputDev::~TextOutputDev() { 666TextOutputDev::~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;
@@ -654,8 +681,8 @@ void TextOutputDev::startPage(int pageNum, GfxState *state) {
654 681
655void TextOutputDev::endPage() { 682void 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
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
@@ -2,7 +2,7 @@
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
@@ -22,6 +22,10 @@ class GfxState;
22class GString; 22class GString;
23 23
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25
26typedef void (*TextOutputFunc)(void *stream, char *text, int len);
27
28//------------------------------------------------------------------------
25// TextString 29// TextString
26//------------------------------------------------------------------------ 30//------------------------------------------------------------------------
27 31
@@ -97,7 +101,7 @@ public:
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();
@@ -128,6 +132,10 @@ public:
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
@@ -143,6 +151,10 @@ public:
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
@@ -179,8 +191,10 @@ public:
179 191
180private: 192private:
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?
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
@@ -2,7 +2,7 @@
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
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
@@ -4,7 +4,7 @@
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
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
@@ -2,7 +2,7 @@
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
@@ -13,6 +13,8 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
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 },
@@ -41,6 +43,23 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
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 },
@@ -135,6 +154,45 @@ static UnicodeMapRange ascii7UnicodeMapRanges[] = {
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 },
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
@@ -2,7 +2,7 @@
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
@@ -25,6 +25,7 @@
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//------------------------------------------------------------------------
@@ -49,10 +50,11 @@
49//------------------------------------------------------------------------ 50//------------------------------------------------------------------------
50 51
51XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { 52XRef::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;
@@ -67,6 +69,7 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
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
@@ -74,7 +77,7 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
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)) ;
@@ -86,6 +89,7 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
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 }
@@ -101,6 +105,7 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
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}
@@ -115,17 +120,18 @@ XRef::~XRef() {
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.
118int XRef::readTrailer() { 123Guint 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;
@@ -141,7 +147,7 @@ int XRef::readTrailer() {
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 --
@@ -176,8 +182,9 @@ int XRef::readTrailer() {
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);
@@ -204,7 +211,7 @@ int XRef::readTrailer() {
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.
207GBool XRef::readXRef(int *pos) { 214GBool 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];
@@ -261,7 +268,7 @@ GBool XRef::readXRef(int *pos) {
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;
@@ -273,9 +280,9 @@ GBool XRef::readXRef(int *pos) {
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') {
@@ -293,7 +300,7 @@ GBool XRef::readXRef(int *pos) {
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 }
@@ -301,8 +308,9 @@ GBool XRef::readXRef(int *pos) {
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;
@@ -314,7 +322,7 @@ GBool XRef::readXRef(int *pos) {
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;
@@ -337,7 +345,7 @@ 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;
@@ -360,8 +368,9 @@ GBool XRef::constructXRef() {
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);
@@ -403,7 +412,7 @@ GBool XRef::constructXRef() {
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;
@@ -421,7 +430,8 @@ GBool XRef::constructXRef() {
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 }
@@ -580,10 +590,11 @@ Object *XRef::fetch(int num, int gen, Object *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);
@@ -618,12 +629,12 @@ Object *XRef::getDocInfoNF(Object *obj) {
618 return trailerDict.dictLookupNF("Info", obj); 629 return trailerDict.dictLookupNF("Info", obj);
619} 630}
620 631
621int XRef::getStreamEnd(int streamStart) { 632GBool 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;
@@ -637,5 +648,18 @@ int XRef::getStreamEnd(int streamStart) {
637 a = m; 648 a = m;
638 } 649 }
639 } 650 }
640 return streamEnds[b]; 651 *streamEnd = streamEnds[b];
652 return gTrue;
653}
654
655Guint 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
@@ -2,7 +2,7 @@
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
@@ -24,7 +24,7 @@ class Stream;
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25 25
26struct XRefEntry { 26struct XRefEntry {
27 int offset; 27 Guint offset;
28 int gen; 28 int gen;
29 GBool used; 29 GBool used;
30}; 30};
@@ -41,6 +41,9 @@ public:
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; }
@@ -68,28 +71,29 @@ public:
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
81private: 84private:
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
@@ -102,10 +106,11 @@ private:
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