summaryrefslogtreecommitdiff
authorsandman <sandman>2002-05-23 23:51:52 (UTC)
committer sandman <sandman>2002-05-23 23:51:52 (UTC)
commit2f3bb7b07f833273d966d41813e68bfe8b9d8d76 (patch) (unidiff)
tree00beb1bd9e7f4ba79e22334a0d258269b28f4564
parent6e82b45dd416ceeba78765717b700e853c96a137 (diff)
downloadopie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.zip
opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.gz
opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.bz2
Port to xpdf 1.01
Diffstat (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
@@ -76,12 +76,19 @@ public:
76 // (Upside-down means (0,0) is the top left corner of the page.) 76 // (Upside-down means (0,0) is the top left corner of the page.)
77 virtual GBool upsideDown() { return gTrue; } 77 virtual GBool upsideDown() { return gTrue; }
78 78
79 // Does this device use drawChar() or drawString()? 79 // Does this device use drawChar() or drawString()?
80 virtual GBool useDrawChar() { return gTrue; } 80 virtual GBool useDrawChar() { return gTrue; }
81 81
82 // Does this device use beginType3Char/endType3Char? Otherwise,
83 // text in Type 3 fonts will be drawn with drawChar/drawString.
84 virtual GBool interpretType3Chars() { return gFalse; }
85
86 // Does this device need non-text content?
87 virtual GBool needNonText() { return gFalse; }
88
82 //----- initialization and control 89 //----- initialization and control
83 90
84 // Start a page. 91 // Start a page.
85 virtual void startPage(int pageNum, GfxState *state); 92 virtual void startPage(int pageNum, GfxState *state);
86 93
87 // End a page. 94 // End a page.
diff --git a/noncore/unsupported/qpdf/README b/noncore/unsupported/qpdf/README
index 36ce6bc..65e7aaf 100644
--- a/noncore/unsupported/qpdf/README
+++ b/noncore/unsupported/qpdf/README
@@ -1,10 +1,10 @@
1 1
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
8Changes in 20020406: 8Changes in 20020406:
9 - Font substitution handling improved. 9 - Font substitution handling improved.
10 - Unknown characters are simply ignored now. 10 - Unknown characters are simply ignored now.
@@ -17,18 +17,25 @@ Changes in 20020407:
17 17
18Changes in 20020408: 18Changes in 20020408:
19 - Progress indicator added 19 - Progress indicator added
20 - Problems with type 3 fonts (not fully supported by XPDF) solved 20 - Problems with type 3 fonts (not fully supported by XPDF) solved
21 - Heavy optimizations in the image rendering code 21 - Heavy optimizations in the image rendering code
22 22
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
32 with a FPU, all doubles have been replaced with a C++ class "fouble" (fixed 39 with a FPU, all doubles have been replaced with a C++ class "fouble" (fixed
33 double), which operates on 32bit integers with fixed point arithmetic. 40 double), which operates on 32bit integers with fixed point arithmetic.
34 This gave a speedup of up to 800% for image rendering. 41 This gave a speedup of up to 800% for image rendering.
@@ -49,41 +56,25 @@ ToDo:
49 in detail. 56 in detail.
50 57
51 - Links are currently simply ignored. 58 - Links are currently simply ignored.
52 59
53 60
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
88Robert (griebl@gmx.de) 79Robert (griebl@gmx.de)
89 \ No newline at end of file 80 \ No newline at end of file
diff --git a/noncore/unsupported/qpdf/UTF8.h b/noncore/unsupported/qpdf/UTF8.h
index aacf663..95adecf 100644
--- a/noncore/unsupported/qpdf/UTF8.h
+++ b/noncore/unsupported/qpdf/UTF8.h
@@ -19,6 +19,20 @@ static int mapUTF8 ( Unicode u, char *buf, int bufSize )
19 ::memcpy ( buf, utf. data ( ), len ); 19 ::memcpy ( buf, utf. data ( ), len );
20 return len; 20 return len;
21 } 21 }
22 else 22 else
23 return 0; 23 return 0;
24} 24}
25
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
@@ -13,18 +13,18 @@
13 13
14#include "QPEOutputDev.h" 14#include "QPEOutputDev.h"
15 15
16#include <qpe/qpeapplication.h> 16#include <qpe/qpeapplication.h>
17#include <qpe/resource.h> 17#include <qpe/resource.h>
18#include <qpe/applnk.h> 18#include <qpe/applnk.h>
19#include <qpe/fileselector.h>
20#include <qpe/qcopenvelope_qws.h> 19#include <qpe/qcopenvelope_qws.h>
21 20
22 21
23#include <qclipboard.h> 22#include <qclipboard.h>
24#include <qtoolbar.h> 23#include <qtoolbar.h>
24#include <qtoolbutton.h>
25#include <qmenubar.h> 25#include <qmenubar.h>
26#include <qpopupmenu.h> 26#include <qpopupmenu.h>
27#include <qwidgetstack.h> 27#include <qwidgetstack.h>
28#include <qtimer.h> 28#include <qtimer.h>
29#include <qfileinfo.h> 29#include <qfileinfo.h>
30#include <qstring.h> 30#include <qstring.h>
@@ -34,12 +34,18 @@
34#include <qdialog.h> 34#include <qdialog.h>
35#include <qlabel.h> 35#include <qlabel.h>
36#include <qmessagebox.h> 36#include <qmessagebox.h>
37 37
38#include "qpdf.h" 38#include "qpdf.h"
39 39
40#ifdef QPDF_QPE_ONLY
41#include <qpe/fileselector.h>
42#else
43#include <opie/ofileselector.h>
44#endif
45
40 46
41int main ( int argc, char **argv ) 47int main ( int argc, char **argv )
42{ 48{
43 QPEApplication app ( argc, argv ); 49 QPEApplication app ( argc, argv );
44 50
45 // read config file 51 // read config file
@@ -78,13 +84,18 @@ QPdfDlg::QPdfDlg ( ) : QMainWindow ( )
78 m_stack-> setSizePolicy ( QSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding )); 84 m_stack-> setSizePolicy ( QSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding ));
79 setCentralWidget ( m_stack ); 85 setCentralWidget ( m_stack );
80 86
81 m_outdev = new QPEOutputDev ( m_stack ); 87 m_outdev = new QPEOutputDev ( m_stack );
82 connect ( m_outdev, SIGNAL( selectionChanged ( const QRect & )), this, SLOT( copyToClipboard ( const QRect & ))); 88 connect ( m_outdev, SIGNAL( selectionChanged ( const QRect & )), this, SLOT( copyToClipboard ( const QRect & )));
83 89
90#ifdef QPDF_QPE_ONLY
84 m_filesel = new FileSelector ( "application/pdf", m_stack, "fs", false, true ); 91 m_filesel = new FileSelector ( "application/pdf", m_stack, "fs", false, true );
92#else
93 m_filesel = new OFileSelector ( "application/pdf", m_stack, "fs", false, true );
94#endif
95
85 connect ( m_filesel, SIGNAL( closeMe ( )), this, SLOT( closeFileSelector ( ))); 96 connect ( m_filesel, SIGNAL( closeMe ( )), this, SLOT( closeFileSelector ( )));
86 connect ( m_filesel, SIGNAL( fileSelected ( const DocLnk & )), this, SLOT( openFile ( const DocLnk & ))); 97 connect ( m_filesel, SIGNAL( fileSelected ( const DocLnk & )), this, SLOT( openFile ( const DocLnk & )));
87 98
88 m_tb_menu = new QToolBar ( this ); 99 m_tb_menu = new QToolBar ( this );
89 m_tb_menu-> setHorizontalStretchable ( true ); 100 m_tb_menu-> setHorizontalStretchable ( true );
90 101
diff --git a/noncore/unsupported/qpdf/qpdf.h b/noncore/unsupported/qpdf/qpdf.h
index b4ce554..8b3cff9 100644
--- a/noncore/unsupported/qpdf/qpdf.h
+++ b/noncore/unsupported/qpdf/qpdf.h
@@ -2,18 +2,20 @@
2#define __QPDF_H__ 2#define __QPDF_H__
3 3
4#include "aconf.h" 4#include "aconf.h"
5 5
6#include <qmainwindow.h> 6#include <qmainwindow.h>
7 7
8#define QPDF_QPE_ONLY 1 // ofileselector does not work right currently
8 9
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
17 19
18class QPdfDlg : public QMainWindow { 20class QPdfDlg : public QMainWindow {
19 Q_OBJECT 21 Q_OBJECT
@@ -65,13 +67,18 @@ protected:
65 virtual void resizeEvent ( QResizeEvent *e ); 67 virtual void resizeEvent ( QResizeEvent *e );
66 virtual void focusInEvent ( QFocusEvent *e ); 68 virtual void focusInEvent ( QFocusEvent *e );
67 69
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;
75 QPopupMenu *m_pm_zoom; 82 QPopupMenu *m_pm_zoom;
76 83
77 QToolButton *m_to_find, *m_to_full; 84 QToolButton *m_to_find, *m_to_full;
diff --git a/noncore/unsupported/qpdf/qpdf.pro b/noncore/unsupported/qpdf/qpdf.pro
index 0c2e38b..fe5abfb 100644
--- a/noncore/unsupported/qpdf/qpdf.pro
+++ b/noncore/unsupported/qpdf/qpdf.pro
@@ -10,13 +10,13 @@ SOURCES = xpdf/Array.cc \
10 xpdf/Catalog.cc \ 10 xpdf/Catalog.cc \
11 xpdf/CharCodeToUnicode.cc \ 11 xpdf/CharCodeToUnicode.cc \
12 xpdf/Decrypt.cc \ 12 xpdf/Decrypt.cc \
13 xpdf/Dict.cc \ 13 xpdf/Dict.cc \
14 xpdf/Error.cc \ 14 xpdf/Error.cc \
15 xpdf/FontEncodingTables.cc \ 15 xpdf/FontEncodingTables.cc \
16 xpdf/FormWidget.cc \ 16 xpdf/Annot.cc \
17 xpdf/Function.cc \ 17 xpdf/Function.cc \
18 xpdf/Gfx.cc \ 18 xpdf/Gfx.cc \
19 xpdf/GfxFont.cc \ 19 xpdf/GfxFont.cc \
20 xpdf/GfxState.cc \ 20 xpdf/GfxState.cc \
21 xpdf/GlobalParams.cc \ 21 xpdf/GlobalParams.cc \
22 xpdf/Lexer.cc \ 22 xpdf/Lexer.cc \
@@ -24,12 +24,13 @@ SOURCES = xpdf/Array.cc \
24 xpdf/NameToCharCode.cc \ 24 xpdf/NameToCharCode.cc \
25 xpdf/Object.cc \ 25 xpdf/Object.cc \
26 xpdf/OutputDev.cc \ 26 xpdf/OutputDev.cc \
27 xpdf/PDFDoc.cc \ 27 xpdf/PDFDoc.cc \
28 xpdf/Page.cc \ 28 xpdf/Page.cc \
29 xpdf/Parser.cc \ 29 xpdf/Parser.cc \
30 xpdf/PSTokenizer.cc \
30 xpdf/Stream.cc \ 31 xpdf/Stream.cc \
31 xpdf/TextOutputDev.cc \ 32 xpdf/TextOutputDev.cc \
32 xpdf/UnicodeMap.cc \ 33 xpdf/UnicodeMap.cc \
33 xpdf/XRef.cc \ 34 xpdf/XRef.cc \
34 goo/GHash.cc \ 35 goo/GHash.cc \
35 goo/GString.cc \ 36 goo/GString.cc \
@@ -49,12 +50,12 @@ INCLUDEPATH += . \
49 .. \ 50 .. \
50 xpdf \ 51 xpdf \
51 $(OPIEDIR)/include \ 52 $(OPIEDIR)/include \
52 ../goo \ 53 ../goo \
53 goo 54 goo
54 55
55LIBS += -L $(OPIEDIR)/lib -lqpe 56LIBS += -L $(OPIEDIR)/lib -lqpe -lopie
56 57
57DESTDIR = $(OPIEDIR)/bin 58DESTDIR = $(OPIEDIR)/bin
58TARGET = qpdf 59TARGET = qpdf
59 60
60TRANSLATIONS = ../../i18n/de/qpdf.ts 61TRANSLATIONS = ../../i18n/de/qpdf.ts
diff --git a/noncore/unsupported/qpdf/xpdf/FormWidget.cc b/noncore/unsupported/qpdf/xpdf/Annot.cc
index 05c67a4..49ae50a 100644
--- a/noncore/unsupported/qpdf/xpdf/FormWidget.cc
+++ b/noncore/unsupported/qpdf/xpdf/Annot.cc
@@ -1,29 +1,29 @@
1//======================================================================== 1//========================================================================
2// 2//
3// FormWidget.cc 3// Annot.cc
4// 4//
5// Copyright 2000 Derek B. Noonburg 5// Copyright 2000-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include "gmem.h" 14#include "gmem.h"
15#include "Object.h" 15#include "Object.h"
16#include "Gfx.h" 16#include "Gfx.h"
17#include "FormWidget.h" 17#include "Annot.h"
18 18
19//------------------------------------------------------------------------ 19//------------------------------------------------------------------------
20// FormWidget 20// Annot
21//------------------------------------------------------------------------ 21//------------------------------------------------------------------------
22 22
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
27 ok = gFalse; 27 ok = gFalse;
28 xref = xrefA; 28 xref = xrefA;
29 29
@@ -74,66 +74,65 @@ FormWidget::FormWidget(XRef *xrefA, Dict *dict) {
74 xMin = yMin = 0; 74 xMin = yMin = 0;
75 xMax = yMax = 1; 75 xMax = yMax = 1;
76 } 76 }
77 obj1.free(); 77 obj1.free();
78} 78}
79 79
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();
126 } 125 }
127 obj1.free(); 126 obj1.free();
128 } 127 }
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,67 +1,69 @@
1//======================================================================== 1//========================================================================
2// 2//
3// FormWidget.h 3// Annot.h
4// 4//
5// Copyright 2000 Derek B. Noonburg 5// Copyright 2000-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef FORMWIDGET_H 9#ifndef ANNOT_H
10#define FORMWIDGET_H 10#define ANNOT_H
11 11
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include <aconf.h>
17
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);
31 33
32 // Get appearance object. 34 // Get appearance object.
33 Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); } 35 Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
34 36
35private: 37private:
36 38
37 XRef *xref; // the xref table for this PDF file 39 XRef *xref; // the xref table for this PDF file
38 Object appearance; // a reference to the Form XObject stream 40 Object appearance; // a reference to the Form XObject stream
39 // for the normal appearance 41 // for the normal appearance
40 fouble xMin, yMin, // widget rectangle 42 fouble xMin, yMin, // annotation rectangle
41 xMax, yMax; 43 xMax, yMax;
42 GBool ok; 44 GBool ok;
43}; 45};
44 46
45//------------------------------------------------------------------------ 47//------------------------------------------------------------------------
46// FormWidgets 48// Annots
47//------------------------------------------------------------------------ 49//------------------------------------------------------------------------
48 50
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
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Array.cc 3// Array.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
diff --git a/noncore/unsupported/qpdf/xpdf/Array.h b/noncore/unsupported/qpdf/xpdf/Array.h
index 1616fc3..a118f68 100644
--- a/noncore/unsupported/qpdf/xpdf/Array.h
+++ b/noncore/unsupported/qpdf/xpdf/Array.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Array.h 3// Array.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef ARRAY_H 9#ifndef ARRAY_H
10#define ARRAY_H 10#define ARRAY_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFont.h b/noncore/unsupported/qpdf/xpdf/BuiltinFont.h
index b4fa24c..a795311 100644
--- a/noncore/unsupported/qpdf/xpdf/BuiltinFont.h
+++ b/noncore/unsupported/qpdf/xpdf/BuiltinFont.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// BuiltinFont.h 3// BuiltinFont.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef BUILTINFONT_H 9#ifndef BUILTINFONT_H
10#define BUILTINFONT_H 10#define BUILTINFONT_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc
index 6833972..845abcd 100644
--- a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc
+++ b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// BuiltinFontTables.cc 3// BuiltinFontTables.cc
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#include <aconf.h> 9#include <aconf.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include "FontEncodingTables.h" 11#include "FontEncodingTables.h"
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h
index 9a17ce9..3a8892e 100644
--- a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h
+++ b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// BuiltinFontTables.h 3// BuiltinFontTables.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef BUILTINFONTTABLES_H 9#ifndef BUILTINFONTTABLES_H
10#define BUILTINFONTTABLES_H 10#define BUILTINFONTTABLES_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/CMap.cc b/noncore/unsupported/qpdf/xpdf/CMap.cc
index 57809f0..b49cffd 100644
--- a/noncore/unsupported/qpdf/xpdf/CMap.cc
+++ b/noncore/unsupported/qpdf/xpdf/CMap.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// CMap.cc 3// CMap.cc
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -17,12 +17,13 @@
17#include <ctype.h> 17#include <ctype.h>
18#include "gmem.h" 18#include "gmem.h"
19#include "gfile.h" 19#include "gfile.h"
20#include "GString.h" 20#include "GString.h"
21#include "Error.h" 21#include "Error.h"
22#include "GlobalParams.h" 22#include "GlobalParams.h"
23#include "PSTokenizer.h"
23#include "CMap.h" 24#include "CMap.h"
24 25
25//------------------------------------------------------------------------ 26//------------------------------------------------------------------------
26 27
27struct CMapVectorEntry { 28struct CMapVectorEntry {
28 GBool isVector; 29 GBool isVector;
@@ -31,21 +32,26 @@ struct CMapVectorEntry {
31 CID cid; 32 CID cid;
32 }; 33 };
33}; 34};
34 35
35//------------------------------------------------------------------------ 36//------------------------------------------------------------------------
36 37
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
49 // Check for an identity CMap. 55 // Check for an identity CMap.
50 if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) { 56 if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) {
51 return new CMap(collectionA->copy(), cMapNameA->copy(), 0); 57 return new CMap(collectionA->copy(), cMapNameA->copy(), 0);
@@ -58,56 +64,70 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA,
58 cMapNameA->getCString(), collectionA->getCString()); 64 cMapNameA->getCString(), collectionA->getCString());
59 return NULL; 65 return NULL;
60 } 66 }
61 67
62 cmap = new CMap(collectionA->copy(), cMapNameA->copy()); 68 cmap = new CMap(collectionA->copy(), cMapNameA->copy());
63 69
64 inCodeSpace = inCIDRange = gFalse; 70 pst = new PSTokenizer(&getCharFromFile, f);
65 while (getLine(buf, sizeof(buf), f)) { 71 pst->getToken(tok1, sizeof(tok1), &n1);
66 tok1 = strtok(buf, " \t\r\n"); 72 while (pst->getToken(tok2, sizeof(tok2), &n2)) {
67 if (!tok1 || tok1[0] == '%') { 73 if (!strcmp(tok2, "usecmap")) {
68 continue;
69 }
70 tok2 = strtok(NULL, " \t\r\n");
71 tok3 = strtok(NULL, " \t\r\n");
72 if (inCodeSpace) {
73 if (!strcmp(tok1, "endcodespacerange")) {
74 inCodeSpace = gFalse;
75 } else if (tok2 && tok1[0] == '<' && tok2[0] == '<' &&
76 (n = strlen(tok1)) == strlen(tok2) &&
77 n >= 4 && (n & 1) == 0) {
78 tok1[n - 1] = tok2[n - 1] = '\0';
79 sscanf(tok1 + 1, "%x", &start);
80 sscanf(tok2 + 1, "%x", &end);
81 n = (n - 2) / 2;
82 cmap->addCodeSpace(cmap->vector, start, end, n);
83 }
84 } else if (inCIDRange) {
85 if (!strcmp(tok1, "endcidrange")) {
86 inCIDRange = gFalse;
87 } else if (tok2 && tok3 && tok1[0] == '<' && tok2[0] == '<' &&
88 (n = strlen(tok1)) == strlen(tok2) &&
89 n >= 4 && (n & 1) == 0) {
90 tok1[n - 1] = tok2[n - 1] = '\0';
91 sscanf(tok1 + 1, "%x", &start);
92 sscanf(tok2 + 1, "%x", &end);
93 n = (n - 2) / 2;
94 cmap->addCIDs(start, end, n, (CID)atoi(tok3));
95 }
96 } else if (tok2 && !strcmp(tok2, "usecmap")) {
97 if (tok1[0] == '/') { 74 if (tok1[0] == '/') {
98 cmap->useCMap(cache, tok1 + 1); 75 cmap->useCMap(cache, tok1 + 1);
99 } 76 }
77 pst->getToken(tok1, sizeof(tok1), &n1);
100 } else if (!strcmp(tok1, "/WMode")) { 78 } else if (!strcmp(tok1, "/WMode")) {
101 cmap->wMode = atoi(tok2); 79 cmap->wMode = atoi(tok2);
102 } else if (tok2 && !strcmp(tok2, "begincodespacerange")) { 80 pst->getToken(tok1, sizeof(tok1), &n1);
103 inCodeSpace = gTrue; 81 } else if (!strcmp(tok2, "begincodespacerange")) {
104 } else if (tok2 && !strcmp(tok2, "begincidrange")) { 82 while (pst->getToken(tok1, sizeof(tok1), &n1)) {
105 inCIDRange = gTrue; 83 if (!strcmp(tok1, "endcodespacerange")) {
84 break;
85 }
86 if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
87 !strcmp(tok2, "endcodespacerange")) {
88 error(-1, "Illegal entry in codespacerange block in CMap");
89 break;
90 }
91 if (tok1[0] == '<' && tok2[0] == '<' &&
92 n1 == n2 && n1 >= 4 && (n1 & 1) == 0) {
93 tok1[n1 - 1] = tok2[n1 - 1] = '\0';
94 sscanf(tok1 + 1, "%x", &start);
95 sscanf(tok2 + 1, "%x", &end);
96 n1 = (n1 - 2) / 2;
97 cmap->addCodeSpace(cmap->vector, start, end, n1);
98 }
99 }
100 pst->getToken(tok1, sizeof(tok1), &n1);
101 } else if (!strcmp(tok2, "begincidrange")) {
102 while (pst->getToken(tok1, sizeof(tok1), &n1)) {
103 if (!strcmp(tok1, "endcidrange")) {
104 break;
105 }
106 if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
107 !strcmp(tok2, "endcidrange") ||
108 !pst->getToken(tok3, sizeof(tok3), &n3) ||
109 !strcmp(tok3, "endcidrange")) {
110 error(-1, "Illegal entry in cidrange block in CMap");
111 break;
112 }
113 if (tok1[0] == '<' && tok2[0] == '<' &&
114 n1 == n2 && n1 >= 4 && (n1 & 1) == 0) {
115 tok1[n1 - 1] = tok2[n1 - 1] = '\0';
116 sscanf(tok1 + 1, "%x", &start);
117 sscanf(tok2 + 1, "%x", &end);
118 n1 = (n1 - 2) / 2;
119 cmap->addCIDs(start, end, n1, (CID)atoi(tok3));
120 }
121 }
122 pst->getToken(tok1, sizeof(tok1), &n1);
123 } else {
124 strcpy(tok1, tok2);
106 } 125 }
107 } 126 }
127 delete pst;
108 128
109 fclose(f); 129 fclose(f);
110 130
111 return cmap; 131 return cmap;
112} 132}
113 133
diff --git a/noncore/unsupported/qpdf/xpdf/CMap.h b/noncore/unsupported/qpdf/xpdf/CMap.h
index 8b29ef7..fe49acf 100644
--- a/noncore/unsupported/qpdf/xpdf/CMap.h
+++ b/noncore/unsupported/qpdf/xpdf/CMap.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// CMap.h 3// CMap.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef CMAP_H 9#ifndef CMAP_H
10#define CMAP_H 10#define CMAP_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/Catalog.cc b/noncore/unsupported/qpdf/xpdf/Catalog.cc
index 6a0c2d5..1212e2e 100644
--- a/noncore/unsupported/qpdf/xpdf/Catalog.cc
+++ b/noncore/unsupported/qpdf/xpdf/Catalog.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Catalog.cc 3// Catalog.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -143,13 +143,13 @@ GString *Catalog::readMetadata() {
143 143
144 if (!metadata.isStream()) { 144 if (!metadata.isStream()) {
145 return NULL; 145 return NULL;
146 } 146 }
147 dict = metadata.streamGetDict(); 147 dict = metadata.streamGetDict();
148 if (!dict->lookup("Subtype", &obj)->isName("XML")) { 148 if (!dict->lookup("Subtype", &obj)->isName("XML")) {
149 error(-1, "Unknown Metadata type: '%s'\n", 149 error(-1, "Unknown Metadata type: '%s'",
150 obj.isName() ? obj.getName() : "???"); 150 obj.isName() ? obj.getName() : "???");
151 } 151 }
152 obj.free(); 152 obj.free();
153 s = new GString(); 153 s = new GString();
154 metadata.streamReset(); 154 metadata.streamReset();
155 while ((c = metadata.streamGetChar()) != EOF) { 155 while ((c = metadata.streamGetChar()) != EOF) {
@@ -262,16 +262,16 @@ LinkDest *Catalog::findDest(GString *name) {
262 if (!found) 262 if (!found)
263 return NULL; 263 return NULL;
264 264
265 // construct LinkDest 265 // construct LinkDest
266 dest = NULL; 266 dest = NULL;
267 if (obj1.isArray()) { 267 if (obj1.isArray()) {
268 dest = new LinkDest(obj1.getArray(), gTrue); 268 dest = new LinkDest(obj1.getArray());
269 } else if (obj1.isDict()) { 269 } else if (obj1.isDict()) {
270 if (obj1.dictLookup("D", &obj2)->isArray()) 270 if (obj1.dictLookup("D", &obj2)->isArray())
271 dest = new LinkDest(obj2.getArray(), gTrue); 271 dest = new LinkDest(obj2.getArray());
272 else 272 else
273 error(-1, "Bad named destination value"); 273 error(-1, "Bad named destination value");
274 obj2.free(); 274 obj2.free();
275 } else { 275 } else {
276 error(-1, "Bad named destination value"); 276 error(-1, "Bad named destination value");
277 } 277 }
diff --git a/noncore/unsupported/qpdf/xpdf/Catalog.h b/noncore/unsupported/qpdf/xpdf/Catalog.h
index 197f5b8..afad803 100644
--- a/noncore/unsupported/qpdf/xpdf/Catalog.h
+++ b/noncore/unsupported/qpdf/xpdf/Catalog.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Catalog.h 3// Catalog.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef CATALOG_H 9#ifndef CATALOG_H
10#define CATALOG_H 10#define CATALOG_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc
index 6793398..912981e 100644
--- a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc
+++ b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// CharCodeToUnicode.cc 3// CharCodeToUnicode.cc
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -15,12 +15,13 @@
15#include <string.h> 15#include <string.h>
16#include "gmem.h" 16#include "gmem.h"
17#include "gfile.h" 17#include "gfile.h"
18#include "GString.h" 18#include "GString.h"
19#include "Error.h" 19#include "Error.h"
20#include "GlobalParams.h" 20#include "GlobalParams.h"
21#include "PSTokenizer.h"
21#include "CharCodeToUnicode.h" 22#include "CharCodeToUnicode.h"
22 23
23//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
24 25
25#define maxUnicodeString 8 26#define maxUnicodeString 8
26 27
@@ -29,12 +30,32 @@ struct CharCodeToUnicodeString {
29 Unicode u[maxUnicodeString]; 30 Unicode u[maxUnicodeString];
30 int len; 31 int len;
31}; 32};
32 33
33//------------------------------------------------------------------------ 34//------------------------------------------------------------------------
34 35
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;
38 CharCode size, mapLenA; 59 CharCode size, mapLenA;
39 char buf[64]; 60 char buf[64];
40 Unicode u; 61 Unicode u;
@@ -72,98 +93,83 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) {
72} 93}
73 94
74CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) { 95CharCodeToUnicode *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;
122 Unicode u; 116 Unicode u;
123 char uHex[5]; 117 char uHex[5];
124 int j; 118 int j;
125 GString *name; 119 GString *name;
126 FILE *f; 120 FILE *f;
127 121
128 nDigits = nBits / 4; 122 nDigits = nBits / 4;
129 inBFChar = inBFRange = gFalse; 123 pst = new PSTokenizer(getCharFunc, data);
130 while ((*getLineFunc)(buf, sizeof(buf), data)) { 124 pst->getToken(tok1, sizeof(tok1), &n1);
131 tok1 = strtok(buf, " \t\r\n"); 125 while (pst->getToken(tok2, sizeof(tok2), &n2)) {
132 if (!tok1 || tok1[0] == '%') { 126 if (!strcmp(tok2, "usecmap")) {
133 continue; 127 if (tok1[0] == '/') {
134 } 128 name = new GString(tok1 + 1);
135 tok2 = strtok(NULL, " \t\r\n"); 129 if ((f = globalParams->findToUnicodeFile(name))) {
136 tok3 = strtok(NULL, " \t\r\n"); 130 parseCMap1(&getCharFromFile, f, nBits);
137 if (inBFChar) { 131 fclose(f);
138 if (!strcmp(tok1, "endbfchar")) { 132 } else {
139 inBFChar = gFalse; 133 error(-1, "Couldn't find ToUnicode CMap file for '%s'",
140 } else if (tok2) { 134 name->getCString());
141 n1 = strlen(tok1); 135 }
142 n2 = strlen(tok2); 136 delete name;
137 }
138 pst->getToken(tok1, sizeof(tok1), &n1);
139 } else if (!strcmp(tok2, "beginbfchar")) {
140 while (pst->getToken(tok1, sizeof(tok1), &n1)) {
141 if (!strcmp(tok1, "endbfchar")) {
142 break;
143 }
144 if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
145 !strcmp(tok2, "endbfchar")) {
146 error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
147 break;
148 }
143 if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && 149 if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
144 tok2[0] == '<' && tok2[n2 - 1] == '>')) { 150 tok2[0] == '<' && tok2[n2 - 1] == '>')) {
145 error(-1, "Illegal line in bfchar block in ToUnicode CMap"); 151 error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
146 continue; 152 continue;
147 } 153 }
148 tok1[n1 - 1] = tok2[n2 - 1] = '\0'; 154 tok1[n1 - 1] = tok2[n2 - 1] = '\0';
149 if (sscanf(tok1 + 1, "%x", &code1) != 1) { 155 if (sscanf(tok1 + 1, "%x", &code1) != 1) {
150 error(-1, "Illegal line in bfchar block in ToUnicode CMap"); 156 error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
151 continue; 157 continue;
152 } 158 }
153 if (code1 >= mapLen) { 159 if (code1 >= mapLen) {
154 oldLen = mapLen; 160 oldLen = mapLen;
155 mapLen = (code1 + 256) & ~255; 161 mapLen = (code1 + 256) & ~255;
156 map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode)); 162 map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode));
157 for (i = oldLen; i < mapLen; ++i) { 163 for (i = oldLen; i < mapLen; ++i) {
158 map[i] = 0; 164 map[i] = 0;
159 } 165 }
160 } 166 }
161 if (n2 == 6) { 167 if (n2 == 6) {
162 if (sscanf(tok2 + 1, "%x", &u) != 1) { 168 if (sscanf(tok2 + 1, "%x", &u) != 1) {
163 error(-1, "Illegal line in bfchar block in ToUnicode CMap"); 169 error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
164 continue; 170 continue;
165 } 171 }
166 map[code1] = u; 172 map[code1] = u;
167 } else { 173 } else {
168 map[code1] = 0; 174 map[code1] = 0;
169 if (sMapLen == sMapSize) { 175 if (sMapLen == sMapSize) {
@@ -174,50 +180,54 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
174 sMap[sMapLen].c = code1; 180 sMap[sMapLen].c = code1;
175 sMap[sMapLen].len = (n2 - 2) / 4; 181 sMap[sMapLen].len = (n2 - 2) / 4;
176 for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) { 182 for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) {
177 strncpy(uHex, tok2 + 1 + j*4, 4); 183 strncpy(uHex, tok2 + 1 + j*4, 4);
178 uHex[4] = '\0'; 184 uHex[4] = '\0';
179 if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) { 185 if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
180 error(-1, "Illegal line in bfchar block in ToUnicode CMap"); 186 error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
181 } 187 }
182 } 188 }
183 ++sMapLen; 189 ++sMapLen;
184 } 190 }
185 } else {
186 error(-1, "Illegal bfchar block in ToUnicode CMap");
187 } 191 }
188 } else if (inBFRange) { 192 pst->getToken(tok1, sizeof(tok1), &n1);
189 if (!strcmp(tok1, "endbfrange")) { 193 } else if (!strcmp(tok2, "beginbfrange")) {
190 inBFRange = gFalse; 194 while (pst->getToken(tok1, sizeof(tok1), &n1)) {
191 } else if (tok2 && tok3) { 195 if (!strcmp(tok1, "endbfrange")) {
192 n1 = strlen(tok1); 196 break;
193 n2 = strlen(tok2); 197 }
194 n3 = strlen(tok3); 198 if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
199 !strcmp(tok2, "endbfrange") ||
200 !pst->getToken(tok3, sizeof(tok3), &n3) ||
201 !strcmp(tok3, "endbfrange")) {
202 error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
203 break;
204 }
195 if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && 205 if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
196 n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' && 206 n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' &&
197 tok3[0] == '<' && tok3[n3 - 1] == '>')) { 207 tok3[0] == '<' && tok3[n3 - 1] == '>')) {
198 error(-1, "Illegal line in bfrange block in ToUnicode CMap"); 208 error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
199 continue; 209 continue;
200 } 210 }
201 tok1[n1 - 1] = tok2[n2 - 1] = tok3[n3 - 1] = '\0'; 211 tok1[n1 - 1] = tok2[n2 - 1] = tok3[n3 - 1] = '\0';
202 if (sscanf(tok1 + 1, "%x", &code1) != 1 || 212 if (sscanf(tok1 + 1, "%x", &code1) != 1 ||
203 sscanf(tok2 + 1, "%x", &code2) != 1) { 213 sscanf(tok2 + 1, "%x", &code2) != 1) {
204 error(-1, "Illegal line in bfrange block in ToUnicode CMap"); 214 error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
205 continue; 215 continue;
206 } 216 }
207 if (code2 >= mapLen) { 217 if (code2 >= mapLen) {
208 oldLen = mapLen; 218 oldLen = mapLen;
209 mapLen = (code2 + 256) & ~255; 219 mapLen = (code2 + 256) & ~255;
210 map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode)); 220 map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode));
211 for (i = oldLen; i < mapLen; ++i) { 221 for (i = oldLen; i < mapLen; ++i) {
212 map[i] = 0; 222 map[i] = 0;
213 } 223 }
214 } 224 }
215 if (n3 == 6) { 225 if (n3 == 6) {
216 if (sscanf(tok3 + 1, "%x", &u) != 1) { 226 if (sscanf(tok3 + 1, "%x", &u) != 1) {
217 error(-1, "Illegal line in bfrange block in ToUnicode CMap"); 227 error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
218 continue; 228 continue;
219 } 229 }
220 for (; code1 <= code2; ++code1) { 230 for (; code1 <= code2; ++code1) {
221 map[code1] = u++; 231 map[code1] = u++;
222 } 232 }
223 } else { 233 } else {
@@ -231,40 +241,26 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
231 sMap[sMapLen].c = code1; 241 sMap[sMapLen].c = code1;
232 sMap[sMapLen].len = (n3 - 2) / 4; 242 sMap[sMapLen].len = (n3 - 2) / 4;
233 for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) { 243 for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) {
234 strncpy(uHex, tok3 + 1 + j*4, 4); 244 strncpy(uHex, tok3 + 1 + j*4, 4);
235 uHex[4] = '\0'; 245 uHex[4] = '\0';
236 if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) { 246 if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
237 error(-1, "Illegal line in bfrange block in ToUnicode CMap"); 247 error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
238 } 248 }
239 } 249 }
240 sMap[sMapLen].u[sMap[sMapLen].len - 1] += i; 250 sMap[sMapLen].u[sMap[sMapLen].len - 1] += i;
241 ++sMapLen; 251 ++sMapLen;
242 } 252 }
243 } 253 }
244 } else {
245 error(-1, "Illegal bfrange block in ToUnicode CMap");
246 } 254 }
247 } else if (tok2 && !strcmp(tok2, "usecmap")) { 255 pst->getToken(tok1, sizeof(tok1), &n1);
248 if (tok1[0] == '/') { 256 } else {
249 name = new GString(tok1 + 1); 257 strcpy(tok1, tok2);
250 if ((f = globalParams->findToUnicodeFile(name))) {
251 parseCMap1((char *(*)(char *, int, void *))&getLine, f, nBits);
252 fclose(f);
253 } else {
254 error(-1, "Couldn't find ToUnicode CMap file for '%s'",
255 name->getCString());
256 }
257 delete name;
258 }
259 } else if (tok2 && !strcmp(tok2, "beginbfchar")) {
260 inBFChar = gTrue;
261 } else if (tok2 && !strcmp(tok2, "beginbfrange")) {
262 inBFRange = gTrue;
263 } 258 }
264 } 259 }
260 delete pst;
265} 261}
266 262
267CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) { 263CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) {
268 CharCode i; 264 CharCode i;
269 265
270 collection = collectionA; 266 collection = collectionA;
diff --git a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h
index c811d72..06916c8 100644
--- a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h
+++ b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h
@@ -1,13 +1,13 @@
1//======================================================================== 1//========================================================================
2// 2//
3// CharCodeToUnicode.h 3// CharCodeToUnicode.h
4// 4//
5// Mapping from character codes to Unicode. 5// Mapping from character codes to Unicode.
6// 6//
7// Copyright 2001 Derek B. Noonburg 7// Copyright 2001-2002 Glyph & Cog, LLC
8// 8//
9//======================================================================== 9//========================================================================
10 10
11#ifndef CHARCODETOUNICODE_H 11#ifndef CHARCODETOUNICODE_H
12#define CHARCODETOUNICODE_H 12#define CHARCODETOUNICODE_H
13 13
@@ -47,14 +47,13 @@ public:
47 47
48 // Map a CharCode to Unicode. 48 // Map a CharCode to Unicode.
49 int mapToUnicode(CharCode c, Unicode *u, int size); 49 int mapToUnicode(CharCode c, Unicode *u, int size);
50 50
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,
58 CharCodeToUnicodeString *sMapA, int sMapLenA); 57 CharCodeToUnicodeString *sMapA, int sMapLenA);
59 58
60 GString *collection; 59 GString *collection;
diff --git a/noncore/unsupported/qpdf/xpdf/CharTypes.h b/noncore/unsupported/qpdf/xpdf/CharTypes.h
index 8938be5..bae2f26 100644
--- a/noncore/unsupported/qpdf/xpdf/CharTypes.h
+++ b/noncore/unsupported/qpdf/xpdf/CharTypes.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// CharTypes.h 3// CharTypes.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef CHARTYPES_H 9#ifndef CHARTYPES_H
10#define CHARTYPES_H 10#define CHARTYPES_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/Decrypt.cc b/noncore/unsupported/qpdf/xpdf/Decrypt.cc
index 2def802..8de4091 100644
--- a/noncore/unsupported/qpdf/xpdf/Decrypt.cc
+++ b/noncore/unsupported/qpdf/xpdf/Decrypt.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Decrypt.cc 3// Decrypt.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
diff --git a/noncore/unsupported/qpdf/xpdf/Decrypt.h b/noncore/unsupported/qpdf/xpdf/Decrypt.h
index 1bdb2b7..52afb2f 100644
--- a/noncore/unsupported/qpdf/xpdf/Decrypt.h
+++ b/noncore/unsupported/qpdf/xpdf/Decrypt.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Decrypt.h 3// Decrypt.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef DECRYPT_H 9#ifndef DECRYPT_H
10#define DECRYPT_H 10#define DECRYPT_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/Dict.cc b/noncore/unsupported/qpdf/xpdf/Dict.cc
index 1a49ca5..5eb077e 100644
--- a/noncore/unsupported/qpdf/xpdf/Dict.cc
+++ b/noncore/unsupported/qpdf/xpdf/Dict.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Dict.cc 3// Dict.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
diff --git a/noncore/unsupported/qpdf/xpdf/Dict.h b/noncore/unsupported/qpdf/xpdf/Dict.h
index c4f1ea5..b994514 100644
--- a/noncore/unsupported/qpdf/xpdf/Dict.h
+++ b/noncore/unsupported/qpdf/xpdf/Dict.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Dict.h 3// Dict.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef DICT_H 9#ifndef DICT_H
10#define DICT_H 10#define DICT_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h b/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h
index 048e25d..8e73486 100644
--- a/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h
+++ b/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h
@@ -1,20 +1,20 @@
1//======================================================================== 1//========================================================================
2// 2//
3// DisplayFontTable.h 3// DisplayFontTable.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9static struct { 9static struct {
10 char *name; 10 char *name;
11 char *xlfd; 11 char *xlfd;
12 char *encoding; 12 char *encoding;
13} displayFontTab[] = { 13} displayFontTab[] = {
14#if _NO_USE_FOR_QPE 14#if 0
15 {"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 15 {"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
16 {"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 16 {"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
17 {"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 17 {"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
18 {"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 18 {"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
19 {"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 19 {"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
20 {"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 20 {"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
@@ -24,8 +24,8 @@ static struct {
24 {"Times-Bold", "-*-times-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 24 {"Times-Bold", "-*-times-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
25 {"Times-BoldItalic", "-*-times-bold-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 25 {"Times-BoldItalic", "-*-times-bold-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
26 {"Times-Italic", "-*-times-medium-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 26 {"Times-Italic", "-*-times-medium-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
27 {"Times-Roman", "-*-times-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 27 {"Times-Roman", "-*-times-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
28 {"ZapfDingbats", "-*-zapfdingbats-medium-r-normal-*-%s-*-*-*-*-*-*-*", "ZapfDingbats"}, 28 {"ZapfDingbats", "-*-zapfdingbats-medium-r-normal-*-%s-*-*-*-*-*-*-*", "ZapfDingbats"},
29#endif 29#endif
30 {NULL} 30 {NULL,0,0}
31}; 31};
diff --git a/noncore/unsupported/qpdf/xpdf/Error.cc b/noncore/unsupported/qpdf/xpdf/Error.cc
index 8763846..3eae5c9 100644
--- a/noncore/unsupported/qpdf/xpdf/Error.cc
+++ b/noncore/unsupported/qpdf/xpdf/Error.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Error.cc 3// Error.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
diff --git a/noncore/unsupported/qpdf/xpdf/Error.h b/noncore/unsupported/qpdf/xpdf/Error.h
index 151e961..77801c5 100644
--- a/noncore/unsupported/qpdf/xpdf/Error.h
+++ b/noncore/unsupported/qpdf/xpdf/Error.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Error.h 3// Error.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef ERROR_H 9#ifndef ERROR_H
10#define ERROR_H 10#define ERROR_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/ErrorCodes.h b/noncore/unsupported/qpdf/xpdf/ErrorCodes.h
new file mode 100644
index 0000000..4e0d38a
--- a/dev/null
+++ b/noncore/unsupported/qpdf/xpdf/ErrorCodes.h
@@ -0,0 +1,24 @@
1//========================================================================
2//
3// ErrorCodes.h
4//
5// Copyright 2002 Glyph & Cog, LLC
6//
7//========================================================================
8
9#ifndef ERRORCODES_H
10#define ERRORCODES_H
11
12 #define errNone 0// no error
13
14 #define errOpenFile 1// couldn't open the PDF file
15
16 #define errBadCatalog 2// couldn't read the page catalog
17
18 #define errDamaged 3// PDF file was damaged and couldn't be
19 // repaired
20
21 #define errEncrypted 4// file was encrypted and password was
22 // incorrect or not supplied
23
24#endif
diff --git a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc
index 12a1a27..bd5f9cf 100644
--- a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc
+++ b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// FontEncodingTables.cc 3// FontEncodingTables.cc
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#include <aconf.h> 9#include <aconf.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include "FontEncodingTables.h" 11#include "FontEncodingTables.h"
diff --git a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h
index 4646a43..deee0a8 100644
--- a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h
+++ b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// FontEncodingTables.h 3// FontEncodingTables.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef FONTENCODINGTABLES_H 9#ifndef FONTENCODINGTABLES_H
10#define FONTENCODINGTABLES_H 10#define FONTENCODINGTABLES_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/Function.cc b/noncore/unsupported/qpdf/xpdf/Function.cc
index 815cc89..ebf3718 100644
--- a/noncore/unsupported/qpdf/xpdf/Function.cc
+++ b/noncore/unsupported/qpdf/xpdf/Function.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Function.cc 3// Function.cc
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -412,33 +412,34 @@ void SampledFunction::transform(fouble *in, fouble *out) {
412ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { 412ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
413 Object obj1, obj2; 413 Object obj1, obj2;
414 GBool hasN; 414 GBool hasN;
415 int i; 415 int i;
416 416
417 ok = gFalse; 417 ok = gFalse;
418 hasN = gFalse;
419 418
420 //----- initialize the generic stuff 419 //----- initialize the generic stuff
421 if (!init(dict)) { 420 if (!init(dict)) {
422 goto err1; 421 goto err1;
423 } 422 }
424 if (m != 1) { 423 if (m != 1) {
425 error(-1, "Exponential function with more than one input"); 424 error(-1, "Exponential function with more than one input");
426 goto err1; 425 goto err1;
427 } 426 }
427 hasN = hasRange;
428 428
429 //----- default values 429 //----- default values
430 for (i = 0; i < funcMaxOutputs; ++i) { 430 for (i = 0; i < funcMaxOutputs; ++i) {
431 c0[i] = 0; 431 c0[i] = 0;
432 c1[i] = 1; 432 c1[i] = 1;
433 } 433 }
434 434
435 //----- C0 435 //----- C0
436 if (dict->lookup("C0", &obj1)->isArray()) { 436 if (dict->lookup("C0", &obj1)->isArray()) {
437 if (!hasN) { 437 if (!hasN) {
438 n = obj1.arrayGetLength(); 438 n = obj1.arrayGetLength();
439 hasN = gTrue;
439 } else if (obj1.arrayGetLength() != n) { 440 } else if (obj1.arrayGetLength() != n) {
440 error(-1, "Function's C0 array is wrong length"); 441 error(-1, "Function's C0 array is wrong length");
441 goto err2; 442 goto err2;
442 } 443 }
443 for (i = 0; i < n; ++i) { 444 for (i = 0; i < n; ++i) {
444 obj1.arrayGet(i, &obj2); 445 obj1.arrayGet(i, &obj2);
@@ -453,12 +454,13 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
453 obj1.free(); 454 obj1.free();
454 455
455 //----- C1 456 //----- C1
456 if (dict->lookup("C1", &obj1)->isArray()) { 457 if (dict->lookup("C1", &obj1)->isArray()) {
457 if (!hasN) { 458 if (!hasN) {
458 n = obj1.arrayGetLength(); 459 n = obj1.arrayGetLength();
460 hasN = gTrue;
459 } else if (obj1.arrayGetLength() != n) { 461 } else if (obj1.arrayGetLength() != n) {
460 error(-1, "Function's C1 array is wrong length"); 462 error(-1, "Function's C1 array is wrong length");
461 goto err2; 463 goto err2;
462 } 464 }
463 for (i = 0; i < n; ++i) { 465 for (i = 0; i < n; ++i) {
464 obj1.arrayGet(i, &obj2); 466 obj1.arrayGet(i, &obj2);
@@ -477,12 +479,19 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
477 error(-1, "Function has missing or invalid N"); 479 error(-1, "Function has missing or invalid N");
478 goto err2; 480 goto err2;
479 } 481 }
480 e = obj1.getNum(); 482 e = obj1.getNum();
481 obj1.free(); 483 obj1.free();
482 484
485 // this isn't supposed to happen, but I've run into (broken) PDF
486 // files where it does
487 if (!hasN) {
488 error(-1, "Exponential function does not define number of output values");
489 n = 1;
490 }
491
483 ok = gTrue; 492 ok = gTrue;
484 return; 493 return;
485 494
486 err3: 495 err3:
487 obj2.free(); 496 obj2.free();
488 err2: 497 err2:
diff --git a/noncore/unsupported/qpdf/xpdf/Function.h b/noncore/unsupported/qpdf/xpdf/Function.h
index a223359..deb4630 100644
--- a/noncore/unsupported/qpdf/xpdf/Function.h
+++ b/noncore/unsupported/qpdf/xpdf/Function.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Function.h 3// Function.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef FUNCTION_H 9#ifndef FUNCTION_H
10#define FUNCTION_H 10#define FUNCTION_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/Gfx.cc b/noncore/unsupported/qpdf/xpdf/Gfx.cc
index c19971c..17d613e 100644
--- a/noncore/unsupported/qpdf/xpdf/Gfx.cc
+++ b/noncore/unsupported/qpdf/xpdf/Gfx.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Gfx.cc 3// Gfx.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -27,22 +27,33 @@
27#include "GfxState.h" 27#include "GfxState.h"
28#include "OutputDev.h" 28#include "OutputDev.h"
29#include "Page.h" 29#include "Page.h"
30#include "Error.h" 30#include "Error.h"
31#include "Gfx.h" 31#include "Gfx.h"
32 32
33// the MSVC math.h doesn't define this
34#ifndef M_PI
35#define M_PI 3.14159265358979323846
36#endif
37
33//------------------------------------------------------------------------ 38//------------------------------------------------------------------------
34// constants 39// constants
35//------------------------------------------------------------------------ 40//------------------------------------------------------------------------
36 41
37// Max number of splits along the t axis for an axial shading fill. 42// Max number of splits along the t axis for an axial shading fill.
38#define axialMaxSplits 256 43#define axialMaxSplits 256
39 44
40// Max delta allowed in any color component for an axial shading fill. 45// Max delta allowed in any color component for an axial shading fill.
41#define axialColorDelta (1 / 256.0) 46#define axialColorDelta (1 / 256.0)
42 47
48// Max number of splits along the t axis for a radial shading fill.
49#define radialMaxSplits 256
50
51// Max delta allowed in any color component for a radial shading fill.
52#define radialColorDelta (1 / 256.0)
53
43//------------------------------------------------------------------------ 54//------------------------------------------------------------------------
44// Operator table 55// Operator table
45//------------------------------------------------------------------------ 56//------------------------------------------------------------------------
46 57
47Operator Gfx::opTab[] = { 58Operator Gfx::opTab[] = {
48 {"\"", 3, {tchkNum, tchkNum, tchkString}, 59 {"\"", 3, {tchkNum, tchkNum, tchkString},
@@ -371,12 +382,13 @@ GBool GfxResources::lookupGState(char *name, Object *obj) {
371Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, 382Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
372 PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, 383 PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate,
373 GBool printCommandsA) { 384 GBool printCommandsA) {
374 int i; 385 int i;
375 386
376 xref = xrefA; 387 xref = xrefA;
388 subPage = gFalse;
377 printCommands = printCommandsA; 389 printCommands = printCommandsA;
378 390
379 // start the resource stack 391 // start the resource stack
380 res = new GfxResources(xref, resDict, NULL); 392 res = new GfxResources(xref, resDict, NULL);
381 393
382 // initialize 394 // initialize
@@ -402,27 +414,60 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
402 state->clip(); 414 state->clip();
403 out->clip(state); 415 out->clip(state);
404 state->clearPath(); 416 state->clearPath();
405 } 417 }
406} 418}
407 419
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) {
426 Object obj2; 471 Object obj2;
427 int i; 472 int i;
428 473
@@ -446,17 +491,17 @@ void Gfx::display(Object *obj, GBool topLevel) {
446 parser = NULL; 491 parser = NULL;
447} 492}
448 493
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()) {
460 505
461 // got a command - execute it 506 // got a command - execute it
462 if (obj.isCmd()) { 507 if (obj.isCmd()) {
@@ -473,15 +518,15 @@ void Gfx::go(GBool topLevel) {
473 obj.free(); 518 obj.free();
474 for (i = 0; i < numArgs; ++i) 519 for (i = 0; i < numArgs; ++i)
475 args[i].free(); 520 args[i].free();
476 numArgs = 0; 521 numArgs = 0;
477 522
478 // periodically update display 523 // periodically update display
479 if (++numCmds == 200) { 524 if (++updateLevel >= 20000) {
480 out->dump(); 525 out->dump();
481 numCmds = 0; 526 updateLevel = 0;
482 } 527 }
483 528
484 // got an argument - save it 529 // got an argument - save it
485 } else if (numArgs < maxArgs) { 530 } else if (numArgs < maxArgs) {
486 args[numArgs++] = obj; 531 args[numArgs++] = obj;
487 532
@@ -516,13 +561,13 @@ void Gfx::go(GBool topLevel) {
516 } 561 }
517 for (i = 0; i < numArgs; ++i) 562 for (i = 0; i < numArgs; ++i)
518 args[i].free(); 563 args[i].free();
519 } 564 }
520 565
521 // update display 566 // update display
522 if (topLevel && numCmds > 0) { 567 if (topLevel && updateLevel > 0) {
523 out->dump(); 568 out->dump();
524 } 569 }
525} 570}
526 571
527void Gfx::execOp(Object *cmd, Object args[], int numArgs) { 572void Gfx::execOp(Object *cmd, Object args[], int numArgs) {
528 Operator *op; 573 Operator *op;
@@ -1135,13 +1180,13 @@ void Gfx::doPatternFill(GBool eoFill) {
1135 GfxTilingPattern *tPat; 1180 GfxTilingPattern *tPat;
1136 GfxColorSpace *cs; 1181 GfxColorSpace *cs;
1137 fouble xMin, yMin, xMax, yMax, x, y, x1, y1; 1182 fouble xMin, yMin, xMax, yMax, x, y, x1, y1;
1138 fouble cxMin, cyMin, cxMax, cyMax; 1183 fouble cxMin, cyMin, cxMax, cyMax;
1139 int xi0, yi0, xi1, yi1, xi, yi; 1184 int xi0, yi0, xi1, yi1, xi, yi;
1140 fouble *ctm, *btm, *ptm; 1185 fouble *ctm, *btm, *ptm;
1141 fouble m[6], ictm[6], m1[6], im[6], imb[6]; 1186 fouble m[6], ictm[6], m1[6], imb[6];
1142 fouble det; 1187 fouble det;
1143 fouble xstep, ystep; 1188 fouble xstep, ystep;
1144 int i; 1189 int i;
1145 1190
1146 // this is a bit of a kludge -- patterns can be really slow, so we 1191 // this is a bit of a kludge -- patterns can be really slow, so we
1147 // skip them if we're only doing text extraction, since they almost 1192 // skip them if we're only doing text extraction, since they almost
@@ -1186,21 +1231,12 @@ void Gfx::doPatternFill(GBool eoFill) {
1186 m[1] = m1[0] * ictm[1] + m1[1] * ictm[3]; 1231 m[1] = m1[0] * ictm[1] + m1[1] * ictm[3];
1187 m[2] = m1[2] * ictm[0] + m1[3] * ictm[2]; 1232 m[2] = m1[2] * ictm[0] + m1[3] * ictm[2];
1188 m[3] = m1[2] * ictm[1] + m1[3] * ictm[3]; 1233 m[3] = m1[2] * ictm[1] + m1[3] * ictm[3];
1189 m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4]; 1234 m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
1190 m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5]; 1235 m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5];
1191 1236
1192 // construct a (current space) -> (pattern space) transform matrix
1193 det = 1 / (m[0] * m[3] - m[1] * m[2]);
1194 im[0] = m[3] * det;
1195 im[1] = -m[1] * det;
1196 im[2] = -m[2] * det;
1197 im[3] = m[0] * det;
1198 im[4] = (m[2] * m[5] - m[3] * m[4]) * det;
1199 im[5] = (m[1] * m[4] - m[0] * m[5]) * det;
1200
1201 // construct a (base space) -> (pattern space) transform matrix 1237 // construct a (base space) -> (pattern space) transform matrix
1202 det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]); 1238 det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]);
1203 imb[0] = m1[3] * det; 1239 imb[0] = m1[3] * det;
1204 imb[1] = -m1[1] * det; 1240 imb[1] = -m1[1] * det;
1205 imb[2] = -m1[2] * det; 1241 imb[2] = -m1[2] * det;
1206 imb[3] = m1[0] * det; 1242 imb[3] = m1[0] * det;
@@ -1328,86 +1364,40 @@ void Gfx::opShFill(Object args[], int numArgs) {
1328 1364
1329 // do shading type-specific operations 1365 // do shading type-specific operations
1330 switch (shading->getType()) { 1366 switch (shading->getType()) {
1331 case 2: 1367 case 2:
1332 doAxialShFill((GfxAxialShading *)shading); 1368 doAxialShFill((GfxAxialShading *)shading);
1333 break; 1369 break;
1370 case 3:
1371 doRadialShFill((GfxRadialShading *)shading);
1372 break;
1334 } 1373 }
1335 1374
1336 // restore graphics state 1375 // restore graphics state
1337 state = state->restore(); 1376 state = state->restore();
1338 out->restoreState(state); 1377 out->restoreState(state);
1339 1378
1340 delete shading; 1379 delete shading;
1341} 1380}
1342 1381
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;
1352 fouble ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1; 1388 fouble ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
1353 fouble t0, t1, tt; 1389 fouble t0, t1, tt;
1354 fouble ta[axialMaxSplits + 1]; 1390 fouble ta[axialMaxSplits + 1];
1355 int next[axialMaxSplits + 1]; 1391 int next[axialMaxSplits + 1];
1356 GfxColor color0, color1; 1392 GfxColor color0, color1;
1357 int nComps; 1393 int nComps;
1358 int i, j, k, kk; 1394 int i, j, k, kk;
1359 1395
1360 // get clip region bbox and transform to current user space 1396 // get the clip region bbox
1361 state->getClipBBox(&x0, &y0, &x1, &y1); 1397 state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
1362 ctm = state->getCTM();
1363 det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
1364 ictm[0] = ctm[3] * det;
1365 ictm[1] = -ctm[1] * det;
1366 ictm[2] = -ctm[2] * det;
1367 ictm[3] = ctm[0] * det;
1368 ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
1369 ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
1370 xMin = xMax = x0 * ictm[0] + y0 * ictm[2] + ictm[4];
1371 yMin = yMax = x0 * ictm[1] + y0 * ictm[3] + ictm[5];
1372 tx = x0 * ictm[0] + y1 * ictm[2] + ictm[4];
1373 ty = x0 * ictm[1] + y1 * ictm[3] + ictm[5];
1374 if (tx < xMin) {
1375 xMin = tx;
1376 } else if (tx > xMax) {
1377 xMax = tx;
1378 }
1379 if (ty < yMin) {
1380 yMin = ty;
1381 } else if (ty > yMax) {
1382 yMax = ty;
1383 }
1384 tx = x1 * ictm[0] + y0 * ictm[2] + ictm[4];
1385 ty = x1 * ictm[1] + y0 * ictm[3] + ictm[5];
1386 if (tx < xMin) {
1387 xMin = tx;
1388 } else if (tx > xMax) {
1389 xMax = tx;
1390 }
1391 if (ty < yMin) {
1392 yMin = ty;
1393 } else if (ty > yMax) {
1394 yMax = ty;
1395 }
1396 tx = x1 * ictm[0] + y1 * ictm[2] + ictm[4];
1397 ty = x1 * ictm[1] + y1 * ictm[3] + ictm[5];
1398 if (tx < xMin) {
1399 xMin = tx;
1400 } else if (tx > xMax) {
1401 xMax = tx;
1402 }
1403 if (ty < yMin) {
1404 yMin = ty;
1405 } else if (ty > yMax) {
1406 yMax = ty;
1407 }
1408 1398
1409 // compute min and max t values, based on the four corners of the 1399 // compute min and max t values, based on the four corners of the
1410 // clip region bbox 1400 // clip region bbox
1411 shading->getCoords(&x0, &y0, &x1, &y1); 1401 shading->getCoords(&x0, &y0, &x1, &y1);
1412 dx = x1 - x0; 1402 dx = x1 - x0;
1413 dy = y1 - y0; 1403 dy = y1 - y0;
@@ -1616,12 +1606,208 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
1616 vy0 = vy1; 1606 vy0 = vy1;
1617 color0 = color1; 1607 color0 = color1;
1618 i = next[i]; 1608 i = next[i];
1619 } 1609 }
1620} 1610}
1621 1611
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();
1625 if (clip == clipNormal) { 1811 if (clip == clipNormal) {
1626 out->clip(state); 1812 out->clip(state);
1627 } else { 1813 } else {
@@ -1797,60 +1983,68 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) {
1797 doShowText(args[2].getString()); 1983 doShowText(args[2].getString());
1798} 1984}
1799 1985
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());
1817 } else { 2009 } else {
1818 error(getPos(), "Element of show/space array must be number or string"); 2010 error(getPos(), "Element of show/space array must be number or string");
1819 } 2011 }
1820 obj.free(); 2012 obj.free();
1821 } 2013 }
1822} 2014}
1823 2015
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];
1854 } 2048 }
1855 mat = state->getTextMat(); 2049 mat = state->getTextMat();
1856 newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2]; 2050 newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2];
@@ -1864,77 +2058,93 @@ void Gfx::doShowText(GString *s) {
1864 newCTM[3] = mat[2] * newCTM[1] + mat[3] * newCTM[3]; 2058 newCTM[3] = mat[2] * newCTM[1] + mat[3] * newCTM[3];
1865 newCTM[0] *= state->getFontSize(); 2059 newCTM[0] *= state->getFontSize();
1866 newCTM[3] *= state->getFontSize(); 2060 newCTM[3] *= state->getFontSize();
1867 newCTM[0] *= state->getHorizScaling(); 2061 newCTM[0] *= state->getHorizScaling();
1868 newCTM[2] *= state->getHorizScaling(); 2062 newCTM[2] *= state->getHorizScaling();
1869 state->textTransformDelta(0, state->getRise(), &riseX, &riseY); 2063 state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
2064 curX = state->getCurX();
2065 curY = state->getCurY();
1870 oldParser = parser; 2066 oldParser = parser;
1871 p = s->getCString(); 2067 p = s->getCString();
1872 len = s->getLength(); 2068 len = s->getLength();
1873 while (len > 0) { 2069 while (len > 0) {
1874 n = font->getNextChar(p, len, &code, 2070 n = font->getNextChar(p, len, &code,
1875 u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, 2071 u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
1876 &dx, &dy, &originX, &originY); 2072 &dx, &dy, &originX, &originY);
1877 state->transform(state->getCurX() + riseX, state->getCurY() + riseY,
1878 &x, &y);
1879 out->saveState(state);
1880 state = state->save();
1881 state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
1882 //~ out->updateCTM(???)
1883 ((Gfx8BitFont *)font)->getCharProc(code, &charProc);
1884 if (charProc.isStream()) {
1885 display(&charProc, gFalse);
1886 } else {
1887 error(getPos(), "Missing or bad Type3 CharProc entry");
1888 }
1889 state = state->restore();
1890 out->restoreState(state);
1891 charProc.free();
1892 dx = dx * state->getFontSize() + state->getCharSpace(); 2073 dx = dx * state->getFontSize() + state->getCharSpace();
1893 if (n == 1 && *p == ' ') { 2074 if (n == 1 && *p == ' ') {
1894 dx += state->getWordSpace(); 2075 dx += state->getWordSpace();
1895 } 2076 }
1896 dx *= state->getHorizScaling(); 2077 dx *= state->getHorizScaling();
1897 dy *= state->getFontSize(); 2078 dy *= state->getFontSize();
1898 state->textTransformDelta(dx, dy, &tdx, &tdy); 2079 state->textTransformDelta(dx, dy, &tdx, &tdy);
1899 state->shift(tdx, tdy); 2080 state->transform(curX + riseX, curY + riseY, &x, &y);
2081 out->saveState(state);
2082 state = state->save();
2083 state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
2084 //~ out->updateCTM(???)
2085 if (!out->beginType3Char(state, code, u, uLen)) {
2086 ((Gfx8BitFont *)font)->getCharProc(code, &charProc);
2087 if ((resDict = ((Gfx8BitFont *)font)->getResources())) {
2088 pushResources(resDict);
2089 }
2090 if (charProc.isStream()) {
2091 display(&charProc, gFalse);
2092 } else {
2093 error(getPos(), "Missing or bad Type3 CharProc entry");
2094 }
2095 out->endType3Char(state);
2096 if (resDict) {
2097 popResources();
2098 }
2099 charProc.free();
2100 }
2101 state = state->restore();
2102 out->restoreState(state);
2103 // GfxState::restore() does *not* restore the current position,
2104 // so we track it here with (curX, curY)
2105 curX += tdx;
2106 curY += tdy;
2107 state->moveTo(curX, curY);
1900 p += n; 2108 p += n;
1901 len -= n; 2109 len -= n;
1902 } 2110 }
1903 parser = oldParser; 2111 parser = oldParser;
1904 out->endString(state);
1905 return;
1906 }
1907#endif
1908 2112
1909 if (out->useDrawChar()) { 2113 } else if (out->useDrawChar()) {
1910 state->textTransformDelta(0, state->getRise(), &riseX, &riseY); 2114 state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
1911 out->beginString(state, s);
1912 p = s->getCString(); 2115 p = s->getCString();
1913 len = s->getLength(); 2116 len = s->getLength();
1914 while (len > 0) { 2117 while (len > 0) {
1915 n = font->getNextChar(p, len, &code, 2118 n = font->getNextChar(p, len, &code,
1916 u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, 2119 u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
1917 &dx, &dy, &originX, &originY); 2120 &dx, &dy, &originX, &originY);
1918 dx = dx * state->getFontSize() + state->getCharSpace(); 2121 if (wMode) {
1919 if (n == 1 && *p == ' ') { 2122 dx *= state->getFontSize();
1920 dx += state->getWordSpace(); 2123 dy = dy * state->getFontSize() + state->getCharSpace();
2124 if (n == 1 && *p == ' ') {
2125 dy += state->getWordSpace();
2126 }
2127 } else {
2128 dx = dx * state->getFontSize() + state->getCharSpace();
2129 if (n == 1 && *p == ' ') {
2130 dx += state->getWordSpace();
2131 }
2132 dx *= state->getHorizScaling();
2133 dy *= state->getFontSize();
1921 } 2134 }
1922 dx *= state->getHorizScaling();
1923 dy *= state->getFontSize();
1924 state->textTransformDelta(dx, dy, &tdx, &tdy); 2135 state->textTransformDelta(dx, dy, &tdx, &tdy);
1925 originX *= state->getFontSize(); 2136 originX *= state->getFontSize();
1926 originY *= state->getFontSize(); 2137 originY *= state->getFontSize();
1927 state->textTransformDelta(originX, originY, &tOriginX, &tOriginY); 2138 state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
1928 out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY, 2139 out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
1929 tdx, tdy, tOriginX, tOriginY, code, u, uLen); 2140 tdx, tdy, tOriginX, tOriginY, code, u, uLen);
1930 state->shift(tdx, tdy); 2141 state->shift(tdx, tdy);
1931 p += n; 2142 p += n;
1932 len -= n; 2143 len -= n;
1933 } 2144 }
1934 out->endString(state);
1935 2145
1936 } else { 2146 } else {
1937 dx = dy = 0; 2147 dx = dy = 0;
1938 p = s->getCString(); 2148 p = s->getCString();
1939 len = s->getLength(); 2149 len = s->getLength();
1940 nChars = nSpaces = 0; 2150 nChars = nSpaces = 0;
@@ -1948,29 +2158,42 @@ void Gfx::doShowText(GString *s) {
1948 ++nSpaces; 2158 ++nSpaces;
1949 } 2159 }
1950 ++nChars; 2160 ++nChars;
1951 p += n; 2161 p += n;
1952 len -= n; 2162 len -= n;
1953 } 2163 }
1954 dx = dx * state->getFontSize() 2164 if (wMode) {
1955 + nChars * state->getCharSpace() 2165 dx *= state->getFontSize();
1956 + nSpaces * state->getWordSpace(); 2166 dy = dy * state->getFontSize()
1957 dx *= state->getHorizScaling(); 2167 + nChars * state->getCharSpace()
1958 dy *= state->getFontSize(); 2168 + nSpaces * state->getWordSpace();
2169 } else {
2170 dx = dx * state->getFontSize()
2171 + nChars * state->getCharSpace()
2172 + nSpaces * state->getWordSpace();
2173 dx *= state->getHorizScaling();
2174 dy *= state->getFontSize();
2175 }
1959 state->textTransformDelta(dx, dy, &tdx, &tdy); 2176 state->textTransformDelta(dx, dy, &tdx, &tdy);
1960 out->drawString(state, s); 2177 out->drawString(state, s);
1961 state->shift(tdx, tdy); 2178 state->shift(tdx, tdy);
1962 } 2179 }
2180
2181 if (out->useDrawChar()) {
2182 out->endString(state);
2183 }
2184
2185 updateLevel += 10 * s->getLength();
1963} 2186}
1964 2187
1965//------------------------------------------------------------------------ 2188//------------------------------------------------------------------------
1966// XObject operators 2189// XObject operators
1967//------------------------------------------------------------------------ 2190//------------------------------------------------------------------------
1968 2191
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
1974 2197
1975 if (!res->lookupXObject(args[0].getName(), &obj1)) { 2198 if (!res->lookupXObject(args[0].getName(), &obj1)) {
1976 return; 2199 return;
@@ -1990,12 +2213,16 @@ void Gfx::opXObject(Object args[], int numArgs) {
1990 if (obj2.isName("Image")) { 2213 if (obj2.isName("Image")) {
1991 res->lookupXObjectNF(args[0].getName(), &refObj); 2214 res->lookupXObjectNF(args[0].getName(), &refObj);
1992 doImage(&refObj, obj1.getStream(), gFalse); 2215 doImage(&refObj, obj1.getStream(), gFalse);
1993 refObj.free(); 2216 refObj.free();
1994 } else if (obj2.isName("Form")) { 2217 } else if (obj2.isName("Form")) {
1995 doForm(&obj1); 2218 doForm(&obj1);
2219 } else if (obj2.isName("PS")) {
2220 obj1.streamGetDict()->lookup("Level1", &obj3);
2221 out->psXObject(obj1.getStream(),
2222 obj3.isStream() ? obj3.getStream() : (Stream *)NULL);
1996 } else if (obj2.isName()) { 2223 } else if (obj2.isName()) {
1997 error(getPos(), "Unknown XObject subtype '%s'", obj2.getName()); 2224 error(getPos(), "Unknown XObject subtype '%s'", obj2.getName());
1998 } else { 2225 } else {
1999 error(getPos(), "XObject subtype is missing or wrong type"); 2226 error(getPos(), "XObject subtype is missing or wrong type");
2000 } 2227 }
2001 obj2.free(); 2228 obj2.free();
@@ -2145,12 +2372,17 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
2145 haveMask ? maskColors : (int *)NULL, inlineImg); 2372 haveMask ? maskColors : (int *)NULL, inlineImg);
2146 delete colorMap; 2373 delete colorMap;
2147 2374
2148 maskObj.free(); 2375 maskObj.free();
2149 } 2376 }
2150 2377
2378 if ((i = width * height) > 1000) {
2379 i = 1000;
2380 }
2381 updateLevel += i;
2382
2151 return; 2383 return;
2152 2384
2153 err2: 2385 err2:
2154 obj1.free(); 2386 obj1.free();
2155 err1: 2387 err1:
2156 error(getPos(), "Bad image parameters"); 2388 error(getPos(), "Bad image parameters");
@@ -2212,25 +2444,28 @@ void Gfx::doForm(Object *str) {
2212 // draw it 2444 // draw it
2213 doForm1(str, resDict, m, bbox); 2445 doForm1(str, resDict, m, bbox);
2214 2446
2215 resObj.free(); 2447 resObj.free();
2216} 2448}
2217 2449
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();
2234 error(getPos(), "Bad form bounding box"); 2469 error(getPos(), "Bad form bounding box");
2235 return; 2470 return;
2236 } 2471 }
@@ -2238,13 +2473,13 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
2238 bboxObj.arrayGet(i, &obj1); 2473 bboxObj.arrayGet(i, &obj1);
2239 bbox[i] = obj1.getNum(); 2474 bbox[i] = obj1.getNum();
2240 obj1.free(); 2475 obj1.free();
2241 } 2476 }
2242 bboxObj.free(); 2477 bboxObj.free();
2243 2478
2244 // get matrix 2479 // get the form matrix
2245 dict->lookup("Matrix", &matrixObj); 2480 dict->lookup("Matrix", &matrixObj);
2246 if (matrixObj.isArray()) { 2481 if (matrixObj.isArray()) {
2247 for (i = 0; i < 6; ++i) { 2482 for (i = 0; i < 6; ++i) {
2248 matrixObj.arrayGet(i, &obj1); 2483 matrixObj.arrayGet(i, &obj1);
2249 m[i] = obj1.getNum(); 2484 m[i] = obj1.getNum();
2250 obj1.free(); 2485 obj1.free();
@@ -2253,22 +2488,70 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
2253 m[0] = 1; m[1] = 0; 2488 m[0] = 1; m[1] = 0;
2254 m[2] = 0; m[3] = 1; 2489 m[2] = 0; m[3] = 1;
2255 m[4] = 0; m[5] = 0; 2490 m[4] = 0; m[5] = 0;
2256 } 2491 }
2257 matrixObj.free(); 2492 matrixObj.free();
2258 2493
2259 // scale form bbox to widget rectangle 2494 // transform the form bbox from form space to user space
2260 sx = fabs((xMax - xMin) / (bbox[2] - bbox[0])); 2495 formX0 = bbox[0] * m[0] + bbox[1] * m[2] + m[4];
2261 sy = fabs((yMax - yMin) / (bbox[3] - bbox[1])); 2496 formY0 = bbox[0] * m[1] + bbox[1] * m[3] + m[5];
2262 m[0] *= sx; m[1] *= sy; 2497 formX1 = bbox[2] * m[0] + bbox[3] * m[2] + m[4];
2263 m[2] *= sx; m[3] *= sy; 2498 formY1 = bbox[2] * m[1] + bbox[3] * m[3] + m[5];
2264 m[4] *= sx; m[5] *= sy; 2499
2500 // transform the annotation bbox from default user space to user
2501 // space: (bbox * baseMatrix) * iCTM
2502 ctm = state->getCTM();
2503 det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
2504 ictm[0] = ctm[3] * det;
2505 ictm[1] = -ctm[1] * det;
2506 ictm[2] = -ctm[2] * det;
2507 ictm[3] = ctm[0] * det;
2508 ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
2509 ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
2510 x = baseMatrix[0] * xMin + baseMatrix[2] * yMin + baseMatrix[4];
2511 y = baseMatrix[1] * xMin + baseMatrix[3] * yMin + baseMatrix[5];
2512 annotX0 = ictm[0] * x + ictm[2] * y + ictm[4];
2513 annotY0 = ictm[1] * x + ictm[3] * y + ictm[5];
2514 x = baseMatrix[0] * xMax + baseMatrix[2] * yMax + baseMatrix[4];
2515 y = baseMatrix[1] * xMax + baseMatrix[3] * yMax + baseMatrix[5];
2516 annotX1 = ictm[0] * x + ictm[2] * y + ictm[4];
2517 annotY1 = ictm[1] * x + ictm[3] * y + ictm[5];
2518
2519 // swap min/max coords
2520 if (formX0 > formX1) {
2521 x = formX0; formX0 = formX1; formX1 = x;
2522 }
2523 if (formY0 > formY1) {
2524 y = formY0; formY0 = formY1; formY1 = y;
2525 }
2526 if (annotX0 > annotX1) {
2527 x = annotX0; annotX0 = annotX1; annotX1 = x;
2528 }
2529 if (annotY0 > annotY1) {
2530 y = annotY0; annotY0 = annotY1; annotY1 = y;
2531 }
2265 2532
2266 // translate to widget rectangle 2533 // scale the form to fit the annotation bbox
2267 m[4] += xMin; 2534 if (formX1 == formX0) {
2268 m[5] += yMin; 2535 // this shouldn't happen
2536 sx = 1;
2537 } else {
2538 sx = (annotX1 - annotX0) / (formX1 - formX0);
2539 }
2540 if (formY1 == formY0) {
2541 // this shouldn't happen
2542 sy = 1;
2543 } else {
2544 sy = (annotY1 - annotY0) / (formY1 - formY0);
2545 }
2546 m[0] *= sx;
2547 m[2] *= sx;
2548 m[4] = (m[4] - formX0) * sx + annotX0;
2549 m[1] *= sy;
2550 m[3] *= sy;
2551 m[5] = (m[5] - formY0) * sy + annotY0;
2269 2552
2270 // get resources 2553 // get resources
2271 dict->lookup("Resources", &resObj); 2554 dict->lookup("Resources", &resObj);
2272 resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; 2555 resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL;
2273 2556
2274 // draw it 2557 // draw it
@@ -2278,17 +2561,16 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
2278 bboxObj.free(); 2561 bboxObj.free();
2279} 2562}
2280 2563
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);
2292 state = state->save(); 2574 state = state->save();
2293 2575
2294 // save current parser 2576 // save current parser
@@ -2329,17 +2611,27 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
2329 2611
2330 // restore graphics state 2612 // restore graphics state
2331 state = state->restore(); 2613 state = state->restore();
2332 out->restoreState(state); 2614 out->restoreState(state);
2333 2615
2334 // pop resource stack 2616 // pop resource stack
2617 popResources();
2618
2619 return;
2620}
2621
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//------------------------------------------------------------------------
2343// in-line image operators 2635// in-line image operators
2344//------------------------------------------------------------------------ 2636//------------------------------------------------------------------------
2345 2637
@@ -2375,25 +2667,30 @@ Stream *Gfx::buildImageStream() {
2375 dict.initDict(xref); 2667 dict.initDict(xref);
2376 parser->getObj(&obj); 2668 parser->getObj(&obj);
2377 while (!obj.isCmd("ID") && !obj.isEOF()) { 2669 while (!obj.isCmd("ID") && !obj.isEOF()) {
2378 if (!obj.isName()) { 2670 if (!obj.isName()) {
2379 error(getPos(), "Inline image dictionary key must be a name object"); 2671 error(getPos(), "Inline image dictionary key must be a name object");
2380 obj.free(); 2672 obj.free();
2381 parser->getObj(&obj);
2382 } else { 2673 } else {
2383 key = copyString(obj.getName()); 2674 key = copyString(obj.getName());
2384 obj.free(); 2675 obj.free();
2385 parser->getObj(&obj); 2676 parser->getObj(&obj);
2386 if (obj.isEOF() || obj.isError()) 2677 if (obj.isEOF() || obj.isError()) {
2678 gfree(key);
2387 break; 2679 break;
2680 }
2388 dict.dictAdd(key, &obj); 2681 dict.dictAdd(key, &obj);
2389 } 2682 }
2390 parser->getObj(&obj); 2683 parser->getObj(&obj);
2391 } 2684 }
2392 if (obj.isEOF()) 2685 if (obj.isEOF()) {
2393 error(getPos(), "End of file in inline image"); 2686 error(getPos(), "End of file in inline image");
2687 obj.free();
2688 dict.free();
2689 return NULL;
2690 }
2394 obj.free(); 2691 obj.free();
2395 2692
2396 // make stream 2693 // make stream
2397 str = new EmbedStream(parser->getStream(), &dict); 2694 str = new EmbedStream(parser->getStream(), &dict);
2398 str = str->addFilters(&dict); 2695 str = str->addFilters(&dict);
2399 2696
@@ -2410,17 +2707,19 @@ void Gfx::opEndImage(Object args[], int numArgs) {
2410 2707
2411//------------------------------------------------------------------------ 2708//------------------------------------------------------------------------
2412// type 3 font operators 2709// type 3 font operators
2413//------------------------------------------------------------------------ 2710//------------------------------------------------------------------------
2414 2711
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//------------------------------------------------------------------------
2424// compatibility operators 2723// compatibility operators
2425//------------------------------------------------------------------------ 2724//------------------------------------------------------------------------
2426 2725
diff --git a/noncore/unsupported/qpdf/xpdf/Gfx.h b/noncore/unsupported/qpdf/xpdf/Gfx.h
index be5f2c2..2ecfb24 100644
--- a/noncore/unsupported/qpdf/xpdf/Gfx.h
+++ b/noncore/unsupported/qpdf/xpdf/Gfx.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Gfx.h 3// Gfx.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef GFX_H 9#ifndef GFX_H
10#define GFX_H 10#define GFX_H
11 11
@@ -24,12 +24,13 @@ class Dict;
24class OutputDev; 24class OutputDev;
25class GfxFontDict; 25class GfxFontDict;
26class GfxFont; 26class 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;
33 34
34//------------------------------------------------------------------------ 35//------------------------------------------------------------------------
35// Gfx 36// Gfx
@@ -94,27 +95,37 @@ public:
94 95
95 // Constructor for regular output. 96 // Constructor for regular output.
96 Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, 97 Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
97 PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, 98 PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate,
98 GBool printCommandsA); 99 GBool printCommandsA);
99 100
100 // Destructor. 101 // Constructor for a sub-page object.
102 Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
103 PDFRectangle *box, GBool crop, PDFRectangle *cropBox);
104
101 ~Gfx(); 105 ~Gfx();
102 106
103 // Interpret a stream or array of streams. 107 // Interpret a stream or array of streams.
104 void display(Object *obj, GBool topLevel = gTrue); 108 void display(Object *obj, GBool topLevel = gTrue);
105 109
106 void doWidgetForm(Object *str, fouble xMin, fouble yMin, 110 // Display an annotation, given its appearance (a Form XObject) and
107 fouble xMax, fouble yMax); 111 // bounding box (in default user space).
112 void doAnnot(Object *str, fouble xMin, fouble yMin,
113 fouble xMax, fouble yMax);
114
115 void pushResources(Dict *resDict);
116 void popResources();
108 117
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
118 GfxClipType clip; // do a clip? 129 GfxClipType clip; // do a clip?
119 int ignoreUndef; // current BX/EX nesting level 130 int ignoreUndef; // current BX/EX nesting level
120 fouble baseMatrix[6]; // default matrix for most recent 131 fouble baseMatrix[6]; // default matrix for most recent
@@ -176,12 +187,13 @@ private:
176 void opCloseFillStroke(Object args[], int numArgs); 187 void opCloseFillStroke(Object args[], int numArgs);
177 void opEOFillStroke(Object args[], int numArgs); 188 void opEOFillStroke(Object args[], int numArgs);
178 void opCloseEOFillStroke(Object args[], int numArgs); 189 void opCloseEOFillStroke(Object args[], int numArgs);
179 void doPatternFill(GBool eoFill); 190 void doPatternFill(GBool eoFill);
180 void opShFill(Object args[], int numArgs); 191 void opShFill(Object args[], int numArgs);
181 void doAxialShFill(GfxAxialShading *shading); 192 void doAxialShFill(GfxAxialShading *shading);
193 void doRadialShFill(GfxRadialShading *shading);
182 void doEndPath(); 194 void doEndPath();
183 195
184 // path clipping operators 196 // path clipping operators
185 void opClip(Object args[], int numArgs); 197 void opClip(Object args[], int numArgs);
186 void opEOClip(Object args[], int numArgs); 198 void opEOClip(Object args[], int numArgs);
187 199
diff --git a/noncore/unsupported/qpdf/xpdf/GfxFont.cc b/noncore/unsupported/qpdf/xpdf/GfxFont.cc
index 518f97b..8d722d6 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxFont.cc
+++ b/noncore/unsupported/qpdf/xpdf/GfxFont.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// GfxFont.cc 3// GfxFont.cc
4// 4//
5// Copyright 1996-2001 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -451,19 +451,30 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
451 } 451 }
452 obj2.free(); 452 obj2.free();
453 } 453 }
454 } 454 }
455 obj1.free(); 455 obj1.free();
456 456
457 // get Type3 font definition 457 // get Type 3 bounding box, font definition, and resources
458 if (type == fontType3) { 458 if (type == fontType3) {
459 fontDict->lookup("CharProcs", &charProcs); 459 if (fontDict->lookup("FontBBox", &obj1)->isArray()) {
460 if (!charProcs.isDict()) { 460 for (i = 0; i < 4 && i < obj1.arrayGetLength(); ++i) {
461 if (obj1.arrayGet(i, &obj2)->isNum()) {
462 fontBBox[i] = obj2.getNum();
463 }
464 obj2.free();
465 }
466 }
467 obj1.free();
468 if (!fontDict->lookup("CharProcs", &charProcs)->isDict()) {
461 error(-1, "Missing or invalid CharProcs dictionary in Type 3 font"); 469 error(-1, "Missing or invalid CharProcs dictionary in Type 3 font");
462 charProcs.free(); 470 charProcs.free();
463 } 471 }
472 if (!fontDict->lookup("Resources", &resources)->isDict()) {
473 resources.free();
474 }
464 } 475 }
465 476
466 //----- build the font encoding ----- 477 //----- build the font encoding -----
467 478
468 // Encodings start with a base encoding, which can come from 479 // Encodings start with a base encoding, which can come from
469 // (in order of priority): 480 // (in order of priority):
@@ -510,29 +521,34 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
510 } else if (obj1.isName("StandardEncoding")) { 521 } else if (obj1.isName("StandardEncoding")) {
511 hasEncoding = gTrue; 522 hasEncoding = gTrue;
512 baseEnc = standardEncoding; 523 baseEnc = standardEncoding;
513 } 524 }
514 525
515 // check embedded or external font file for base encoding 526 // check embedded or external font file for base encoding
527 // (only for Type 1 fonts - trying to get an encoding out of a
528 // TrueType font is a losing proposition)
516 fontFile = NULL; 529 fontFile = NULL;
517 buf = NULL; 530 buf = NULL;
518 if ((type == fontType1 || type == fontType1C || type == fontTrueType) && 531 if ((type == fontType1 || type == fontType1C) &&
519 (extFontFile || embFontID.num >= 0)) { 532 (extFontFile || embFontID.num >= 0)) {
520 if (extFontFile) { 533 if (extFontFile) {
521 buf = readExtFontFile(&len); 534 buf = readExtFontFile(&len);
522 } else { 535 } else {
523 buf = readEmbFontFile(xref, &len); 536 buf = readEmbFontFile(xref, &len);
524 } 537 }
525 if (buf) { 538 if (buf) {
526#if 0 539#if 0
540 if (type == fontType1C && !strncmp(buf, "%!", 2)) {
541 // various tools (including Adobe's) occasionally embed Type 1
542 // fonts but label them Type 1C
543 type = fontType1;
544 }
527 if (type == fontType1) { 545 if (type == fontType1) {
528 fontFile = new Type1FontFile(buf, len); 546 fontFile = new Type1FontFile(buf, len);
529 } else if (type == fontType1C) {
530 fontFile = new Type1CFontFile(buf, len);
531 } else { 547 } else {
532 fontFile = new TrueTypeFontFile(buf, len); 548 fontFile = new Type1CFontFile(buf, len);
533 } 549 }
534 if (fontFile->getName()) { 550 if (fontFile->getName()) {
535 if (embFontName) { 551 if (embFontName) {
536 delete embFontName; 552 delete embFontName;
537 } 553 }
538 embFontName = new GString(fontFile->getName()); 554 embFontName = new GString(fontFile->getName());
@@ -566,12 +582,13 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
566 } 582 }
567 583
568 // merge differences into encoding 584 // merge differences into encoding
569 if (obj1.isDict()) { 585 if (obj1.isDict()) {
570 obj1.dictLookup("Differences", &obj2); 586 obj1.dictLookup("Differences", &obj2);
571 if (obj2.isArray()) { 587 if (obj2.isArray()) {
588 hasEncoding = gTrue;
572 code = 0; 589 code = 0;
573 for (i = 0; i < obj2.arrayGetLength(); ++i) { 590 for (i = 0; i < obj2.arrayGetLength(); ++i) {
574 obj2.arrayGet(i, &obj3); 591 obj2.arrayGet(i, &obj3);
575 if (obj3.isInt()) { 592 if (obj3.isInt()) {
576 code = obj3.getInt(); 593 code = obj3.getInt();
577 } else if (obj3.isName()) { 594 } else if (obj3.isName()) {
@@ -633,14 +650,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
633 } else { 650 } else {
634 toUnicode[code] = 0; 651 toUnicode[code] = 0;
635 } 652 }
636 } 653 }
637 654
638 // pass 2: try to fill in the missing chars, looking for names of 655 // pass 2: try to fill in the missing chars, looking for names of
639 // the form 'Axx', 'xx', 'Ann', or 'nn', where 'A' is any letter, 656 // the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B'
640 // 'xx' is two hex digits, and 'nn' is 2-4 decimal digits 657 // are any letters, 'xx' is two hex digits, and 'nn' is 2-4
658 // decimal digits
641 if (missing && globalParams->getMapNumericCharNames()) { 659 if (missing && globalParams->getMapNumericCharNames()) {
642 for (code = 0; code < 256; ++code) { 660 for (code = 0; code < 256; ++code) {
643 if ((charName = enc[code]) && !toUnicode[code] && 661 if ((charName = enc[code]) && !toUnicode[code] &&
644 strcmp(charName, ".notdef")) { 662 strcmp(charName, ".notdef")) {
645 n = strlen(charName); 663 n = strlen(charName);
646 code2 = -1; 664 code2 = -1;
@@ -653,12 +671,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
653 } else if (!hex && n >= 2 && n <= 4 && 671 } else if (!hex && n >= 2 && n <= 4 &&
654 isdigit(charName[0]) && isdigit(charName[1])) { 672 isdigit(charName[0]) && isdigit(charName[1])) {
655 code2 = atoi(charName); 673 code2 = atoi(charName);
656 } else if (n >= 3 && n <= 5 && 674 } else if (n >= 3 && n <= 5 &&
657 isdigit(charName[1]) && isdigit(charName[2])) { 675 isdigit(charName[1]) && isdigit(charName[2])) {
658 code2 = atoi(charName+1); 676 code2 = atoi(charName+1);
677 } else if (n >= 4 && n <= 6 &&
678 isdigit(charName[2]) && isdigit(charName[3])) {
679 code2 = atoi(charName+2);
659 } 680 }
660 if (code2 >= 0 && code2 <= 0xff) { 681 if (code2 >= 0 && code2 <= 0xff) {
661 toUnicode[code] = (Unicode)code2; 682 toUnicode[code] = (Unicode)code2;
662 } 683 }
663 } 684 }
664 } 685 }
@@ -681,16 +702,20 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
681 fontDict->lookup("LastChar", &obj1); 702 fontDict->lookup("LastChar", &obj1);
682 lastChar = obj1.isInt() ? obj1.getInt() : 255; 703 lastChar = obj1.isInt() ? obj1.getInt() : 255;
683 obj1.free(); 704 obj1.free();
684 mul = (type == fontType3) ? fontMat[0] : fouble(0.001); 705 mul = (type == fontType3) ? fontMat[0] : fouble(0.001);
685 fontDict->lookup("Widths", &obj1); 706 fontDict->lookup("Widths", &obj1);
686 if (obj1.isArray()) { 707 if (obj1.isArray()) {
708 flags |= fontFixedWidth;
687 for (code = firstChar; code <= lastChar; ++code) { 709 for (code = firstChar; code <= lastChar; ++code) {
688 obj1.arrayGet(code - firstChar, &obj2); 710 obj1.arrayGet(code - firstChar, &obj2);
689 if (obj2.isNum()) { 711 if (obj2.isNum()) {
690 widths[code] = obj2.getNum() * mul; 712 widths[code] = obj2.getNum() * mul;
713 if (widths[code] != widths[firstChar]) {
714 flags &= ~fontFixedWidth;
715 }
691 } 716 }
692 obj2.free(); 717 obj2.free();
693 } 718 }
694 719
695 // use widths from built-in font 720 // use widths from built-in font
696 } else if (builtinFont) { 721 } else if (builtinFont) {
@@ -749,12 +774,15 @@ Gfx8BitFont::~Gfx8BitFont() {
749 } 774 }
750 } 775 }
751 ctu->decRefCnt(); 776 ctu->decRefCnt();
752 if (charProcs.isDict()) { 777 if (charProcs.isDict()) {
753 charProcs.free(); 778 charProcs.free();
754 } 779 }
780 if (resources.isDict()) {
781 resources.free();
782 }
755} 783}
756 784
757int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, 785int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,
758 Unicode *u, int uSize, int *uLen, 786 Unicode *u, int uSize, int *uLen,
759 fouble *dx, fouble *dy, fouble *ox, fouble *oy) { 787 fouble *dx, fouble *dy, fouble *ox, fouble *oy) {
760 CharCode c; 788 CharCode c;
@@ -768,21 +796,29 @@ int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,
768 796
769CharCodeToUnicode *Gfx8BitFont::getToUnicode() { 797CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
770 ctu->incRefCnt(); 798 ctu->incRefCnt();
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);
777 } else { 809 } else {
778 proc->initNull(); 810 proc->initNull();
779 } 811 }
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//------------------------------------------------------------------------
786 822
787static int cmpWidthExcep(const void *w1, const void *w2) { 823static int cmpWidthExcep(const void *w1, const void *w2) {
788 return ((GfxFontCIDWidthExcep *)w1)->first - 824 return ((GfxFontCIDWidthExcep *)w1)->first -
@@ -1183,12 +1219,16 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
1183 *ox = vx; 1219 *ox = vx;
1184 *oy = vy; 1220 *oy = vy;
1185 1221
1186 return n; 1222 return n;
1187} 1223}
1188 1224
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;
1192} 1232}
1193 1233
1194GString *GfxCIDFont::getCollection() { 1234GString *GfxCIDFont::getCollection() {
@@ -1213,13 +1253,13 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
1213 obj1.getRef(), obj2.getDict()); 1253 obj1.getRef(), obj2.getDict());
1214 if (fonts[i] && !fonts[i]->isOk()) { 1254 if (fonts[i] && !fonts[i]->isOk()) {
1215 delete fonts[i]; 1255 delete fonts[i];
1216 fonts[i] = NULL; 1256 fonts[i] = NULL;
1217 } 1257 }
1218 } else { 1258 } else {
1219 error(-1, "font resource is not a dictionary"); 1259 error(-1, "font resource is not a dictionary reference");
1220 fonts[i] = NULL; 1260 fonts[i] = NULL;
1221 } 1261 }
1222 obj1.free(); 1262 obj1.free();
1223 obj2.free(); 1263 obj2.free();
1224 } 1264 }
1225} 1265}
diff --git a/noncore/unsupported/qpdf/xpdf/GfxFont.h b/noncore/unsupported/qpdf/xpdf/GfxFont.h
index b1aa952..8e9fe38 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxFont.h
+++ b/noncore/unsupported/qpdf/xpdf/GfxFont.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// GfxFont.h 3// GfxFont.h
4// 4//
5// Copyright 1996-2001 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef GFXFONT_H 9#ifndef GFXFONT_H
10#define GFXFONT_H 10#define GFXFONT_H
11 11
@@ -110,14 +110,13 @@ public:
110 // Returns false if there is no embedded font. 110 // Returns false if there is no embedded font.
111 GBool getEmbeddedFontID(Ref *embID) 111 GBool getEmbeddedFontID(Ref *embID)
112 { *embID = embFontID; return embFontID.num >= 0; } 112 { *embID = embFontID; return embFontID.num >= 0; }
113 113
114 // Get the PostScript font name for the embedded font. Returns 114 // Get the PostScript font name for the embedded font. Returns
115 // NULL if there is no embedded font. 115 // NULL if there is no embedded font.
116 char *getEmbeddedFontName() 116 GString *getEmbeddedFontName() { return embFontName; }
117 { return embFontName ? embFontName->getCString() : (char *)NULL; }
118 117
119 // Get the name of the external font file. Returns NULL if there 118 // Get the name of the external font file. Returns NULL if there
120 // is no external font file. 119 // is no external font file.
121 GString *getExtFontFile() { return extFontFile; } 120 GString *getExtFontFile() { return extFontFile; }
122 121
123 // Get font descriptor flags. 122 // Get font descriptor flags.
@@ -134,12 +133,15 @@ public:
134 fouble *getFontBBox() { return fontBBox; } 133 fouble *getFontBBox() { return fontBBox; }
135 134
136 // Return the ascent and descent values. 135 // Return the ascent and descent values.
137 fouble getAscent() { return ascent; } 136 fouble getAscent() { return ascent; }
138 fouble getDescent() { return descent; } 137 fouble getDescent() { return descent; }
139 138
139 // Return the writing mode (0=horizontal, 1=vertical).
140 virtual int getWMode() { return 0; }
141
140 // Read an external or embedded font file into a buffer. 142 // Read an external or embedded font file into a buffer.
141 char *readExtFontFile(int *len); 143 char *readExtFontFile(int *len);
142 char *readEmbFontFile(XRef *xref, int *len); 144 char *readEmbFontFile(XRef *xref, int *len);
143 145
144 // Get the next char from a string <s> of <len> bytes, returning the 146 // Get the next char from a string <s> of <len> bytes, returning the
145 // char <code>, its Unicode mapping <u>, its displacement vector 147 // char <code>, its Unicode mapping <u>, its displacement vector
@@ -152,24 +154,24 @@ public:
152 fouble *dx, fouble *dy, fouble *ox, fouble *oy) = 0; 154 fouble *dx, fouble *dy, fouble *ox, fouble *oy) = 0;
153 155
154protected: 156protected:
155 157
156 void readFontDescriptor(XRef *xref, Dict *fontDict); 158 void readFontDescriptor(XRef *xref, Dict *fontDict);
157 CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits); 159 CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits);
158 void GfxFont::findExtFontFile(); 160 void findExtFontFile();
159 161
160 GString *tag; // PDF font tag 162 GString *tag; // PDF font tag
161 Ref id; // reference (used as unique ID) 163 Ref id; // reference (used as unique ID)
162 GString *name; // font name 164 GString *name; // font name
163 GfxFontType type; // type of font 165 GfxFontType type; // type of font
164 int flags; // font descriptor flags 166 int flags; // font descriptor flags
165 GString *embFontName; // name of embedded font 167 GString *embFontName; // name of embedded font
166 Ref embFontID; // ref to embedded font file stream 168 Ref embFontID; // ref to embedded font file stream
167 GString *extFontFile; // external font file name 169 GString *extFontFile; // external font file name
168 fouble fontMat[6]; // font matrix (Type 3 only) 170 fouble fontMat[6]; // font matrix (Type 3 only)
169 fouble fontBBox[4]; // font bounding box 171 fouble fontBBox[4]; // font bounding box (Type 3 only)
170 fouble missingWidth; // "default" width 172 fouble missingWidth; // "default" width
171 fouble ascent; // max height above baseline 173 fouble ascent; // max height above baseline
172 fouble descent; // max depth below baseline 174 fouble descent; // max depth below baseline
173 GBool ok; 175 GBool ok;
174}; 176};
175 177
@@ -201,24 +203,31 @@ public:
201 // Returns true if the PDF font specified an encoding. 203 // Returns true if the PDF font specified an encoding.
202 GBool getHasEncoding() { return hasEncoding; } 204 GBool getHasEncoding() { return hasEncoding; }
203 205
204 // Get width of a character or string. 206 // Get width of a character or string.
205 fouble getWidth(Guchar c) { return widths[c]; } 207 fouble getWidth(Guchar c) { return widths[c]; }
206 208
209 // Return the Type 3 CharProc dictionary, or NULL if none.
210 Dict *getCharProcs();
211
207 // Return the Type 3 CharProc for the character associated with <code>. 212 // Return the Type 3 CharProc for the character associated with <code>.
208 Object *getCharProc(int code, Object *proc); 213 Object *getCharProc(int code, Object *proc);
209 214
215 // Return the Type 3 Resources dictionary, or NULL if none.
216 Dict *getResources();
217
210private: 218private:
211 219
212 char *enc[256]; // char code --> char name 220 char *enc[256]; // char code --> char name
213 char encFree[256]; // boolean for each char name: if set, 221 char encFree[256]; // boolean for each char name: if set,
214 // the string is malloc'ed 222 // the string is malloc'ed
215 CharCodeToUnicode *ctu;// char code --> Unicode 223 CharCodeToUnicode *ctu;// char code --> Unicode
216 GBool hasEncoding; 224 GBool hasEncoding;
217 fouble widths[256]; // character widths 225 fouble widths[256]; // character widths
218 Object charProcs; // Type3 CharProcs dictionary 226 Object charProcs; // Type 3 CharProcs dictionary
227 Object resources; // Type 3 Resources dictionary
219}; 228};
220 229
221//------------------------------------------------------------------------ 230//------------------------------------------------------------------------
222// GfxCIDFont 231// GfxCIDFont
223//------------------------------------------------------------------------ 232//------------------------------------------------------------------------
224 233
@@ -233,12 +242,15 @@ public:
233 virtual GBool isCIDFont() { return gTrue; } 242 virtual GBool isCIDFont() { return gTrue; }
234 243
235 virtual int getNextChar(char *s, int len, CharCode *code, 244 virtual int getNextChar(char *s, int len, CharCode *code,
236 Unicode *u, int uSize, int *uLen, 245 Unicode *u, int uSize, int *uLen,
237 fouble *dx, fouble *dy, fouble *ox, fouble *oy); 246 fouble *dx, fouble *dy, fouble *ox, fouble *oy);
238 247
248 // Return the writing mode (0=horizontal, 1=vertical).
249 virtual int getWMode();
250
239 // Return the Unicode map. 251 // Return the Unicode map.
240 CharCodeToUnicode *getToUnicode(); 252 CharCodeToUnicode *getToUnicode();
241 253
242 // Get the collection name (<registry>-<ordering>). 254 // Get the collection name (<registry>-<ordering>).
243 GString *getCollection(); 255 GString *getCollection();
244 256
diff --git a/noncore/unsupported/qpdf/xpdf/GfxState.cc b/noncore/unsupported/qpdf/xpdf/GfxState.cc
index af4e0d4..befd45a 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxState.cc
+++ b/noncore/unsupported/qpdf/xpdf/GfxState.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// GfxState.cc 3// GfxState.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -405,15 +405,28 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) {
405 - 0.299 * color->c[0] 405 - 0.299 * color->c[0]
406 - 0.587 * color->c[1] 406 - 0.587 * color->c[1]
407 - 0.114 * color->c[2]); 407 - 0.114 * color->c[2]);
408} 408}
409 409
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) {
417 cmyk->c = clip01(color->c[0]); 430 cmyk->c = clip01(color->c[0]);
418 cmyk->m = clip01(color->c[1]); 431 cmyk->m = clip01(color->c[1]);
419 cmyk->y = clip01(color->c[2]); 432 cmyk->y = clip01(color->c[2]);
@@ -1265,16 +1278,12 @@ GfxShading *GfxShading::parse(Object *obj) {
1265 error(-1, "Invalid ShadingType in shading dictionary"); 1278 error(-1, "Invalid ShadingType in shading dictionary");
1266 obj1.free(); 1279 obj1.free();
1267 goto err1; 1280 goto err1;
1268 } 1281 }
1269 typeA = obj1.getInt(); 1282 typeA = obj1.getInt();
1270 obj1.free(); 1283 obj1.free();
1271 if (typeA != 2) {
1272 error(-1, "Unimplemented shading type %d", typeA);
1273 goto err1;
1274 }
1275 1284
1276 obj->dictLookup("ColorSpace", &obj1); 1285 obj->dictLookup("ColorSpace", &obj1);
1277 if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) { 1286 if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) {
1278 error(-1, "Bad color space in shading dictionary"); 1287 error(-1, "Bad color space in shading dictionary");
1279 obj1.free(); 1288 obj1.free();
1280 goto err1; 1289 goto err1;
@@ -1314,13 +1323,23 @@ GfxShading *GfxShading::parse(Object *obj) {
1314 } else { 1323 } else {
1315 error(-1, "Bad BBox in shading dictionary"); 1324 error(-1, "Bad BBox in shading dictionary");
1316 } 1325 }
1317 } 1326 }
1318 obj1.free(); 1327 obj1.free();
1319 1328
1320 shading = GfxAxialShading::parse(obj->getDict()); 1329 switch (typeA) {
1330 case 2:
1331 shading = GfxAxialShading::parse(obj->getDict());
1332 break;
1333 case 3:
1334 shading = GfxRadialShading::parse(obj->getDict());
1335 break;
1336 default:
1337 error(-1, "Unimplemented shading type %d", typeA);
1338 goto err1;
1339 }
1321 1340
1322 if (shading) { 1341 if (shading) {
1323 shading->type = typeA; 1342 shading->type = typeA;
1324 shading->colorSpace = colorSpaceA; 1343 shading->colorSpace = colorSpaceA;
1325 shading->background = backgroundA; 1344 shading->background = backgroundA;
1326 shading->hasBackground = hasBackgroundA; 1345 shading->hasBackground = hasBackgroundA;
@@ -1454,12 +1473,134 @@ void GfxAxialShading::getColor(fouble t, GfxColor *color) {
1454 for (i = 0; i < nFuncs; ++i) { 1473 for (i = 0; i < nFuncs; ++i) {
1455 funcs[i]->transform(&t, &color->c[i]); 1474 funcs[i]->transform(&t, &color->c[i]);
1456 } 1475 }
1457} 1476}
1458 1477
1459//------------------------------------------------------------------------ 1478//------------------------------------------------------------------------
1479// GfxRadialShading
1480//------------------------------------------------------------------------
1481
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
1463GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, 1604GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode,
1464 GfxColorSpace *colorSpaceA) { 1605 GfxColorSpace *colorSpaceA) {
1465 GfxIndexedColorSpace *indexedCS; 1606 GfxIndexedColorSpace *indexedCS;
@@ -1915,12 +2056,73 @@ GfxState::GfxState(GfxState *state) {
1915 lineDash = (fouble *)gmalloc(lineDashLength * sizeof(fouble)); 2056 lineDash = (fouble *)gmalloc(lineDashLength * sizeof(fouble));
1916 memcpy(lineDash, state->lineDash, lineDashLength * sizeof(fouble)); 2057 memcpy(lineDash, state->lineDash, lineDashLength * sizeof(fouble));
1917 } 2058 }
1918 saved = NULL; 2059 saved = NULL;
1919} 2060}
1920 2061
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
1924 x = ctm[0] + ctm[2]; 2126 x = ctm[0] + ctm[2];
1925 y = ctm[1] + ctm[3]; 2127 y = ctm[1] + ctm[3];
1926 return w * sqrt(0.5 * (x * x + y * y)); 2128 return w * sqrt(0.5 * (x * x + y * y));
@@ -1943,33 +2145,54 @@ void GfxState::getFontTransMat(fouble *m11, fouble *m12,
1943 *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize; 2145 *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize;
1944 *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize; 2146 *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize;
1945} 2147}
1946 2148
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,
1958 fouble d, fouble e, fouble f) { 2171 fouble d, fouble e, fouble f) {
1959 fouble a1 = ctm[0]; 2172 fouble a1 = ctm[0];
1960 fouble b1 = ctm[1]; 2173 fouble b1 = ctm[1];
1961 fouble c1 = ctm[2]; 2174 fouble c1 = ctm[2];
1962 fouble d1 = ctm[3]; 2175 fouble d1 = ctm[3];
2176 int i;
1963 2177
1964 ctm[0] = a * a1 + b * c1; 2178 ctm[0] = a * a1 + b * c1;
1965 ctm[1] = a * b1 + b * d1; 2179 ctm[1] = a * b1 + b * d1;
1966 ctm[2] = c * a1 + d * c1; 2180 ctm[2] = c * a1 + d * c1;
1967 ctm[3] = c * b1 + d * d1; 2181 ctm[3] = c * b1 + d * d1;
1968 ctm[4] = e * a1 + f * c1 + ctm[4]; 2182 ctm[4] = e * a1 + f * c1 + ctm[4];
1969 ctm[5] = e * b1 + f * d1 + ctm[5]; 2183 ctm[5] = e * b1 + f * d1 + ctm[5];
2184
2185 // avoid FP exceptions on badly messed up PDF files
2186 for (i = 0; i < 6; ++i) {
2187 if (ctm[i] > fouble(1e3)) {
2188 ctm[i] = fouble(1e3);
2189 } else if (ctm[i] < -fouble(1e3)) {
2190 ctm[i] = -fouble(1e3);
2191 }
2192 }
1970} 2193}
1971 2194
1972void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { 2195void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
1973 if (fillColorSpace) { 2196 if (fillColorSpace) {
1974 delete fillColorSpace; 2197 delete fillColorSpace;
1975 } 2198 }
@@ -2048,16 +2271,16 @@ void GfxState::clip() {
2048 } 2271 }
2049 if (yMax < clipYMax) { 2272 if (yMax < clipYMax) {
2050 clipYMax = yMax; 2273 clipYMax = yMax;
2051 } 2274 }
2052} 2275}
2053 2276
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}
2061 2284
2062void GfxState::shift(fouble dx, fouble dy) { 2285void GfxState::shift(fouble dx, fouble dy) {
2063 curX += dx; 2286 curX += dx;
@@ -2092,6 +2315,7 @@ GfxState *GfxState::restore() {
2092 } else { 2315 } else {
2093 oldState = this; 2316 oldState = this;
2094 } 2317 }
2095 2318
2096 return oldState; 2319 return oldState;
2097} 2320}
2321
diff --git a/noncore/unsupported/qpdf/xpdf/GfxState.h b/noncore/unsupported/qpdf/xpdf/GfxState.h
index 7fe16ea..328f9a8 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxState.h
+++ b/noncore/unsupported/qpdf/xpdf/GfxState.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// GfxState.h 3// GfxState.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef GFXSTATE_H 9#ifndef GFXSTATE_H
10#define GFXSTATE_H 10#define GFXSTATE_H
11 11
@@ -565,12 +565,46 @@ private:
565 Function *funcs[gfxColorMaxComps]; 565 Function *funcs[gfxColorMaxComps];
566 int nFuncs; 566 int nFuncs;
567 GBool extend0, extend1; 567 GBool extend0, extend1;
568}; 568};
569 569
570//------------------------------------------------------------------------ 570//------------------------------------------------------------------------
571// GfxRadialShading
572//------------------------------------------------------------------------
573
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
574class GfxImageColorMap { 608class GfxImageColorMap {
575public: 609public:
576 610
@@ -780,12 +814,13 @@ public:
780 int getRender() { return render; } 814 int getRender() { return render; }
781 GfxPath *getPath() { return path; } 815 GfxPath *getPath() { return path; }
782 fouble getCurX() { return curX; } 816 fouble getCurX() { return curX; }
783 fouble getCurY() { return curY; } 817 fouble getCurY() { return curY; }
784 void getClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax) 818 void getClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax)
785 { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; } 819 { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; }
820 void getUserClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax);
786 fouble getLineX() { return lineX; } 821 fouble getLineX() { return lineX; }
787 fouble getLineY() { return lineY; } 822 fouble getLineY() { return lineY; }
788 823
789 // Is there a current point/path? 824 // Is there a current point/path?
790 GBool isCurPt() { return path->isCurPt(); } 825 GBool isCurPt() { return path->isCurPt(); }
791 GBool isPath() { return path->isPath(); } 826 GBool isPath() { return path->isPath(); }
@@ -862,13 +897,13 @@ public:
862 // Update clip region. 897 // Update clip region.
863 void clip(); 898 void clip();
864 899
865 // Text position. 900 // Text position.
866 void textMoveTo(fouble tx, fouble ty) 901 void textMoveTo(fouble tx, fouble ty)
867 { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); } 902 { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); }
868 void textShift(fouble tx); 903 void textShift(fouble tx, fouble ty);
869 void shift(fouble dx, fouble dy); 904 void shift(fouble dx, fouble dy);
870 905
871 // Push/pop GfxState on/off stack. 906 // Push/pop GfxState on/off stack.
872 GfxState *save(); 907 GfxState *save();
873 GfxState *restore(); 908 GfxState *restore();
874 GBool hasSaves() { return saved != NULL; } 909 GBool hasSaves() { return saved != NULL; }
diff --git a/noncore/unsupported/qpdf/xpdf/GlobalParams.cc b/noncore/unsupported/qpdf/xpdf/GlobalParams.cc
index 8be58a3..0bc908e 100644
--- a/noncore/unsupported/qpdf/xpdf/GlobalParams.cc
+++ b/noncore/unsupported/qpdf/xpdf/GlobalParams.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// GlobalParams.cc 3// GlobalParams.cc
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -93,42 +93,45 @@ DisplayFontParam::~DisplayFontParam() {
93} 93}
94 94
95//------------------------------------------------------------------------ 95//------------------------------------------------------------------------
96// PSFontParam 96// PSFontParam
97//------------------------------------------------------------------------ 97//------------------------------------------------------------------------
98 98
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//------------------------------------------------------------------------
110// parsing 116// parsing
111//------------------------------------------------------------------------ 117//------------------------------------------------------------------------
112 118
113GlobalParams::GlobalParams(char *cfgFileName) { 119GlobalParams::GlobalParams(char *cfgFileName) {
114 UnicodeMap *map; 120 UnicodeMap *map;
115 DisplayFontParam *dfp; 121 DisplayFontParam *dfp;
116 GString *fileName; 122 GString *fileName;
117 FILE *f; 123 FILE *f;
118 char buf[512];
119 int line;
120 GList *tokens;
121 GString *cmd;
122 char *p1, *p2;
123 int i; 124 int i;
124 125
125 initBuiltinFontTables(); 126 initBuiltinFontTables();
126 127
128 // scan the encoding in reverse because we want the lowest-numbered
129 // index for each char name ('space' is encoded twice)
127 macRomanReverseMap = new NameToCharCode(); 130 macRomanReverseMap = new NameToCharCode();
128 for (i = 0; i < 256; ++i) { 131 for (i = 255; i >= 0; --i) {
129 if (macRomanEncoding[i]) { 132 if (macRomanEncoding[i]) {
130 macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i); 133 macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
131 } 134 }
132 } 135 }
133 136
134 nameToUnicode = new NameToCharCode(); 137 nameToUnicode = new NameToCharCode();
@@ -136,12 +139,13 @@ GlobalParams::GlobalParams(char *cfgFileName) {
136 residentUnicodeMaps = new GHash(); 139 residentUnicodeMaps = new GHash();
137 unicodeMaps = new GHash(gTrue); 140 unicodeMaps = new GHash(gTrue);
138 cMapDirs = new GHash(gTrue); 141 cMapDirs = new GHash(gTrue);
139 toUnicodeDirs = new GList(); 142 toUnicodeDirs = new GList();
140 displayFonts = new GHash(); 143 displayFonts = new GHash();
141 displayCIDFonts = new GHash(); 144 displayCIDFonts = new GHash();
145 displayNamedCIDFonts = new GHash();
142#if HAVE_PAPER_H 146#if HAVE_PAPER_H
143 const struct paper *paperType; 147 const struct paper *paperType;
144 paperinit(); 148 paperinit();
145 paperType = paperinfo(systempapername()); 149 paperType = paperinfo(systempapername());
146 psPaperWidth = (int)paperpswidth(paperType); 150 psPaperWidth = (int)paperpswidth(paperType);
147 psPaperHeight = (int)paperpsheight(paperType); 151 psPaperHeight = (int)paperpsheight(paperType);
@@ -151,24 +155,30 @@ GlobalParams::GlobalParams(char *cfgFileName) {
151 psPaperHeight = defPaperHeight; 155 psPaperHeight = defPaperHeight;
152#endif 156#endif
153 psDuplex = gFalse; 157 psDuplex = gFalse;
154 psLevel = psLevel2; 158 psLevel = psLevel2;
155 psFile = NULL; 159 psFile = NULL;
156 psFonts = new GHash(); 160 psFonts = new GHash();
161 psNamedFonts16 = new GList();
162 psFonts16 = new GList();
157 psEmbedType1 = gTrue; 163 psEmbedType1 = gTrue;
158 psEmbedTrueType = gTrue; 164 psEmbedTrueType = gTrue;
165 psEmbedCIDPostScript = gTrue;
166 psEmbedCIDTrueType = gTrue;
159 psOPI = gFalse; 167 psOPI = gFalse;
168 psASCIIHex = gFalse;
160 textEncoding = new GString("Latin1"); 169 textEncoding = new GString("Latin1");
161#if defined(WIN32) 170#if defined(WIN32)
162 textEOL = eolDOS; 171 textEOL = eolDOS;
163#elif defined(MACOS) 172#elif defined(MACOS)
164 textEOL = eolMac; 173 textEOL = eolMac;
165#else 174#else
166 textEOL = eolUnix; 175 textEOL = eolUnix;
167#endif 176#endif
168 fontDirs = new GList(); 177 fontDirs = new GList();
178 initialZoom = new GString("1");
169 t1libControl = fontRastAALow; 179 t1libControl = fontRastAALow;
170 freetypeControl = fontRastAALow; 180 freetypeControl = fontRastAALow;
171 urlCommand = NULL; 181 urlCommand = NULL;
172 mapNumericCharNames = gTrue; 182 mapNumericCharNames = gTrue;
173 errQuiet = gFalse; 183 errQuiet = gFalse;
174 184
@@ -190,12 +200,14 @@ GlobalParams::GlobalParams(char *cfgFileName) {
190 residentUnicodeMaps->add(map->getEncodingName(), map); 200 residentUnicodeMaps->add(map->getEncodingName(), map);
191 map = new UnicodeMap("ZapfDingbats", zapfDingbatsUnicodeMapRanges, 201 map = new UnicodeMap("ZapfDingbats", zapfDingbatsUnicodeMapRanges,
192 zapfDingbatsUnicodeMapLen); 202 zapfDingbatsUnicodeMapLen);
193 residentUnicodeMaps->add(map->getEncodingName(), map); 203 residentUnicodeMaps->add(map->getEncodingName(), map);
194 map = new UnicodeMap("UTF-8", &mapUTF8); 204 map = new UnicodeMap("UTF-8", &mapUTF8);
195 residentUnicodeMaps->add(map->getEncodingName(), map); 205 residentUnicodeMaps->add(map->getEncodingName(), map);
206 map = new UnicodeMap("UCS-2", &mapUCS2);
207 residentUnicodeMaps->add(map->getEncodingName(), map);
196 208
197 // default displayFonts table 209 // default displayFonts table
198 for (i = 0; displayFontTab[i].name; ++i) { 210 for (i = 0; displayFontTab[i].name; ++i) {
199 dfp = new DisplayFontParam(displayFontTab[i].name, 211 dfp = new DisplayFontParam(displayFontTab[i].name,
200 displayFontTab[i].xlfd, 212 displayFontTab[i].xlfd,
201 displayFontTab[i].encoding); 213 displayFontTab[i].encoding);
@@ -216,12 +228,13 @@ GlobalParams::GlobalParams(char *cfgFileName) {
216 if (!(f = fopen(fileName->getCString(), "r"))) { 228 if (!(f = fopen(fileName->getCString(), "r"))) {
217 delete fileName; 229 delete fileName;
218 } 230 }
219 } 231 }
220 if (!f) { 232 if (!f) {
221#if defined(WIN32) && !defined(__CYGWIN32__) 233#if defined(WIN32) && !defined(__CYGWIN32__)
234 char buf[512];
222 i = GetModuleFileName(NULL, buf, sizeof(buf)); 235 i = GetModuleFileName(NULL, buf, sizeof(buf));
223 if (i <= 0 || i >= sizeof(buf)) { 236 if (i <= 0 || i >= sizeof(buf)) {
224 // error or path too long for buffer - just use the current dir 237 // error or path too long for buffer - just use the current dir
225 buf[i] = '\0'; 238 buf[i] = '\0';
226 } 239 }
227 fileName = grabPath(buf); 240 fileName = grabPath(buf);
@@ -231,104 +244,147 @@ GlobalParams::GlobalParams(char *cfgFileName) {
231#endif 244#endif
232 if (!(f = fopen(fileName->getCString(), "r"))) { 245 if (!(f = fopen(fileName->getCString(), "r"))) {
233 delete fileName; 246 delete fileName;
234 } 247 }
235 } 248 }
236 if (f) { 249 if (f) {
237 line = 1; 250 parseFile(fileName, f);
238 while (fgets(buf, sizeof(buf) - 1, f)) { 251 delete fileName;
239 252 }
240 // break the line into tokens 253}
241 tokens = new GList(); 254
242 p1 = buf; 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
332void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName, 388void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
333 int line) { 389 int line) {
334 GString *name; 390 GString *name;
@@ -423,13 +479,13 @@ void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
423 fileName->getCString(), line); 479 fileName->getCString(), line);
424 return; 480 return;
425 } 481 }
426 toUnicodeDirs->append(((GString *)tokens->get(1))->copy()); 482 toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
427} 483}
428 484
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;
433 489
434 if (tokens->getLength() < 2) { 490 if (tokens->getLength() < 2) {
435 goto err1; 491 goto err1;
@@ -455,29 +511,22 @@ void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
455 goto err2; 511 goto err2;
456 } 512 }
457 param->tt.fileName = ((GString *)tokens->get(2))->copy(); 513 param->tt.fileName = ((GString *)tokens->get(2))->copy();
458 break; 514 break;
459 } 515 }
460 516
461 if (isCID) { 517 if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
462 if ((old = (DisplayFontParam *)displayCIDFonts->remove(param->name))) { 518 delete old;
463 delete old;
464 }
465 displayCIDFonts->add(param->name, param);
466 } else {
467 if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
468 delete old;
469 }
470 displayFonts->add(param->name, param);
471 } 519 }
520 fontHash->add(param->name, param);
472 return; 521 return;
473 522
474 err2: 523 err2:
475 delete param; 524 delete param;
476 err1: 525 err1:
477 error(-1, "Bad 'displayFont...' config file command (%s:%d)", 526 error(-1, "Bad 'display*Font*' config file command (%s:%d)",
478 fileName->getCString(), line); 527 fileName->getCString(), line);
479} 528}
480 529
481void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName, 530void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
482 int line) { 531 int line) {
483 GString *tok; 532 GString *tok;
@@ -513,12 +562,16 @@ void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
513 } else if (!tok->cmp("level1sep")) { 562 } else if (!tok->cmp("level1sep")) {
514 psLevel = psLevel1Sep; 563 psLevel = psLevel1Sep;
515 } else if (!tok->cmp("level2")) { 564 } else if (!tok->cmp("level2")) {
516 psLevel = psLevel2; 565 psLevel = psLevel2;
517 } else if (!tok->cmp("level2sep")) { 566 } else if (!tok->cmp("level2sep")) {
518 psLevel = psLevel2Sep; 567 psLevel = psLevel2Sep;
568 } else if (!tok->cmp("level3")) {
569 psLevel = psLevel3;
570 } else if (!tok->cmp("level3Sep")) {
571 psLevel = psLevel3Sep;
519 } else { 572 } else {
520 error(-1, "Bad 'psLevel' config file command (%s:%d)", 573 error(-1, "Bad 'psLevel' config file command (%s:%d)",
521 fileName->getCString(), line); 574 fileName->getCString(), line);
522 } 575 }
523} 576}
524 577
@@ -539,17 +592,45 @@ void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
539 592
540 if (tokens->getLength() != 3) { 593 if (tokens->getLength() != 3) {
541 error(-1, "Bad 'psFont' config file command (%s:%d)", 594 error(-1, "Bad 'psFont' config file command (%s:%d)",
542 fileName->getCString(), line); 595 fileName->getCString(), line);
543 return; 596 return;
544 } 597 }
545 param = new PSFontParam(((GString *)tokens->get(1))->copy(), 598 param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
546 ((GString *)tokens->get(2))->copy()); 599 ((GString *)tokens->get(2))->copy(), NULL);
547 psFonts->add(param->pdfFontName, param); 600 psFonts->add(param->pdfFontName, param);
548} 601}
549 602
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) {
553 error(-1, "Bad 'textEncoding' config file command (%s:%d)", 634 error(-1, "Bad 'textEncoding' config file command (%s:%d)",
554 fileName->getCString(), line); 635 fileName->getCString(), line);
555 return; 636 return;
@@ -585,23 +666,21 @@ void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
585 fileName->getCString(), line); 666 fileName->getCString(), line);
586 return; 667 return;
587 } 668 }
588 fontDirs->append(((GString *)tokens->get(1))->copy()); 669 fontDirs->append(((GString *)tokens->get(1))->copy());
589} 670}
590 671
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,
605 GList *tokens, GString *fileName, 684 GList *tokens, GString *fileName,
606 int line) { 685 int line) {
607 GString *tok; 686 GString *tok;
@@ -615,12 +694,25 @@ void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val,
615 if (!setFontRastControl(val, tok->getCString())) { 694 if (!setFontRastControl(val, tok->getCString())) {
616 error(-1, "Bad '%s' config file command (%s:%d)", 695 error(-1, "Bad '%s' config file command (%s:%d)",
617 cmdName, fileName->getCString(), line); 696 cmdName, fileName->getCString(), line);
618 } 697 }
619} 698}
620 699
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;
624 716
625 if (tokens->getLength() != 2) { 717 if (tokens->getLength() != 2) {
626 error(-1, "Bad '%s' config file command (%s:%d)", 718 error(-1, "Bad '%s' config file command (%s:%d)",
@@ -651,18 +743,22 @@ GlobalParams::~GlobalParams() {
651 deleteGHash(cidToUnicodes, GString); 743 deleteGHash(cidToUnicodes, GString);
652 deleteGHash(residentUnicodeMaps, UnicodeMap); 744 deleteGHash(residentUnicodeMaps, UnicodeMap);
653 deleteGHash(unicodeMaps, GString); 745 deleteGHash(unicodeMaps, GString);
654 deleteGList(toUnicodeDirs, GString); 746 deleteGList(toUnicodeDirs, GString);
655 deleteGHash(displayFonts, DisplayFontParam); 747 deleteGHash(displayFonts, DisplayFontParam);
656 deleteGHash(displayCIDFonts, DisplayFontParam); 748 deleteGHash(displayCIDFonts, DisplayFontParam);
749 deleteGHash(displayNamedCIDFonts, DisplayFontParam);
657 if (psFile) { 750 if (psFile) {
658 delete psFile; 751 delete psFile;
659 } 752 }
660 deleteGHash(psFonts, PSFontParam); 753 deleteGHash(psFonts, PSFontParam);
754 deleteGList(psNamedFonts16, PSFontParam);
755 deleteGList(psFonts16, PSFontParam);
661 delete textEncoding; 756 delete textEncoding;
662 deleteGList(fontDirs, GString); 757 deleteGList(fontDirs, GString);
758 delete initialZoom;
663 if (urlCommand) { 759 if (urlCommand) {
664 delete urlCommand; 760 delete urlCommand;
665 } 761 }
666 762
667 cMapDirs->startIter(&iter); 763 cMapDirs->startIter(&iter);
668 while (cMapDirs->getNext(&iter, &key, (void **)&list)) { 764 while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
@@ -749,20 +845,56 @@ FILE *GlobalParams::findToUnicodeFile(GString *name) {
749} 845}
750 846
751DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) { 847DisplayFontParam *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;
766 FILE *f; 898 FILE *f;
767 int i; 899 int i;
768 900
@@ -863,16 +995,28 @@ void GlobalParams::setPSEmbedType1(GBool embed) {
863} 995}
864 996
865void GlobalParams::setPSEmbedTrueType(GBool embed) { 997void 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);
876} 1020}
877 1021
878GBool GlobalParams::setTextEOL(char *s) { 1022GBool GlobalParams::setTextEOL(char *s) {
@@ -885,12 +1029,17 @@ GBool GlobalParams::setTextEOL(char *s) {
885 } else { 1029 } else {
886 return gFalse; 1030 return gFalse;
887 } 1031 }
888 return gTrue; 1032 return gTrue;
889} 1033}
890 1034
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}
894 1043
895GBool GlobalParams::setFreeTypeControl(char *s) { 1044GBool GlobalParams::setFreeTypeControl(char *s) {
896 return setFontRastControl(&freetypeControl, s); 1045 return setFontRastControl(&freetypeControl, s);
diff --git a/noncore/unsupported/qpdf/xpdf/GlobalParams.h b/noncore/unsupported/qpdf/xpdf/GlobalParams.h
index ecbb5fc..b651110 100644
--- a/noncore/unsupported/qpdf/xpdf/GlobalParams.h
+++ b/noncore/unsupported/qpdf/xpdf/GlobalParams.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// GlobalParams.h 3// GlobalParams.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef GLOBALPARAMS_H 9#ifndef GLOBALPARAMS_H
10#define GLOBALPARAMS_H 10#define GLOBALPARAMS_H
11 11
@@ -42,14 +42,15 @@ enum DisplayFontParamKind {
42 displayFontTT 42 displayFontTT
43}; 43};
44 44
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 {
53 GString *xlfd; 54 GString *xlfd;
54 GString *encoding; 55 GString *encoding;
55 } x; 56 } x;
@@ -76,26 +77,34 @@ enum FontRastControl {
76 77
77//------------------------------------------------------------------------ 78//------------------------------------------------------------------------
78 79
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
89//------------------------------------------------------------------------ 96//------------------------------------------------------------------------
90 97
91enum PSLevel { 98enum PSLevel {
92 psLevel1, 99 psLevel1,
93 psLevel1Sep, 100 psLevel1Sep,
94 psLevel2, 101 psLevel2,
95 psLevel2Sep 102 psLevel2Sep,
103 psLevel3,
104 psLevel3Sep
96}; 105};
97 106
98//------------------------------------------------------------------------ 107//------------------------------------------------------------------------
99 108
100enum EndOfLineKind { 109enum EndOfLineKind {
101 eolUnix, // LF 110 eolUnix, // LF
@@ -122,25 +131,30 @@ public:
122 FILE *getCIDToUnicodeFile(GString *collection); 131 FILE *getCIDToUnicodeFile(GString *collection);
123 UnicodeMap *getResidentUnicodeMap(GString *encodingName); 132 UnicodeMap *getResidentUnicodeMap(GString *encodingName);
124 FILE *getUnicodeMapFile(GString *encodingName); 133 FILE *getUnicodeMapFile(GString *encodingName);
125 FILE *findCMapFile(GString *collection, GString *cMapName); 134 FILE *findCMapFile(GString *collection, GString *cMapName);
126 FILE *findToUnicodeFile(GString *name); 135 FILE *findToUnicodeFile(GString *name);
127 DisplayFontParam *getDisplayFont(GString *fontName); 136 DisplayFontParam *getDisplayFont(GString *fontName);
128 DisplayFontParam *getDisplayCIDFont(GString *collection); 137 DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection);
129 GString *getPSFile() { return psFile; } 138 GString *getPSFile() { return psFile; }
130 int getPSPaperWidth() { return psPaperWidth; } 139 int getPSPaperWidth() { return psPaperWidth; }
131 int getPSPaperHeight() { return psPaperHeight; } 140 int getPSPaperHeight() { return psPaperHeight; }
132 GBool getPSDuplex() { return psDuplex; } 141 GBool getPSDuplex() { return psDuplex; }
133 PSLevel getPSLevel() { return psLevel; } 142 PSLevel getPSLevel() { return psLevel; }
134 PSFontParam *getPSFont(GString *fontName); 143 PSFontParam *getPSFont(GString *fontName);
144 PSFontParam *getPSFont16(GString *fontName, GString *collection, int wMode);
135 GBool getPSEmbedType1() { return psEmbedType1; } 145 GBool getPSEmbedType1() { return psEmbedType1; }
136 GBool getPSEmbedTrueType() { return psEmbedTrueType; } 146 GBool getPSEmbedTrueType() { return psEmbedTrueType; }
147 GBool getPSEmbedCIDPostScript() { return psEmbedCIDPostScript; }
148 GBool getPSEmbedCIDTrueType() { return psEmbedCIDTrueType; }
137 GBool getPSOPI() { return psOPI; } 149 GBool getPSOPI() { return psOPI; }
150 GBool getPSASCIIHex() { return psASCIIHex; }
138 GString *getTextEncodingName() { return textEncoding; } 151 GString *getTextEncodingName() { return textEncoding; }
139 EndOfLineKind getTextEOL() { return textEOL; } 152 EndOfLineKind getTextEOL() { return textEOL; }
140 GString *findFontFile(GString *fontName, char *ext1, char *ext2); 153 GString *findFontFile(GString *fontName, char *ext1, char *ext2);
154 GString *getInitialZoom() { return initialZoom; }
141 FontRastControl getT1libControl() { return t1libControl; } 155 FontRastControl getT1libControl() { return t1libControl; }
142 FontRastControl getFreeTypeControl() { return freetypeControl; } 156 FontRastControl getFreeTypeControl() { return freetypeControl; }
143 GString *getURLCommand() { return urlCommand; } 157 GString *getURLCommand() { return urlCommand; }
144 GBool getMapNumericCharNames() { return mapNumericCharNames; } 158 GBool getMapNumericCharNames() { return mapNumericCharNames; }
145 GBool getErrQuiet() { return errQuiet; } 159 GBool getErrQuiet() { return errQuiet; }
146 160
@@ -156,35 +170,44 @@ public:
156 void setPSPaperWidth(int width); 170 void setPSPaperWidth(int width);
157 void setPSPaperHeight(int height); 171 void setPSPaperHeight(int height);
158 void setPSDuplex(GBool duplex); 172 void setPSDuplex(GBool duplex);
159 void setPSLevel(PSLevel level); 173 void setPSLevel(PSLevel level);
160 void setPSEmbedType1(GBool embed); 174 void setPSEmbedType1(GBool embed);
161 void setPSEmbedTrueType(GBool embed); 175 void setPSEmbedTrueType(GBool embed);
176 void setPSEmbedCIDPostScript(GBool embed);
177 void setPSEmbedCIDTrueType(GBool embed);
162 void setPSOPI(GBool opi); 178 void setPSOPI(GBool opi);
179 void setPSASCIIHex(GBool hex);
163 void setTextEncoding(char *encodingName); 180 void setTextEncoding(char *encodingName);
164 GBool setTextEOL(char *s); 181 GBool setTextEOL(char *s);
182 void setInitialZoom(char *s);
165 GBool setT1libControl(char *s); 183 GBool setT1libControl(char *s);
166 GBool setFreeTypeControl(char *s); 184 GBool setFreeTypeControl(char *s);
167 void setErrQuiet(GBool errQuietA); 185 void setErrQuiet(GBool errQuietA);
168 186
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);
188 void parseYesNo(char *cmdName, GBool *flag, 211 void parseYesNo(char *cmdName, GBool *flag,
189 GList *tokens, GString *fileName, int line); 212 GList *tokens, GString *fileName, int line);
190 GBool setFontRastControl(FontRastControl *val, char *s); 213 GBool setFontRastControl(FontRastControl *val, char *s);
@@ -209,27 +232,35 @@ private:
209 // name [GList[GString]] 232 // name [GList[GString]]
210 GList *toUnicodeDirs; // list of ToUnicode CMap dirs [GString] 233 GList *toUnicodeDirs; // list of ToUnicode CMap dirs [GString]
211 GHash *displayFonts; // display font info, indexed by font name 234 GHash *displayFonts; // display font info, indexed by font name
212 // [DisplayFontParam] 235 // [DisplayFontParam]
213 GHash *displayCIDFonts;// display CID font info, indexed by 236 GHash *displayCIDFonts;// display CID font info, indexed by
214 // collection [DisplayFontParam] 237 // collection [DisplayFontParam]
238 GHash *displayNamedCIDFonts;// display CID font info, indexed by
239 // font name [DisplayFontParam]
215 GString *psFile; // PostScript file or command (for xpdf) 240 GString *psFile; // PostScript file or command (for xpdf)
216 int psPaperWidth; // paper size, in PostScript points, for 241 int psPaperWidth; // paper size, in PostScript points, for
217 int psPaperHeight; // PostScript output 242 int psPaperHeight; // PostScript output
218 GBool psDuplex; // enable duplexing in PostScript? 243 GBool psDuplex; // enable duplexing in PostScript?
219 PSLevel psLevel; // PostScript level to generate 244 PSLevel psLevel; // PostScript level to generate
220 GHash *psFonts; // PostScript font info, indexed by PDF 245 GHash *psFonts; // PostScript font info, indexed by PDF
221 // font name [PSFontParam] 246 // font name [PSFontParam]
247 GList *psNamedFonts16;// named 16-bit fonts [PSFontParam]
248 GList *psFonts16; // generic 16-bit fonts [PSFontParam]
222 GBool psEmbedType1; // embed Type 1 fonts? 249 GBool psEmbedType1; // embed Type 1 fonts?
223 GBool psEmbedTrueType;// embed TrueType fonts? 250 GBool psEmbedTrueType;// embed TrueType fonts?
251 GBool psEmbedCIDPostScript;// embed CID PostScript fonts?
252 GBool psEmbedCIDTrueType;// embed CID TrueType fonts?
224 GBool psOPI; // generate PostScript OPI comments? 253 GBool psOPI; // generate PostScript OPI comments?
254 GBool psASCIIHex; // use ASCIIHex instead of ASCII85?
225 GString *textEncoding;// encoding (unicodeMap) to use for text 255 GString *textEncoding;// encoding (unicodeMap) to use for text
226 // output 256 // output
227 EndOfLineKind textEOL;// type of EOL marker to use for text 257 EndOfLineKind textEOL;// type of EOL marker to use for text
228 // output 258 // output
229 GList *fontDirs; // list of font dirs [GString] 259 GList *fontDirs; // list of font dirs [GString]
260 GString *initialZoom; // initial zoom level
230 FontRastControl t1libControl;// t1lib rasterization mode 261 FontRastControl t1libControl;// t1lib rasterization mode
231 FontRastControl // FreeType rasterization mode 262 FontRastControl // FreeType rasterization mode
232 freetypeControl; 263 freetypeControl;
233 GString *urlCommand; // command executed for URL links 264 GString *urlCommand; // command executed for URL links
234 GBool mapNumericCharNames;// map numeric char names (from font subsets)? 265 GBool mapNumericCharNames;// map numeric char names (from font subsets)?
235 GBool errQuiet; // suppress error messages? 266 GBool errQuiet; // suppress error messages?
diff --git a/noncore/unsupported/qpdf/xpdf/Lexer.cc b/noncore/unsupported/qpdf/xpdf/Lexer.cc
index fff4bcb..a258950 100644
--- a/noncore/unsupported/qpdf/xpdf/Lexer.cc
+++ b/noncore/unsupported/qpdf/xpdf/Lexer.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Lexer.cc 3// Lexer.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
diff --git a/noncore/unsupported/qpdf/xpdf/Lexer.h b/noncore/unsupported/qpdf/xpdf/Lexer.h
index 5edbeda..8a01ab2 100644
--- a/noncore/unsupported/qpdf/xpdf/Lexer.h
+++ b/noncore/unsupported/qpdf/xpdf/Lexer.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Lexer.h 3// Lexer.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef LEXER_H 9#ifndef LEXER_H
10#define LEXER_H 10#define LEXER_H
11 11
@@ -48,19 +48,20 @@ public:
48 void skipChar() { getChar(); } 48 void skipChar() { getChar(); }
49 49
50 // Get stream. 50 // Get stream.
51 Stream *getStream() 51 Stream *getStream()
52 { return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); } 52 { return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); }
53 53
54 // Get current position in file. 54 // Get current position in file. This is only used for error
55 // messages, so it returns an int instead of a Guint.
55 int getPos() 56 int getPos()
56 { return curStr.isNone() ? -1 : curStr.streamGetPos(); } 57 { return curStr.isNone() ? -1 : (int)curStr.streamGetPos(); }
57 58
58 // Set position in file. 59 // Set position in file.
59 void setPos(int pos) 60 void setPos(Guint pos, int dir = 0)
60 { if (!curStr.isNone()) curStr.streamSetPos(pos); } 61 { if (!curStr.isNone()) curStr.streamSetPos(pos, dir); }
61 62
62private: 63private:
63 64
64 int getChar(); 65 int getChar();
65 int lookChar(); 66 int lookChar();
66 67
diff --git a/noncore/unsupported/qpdf/xpdf/Link.cc b/noncore/unsupported/qpdf/xpdf/Link.cc
index 79a5f6e..c25ec43 100644
--- a/noncore/unsupported/qpdf/xpdf/Link.cc
+++ b/noncore/unsupported/qpdf/xpdf/Link.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Link.cc 3// Link.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -26,37 +26,33 @@
26static GString *getFileSpecName(Object *fileSpecObj); 26static GString *getFileSpecName(Object *fileSpecObj);
27 27
28//------------------------------------------------------------------------ 28//------------------------------------------------------------------------
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);
60 56
61 // XYZ link 57 // XYZ link
62 if (obj1.isName("XYZ")) { 58 if (obj1.isName("XYZ")) {
@@ -218,13 +214,13 @@ LinkGoTo::LinkGoTo(Object *destObj) {
218 namedDest = new GString(destObj->getName()); 214 namedDest = new GString(destObj->getName());
219 } else if (destObj->isString()) { 215 } else if (destObj->isString()) {
220 namedDest = destObj->getString()->copy(); 216 namedDest = destObj->getString()->copy();
221 217
222 // destination dictionary 218 // destination dictionary
223 } else if (destObj->isArray()) { 219 } else if (destObj->isArray()) {
224 dest = new LinkDest(destObj->getArray(), gTrue); 220 dest = new LinkDest(destObj->getArray());
225 if (!dest->isOk()) { 221 if (!dest->isOk()) {
226 delete dest; 222 delete dest;
227 dest = NULL; 223 dest = NULL;
228 } 224 }
229 225
230 // error 226 // error
@@ -256,13 +252,13 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
256 namedDest = new GString(destObj->getName()); 252 namedDest = new GString(destObj->getName());
257 } else if (destObj->isString()) { 253 } else if (destObj->isString()) {
258 namedDest = destObj->getString()->copy(); 254 namedDest = destObj->getString()->copy();
259 255
260 // destination dictionary 256 // destination dictionary
261 } else if (destObj->isArray()) { 257 } else if (destObj->isArray()) {
262 dest = new LinkDest(destObj->getArray(), gFalse); 258 dest = new LinkDest(destObj->getArray());
263 if (!dest->isOk()) { 259 if (!dest->isOk()) {
264 delete dest; 260 delete dest;
265 dest = NULL; 261 dest = NULL;
266 } 262 }
267 263
268 // error 264 // error
@@ -443,13 +439,13 @@ Link::Link(Dict *dict, GString *baseURI) {
443 t = y1; 439 t = y1;
444 y1 = y2; 440 y1 = y2;
445 y2 = t; 441 y2 = t;
446 } 442 }
447 443
448 // get border 444 // get border
449 borderW = 0; 445 borderW = 1;
450 if (!dict->lookup("Border", &obj1)->isNull()) { 446 if (!dict->lookup("Border", &obj1)->isNull()) {
451 if (obj1.isArray() && obj1.arrayGetLength() >= 3) { 447 if (obj1.isArray() && obj1.arrayGetLength() >= 3) {
452 if (obj1.arrayGet(2, &obj2)->isNum()) { 448 if (obj1.arrayGet(2, &obj2)->isNum()) {
453 borderW = obj2.getNum(); 449 borderW = obj2.getNum();
454 } else { 450 } else {
455 error(-1, "Bad annotation border"); 451 error(-1, "Bad annotation border");
@@ -579,13 +575,13 @@ Links::~Links() {
579 gfree(links); 575 gfree(links);
580} 576}
581 577
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 }
589 } 585 }
590 return NULL; 586 return NULL;
591} 587}
diff --git a/noncore/unsupported/qpdf/xpdf/Link.h b/noncore/unsupported/qpdf/xpdf/Link.h
index 0ad4581..7b5ba86 100644
--- a/noncore/unsupported/qpdf/xpdf/Link.h
+++ b/noncore/unsupported/qpdf/xpdf/Link.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Link.h 3// Link.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef LINK_H 9#ifndef LINK_H
10#define LINK_H 10#define LINK_H
11 11
@@ -60,16 +60,14 @@ enum LinkDestKind {
60 destFitBV 60 destFitBV
61}; 61};
62 62
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); }
73 71
74 // Was the LinkDest created successfully? 72 // Was the LinkDest created successfully?
75 GBool isOk() { return ok; } 73 GBool isOk() { return ok; }
diff --git a/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc b/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc
index 06be2f4..b9cde77 100644
--- a/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc
+++ b/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// NameToCharCode.cc 3// NameToCharCode.cc
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
diff --git a/noncore/unsupported/qpdf/xpdf/NameToCharCode.h b/noncore/unsupported/qpdf/xpdf/NameToCharCode.h
index 9f9b1c3..22e41b6 100644
--- a/noncore/unsupported/qpdf/xpdf/NameToCharCode.h
+++ b/noncore/unsupported/qpdf/xpdf/NameToCharCode.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// NameToCharCode.h 3// NameToCharCode.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef NAMETOCHARCODE_H 9#ifndef NAMETOCHARCODE_H
10#define NAMETOCHARCODE_H 10#define NAMETOCHARCODE_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h b/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h
index 7ca635e..432fafb 100644
--- a/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h
+++ b/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// NameToUnicodeTable.h 3// NameToUnicodeTable.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9static struct { 9static struct {
10 Unicode u; 10 Unicode u;
11 char *name; 11 char *name;
diff --git a/noncore/unsupported/qpdf/xpdf/Object.cc b/noncore/unsupported/qpdf/xpdf/Object.cc
index 5ecade3..6d92c6a 100644
--- a/noncore/unsupported/qpdf/xpdf/Object.cc
+++ b/noncore/unsupported/qpdf/xpdf/Object.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Object.cc 3// Object.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
diff --git a/noncore/unsupported/qpdf/xpdf/Object.h b/noncore/unsupported/qpdf/xpdf/Object.h
index 000ffa0..7a67a7d 100644
--- a/noncore/unsupported/qpdf/xpdf/Object.h
+++ b/noncore/unsupported/qpdf/xpdf/Object.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Object.h 3// Object.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef OBJECT_H 9#ifndef OBJECT_H
10#define OBJECT_H 10#define OBJECT_H
11 11
@@ -173,14 +173,14 @@ public:
173 GBool streamIs(char *dictType); 173 GBool streamIs(char *dictType);
174 void streamReset(); 174 void streamReset();
175 void streamClose(); 175 void streamClose();
176 int streamGetChar(); 176 int streamGetChar();
177 int streamLookChar(); 177 int streamLookChar();
178 char *streamGetLine(char *buf, int size); 178 char *streamGetLine(char *buf, int size);
179 int streamGetPos(); 179 Guint streamGetPos();
180 void streamSetPos(int pos); 180 void streamSetPos(Guint pos, int dir = 0);
181 Dict *streamGetDict(); 181 Dict *streamGetDict();
182 182
183 // Output. 183 // Output.
184 char *getTypeName(); 184 char *getTypeName();
185 void print(FILE *f = stdout); 185 void print(FILE *f = stdout);
186 186
@@ -284,16 +284,16 @@ inline int Object::streamGetChar()
284inline int Object::streamLookChar() 284inline int Object::streamLookChar()
285 { return stream->lookChar(); } 285 { return stream->lookChar(); }
286 286
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(); }
298 298
299#endif 299#endif
diff --git a/noncore/unsupported/qpdf/xpdf/OutputDev.cc b/noncore/unsupported/qpdf/xpdf/OutputDev.cc
index 3c02835..1004f0f 100644
--- a/noncore/unsupported/qpdf/xpdf/OutputDev.cc
+++ b/noncore/unsupported/qpdf/xpdf/OutputDev.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// OutputDev.cc 3// OutputDev.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -56,12 +56,17 @@ void OutputDev::updateAll(GfxState *state) {
56 updateLineWidth(state); 56 updateLineWidth(state);
57 updateFillColor(state); 57 updateFillColor(state);
58 updateStrokeColor(state); 58 updateStrokeColor(state);
59 updateFont(state); 59 updateFont(state);
60} 60}
61 61
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) {
65 int i, j; 70 int i, j;
66 71
67 if (inlineImg) { 72 if (inlineImg) {
diff --git a/noncore/unsupported/qpdf/xpdf/OutputDev.h b/noncore/unsupported/qpdf/xpdf/OutputDev.h
index 04cbace..398c035 100644
--- a/noncore/unsupported/qpdf/xpdf/OutputDev.h
+++ b/noncore/unsupported/qpdf/xpdf/OutputDev.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// OutputDev.h 3// OutputDev.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef OUTPUTDEV_H 9#ifndef OUTPUTDEV_H
10#define OUTPUTDEV_H 10#define OUTPUTDEV_H
11 11
@@ -43,12 +43,16 @@ public:
43 // (Upside-down means (0,0) is the top left corner of the page.) 43 // (Upside-down means (0,0) is the top left corner of the page.)
44 virtual GBool upsideDown() = 0; 44 virtual GBool upsideDown() = 0;
45 45
46 // Does this device use drawChar() or drawString()? 46 // Does this device use drawChar() or drawString()?
47 virtual GBool useDrawChar() = 0; 47 virtual GBool useDrawChar() = 0;
48 48
49 // Does this device use beginType3Char/endType3Char? Otherwise,
50 // text in Type 3 fonts will be drawn with drawChar/drawString.
51 virtual GBool interpretType3Chars() = 0;
52
49 // Does this device need non-text content? 53 // Does this device need non-text content?
50 virtual GBool needNonText() { return gTrue; } 54 virtual GBool needNonText() { return gTrue; }
51 55
52 //----- initialization and control 56 //----- initialization and control
53 57
54 // Set default transform matrix. 58 // Set default transform matrix.
@@ -116,12 +120,15 @@ public:
116 virtual void endString(GfxState *state) {} 120 virtual void endString(GfxState *state) {}
117 virtual void drawChar(GfxState *state, fouble x, fouble y, 121 virtual void drawChar(GfxState *state, fouble x, fouble y,
118 fouble dx, fouble dy, 122 fouble dx, fouble dy,
119 fouble originX, fouble originY, 123 fouble originX, fouble originY,
120 CharCode code, Unicode *u, int uLen) {} 124 CharCode code, Unicode *u, int uLen) {}
121 virtual void drawString(GfxState *state, GString *s) {} 125 virtual void drawString(GfxState *state, GString *s) {}
126 virtual GBool beginType3Char(GfxState *state,
127 CharCode code, Unicode *u, int uLen);
128 virtual void endType3Char(GfxState *state) {}
122 129
123 //----- image drawing 130 //----- image drawing
124 virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, 131 virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
125 int width, int height, GBool invert, 132 int width, int height, GBool invert,
126 GBool inlineImg); 133 GBool inlineImg);
127 virtual void drawImage(GfxState *state, Object *ref, Stream *str, 134 virtual void drawImage(GfxState *state, Object *ref, Stream *str,
@@ -131,12 +138,20 @@ public:
131#if OPI_SUPPORT 138#if OPI_SUPPORT
132 //----- OPI functions 139 //----- OPI functions
133 virtual void opiBegin(GfxState *state, Dict *opiDict); 140 virtual void opiBegin(GfxState *state, Dict *opiDict);
134 virtual void opiEnd(GfxState *state, Dict *opiDict); 141 virtual void opiEnd(GfxState *state, Dict *opiDict);
135#endif 142#endif
136 143
144 //----- Type 3 font operators
145 virtual void type3D0(GfxState *state, fouble wx, fouble wy) {}
146 virtual void type3D1(GfxState *state, fouble wx, fouble wy,
147 fouble llx, fouble lly, fouble urx, fouble ury) {}
148
149 //----- PostScript XObjects
150 virtual void psXObject(Stream *psStream, Stream *level1Stream) {}
151
137private: 152private:
138 153
139 fouble defCTM[6]; // default coordinate transform matrix 154 fouble defCTM[6]; // default coordinate transform matrix
140 fouble defICTM[6]; // inverse of default CTM 155 fouble defICTM[6]; // inverse of default CTM
141}; 156};
142 157
diff --git a/noncore/unsupported/qpdf/xpdf/PDFDoc.cc b/noncore/unsupported/qpdf/xpdf/PDFDoc.cc
index 4bbe9b7..97dfa55 100644
--- a/noncore/unsupported/qpdf/xpdf/PDFDoc.cc
+++ b/noncore/unsupported/qpdf/xpdf/PDFDoc.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// PDFDoc.cc 3// PDFDoc.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -21,12 +21,13 @@
21#include "Catalog.h" 21#include "Catalog.h"
22#include "Stream.h" 22#include "Stream.h"
23#include "XRef.h" 23#include "XRef.h"
24#include "Link.h" 24#include "Link.h"
25#include "OutputDev.h" 25#include "OutputDev.h"
26#include "Error.h" 26#include "Error.h"
27#include "ErrorCodes.h"
27#include "Lexer.h" 28#include "Lexer.h"
28#include "Parser.h" 29#include "Parser.h"
29#include "PDFDoc.h" 30#include "PDFDoc.h"
30 31
31//------------------------------------------------------------------------ 32//------------------------------------------------------------------------
32 33
@@ -40,12 +41,13 @@
40PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword, 41PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
41 GString *userPassword, GBool printCommandsA) { 42 GString *userPassword, GBool printCommandsA) {
42 Object obj; 43 Object obj;
43 GString *fileName2; 44 GString *fileName2;
44 45
45 ok = gFalse; 46 ok = gFalse;
47 errCode = errNone;
46 48
47 file = NULL; 49 file = NULL;
48 str = NULL; 50 str = NULL;
49 xref = NULL; 51 xref = NULL;
50 catalog = NULL; 52 catalog = NULL;
51 links = NULL; 53 links = NULL;
@@ -54,40 +56,43 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
54 // try to open file 56 // try to open file
55 fileName = fileNameA; 57 fileName = fileNameA;
56 fileName2 = NULL; 58 fileName2 = NULL;
57#ifdef VMS 59#ifdef VMS
58 if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) { 60 if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) {
59 error(-1, "Couldn't open file '%s'", fileName->getCString()); 61 error(-1, "Couldn't open file '%s'", fileName->getCString());
62 errCode = errOpenFile;
60 return; 63 return;
61 } 64 }
62#else 65#else
63 if (!(file = fopen(fileName->getCString(), "rb"))) { 66 if (!(file = fopen(fileName->getCString(), "rb"))) {
64 fileName2 = fileName->copy(); 67 fileName2 = fileName->copy();
65 fileName2->lowerCase(); 68 fileName2->lowerCase();
66 if (!(file = fopen(fileName2->getCString(), "rb"))) { 69 if (!(file = fopen(fileName2->getCString(), "rb"))) {
67 fileName2->upperCase(); 70 fileName2->upperCase();
68 if (!(file = fopen(fileName2->getCString(), "rb"))) { 71 if (!(file = fopen(fileName2->getCString(), "rb"))) {
69 error(-1, "Couldn't open file '%s'", fileName->getCString()); 72 error(-1, "Couldn't open file '%s'", fileName->getCString());
70 delete fileName2; 73 delete fileName2;
74 errCode = errOpenFile;
71 return; 75 return;
72 } 76 }
73 } 77 }
74 delete fileName2; 78 delete fileName2;
75 } 79 }
76#endif 80#endif
77 81
78 // create stream 82 // create stream
79 obj.initNull(); 83 obj.initNull();
80 str = new FileStream(file, 0, -1, &obj); 84 str = new FileStream(file, 0, gFalse, 0, &obj);
81 85
82 ok = setup(ownerPassword, userPassword); 86 ok = setup(ownerPassword, userPassword);
83} 87}
84 88
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;
91 xref = NULL; 96 xref = NULL;
92 catalog = NULL; 97 catalog = NULL;
93 links = NULL; 98 links = NULL;
@@ -100,19 +105,21 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
100 checkHeader(); 105 checkHeader();
101 106
102 // read xref table 107 // read xref table
103 xref = new XRef(str, ownerPassword, userPassword); 108 xref = new XRef(str, ownerPassword, userPassword);
104 if (!xref->isOk()) { 109 if (!xref->isOk()) {
105 error(-1, "Couldn't read xref table"); 110 error(-1, "Couldn't read xref table");
111 errCode = xref->getErrorCode();
106 return gFalse; 112 return gFalse;
107 } 113 }
108 114
109 // read catalog 115 // read catalog
110 catalog = new Catalog(xref, printCommands); 116 catalog = new Catalog(xref, printCommands);
111 if (!catalog->isOk()) { 117 if (!catalog->isOk()) {
112 error(-1, "Couldn't read page catalog"); 118 error(-1, "Couldn't read page catalog");
119 errCode = errBadCatalog;
113 return gFalse; 120 return gFalse;
114 } 121 }
115 122
116 // done 123 // done
117 return gTrue; 124 return gTrue;
118} 125}
@@ -201,14 +208,15 @@ GBool PDFDoc::isLinearized() {
201 Parser *parser; 208 Parser *parser;
202 Object obj1, obj2, obj3, obj4, obj5; 209 Object obj1, obj2, obj3, obj4, obj5;
203 GBool lin; 210 GBool lin;
204 211
205 lin = gFalse; 212 lin = gFalse;
206 obj1.initNull(); 213 obj1.initNull();
207 parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), 214 parser = new Parser(xref,
208 -1, &obj1))); 215 new Lexer(xref,
216 str->makeSubStream(str->getStart(), gFalse, 0, &obj1)));
209 parser->getObj(&obj1); 217 parser->getObj(&obj1);
210 parser->getObj(&obj2); 218 parser->getObj(&obj2);
211 parser->getObj(&obj3); 219 parser->getObj(&obj3);
212 parser->getObj(&obj4); 220 parser->getObj(&obj4);
213 if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && 221 if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") &&
214 obj4.isDict()) { 222 obj4.isDict()) {
diff --git a/noncore/unsupported/qpdf/xpdf/PDFDoc.h b/noncore/unsupported/qpdf/xpdf/PDFDoc.h
index 592095e..3157683 100644
--- a/noncore/unsupported/qpdf/xpdf/PDFDoc.h
+++ b/noncore/unsupported/qpdf/xpdf/PDFDoc.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// PDFDoc.h 3// PDFDoc.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef PDFDOC_H 9#ifndef PDFDOC_H
10#define PDFDOC_H 10#define PDFDOC_H
11 11
@@ -39,12 +39,15 @@ public:
39 GString *userPassword = NULL, GBool printCommandsA = gFalse); 39 GString *userPassword = NULL, GBool printCommandsA = gFalse);
40 ~PDFDoc(); 40 ~PDFDoc();
41 41
42 // Was PDF document successfully opened? 42 // Was PDF document successfully opened?
43 GBool isOk() { return ok; } 43 GBool isOk() { return ok; }
44 44
45 // Get the error code (if isOk() returns false).
46 int getErrorCode() { return errCode; }
47
45 // Get file name. 48 // Get file name.
46 GString *getFileName() { return fileName; } 49 GString *getFileName() { return fileName; }
47 50
48 // Get the xref table. 51 // Get the xref table.
49 XRef *getXRef() { return xref; } 52 XRef *getXRef() { return xref; }
50 53
@@ -134,9 +137,10 @@ private:
134 XRef *xref; 137 XRef *xref;
135 Catalog *catalog; 138 Catalog *catalog;
136 Links *links; 139 Links *links;
137 GBool printCommands; 140 GBool printCommands;
138 141
139 GBool ok; 142 GBool ok;
143 int errCode;
140}; 144};
141 145
142#endif 146#endif
diff --git a/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc b/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc
new file mode 100644
index 0000000..8d654bd
--- a/dev/null
+++ b/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc
@@ -0,0 +1,133 @@
1//========================================================================
2//
3// PSTokenizer.cc
4//
5// Copyright 2002 Glyph & Cog, LLC
6//
7//========================================================================
8
9#ifdef __GNUC__
10#pragma implementation
11#endif
12
13#include <stdio.h>
14#include <stdlib.h>
15#include "PSTokenizer.h"
16
17//------------------------------------------------------------------------
18
19// A '1' in this array means the character is white space. A '1' or
20// '2' means the character ends a name or command.
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
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Page.cc 3// Page.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -17,13 +17,13 @@
17#include "Dict.h" 17#include "Dict.h"
18#include "XRef.h" 18#include "XRef.h"
19#include "Link.h" 19#include "Link.h"
20#include "OutputDev.h" 20#include "OutputDev.h"
21#ifndef PDF_PARSER_ONLY 21#ifndef PDF_PARSER_ONLY
22#include "Gfx.h" 22#include "Gfx.h"
23#include "FormWidget.h" 23#include "Annot.h"
24#endif 24#endif
25#include "Error.h" 25#include "Error.h"
26#include "Page.h" 26#include "Page.h"
27 27
28//------------------------------------------------------------------------ 28//------------------------------------------------------------------------
29// PageAttrs 29// PageAttrs
@@ -90,22 +90,36 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
90 rotate += 360; 90 rotate += 360;
91 } 91 }
92 while (rotate >= 360) { 92 while (rotate >= 360) {
93 rotate -= 360; 93 rotate -= 360;
94 } 94 }
95 95
96 // misc attributes
97 dict->lookup("LastModified", &lastModified);
98 dict->lookup("BoxColorInfo", &boxColorInfo);
99 dict->lookup("Group", &group);
100 dict->lookup("Metadata", &metadata);
101 dict->lookup("PieceInfo", &pieceInfo);
102 dict->lookup("SeparationInfo", &separationInfo);
103
96 // resource dictionary 104 // resource dictionary
97 dict->lookup("Resources", &obj1); 105 dict->lookup("Resources", &obj1);
98 if (obj1.isDict()) { 106 if (obj1.isDict()) {
99 resources.free(); 107 resources.free();
100 obj1.copy(&resources); 108 obj1.copy(&resources);
101 } 109 }
102 obj1.free(); 110 obj1.free();
103} 111}
104 112
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
109GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) { 123GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) {
110 PDFRectangle tmp; 124 PDFRectangle tmp;
111 Object obj1, obj2; 125 Object obj1, obj2;
@@ -206,13 +220,13 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
206#ifndef PDF_PARSER_ONLY 220#ifndef PDF_PARSER_ONLY
207 PDFRectangle *box, *cropBox; 221 PDFRectangle *box, *cropBox;
208 Gfx *gfx; 222 Gfx *gfx;
209 Object obj; 223 Object obj;
210 Link *link; 224 Link *link;
211 int i; 225 int i;
212 FormWidgets *formWidgets; 226 Annots *annotList;
213 227
214 box = getBox(); 228 box = getBox();
215 cropBox = getCropBox(); 229 cropBox = getCropBox();
216 230
217 if (printCommands) { 231 if (printCommands) {
218 printf("***** MediaBox = ll:%g,%g ur:%g,%g\n", 232 printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
@@ -244,24 +258,24 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
244 link = links->getLink(i); 258 link = links->getLink(i);
245 out->drawLink(link, catalog); 259 out->drawLink(link, catalog);
246 } 260 }
247 out->dump(); 261 out->dump();
248 } 262 }
249 263
250 // draw AcroForm widgets 264 // draw non-link annotations
251 //~ need to reset CTM ??? 265 //~ need to reset CTM ???
252 formWidgets = new FormWidgets(xref, annots.fetch(xref, &obj)); 266 annotList = new Annots(xref, annots.fetch(xref, &obj));
253 obj.free(); 267 obj.free();
254 if (printCommands && formWidgets->getNumWidgets() > 0) { 268 if (annotList->getNumAnnots() > 0) {
255 printf("***** AcroForm widgets\n"); 269 if (printCommands) {
256 } 270 printf("***** Annotations\n");
257 for (i = 0; i < formWidgets->getNumWidgets(); ++i) { 271 }
258 formWidgets->getWidget(i)->draw(gfx); 272 for (i = 0; i < annotList->getNumAnnots(); ++i) {
259 } 273 annotList->getAnnot(i)->draw(gfx);
260 if (formWidgets->getNumWidgets() > 0) { 274 }
261 out->dump(); 275 out->dump();
262 } 276 }
263 delete formWidgets; 277 delete annotList;
264 278
265 delete gfx; 279 delete gfx;
266#endif 280#endif
267} 281}
diff --git a/noncore/unsupported/qpdf/xpdf/Page.h b/noncore/unsupported/qpdf/xpdf/Page.h
index 203878f..57e802a 100644
--- a/noncore/unsupported/qpdf/xpdf/Page.h
+++ b/noncore/unsupported/qpdf/xpdf/Page.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Page.h 3// Page.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef PAGE_H 9#ifndef PAGE_H
10#define PAGE_H 10#define PAGE_H
11 11
@@ -48,12 +48,26 @@ public:
48 PDFRectangle *getCropBox() { return &cropBox; } 48 PDFRectangle *getCropBox() { return &cropBox; }
49 GBool isCropped() { return haveCropBox; } 49 GBool isCropped() { return haveCropBox; }
50 PDFRectangle *getBleedBox() { return &bleedBox; } 50 PDFRectangle *getBleedBox() { return &bleedBox; }
51 PDFRectangle *getTrimBox() { return &trimBox; } 51 PDFRectangle *getTrimBox() { return &trimBox; }
52 PDFRectangle *getArtBox() { return &artBox; } 52 PDFRectangle *getArtBox() { return &artBox; }
53 int getRotate() { return rotate; } 53 int getRotate() { return rotate; }
54 GString *getLastModified()
55 { return lastModified.isString()
56 ? lastModified.getString() : (GString *)NULL; }
57 Dict *getBoxColorInfo()
58 { return boxColorInfo.isDict() ? boxColorInfo.getDict() : (Dict *)NULL; }
59 Dict *getGroup()
60 { return group.isDict() ? group.getDict() : (Dict *)NULL; }
61 Stream *getMetadata()
62 { return metadata.isStream() ? metadata.getStream() : (Stream *)NULL; }
63 Dict *getPieceInfo()
64 { return pieceInfo.isDict() ? pieceInfo.getDict() : (Dict *)NULL; }
65 Dict *getSeparationInfo()
66 { return separationInfo.isDict()
67 ? separationInfo.getDict() : (Dict *)NULL; }
54 Dict *getResourceDict() 68 Dict *getResourceDict()
55 { return resources.isDict() ? resources.getDict() : (Dict *)NULL; } 69 { return resources.isDict() ? resources.getDict() : (Dict *)NULL; }
56 70
57private: 71private:
58 72
59 GBool readBox(Dict *dict, char *key, PDFRectangle *box); 73 GBool readBox(Dict *dict, char *key, PDFRectangle *box);
@@ -63,12 +77,18 @@ private:
63 GBool haveCropBox; 77 GBool haveCropBox;
64 GBool limitToCropBox; 78 GBool limitToCropBox;
65 PDFRectangle bleedBox; 79 PDFRectangle bleedBox;
66 PDFRectangle trimBox; 80 PDFRectangle trimBox;
67 PDFRectangle artBox; 81 PDFRectangle artBox;
68 int rotate; 82 int rotate;
83 Object lastModified;
84 Object boxColorInfo;
85 Object group;
86 Object metadata;
87 Object pieceInfo;
88 Object separationInfo;
69 Object resources; 89 Object resources;
70}; 90};
71 91
72//------------------------------------------------------------------------ 92//------------------------------------------------------------------------
73// Page 93// Page
74//------------------------------------------------------------------------ 94//------------------------------------------------------------------------
@@ -94,12 +114,18 @@ public:
94 fouble getWidth() { return attrs->getBox()->x2 - attrs->getBox()->x1; } 114 fouble getWidth() { return attrs->getBox()->x2 - attrs->getBox()->x1; }
95 fouble getHeight() { return attrs->getBox()->y2 - attrs->getBox()->y1; } 115 fouble getHeight() { return attrs->getBox()->y2 - attrs->getBox()->y1; }
96 PDFRectangle *getBleedBox() { return attrs->getBleedBox(); } 116 PDFRectangle *getBleedBox() { return attrs->getBleedBox(); }
97 PDFRectangle *getTrimBox() { return attrs->getTrimBox(); } 117 PDFRectangle *getTrimBox() { return attrs->getTrimBox(); }
98 PDFRectangle *getArtBox() { return attrs->getArtBox(); } 118 PDFRectangle *getArtBox() { return attrs->getArtBox(); }
99 int getRotate() { return attrs->getRotate(); } 119 int getRotate() { return attrs->getRotate(); }
120 GString *getLastModified() { return attrs->getLastModified(); }
121 Dict *getBoxColorInfo() { return attrs->getBoxColorInfo(); }
122 Dict *getGroup() { return attrs->getGroup(); }
123 Stream *getMetadata() { return attrs->getMetadata(); }
124 Dict *getPieceInfo() { return attrs->getPieceInfo(); }
125 Dict *getSeparationInfo() { return attrs->getSeparationInfo(); }
100 126
101 // Get resource dictionary. 127 // Get resource dictionary.
102 Dict *getResourceDict() { return attrs->getResourceDict(); } 128 Dict *getResourceDict() { return attrs->getResourceDict(); }
103 129
104 // Get annotations array. 130 // Get annotations array.
105 Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); } 131 Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); }
diff --git a/noncore/unsupported/qpdf/xpdf/Parser.cc b/noncore/unsupported/qpdf/xpdf/Parser.cc
index a98753d..4df53c9 100644
--- a/noncore/unsupported/qpdf/xpdf/Parser.cc
+++ b/noncore/unsupported/qpdf/xpdf/Parser.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Parser.cc 3// Parser.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -152,36 +152,37 @@ Object *Parser::getObj(Object *obj) {
152 return obj; 152 return obj;
153} 153}
154 154
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();
162 pos = lexer->getPos(); 162 pos = lexer->getPos();
163 163
164 // get length 164 // get length
165 dict->dictLookup("Length", &obj); 165 dict->dictLookup("Length", &obj);
166 if (obj.isInt()) { 166 if (obj.isInt()) {
167 length = obj.getInt(); 167 length = (Guint)obj.getInt();
168 obj.free(); 168 obj.free();
169 } else { 169 } else {
170 error(getPos(), "Bad 'Length' attribute in stream"); 170 error(getPos(), "Bad 'Length' attribute in stream");
171 obj.free(); 171 obj.free();
172 return NULL; 172 return NULL;
173 } 173 }
174 174
175 // check for length in damaged file 175 // check for length in damaged file
176 if ((endPos = xref->getStreamEnd(pos)) >= 0) { 176 if (xref->getStreamEnd(pos, &endPos)) {
177 length = endPos - pos; 177 length = endPos - pos;
178 } 178 }
179 179
180 // make base stream 180 // make base stream
181 str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict); 181 str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
182 length, dict);
182 183
183 // get filters 184 // get filters
184 str = str->addFilters(dict); 185 str = str->addFilters(dict);
185 186
186 // skip over stream data 187 // skip over stream data
187 lexer->setPos(pos + length); 188 lexer->setPos(pos + length);
diff --git a/noncore/unsupported/qpdf/xpdf/Parser.h b/noncore/unsupported/qpdf/xpdf/Parser.h
index 463d998..c11475b 100644
--- a/noncore/unsupported/qpdf/xpdf/Parser.h
+++ b/noncore/unsupported/qpdf/xpdf/Parser.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Parser.h 3// Parser.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef PARSER_H 9#ifndef PARSER_H
10#define PARSER_H 10#define PARSER_H
11 11
diff --git a/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h b/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h
index 1af8742..f5a77b0 100644
--- a/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h
+++ b/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h
@@ -1,13 +1,13 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Stream-CCITT.h 3// Stream-CCITT.h
4// 4//
5// Tables for CCITT Fax decoding. 5// Tables for CCITT Fax decoding.
6// 6//
7// Copyright 1996 Derek B. Noonburg 7// Copyright 1996-2002 Glyph & Cog, LLC
8// 8//
9//======================================================================== 9//========================================================================
10 10
11struct CCITTCode { 11struct CCITTCode {
12 short bits; 12 short bits;
13 short n; 13 short n;
diff --git a/noncore/unsupported/qpdf/xpdf/Stream.cc b/noncore/unsupported/qpdf/xpdf/Stream.cc
index 18490d4..c558478 100644
--- a/noncore/unsupported/qpdf/xpdf/Stream.cc
+++ b/noncore/unsupported/qpdf/xpdf/Stream.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Stream.cc 3// Stream.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -300,13 +300,13 @@ FilterStream::~FilterStream() {
300} 300}
301 301
302void FilterStream::close() { 302void 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
310//------------------------------------------------------------------------ 310//------------------------------------------------------------------------
311// ImageStream 311// ImageStream
312//------------------------------------------------------------------------ 312//------------------------------------------------------------------------
@@ -551,60 +551,74 @@ GBool StreamPredictor::getNextLine() {
551} 551}
552 552
553//------------------------------------------------------------------------ 553//------------------------------------------------------------------------
554// FileStream 554// FileStream
555//------------------------------------------------------------------------ 555//------------------------------------------------------------------------
556 556
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
581 if (decrypt) 591 if (decrypt)
582 decrypt->reset(); 592 decrypt->reset();
583#endif 593#endif
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
593GBool FileStream::fillBuf() { 607GBool FileStream::fillBuf() {
594 int n; 608 int n;
595#ifndef NO_DECRYPTION 609#ifndef NO_DECRYPTION
596 char *p; 610 char *p;
597#endif 611#endif
598 612
599 bufPos += bufEnd - buf; 613 bufPos += bufEnd - buf;
600 bufPtr = bufEnd = buf; 614 bufPtr = bufEnd = buf;
601 if (length >= 0 && bufPos >= start + length) { 615 if (limited && bufPos >= start + length) {
602 return gFalse; 616 return gFalse;
603 } 617 }
604 if (length >= 0 && bufPos + fileStreamBufSize > start + length) { 618 if (limited && bufPos + fileStreamBufSize > start + length) {
605 n = start + length - bufPos; 619 n = start + length - bufPos;
606 } else { 620 } else {
607 n = fileStreamBufSize; 621 n = fileStreamBufSize;
608 } 622 }
609 n = fread(buf, 1, n, f); 623 n = fread(buf, 1, n, f);
610 bufEnd = buf + n; 624 bufEnd = buf + n;
@@ -618,66 +632,165 @@ GBool FileStream::fillBuf() {
618 } 632 }
619 } 633 }
620#endif 634#endif
621 return gTrue; 635 return gTrue;
622} 636}
623 637
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}
644 672
645void FileStream::moveStart(int delta) { 673void FileStream::moveStart(int delta) {
646 start += delta; 674 start += delta;
647 bufPtr = bufEnd = buf; 675 bufPtr = bufEnd = buf;
648 bufPos = start; 676 bufPos = start;
649} 677}
650 678
651//------------------------------------------------------------------------ 679//------------------------------------------------------------------------
680// MemStream
681//------------------------------------------------------------------------
682
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
655EmbedStream::EmbedStream(Stream *strA, Object *dictA): 767EmbedStream::EmbedStream(Stream *strA, Object *dictA):
656 BaseStream(dictA) { 768 BaseStream(dictA) {
657 str = strA; 769 str = strA;
658} 770}
659 771
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
681//------------------------------------------------------------------------ 794//------------------------------------------------------------------------
682// ASCIIHexStream 795// ASCIIHexStream
683//------------------------------------------------------------------------ 796//------------------------------------------------------------------------
@@ -956,17 +1069,13 @@ void LZWStream::reset() {
956 error(getPos(), "Couldn't popen '%s'", zCmd->getCString()); 1069 error(getPos(), "Couldn't popen '%s'", zCmd->getCString());
957 unlink(zName->getCString()); 1070 unlink(zName->getCString());
958 delete zName; 1071 delete zName;
959 return; 1072 return;
960 } 1073 }
961#else // HAVE_POPEN 1074#else // HAVE_POPEN
962#ifdef VMS 1075 if (!executeCommand(zCmd->getCString())) {
963 if (!system(zCmd->getCString())) {
964#else
965 if (system(zCmd->getCString())) {
966#endif
967 error(getPos(), "Couldn't execute '%s'", zCmd->getCString()); 1076 error(getPos(), "Couldn't execute '%s'", zCmd->getCString());
968 unlink(zName->getCString()); 1077 unlink(zName->getCString());
969 delete zName; 1078 delete zName;
970 return; 1079 return;
971 } 1080 }
972 zName->del(zName->getLength() - 2, 2); 1081 zName->del(zName->getLength() - 2, 2);
@@ -3284,12 +3393,62 @@ int FixedLengthEncoder::lookChar() {
3284 if (length >= 0 && count >= length) 3393 if (length >= 0 && count >= length)
3285 return EOF; 3394 return EOF;
3286 return str->getChar(); 3395 return str->getChar();
3287} 3396}
3288 3397
3289//------------------------------------------------------------------------ 3398//------------------------------------------------------------------------
3399// ASCIIHexEncoder
3400//------------------------------------------------------------------------
3401
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
3293ASCII85Encoder::ASCII85Encoder(Stream *strA): 3452ASCII85Encoder::ASCII85Encoder(Stream *strA):
3294 FilterStream(strA) { 3453 FilterStream(strA) {
3295 bufPtr = bufEnd = buf; 3454 bufPtr = bufEnd = buf;
diff --git a/noncore/unsupported/qpdf/xpdf/Stream.h b/noncore/unsupported/qpdf/xpdf/Stream.h
index 1f9c561..3319dcc 100644
--- a/noncore/unsupported/qpdf/xpdf/Stream.h
+++ b/noncore/unsupported/qpdf/xpdf/Stream.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// Stream.h 3// Stream.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef STREAM_H 9#ifndef STREAM_H
10#define STREAM_H 10#define STREAM_H
11 11
@@ -75,14 +75,16 @@ public:
75 // Get next line from stream. 75 // Get next line from stream.
76 virtual char *getLine(char *buf, int size); 76 virtual char *getLine(char *buf, int size);
77 77
78 // Get current position in file. 78 // Get current position in file.
79 virtual int getPos() = 0; 79 virtual int getPos() = 0;
80 80
81 // Go to a position in the stream. 81 // Go to a position in the stream. If <dir> is negative, the
82 virtual void setPos(int pos) = 0; 82 // position is from the end of the file; otherwise the position is
83 // from the start of the file.
84 virtual void setPos(Guint pos, int dir = 0) = 0;
83 85
84 // Get PostScript command for the filter(s). 86 // Get PostScript command for the filter(s).
85 virtual GString *getPSFilter(char *indent); 87 virtual GString *getPSFilter(char *indent);
86 88
87 // Does this stream type potentially contain non-printable chars? 89 // Does this stream type potentially contain non-printable chars?
88 virtual GBool isBinary(GBool last = gTrue) = 0; 90 virtual GBool isBinary(GBool last = gTrue) = 0;
@@ -115,24 +117,26 @@ private:
115 117
116class BaseStream: public Stream { 118class BaseStream: public Stream {
117public: 119public:
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
136protected: 140protected:
137 141
138 Decrypt *decrypt; 142 Decrypt *decrypt;
@@ -153,13 +157,13 @@ class FilterStream: public Stream {
153public: 157public:
154 158
155 FilterStream(Stream *strA); 159 FilterStream(Stream *strA);
156 virtual ~FilterStream(); 160 virtual ~FilterStream();
157 virtual void close(); 161 virtual void close();
158 virtual int getPos() { return str->getPos(); } 162 virtual int getPos() { return str->getPos(); }
159 virtual void setPos(int pos); 163 virtual void setPos(Guint pos, int dir = 0);
160 virtual BaseStream *getBaseStream() { return str->getBaseStream(); } 164 virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
161 virtual Dict *getDict() { return str->getDict(); } 165 virtual Dict *getDict() { return str->getDict(); }
162 166
163protected: 167protected:
164 168
165 Stream *str; 169 Stream *str;
@@ -239,40 +243,81 @@ private:
239 243
240#define fileStreamBufSize 256 244#define fileStreamBufSize 256
241 245
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();
251 virtual int getChar() 257 virtual int getChar()
252 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } 258 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
253 virtual int lookChar() 259 virtual int lookChar()
254 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } 260 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
255 virtual int getPos() { return bufPos + (bufPtr - buf); } 261 virtual int getPos() { return bufPos + (bufPtr - buf); }
256 virtual void setPos(int pos); 262 virtual void setPos(Guint pos, int dir = 0);
257 virtual GBool isBinary(GBool last = gTrue) { return last; } 263 virtual GBool isBinary(GBool last = gTrue) { return last; }
258 virtual int getStart() { return start; } 264 virtual Guint getStart() { return start; }
259 virtual void moveStart(int delta); 265 virtual void moveStart(int delta);
260 266
261private: 267private:
262 268
263 GBool fillBuf(); 269 GBool fillBuf();
264 270
265 FILE *f; 271 FILE *f;
266 int start; 272 Guint start;
267 int length; 273 GBool limited;
274 Guint length;
268 char buf[fileStreamBufSize]; 275 char buf[fileStreamBufSize];
269 char *bufPtr; 276 char *bufPtr;
270 char *bufEnd; 277 char *bufEnd;
271 int bufPos; 278 Guint bufPos;
272 int savePos; 279 int savePos;
280 GBool saved;
281};
282
283//------------------------------------------------------------------------
284// MemStream
285//------------------------------------------------------------------------
286
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//------------------------------------------------------------------------
276// EmbedStream 321// EmbedStream
277// 322//
278// This is a special stream type used for embedded streams (inline 323// This is a special stream type used for embedded streams (inline
@@ -284,21 +329,22 @@ private:
284 329
285class EmbedStream: public BaseStream { 330class EmbedStream: public BaseStream {
286public: 331public:
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:
302 348
303 Stream *str; 349 Stream *str;
304}; 350};
@@ -656,12 +702,43 @@ private:
656 702
657 int length; 703 int length;
658 int count; 704 int count;
659}; 705};
660 706
661//------------------------------------------------------------------------ 707//------------------------------------------------------------------------
708// ASCIIHexEncoder
709//------------------------------------------------------------------------
710
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
665class ASCII85Encoder: public FilterStream { 742class ASCII85Encoder: public FilterStream {
666public: 743public:
667 744
diff --git a/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc b/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc
index aa9366a..d3b0137 100644
--- a/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc
+++ b/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// TextOutputDev.cc 3// TextOutputDev.cc
4// 4//
5// Copyright 1997 Derek B. Noonburg 5// Copyright 1997-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -45,12 +45,18 @@ TextString::TextString(GfxState *state, fouble fontSize) {
45 } else { 45 } else {
46 // this means that the PDF file draws text without a current font, 46 // this means that the PDF file draws text without a current font,
47 // which should never happen 47 // which should never happen
48 yMin = y - 0.95 * fontSize; 48 yMin = y - 0.95 * fontSize;
49 yMax = y + 0.35 * fontSize; 49 yMax = y + 0.35 * fontSize;
50 } 50 }
51 if (yMin == yMax) {
52 // this is a sanity check for a case that shouldn't happen -- but
53 // if it does happen, we want to avoid dividing by zero later
54 yMin = y;
55 yMax = y + 1;
56 }
51 col = 0; 57 col = 0;
52 text = NULL; 58 text = NULL;
53 xRight = NULL; 59 xRight = NULL;
54 len = size = 0; 60 len = size = 0;
55 yxNext = NULL; 61 yxNext = NULL;
56 xyNext = NULL; 62 xyNext = NULL;
@@ -96,12 +102,13 @@ TextPage::~TextPage() {
96 102
97void TextPage::updateFont(GfxState *state) { 103void TextPage::updateFont(GfxState *state) {
98 GfxFont *font; 104 GfxFont *font;
99 fouble *fm; 105 fouble *fm;
100 char *name; 106 char *name;
101 int code; 107 int code;
108 fouble w;
102 109
103 // adjust the font size 110 // adjust the font size
104 fontSize = state->getTransformedFontSize(); 111 fontSize = state->getTransformedFontSize();
105 if ((font = state->getFont()) && font->getType() == fontType3) { 112 if ((font = state->getFont()) && font->getType() == fontType3) {
106 // This is a hack which makes it possible to deal with some Type 3 113 // This is a hack which makes it possible to deal with some Type 3
107 // fonts. The problem is that it's impossible to know what the 114 // fonts. The problem is that it's impossible to know what the
@@ -113,14 +120,17 @@ void TextPage::updateFont(GfxState *state) {
113 if ((name = ((Gfx8BitFont *)font)->getCharName(code)) && 120 if ((name = ((Gfx8BitFont *)font)->getCharName(code)) &&
114 name[0] == 'm' && name[1] == '\0') { 121 name[0] == 'm' && name[1] == '\0') {
115 break; 122 break;
116 } 123 }
117 } 124 }
118 if (code < 256) { 125 if (code < 256) {
119 // 600 is a generic average 'm' width -- yes, this is a hack 126 w = ((Gfx8BitFont *)font)->getWidth(code);
120 fontSize *= ((Gfx8BitFont *)font)->getWidth(code) / 0.6; 127 if (w != 0) {
128 // 600 is a generic average 'm' width -- yes, this is a hack
129 fontSize *= w / 0.6;
130 }
121 } 131 }
122 fm = font->getFontMatrix(); 132 fm = font->getFontMatrix();
123 if (fm[0] != 0) { 133 if (fm[0] != 0) {
124 fontSize *= fabs(fm[3] / fm[0]); 134 fontSize *= fabs(fm[3] / fm[0]);
125 } 135 }
126 } 136 }
@@ -151,14 +161,16 @@ void TextPage::addChar(GfxState *state, fouble x, fouble y,
151 } 161 }
152 state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(), 162 state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(),
153 0, &dx2, &dy2); 163 0, &dx2, &dy2);
154 dx -= dx2; 164 dx -= dx2;
155 dy -= dy2; 165 dy -= dy2;
156 state->transformDelta(dx, dy, &w1, &h1); 166 state->transformDelta(dx, dy, &w1, &h1);
157 w1 /= uLen; 167 if (uLen != 0) {
158 h1 /= uLen; 168 w1 /= uLen;
169 h1 /= uLen;
170 }
159 for (i = 0; i < uLen; ++i) { 171 for (i = 0; i < uLen; ++i) {
160 curStr->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, u[i]); 172 curStr->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, u[i]);
161 } 173 }
162} 174}
163 175
164void TextPage::endString() { 176void TextPage::endString() {
@@ -426,13 +438,13 @@ GString *TextPage::getText(fouble xMin, fouble yMin,
426 s->append(eol, eolLen); 438 s->append(eol, eolLen);
427 } 439 }
428 uMap->decRefCnt(); 440 uMap->decRefCnt();
429 return s; 441 return s;
430} 442}
431 443
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;
436 TextString *str1, *str2, *str3; 448 TextString *str1, *str2, *str3;
437 fouble yMin, yMax; 449 fouble yMin, yMax;
438 int col1, col2, d, i; 450 int col1, col2, d, i;
@@ -495,43 +507,43 @@ void TextPage::dump(FILE *f) {
495 } 507 }
496 } 508 }
497 str1->col = col1; 509 str1->col = col1;
498 } 510 }
499 511
500#if 0 //~ for debugging 512#if 0 //~ for debugging
501 fprintf(f, "~~~~~~~~~~\n"); 513 fprintf((FILE *)outputStream, "~~~~~~~~~~\n");
502 for (str1 = yxStrings; str1; str1 = str1->yxNext) { 514 for (str1 = yxStrings; str1; str1 = str1->yxNext) {
503 fprintf(f, "(%4d,%4d) - (%4d,%4d) [%3d] '", 515 fprintf((FILE *)outputStream, "(%4d,%4d) - (%4d,%4d) [%3d] '",
504 (int)str1->xMin, (int)str1->yMin, 516 (int)str1->xMin, (int)str1->yMin,
505 (int)str1->xMax, (int)str1->yMax, str1->col); 517 (int)str1->xMax, (int)str1->yMax, str1->col);
506 for (i = 0; i < str1->len; ++i) { 518 for (i = 0; i < str1->len; ++i) {
507 fputc(str1->text[i] & 0xff, stdout); 519 fputc(str1->text[i] & 0xff, stdout);
508 } 520 }
509 printf("'\n"); 521 printf("'\n");
510 } 522 }
511 fprintf(f, "~~~~~~~~~~\n"); 523 fprintf((FILE *)outputStream, "~~~~~~~~~~\n");
512#endif 524#endif
513 525
514 // output 526 // output
515 col1 = 0; 527 col1 = 0;
516 yMax = yxStrings ? yxStrings->yMax : fouble(0); 528 yMax = yxStrings ? yxStrings->yMax : fouble(0);
517 for (str1 = yxStrings; str1; str1 = str1->yxNext) { 529 for (str1 = yxStrings; str1; str1 = str1->yxNext) {
518 530
519 // line this string up with the correct column 531 // line this string up with the correct column
520 if (rawOrder && col1 == 0) { 532 if (rawOrder && col1 == 0) {
521 col1 = str1->col; 533 col1 = str1->col;
522 } else { 534 } else {
523 for (; col1 < str1->col; ++col1) { 535 for (; col1 < str1->col; ++col1) {
524 fwrite(space, 1, spaceLen, f); 536 (*outputFunc)(outputStream, space, spaceLen);
525 } 537 }
526 } 538 }
527 539
528 // print the string 540 // print the string
529 for (i = 0; i < str1->len; ++i) { 541 for (i = 0; i < str1->len; ++i) {
530 if ((n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf))) > 0) { 542 if ((n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf))) > 0) {
531 fwrite(buf, 1, n, f); 543 (*outputFunc)(outputStream, buf, n);
532 } 544 }
533 } 545 }
534 546
535 // increment column 547 // increment column
536 col1 += str1->len; 548 col1 += str1->len;
537 549
@@ -544,13 +556,13 @@ void TextPage::dump(FILE *f) {
544 if (!(str1->yxNext && 556 if (!(str1->yxNext &&
545 !(rawOrder && str1->yxNext->yMax < str1->yMin) && 557 !(rawOrder && str1->yxNext->yMax < str1->yMin) &&
546 str1->yxNext->yMin < 0.2*str1->yMin + 0.8*str1->yMax && 558 str1->yxNext->yMin < 0.2*str1->yMin + 0.8*str1->yMax &&
547 str1->yxNext->xMin >= str1->xMax)) { 559 str1->yxNext->xMin >= str1->xMax)) {
548 560
549 // print a return 561 // print a return
550 fwrite(eol, 1, eolLen, f); 562 (*outputFunc)(outputStream, eol, eolLen);
551 563
552 // print extra vertical space if necessary 564 // print extra vertical space if necessary
553 if (str1->yxNext) { 565 if (str1->yxNext) {
554 566
555 // find yMin for next line 567 // find yMin for next line
556 yMin = str1->yxNext->yMin; 568 yMin = str1->yxNext->yMin;
@@ -570,26 +582,26 @@ void TextPage::dump(FILE *f) {
570 if (rawOrder && d > 2) { 582 if (rawOrder && d > 2) {
571 d = 2; 583 d = 2;
572 } else if (!rawOrder && d > 5) { 584 } else if (!rawOrder && d > 5) {
573 d = 5; 585 d = 5;
574 } 586 }
575 for (; d > 0; --d) { 587 for (; d > 0; --d) {
576 fwrite(eol, 1, eolLen, f); 588 (*outputFunc)(outputStream, eol, eolLen);
577 } 589 }
578 } 590 }
579 591
580 // set up for next line 592 // set up for next line
581 col1 = 0; 593 col1 = 0;
582 yMax = str1->yxNext ? str1->yxNext->yMax : fouble(0); 594 yMax = str1->yxNext ? str1->yxNext->yMax : fouble(0);
583 } 595 }
584 } 596 }
585 597
586 // end of page 598 // end of page
587 fwrite(eol, 1, eolLen, f); 599 (*outputFunc)(outputStream, eol, eolLen);
588 fwrite(eop, 1, eopLen, f); 600 (*outputFunc)(outputStream, eop, eopLen);
589 fwrite(eol, 1, eolLen, f); 601 (*outputFunc)(outputStream, eol, eolLen);
590 602
591 uMap->decRefCnt(); 603 uMap->decRefCnt();
592} 604}
593 605
594void TextPage::clear() { 606void TextPage::clear() {
595 TextString *p1, *p2; 607 TextString *p1, *p2;
@@ -608,57 +620,72 @@ void TextPage::clear() {
608} 620}
609 621
610//------------------------------------------------------------------------ 622//------------------------------------------------------------------------
611// TextOutputDev 623// TextOutputDev
612//------------------------------------------------------------------------ 624//------------------------------------------------------------------------
613 625
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;
617 ok = gTrue; 633 ok = gTrue;
618 634
619 // open file 635 // open file
620 needClose = gFalse; 636 needClose = gFalse;
621 if (fileName) { 637 if (fileName) {
622 if (!strcmp(fileName, "-")) { 638 if (!strcmp(fileName, "-")) {
623 f = stdout; 639 outputStream = stdout;
624 } else if ((f = fopen(fileName, append ? "a" : "w"))) { 640 } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) {
625 needClose = gTrue; 641 needClose = gTrue;
626 } else { 642 } else {
627 error(-1, "Couldn't open text file '%s'", fileName); 643 error(-1, "Couldn't open text file '%s'", fileName);
628 ok = gFalse; 644 ok = gFalse;
629 return; 645 return;
630 } 646 }
647 outputFunc = &outputToFile;
631 } else { 648 } else {
632 f = NULL; 649 outputStream = NULL;
633 } 650 }
634 651
635 // set up text object 652 // set up text object
636 text = new TextPage(rawOrder); 653 text = new TextPage(rawOrder);
637} 654}
638 655
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;
648 } 675 }
649} 676}
650 677
651void TextOutputDev::startPage(int pageNum, GfxState *state) { 678void TextOutputDev::startPage(int pageNum, GfxState *state) {
652 text->clear(); 679 text->clear();
653} 680}
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
662void TextOutputDev::updateFont(GfxState *state) { 689void TextOutputDev::updateFont(GfxState *state) {
663 text->updateFont(state); 690 text->updateFont(state);
664} 691}
diff --git a/noncore/unsupported/qpdf/xpdf/TextOutputDev.h b/noncore/unsupported/qpdf/xpdf/TextOutputDev.h
index 4c71e5e..f0f238e 100644
--- a/noncore/unsupported/qpdf/xpdf/TextOutputDev.h
+++ b/noncore/unsupported/qpdf/xpdf/TextOutputDev.h
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// TextOutputDev.h 3// TextOutputDev.h
4// 4//
5// Copyright 1997 Derek B. Noonburg 5// Copyright 1997-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef TEXTOUTPUTDEV_H 9#ifndef TEXTOUTPUTDEV_H
10#define TEXTOUTPUTDEV_H 10#define TEXTOUTPUTDEV_H
11 11
@@ -19,12 +19,16 @@
19#include "OutputDev.h" 19#include "OutputDev.h"
20 20
21class GfxState; 21class 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
28class TextString { 32class TextString {
29public: 33public:
30 34
@@ -94,13 +98,13 @@ public:
94 98
95 // Get the text which is inside the specified rectangle. 99 // Get the text which is inside the specified rectangle.
96 GString *getText(fouble xMin, fouble yMin, 100 GString *getText(fouble xMin, fouble yMin,
97 fouble xMax, fouble yMax); 101 fouble xMax, fouble yMax);
98 102
99 // Dump contents of page to a file. 103 // Dump contents of page to a file.
100 void dump(FILE *f); 104 void dump(void *outputStream, TextOutputFunc outputFunc);
101 105
102 // Clear the page. 106 // Clear the page.
103 void clear(); 107 void clear();
104 108
105private: 109private:
106 110
@@ -125,12 +129,16 @@ public:
125 129
126 // Open a text output file. If <fileName> is NULL, no file is 130 // Open a text output file. If <fileName> is NULL, no file is
127 // written (this is useful, e.g., for searching text). If 131 // written (this is useful, e.g., for searching text). If
128 // <rawOrder> is true, the text is kept in content stream order. 132 // <rawOrder> is true, the text is kept in content stream order.
129 TextOutputDev(char *fileName, GBool rawOrderA, GBool append); 133 TextOutputDev(char *fileName, GBool rawOrderA, GBool append);
130 134
135 // Create a TextOutputDev which will write to a generic stream. If
136 // <rawOrder> is true, the text is kept in content stream order.
137 TextOutputDev(TextOutputFunc func, void *stream, GBool rawOrderA);
138
131 // Destructor. 139 // Destructor.
132 virtual ~TextOutputDev(); 140 virtual ~TextOutputDev();
133 141
134 // Check if file was successfully created. 142 // Check if file was successfully created.
135 virtual GBool isOk() { return ok; } 143 virtual GBool isOk() { return ok; }
136 144
@@ -140,12 +148,16 @@ public:
140 // (Upside-down means (0,0) is the top left corner of the page.) 148 // (Upside-down means (0,0) is the top left corner of the page.)
141 virtual GBool upsideDown() { return gTrue; } 149 virtual GBool upsideDown() { return gTrue; }
142 150
143 // Does this device use drawChar() or drawString()? 151 // Does this device use drawChar() or drawString()?
144 virtual GBool useDrawChar() { return gTrue; } 152 virtual GBool useDrawChar() { return gTrue; }
145 153
154 // Does this device use beginType3Char/endType3Char? Otherwise,
155 // text in Type 3 fonts will be drawn with drawChar/drawString.
156 virtual GBool interpretType3Chars() { return gFalse; }
157
146 // Does this device need non-text content? 158 // Does this device need non-text content?
147 virtual GBool needNonText() { return gFalse; } 159 virtual GBool needNonText() { return gFalse; }
148 160
149 //----- initialization and control 161 //----- initialization and control
150 162
151 // Start a page. 163 // Start a page.
@@ -176,14 +188,16 @@ public:
176 GBool top, GBool bottom, 188 GBool top, GBool bottom,
177 fouble *xMin, fouble *yMin, 189 fouble *xMin, fouble *yMin,
178 fouble *xMax, fouble *yMax); 190 fouble *xMax, fouble *yMax);
179 191
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?
187}; 201};
188 202
189#endif 203#endif
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc b/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc
index ab823b1..75f23d2 100644
--- a/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc
+++ b/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// UnicodeMap.cc 3// UnicodeMap.cc
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMap.h b/noncore/unsupported/qpdf/xpdf/UnicodeMap.h
index 4d982c8..274c447 100644
--- a/noncore/unsupported/qpdf/xpdf/UnicodeMap.h
+++ b/noncore/unsupported/qpdf/xpdf/UnicodeMap.h
@@ -1,13 +1,13 @@
1//======================================================================== 1//========================================================================
2// 2//
3// UnicodeMap.h 3// UnicodeMap.h
4// 4//
5// Mapping from Unicode to an encoding. 5// Mapping from Unicode to an encoding.
6// 6//
7// Copyright 2001 Derek B. Noonburg 7// Copyright 2001-2002 Glyph & Cog, LLC
8// 8//
9//======================================================================== 9//========================================================================
10 10
11#ifndef UNICODEMAP_H 11#ifndef UNICODEMAP_H
12#define UNICODEMAP_H 12#define UNICODEMAP_H
13 13
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h b/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h
index 6fcd44e..51dee98 100644
--- a/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h
+++ b/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h
@@ -1,21 +1,23 @@
1//======================================================================== 1//========================================================================
2// 2//
3// UnicodeMapTables.h 3// UnicodeMapTables.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9static UnicodeMapRange latin1UnicodeMapRanges[] = { 9static UnicodeMapRange latin1UnicodeMapRanges[] = {
10 { 0x000a, 0x000a, 0x0a, 1 }, 10 { 0x000a, 0x000a, 0x0a, 1 },
11 { 0x000c, 0x000d, 0x0c, 1 }, 11 { 0x000c, 0x000d, 0x0c, 1 },
12 { 0x0020, 0x007e, 0x20, 1 }, 12 { 0x0020, 0x007e, 0x20, 1 },
13 { 0x00a0, 0x00a0, 0x20, 1 }, 13 { 0x00a0, 0x00a0, 0x20, 1 },
14 { 0x00a1, 0x00ac, 0xa1, 1 }, 14 { 0x00a1, 0x00ac, 0xa1, 1 },
15 { 0x00ae, 0x00ff, 0xae, 1 }, 15 { 0x00ae, 0x00ff, 0xae, 1 },
16 { 0x010c, 0x010c, 0x43, 1 },
17 { 0x010d, 0x010d, 0x63, 1 },
16 { 0x0131, 0x0131, 0x69, 1 }, 18 { 0x0131, 0x0131, 0x69, 1 },
17 { 0x0141, 0x0141, 0x4c, 1 }, 19 { 0x0141, 0x0141, 0x4c, 1 },
18 { 0x0142, 0x0142, 0x6c, 1 }, 20 { 0x0142, 0x0142, 0x6c, 1 },
19 { 0x0152, 0x0152, 0x4f45, 2 }, 21 { 0x0152, 0x0152, 0x4f45, 2 },
20 { 0x0153, 0x0153, 0x6f65, 2 }, 22 { 0x0153, 0x0153, 0x6f65, 2 },
21 { 0x0160, 0x0160, 0x53, 1 }, 23 { 0x0160, 0x0160, 0x53, 1 },
@@ -38,12 +40,29 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
38 { 0x2026, 0x2026, 0x2e2e2e, 3 }, 40 { 0x2026, 0x2026, 0x2e2e2e, 3 },
39 { 0x2039, 0x2039, 0x3c, 1 }, 41 { 0x2039, 0x2039, 0x3c, 1 },
40 { 0x203a, 0x203a, 0x3e, 1 }, 42 { 0x203a, 0x203a, 0x3e, 1 },
41 { 0x2044, 0x2044, 0x2f, 1 }, 43 { 0x2044, 0x2044, 0x2f, 1 },
42 { 0x2122, 0x2122, 0x544d, 2 }, 44 { 0x2122, 0x2122, 0x544d, 2 },
43 { 0x2212, 0x2212, 0x2d, 1 }, 45 { 0x2212, 0x2212, 0x2d, 1 },
46 { 0xf6f9, 0xf6f9, 0x4c, 1 },
47 { 0xf6fa, 0xf6fa, 0x4f45, 2 },
48 { 0xf6fc, 0xf6fc, 0xb0, 1 },
49 { 0xf6fd, 0xf6fd, 0x53, 1 },
50 { 0xf6fe, 0xf6fe, 0x7e, 1 },
51 { 0xf6ff, 0xf6ff, 0x5a, 1 },
52 { 0xf721, 0xf721, 0x21, 1 },
53 { 0xf724, 0xf724, 0x24, 1 },
54 { 0xf726, 0xf726, 0x26, 1 },
55 { 0xf730, 0xf739, 0x30, 1 },
56 { 0xf73f, 0xf73f, 0x3f, 1 },
57 { 0xf761, 0xf77a, 0x41, 1 },
58 { 0xf7a1, 0xf7a2, 0xa1, 1 },
59 { 0xf7bf, 0xf7bf, 0xbf, 1 },
60 { 0xf7e0, 0xf7f6, 0xc0, 1 },
61 { 0xf7f8, 0xf7fe, 0xd8, 1 },
62 { 0xf7ff, 0xf7ff, 0x59, 1 },
44 { 0xfb00, 0xfb00, 0x6666, 2 }, 63 { 0xfb00, 0xfb00, 0x6666, 2 },
45 { 0xfb01, 0xfb01, 0x6669, 2 }, 64 { 0xfb01, 0xfb01, 0x6669, 2 },
46 { 0xfb02, 0xfb02, 0x666c, 2 }, 65 { 0xfb02, 0xfb02, 0x666c, 2 },
47 { 0xfb03, 0xfb03, 0x666669, 3 }, 66 { 0xfb03, 0xfb03, 0x666669, 3 },
48 { 0xfb04, 0xfb04, 0x66666c, 3 } 67 { 0xfb04, 0xfb04, 0x66666c, 3 }
49}; 68};
@@ -132,12 +151,51 @@ static UnicodeMapRange ascii7UnicodeMapRanges[] = {
132 { 0x201c, 0x201c, 0x22, 1 }, 151 { 0x201c, 0x201c, 0x22, 1 },
133 { 0x201d, 0x201d, 0x22, 1 }, 152 { 0x201d, 0x201d, 0x22, 1 },
134 { 0x2022, 0x2022, 0x2a, 1 }, 153 { 0x2022, 0x2022, 0x2a, 1 },
135 { 0x2026, 0x2026, 0x2e2e2e, 3 }, 154 { 0x2026, 0x2026, 0x2e2e2e, 3 },
136 { 0x2122, 0x2122, 0x544d, 2 }, 155 { 0x2122, 0x2122, 0x544d, 2 },
137 { 0x2212, 0x2212, 0x2d, 1 }, 156 { 0x2212, 0x2212, 0x2d, 1 },
157 { 0xf6f9, 0xf6f9, 0x4c, 1 },
158 { 0xf6fa, 0xf6fa, 0x4f45, 2 },
159 { 0xf6fd, 0xf6fd, 0x53, 1 },
160 { 0xf6fe, 0xf6fe, 0x7e, 1 },
161 { 0xf6ff, 0xf6ff, 0x5a, 1 },
162 { 0xf721, 0xf721, 0x21, 1 },
163 { 0xf724, 0xf724, 0x24, 1 },
164 { 0xf726, 0xf726, 0x26, 1 },
165 { 0xf730, 0xf739, 0x30, 1 },
166 { 0xf73f, 0xf73f, 0x3f, 1 },
167 { 0xf761, 0xf77a, 0x41, 1 },
168 { 0xf7e0, 0xf7e0, 0x41, 1 },
169 { 0xf7e1, 0xf7e1, 0x41, 1 },
170 { 0xf7e2, 0xf7e2, 0x41, 1 },
171 { 0xf7e3, 0xf7e3, 0x41, 1 },
172 { 0xf7e4, 0xf7e4, 0x41, 1 },
173 { 0xf7e5, 0xf7e5, 0x41, 1 },
174 { 0xf7e6, 0xf7e6, 0x4145, 2 },
175 { 0xf7e7, 0xf7e7, 0x43, 1 },
176 { 0xf7e8, 0xf7e8, 0x45, 1 },
177 { 0xf7e9, 0xf7e9, 0x45, 1 },
178 { 0xf7ea, 0xf7ea, 0x45, 1 },
179 { 0xf7eb, 0xf7eb, 0x45, 1 },
180 { 0xf7ec, 0xf7ec, 0x49, 1 },
181 { 0xf7ed, 0xf7ed, 0x49, 1 },
182 { 0xf7ee, 0xf7ee, 0x49, 1 },
183 { 0xf7ef, 0xf7ef, 0x49, 1 },
184 { 0xf7f1, 0xf7f2, 0x4e, 1 },
185 { 0xf7f3, 0xf7f3, 0x4f, 1 },
186 { 0xf7f4, 0xf7f4, 0x4f, 1 },
187 { 0xf7f5, 0xf7f5, 0x4f, 1 },
188 { 0xf7f6, 0xf7f6, 0x4f, 1 },
189 { 0xf7f8, 0xf7f8, 0x4f, 1 },
190 { 0xf7f9, 0xf7f9, 0x55, 1 },
191 { 0xf7fa, 0xf7fa, 0x55, 1 },
192 { 0xf7fb, 0xf7fb, 0x55, 1 },
193 { 0xf7fc, 0xf7fc, 0x55, 1 },
194 { 0xf7fd, 0xf7fd, 0x59, 1 },
195 { 0xf7ff, 0xf7ff, 0x59, 1 },
138 { 0xfb00, 0xfb00, 0x6666, 2 }, 196 { 0xfb00, 0xfb00, 0x6666, 2 },
139 { 0xfb01, 0xfb01, 0x6669, 2 }, 197 { 0xfb01, 0xfb01, 0x6669, 2 },
140 { 0xfb02, 0xfb02, 0x666c, 2 }, 198 { 0xfb02, 0xfb02, 0x666c, 2 },
141 { 0xfb03, 0xfb03, 0x666669, 3 }, 199 { 0xfb03, 0xfb03, 0x666669, 3 },
142 { 0xfb04, 0xfb04, 0x66666c, 3 } 200 { 0xfb04, 0xfb04, 0x66666c, 3 }
143}; 201};
diff --git a/noncore/unsupported/qpdf/xpdf/XRef.cc b/noncore/unsupported/qpdf/xpdf/XRef.cc
index 5d526e9..0e1bbc9 100644
--- a/noncore/unsupported/qpdf/xpdf/XRef.cc
+++ b/noncore/unsupported/qpdf/xpdf/XRef.cc
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// XRef.cc 3// XRef.cc
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifdef __GNUC__ 9#ifdef __GNUC__
10#pragma implementation 10#pragma implementation
11#endif 11#endif
@@ -22,12 +22,13 @@
22#include "Parser.h" 22#include "Parser.h"
23#include "Dict.h" 23#include "Dict.h"
24#ifndef NO_DECRYPTION 24#ifndef NO_DECRYPTION
25#include "Decrypt.h" 25#include "Decrypt.h"
26#endif 26#endif
27#include "Error.h" 27#include "Error.h"
28#include "ErrorCodes.h"
28#include "XRef.h" 29#include "XRef.h"
29 30
30//------------------------------------------------------------------------ 31//------------------------------------------------------------------------
31 32
32 #define xrefSearchSize 1024// read this many bytes at end of file 33 #define xrefSearchSize 1024// read this many bytes at end of file
33 // to look for 'startxref' 34 // to look for 'startxref'
@@ -46,16 +47,17 @@
46 47
47//------------------------------------------------------------------------ 48//------------------------------------------------------------------------
48// XRef 49// XRef
49//------------------------------------------------------------------------ 50//------------------------------------------------------------------------
50 51
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;
59 streamEndsLen = 0; 61 streamEndsLen = 0;
60 62
61 // read the trailer 63 // read the trailer
@@ -64,31 +66,33 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
64 pos = readTrailer(); 66 pos = readTrailer();
65 67
66 // if there was a problem with the trailer, 68 // if there was a problem with the trailer,
67 // try to reconstruct the xref table 69 // try to reconstruct the xref table
68 if (pos == 0) { 70 if (pos == 0) {
69 if (!(ok = constructXRef())) { 71 if (!(ok = constructXRef())) {
72 errCode = errDamaged;
70 return; 73 return;
71 } 74 }
72 75
73 // trailer is ok - read the xref table 76 // trailer is ok - read the xref table
74 } else { 77 } else {
75 entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry)); 78 entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry));
76 for (i = 0; i < size; ++i) { 79 for (i = 0; i < size; ++i) {
77 entries[i].offset = -1; 80 entries[i].offset = 0xffffffff;
78 entries[i].used = gFalse; 81 entries[i].used = gFalse;
79 } 82 }
80 while (readXRef(&pos)) ; 83 while (readXRef(&pos)) ;
81 84
82 // if there was a problem with the xref table, 85 // if there was a problem with the xref table,
83 // try to reconstruct it 86 // try to reconstruct it
84 if (!ok) { 87 if (!ok) {
85 gfree(entries); 88 gfree(entries);
86 size = 0; 89 size = 0;
87 entries = NULL; 90 entries = NULL;
88 if (!(ok = constructXRef())) { 91 if (!(ok = constructXRef())) {
92 errCode = errDamaged;
89 return; 93 return;
90 } 94 }
91 } 95 }
92 } 96 }
93 97
94 // now set the trailer dictionary's xref pointer so we can fetch 98 // now set the trailer dictionary's xref pointer so we can fetch
@@ -98,12 +102,13 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
98 // check for encryption 102 // check for encryption
99#ifndef NO_DECRYPTION 103#ifndef NO_DECRYPTION
100 encrypted = gFalse; 104 encrypted = gFalse;
101#endif 105#endif
102 if (checkEncrypted(ownerPassword, userPassword)) { 106 if (checkEncrypted(ownerPassword, userPassword)) {
103 ok = gFalse; 107 ok = gFalse;
108 errCode = errEncrypted;
104 return; 109 return;
105 } 110 }
106} 111}
107 112
108XRef::~XRef() { 113XRef::~XRef() {
109 gfree(entries); 114 gfree(entries);
@@ -112,23 +117,24 @@ XRef::~XRef() {
112 gfree(streamEnds); 117 gfree(streamEnds);
113 } 118 }
114} 119}
115 120
116// Read startxref position, xref table size, and root. Returns 121// Read startxref position, xref table size, and root. Returns
117// first xref position. 122// first xref position.
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;
132 buf[n] = c; 138 buf[n] = c;
133 } 139 }
134 buf[n] = '\0'; 140 buf[n] = '\0';
@@ -138,13 +144,13 @@ int XRef::readTrailer() {
138 if (!strncmp(&buf[i], "startxref", 9)) 144 if (!strncmp(&buf[i], "startxref", 9))
139 break; 145 break;
140 } 146 }
141 if (i < 0) 147 if (i < 0)
142 return 0; 148 return 0;
143 for (p = &buf[i+9]; isspace(*p); ++p) ; 149 for (p = &buf[i+9]; isspace(*p); ++p) ;
144 pos = lastXRefPos = atoi(p); 150 pos = lastXRefPos = strToUnsigned(p);
145 151
146 // find trailer dict by looking after first xref table 152 // find trailer dict by looking after first xref table
147 // (NB: we can't just use the trailer dict at the end of the file -- 153 // (NB: we can't just use the trailer dict at the end of the file --
148 // this won't work for linearized files.) 154 // this won't work for linearized files.)
149 str->setPos(start + pos); 155 str->setPos(start + pos);
150 for (i = 0; i < 4; ++i) 156 for (i = 0; i < 4; ++i)
@@ -173,14 +179,15 @@ int XRef::readTrailer() {
173 pos1 += (p - buf) + n * 20; 179 pos1 += (p - buf) + n * 20;
174 } 180 }
175 pos1 += 7; 181 pos1 += 7;
176 182
177 // read trailer dict 183 // read trailer dict
178 obj.initNull(); 184 obj.initNull();
179 parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(start + pos1, 185 parser = new Parser(NULL,
180 -1, &obj))); 186 new Lexer(NULL,
187 str->makeSubStream(start + pos1, gFalse, 0, &obj)));
181 parser->getObj(&trailerDict); 188 parser->getObj(&trailerDict);
182 if (trailerDict.isDict()) { 189 if (trailerDict.isDict()) {
183 trailerDict.dictLookupNF("Size", &obj); 190 trailerDict.dictLookupNF("Size", &obj);
184 if (obj.isInt()) 191 if (obj.isInt())
185 size = obj.getInt(); 192 size = obj.getInt();
186 else 193 else
@@ -201,13 +208,13 @@ int XRef::readTrailer() {
201 208
202 // return first xref position 209 // return first xref position
203 return pos; 210 return pos;
204} 211}
205 212
206// Read an xref table and the prev pointer from the trailer. 213// Read an xref table and the prev pointer from the trailer.
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];
211 GBool more; 218 GBool more;
212 int first, newSize, n, i, j; 219 int first, newSize, n, i, j;
213 int c; 220 int c;
@@ -258,27 +265,27 @@ GBool XRef::readXRef(int *pos) {
258 // check for buggy PDF files with an incorrect (too small) xref 265 // check for buggy PDF files with an incorrect (too small) xref
259 // table size 266 // table size
260 if (first + n > size) { 267 if (first + n > size) {
261 newSize = size + 256; 268 newSize = size + 256;
262 entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); 269 entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
263 for (i = size; i < newSize; ++i) { 270 for (i = size; i < newSize; ++i) {
264 entries[i].offset = -1; 271 entries[i].offset = 0xffffffff;
265 entries[i].used = gFalse; 272 entries[i].used = gFalse;
266 } 273 }
267 size = newSize; 274 size = newSize;
268 } 275 }
269 for (i = first; i < first + n; ++i) { 276 for (i = first; i < first + n; ++i) {
270 for (j = 0; j < 20; ++j) { 277 for (j = 0; j < 20; ++j) {
271 if ((c = str->getChar()) == EOF) { 278 if ((c = str->getChar()) == EOF) {
272 goto err2; 279 goto err2;
273 } 280 }
274 s[j] = (char)c; 281 s[j] = (char)c;
275 } 282 }
276 if (entries[i].offset < 0) { 283 if (entries[i].offset == 0xffffffff) {
277 s[10] = '\0'; 284 s[10] = '\0';
278 entries[i].offset = atoi(s); 285 entries[i].offset = strToUnsigned(s);
279 s[16] = '\0'; 286 s[16] = '\0';
280 entries[i].gen = atoi(&s[11]); 287 entries[i].gen = atoi(&s[11]);
281 if (s[17] == 'n') { 288 if (s[17] == 'n') {
282 entries[i].used = gTrue; 289 entries[i].used = gTrue;
283 } else if (s[17] == 'f') { 290 } else if (s[17] == 'f') {
284 entries[i].used = gFalse; 291 entries[i].used = gFalse;
@@ -290,34 +297,35 @@ GBool XRef::readXRef(int *pos) {
290 // instead of 0. 297 // instead of 0.
291 if (i == 1 && first == 1 && 298 if (i == 1 && first == 1 &&
292 entries[1].offset == 0 && entries[1].gen == 65535 && 299 entries[1].offset == 0 && entries[1].gen == 65535 &&
293 !entries[1].used) { 300 !entries[1].used) {
294 i = first = 0; 301 i = first = 0;
295 entries[0] = entries[1]; 302 entries[0] = entries[1];
296 entries[1].offset = -1; 303 entries[1].offset = 0xffffffff;
297 } 304 }
298 } 305 }
299 } 306 }
300 } 307 }
301 308
302 // read prev pointer from trailer dictionary 309 // read prev pointer from trailer dictionary
303 obj.initNull(); 310 obj.initNull();
304 parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(str->getPos(), 311 parser = new Parser(NULL,
305 -1, &obj))); 312 new Lexer(NULL,
313 str->makeSubStream(str->getPos(), gFalse, 0, &obj)));
306 parser->getObj(&obj); 314 parser->getObj(&obj);
307 if (!obj.isCmd("trailer")) { 315 if (!obj.isCmd("trailer")) {
308 goto err1; 316 goto err1;
309 } 317 }
310 obj.free(); 318 obj.free();
311 parser->getObj(&obj); 319 parser->getObj(&obj);
312 if (!obj.isDict()) { 320 if (!obj.isDict()) {
313 goto err1; 321 goto err1;
314 } 322 }
315 obj.getDict()->lookupNF("Prev", &obj2); 323 obj.getDict()->lookupNF("Prev", &obj2);
316 if (obj2.isInt()) { 324 if (obj2.isInt()) {
317 *pos = obj2.getInt(); 325 *pos = (Guint)obj2.getInt();
318 more = gTrue; 326 more = gTrue;
319 } else { 327 } else {
320 more = gFalse; 328 more = gFalse;
321 } 329 }
322 obj.free(); 330 obj.free();
323 obj2.free(); 331 obj2.free();
@@ -334,13 +342,13 @@ GBool XRef::readXRef(int *pos) {
334 342
335// Attempt to construct an xref table for a damaged file. 343// Attempt to construct an xref table for a damaged file.
336GBool XRef::constructXRef() { 344GBool XRef::constructXRef() {
337 Parser *parser; 345 Parser *parser;
338 Object obj; 346 Object obj;
339 char buf[256]; 347 char buf[256];
340 int pos; 348 Guint pos;
341 int num, gen; 349 int num, gen;
342 int newSize; 350 int newSize;
343 int streamEndsSize; 351 int streamEndsSize;
344 char *p; 352 char *p;
345 int i; 353 int i;
346 GBool gotRoot; 354 GBool gotRoot;
@@ -357,14 +365,15 @@ GBool XRef::constructXRef() {
357 } 365 }
358 p = buf; 366 p = buf;
359 367
360 // got trailer dictionary 368 // got trailer dictionary
361 if (!strncmp(p, "trailer", 7)) { 369 if (!strncmp(p, "trailer", 7)) {
362 obj.initNull(); 370 obj.initNull();
363 parser = new Parser(NULL, new Lexer(NULL, 371 parser = new Parser(NULL,
364 str->makeSubStream(start + pos + 7, -1, &obj))); 372 new Lexer(NULL,
373 str->makeSubStream(start + pos + 7, gFalse, 0, &obj)));
365 if (!trailerDict.isNone()) 374 if (!trailerDict.isNone())
366 trailerDict.free(); 375 trailerDict.free();
367 parser->getObj(&trailerDict); 376 parser->getObj(&trailerDict);
368 if (trailerDict.isDict()) { 377 if (trailerDict.isDict()) {
369 trailerDict.dictLookupNF("Root", &obj); 378 trailerDict.dictLookupNF("Root", &obj);
370 if (obj.isRef()) { 379 if (obj.isRef()) {
@@ -400,13 +409,13 @@ GBool XRef::constructXRef() {
400 if (!strncmp(p, "obj", 3)) { 409 if (!strncmp(p, "obj", 3)) {
401 if (num >= size) { 410 if (num >= size) {
402 newSize = (num + 1 + 255) & ~255; 411 newSize = (num + 1 + 255) & ~255;
403 entries = (XRefEntry *) 412 entries = (XRefEntry *)
404 grealloc(entries, newSize * sizeof(XRefEntry)); 413 grealloc(entries, newSize * sizeof(XRefEntry));
405 for (i = size; i < newSize; ++i) { 414 for (i = size; i < newSize; ++i) {
406 entries[i].offset = -1; 415 entries[i].offset = 0xffffffff;
407 entries[i].used = gFalse; 416 entries[i].used = gFalse;
408 } 417 }
409 size = newSize; 418 size = newSize;
410 } 419 }
411 if (!entries[num].used || gen >= entries[num].gen) { 420 if (!entries[num].used || gen >= entries[num].gen) {
412 entries[num].offset = pos - start; 421 entries[num].offset = pos - start;
@@ -418,13 +427,14 @@ GBool XRef::constructXRef() {
418 } 427 }
419 } 428 }
420 429
421 } else if (!strncmp(p, "endstream", 9)) { 430 } else if (!strncmp(p, "endstream", 9)) {
422 if (streamEndsLen == streamEndsSize) { 431 if (streamEndsLen == streamEndsSize) {
423 streamEndsSize += 64; 432 streamEndsSize += 64;
424 streamEnds = (int *)grealloc(streamEnds, streamEndsSize * sizeof(int)); 433 streamEnds = (Guint *)grealloc(streamEnds,
434 streamEndsSize * sizeof(int));
425 } 435 }
426 streamEnds[streamEndsLen++] = pos; 436 streamEnds[streamEndsLen++] = pos;
427 } 437 }
428 } 438 }
429 439
430 if (gotRoot) 440 if (gotRoot)
@@ -577,16 +587,17 @@ Object *XRef::fetch(int num, int gen, Object *obj) {
577 if (num < 0 || num >= size) { 587 if (num < 0 || num >= size) {
578 obj->initNull(); 588 obj->initNull();
579 return obj; 589 return obj;
580 } 590 }
581 591
582 e = &entries[num]; 592 e = &entries[num];
583 if (e->gen == gen && e->offset >= 0) { 593 if (e->gen == gen && e->offset != 0xffffffff) {
584 obj1.initNull(); 594 obj1.initNull();
585 parser = new Parser(this, new Lexer(this, 595 parser = new Parser(this,
586 str->makeSubStream(start + e->offset, -1, &obj1))); 596 new Lexer(this,
597 str->makeSubStream(start + e->offset, gFalse, 0, &obj1)));
587 parser->getObj(&obj1); 598 parser->getObj(&obj1);
588 parser->getObj(&obj2); 599 parser->getObj(&obj2);
589 parser->getObj(&obj3); 600 parser->getObj(&obj3);
590 if (obj1.isInt() && obj1.getInt() == num && 601 if (obj1.isInt() && obj1.getInt() == num &&
591 obj2.isInt() && obj2.getInt() == gen && 602 obj2.isInt() && obj2.getInt() == gen &&
592 obj3.isCmd("obj")) { 603 obj3.isCmd("obj")) {
@@ -615,18 +626,18 @@ Object *XRef::getDocInfo(Object *obj) {
615 626
616// Added for the pdftex project. 627// Added for the pdftex project.
617Object *XRef::getDocInfoNF(Object *obj) { 628Object *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;
630 b = streamEndsLen - 1; 641 b = streamEndsLen - 1;
631 // invariant: streamEnds[a] < streamStart <= streamEnds[b] 642 // invariant: streamEnds[a] < streamStart <= streamEnds[b]
632 while (b - a > 1) { 643 while (b - a > 1) {
@@ -634,8 +645,21 @@ int XRef::getStreamEnd(int streamStart) {
634 if (streamStart <= streamEnds[m]) { 645 if (streamStart <= streamEnds[m]) {
635 b = m; 646 b = m;
636 } else { 647 } else {
637 a = m; 648 a = m;
638 } 649 }
639 } 650 }
640 return streamEnds[b]; 651 *streamEnd = streamEnds[b];
652 return gTrue;
653}
654
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
@@ -1,11 +1,11 @@
1//======================================================================== 1//========================================================================
2// 2//
3// XRef.h 3// XRef.h
4// 4//
5// Copyright 1996 Derek B. Noonburg 5// Copyright 1996-2002 Glyph & Cog, LLC
6// 6//
7//======================================================================== 7//========================================================================
8 8
9#ifndef XREF_H 9#ifndef XREF_H
10#define XREF_H 10#define XREF_H
11 11
@@ -21,13 +21,13 @@ class Stream;
21 21
22//------------------------------------------------------------------------ 22//------------------------------------------------------------------------
23// XRef 23// XRef
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25 25
26struct XRefEntry { 26struct XRefEntry {
27 int offset; 27 Guint offset;
28 int gen; 28 int gen;
29 GBool used; 29 GBool used;
30}; 30};
31 31
32class XRef { 32class XRef {
33public: 33public:
@@ -38,12 +38,15 @@ public:
38 // Destructor. 38 // Destructor.
39 ~XRef(); 39 ~XRef();
40 40
41 // Is xref table valid? 41 // Is xref table valid?
42 GBool isOk() { return ok; } 42 GBool isOk() { return ok; }
43 43
44 // Get the error code (if isOk() returns false).
45 int getErrorCode() { return errCode; }
46
44 // Is the file encrypted? 47 // Is the file encrypted?
45#ifndef NO_DECRYPTION 48#ifndef NO_DECRYPTION
46 GBool isEncrypted() { return encrypted; } 49 GBool isEncrypted() { return encrypted; }
47#else 50#else
48 GBool isEncrypted() { return gFalse; } 51 GBool isEncrypted() { return gFalse; }
49#endif 52#endif
@@ -65,47 +68,49 @@ public:
65 Object *getDocInfoNF(Object *obj); 68 Object *getDocInfoNF(Object *obj);
66 69
67 // Return the number of objects in the xref table. 70 // Return the number of objects in the xref table.
68 int getNumObjects() { return size; } 71 int getNumObjects() { return size; }
69 72
70 // Return the offset of the last xref table. 73 // Return the offset of the last xref table.
71 int getLastXRefPos() { return lastXRefPos; } 74 Guint getLastXRefPos() { return lastXRefPos; }
72 75
73 // Return the catalog object reference. 76 // Return the catalog object reference.
74 int getRootNum() { return rootNum; } 77 int getRootNum() { return rootNum; }
75 int getRootGen() { return rootGen; } 78 int getRootGen() { return rootGen; }
76 79
77 // Get end position for a stream in a damaged file. 80 // Get end position for a stream in a damaged file.
78 // Returns -1 if unknown or file is not damaged. 81 // Returns false if unknown or file is not damaged.
79 int getStreamEnd(int streamStart); 82 GBool getStreamEnd(Guint streamStart, Guint *streamEnd);
80 83
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
96 GBool encrypted; // true if file is encrypted 100 GBool encrypted; // true if file is encrypted
97 int encVersion; // encryption algorithm 101 int encVersion; // encryption algorithm
98 int encRevision; // security handler revision 102 int encRevision; // security handler revision
99 int keyLength; // length of key, in bytes 103 int keyLength; // length of key, in bytes
100 int permFlags; // permission bits 104 int permFlags; // permission bits
101 Guchar fileKey[16]; // file decryption key 105 Guchar fileKey[16]; // file decryption key
102 GBool ownerPasswordOk;// true if owner password is correct 106 GBool ownerPasswordOk;// true if owner password is correct
103#endif 107#endif
104 108
105 int readTrailer(); 109 Guint readTrailer();
106 GBool readXRef(int *pos); 110 GBool readXRef(Guint *pos);
107 GBool constructXRef(); 111 GBool constructXRef();
108 GBool checkEncrypted(GString *ownerPassword, GString *userPassword); 112 GBool checkEncrypted(GString *ownerPassword, GString *userPassword);
113 Guint strToUnsigned(char *s);
109}; 114};
110 115
111#endif 116#endif