summaryrefslogtreecommitdiff
path: root/noncore/unsupported
authorsandman <sandman>2002-05-23 23:51:52 (UTC)
committer sandman <sandman>2002-05-23 23:51:52 (UTC)
commit2f3bb7b07f833273d966d41813e68bfe8b9d8d76 (patch) (unidiff)
tree00beb1bd9e7f4ba79e22334a0d258269b28f4564 /noncore/unsupported
parent6e82b45dd416ceeba78765717b700e853c96a137 (diff)
downloadopie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.zip
opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.gz
opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.bz2
Port to xpdf 1.01
Diffstat (limited to 'noncore/unsupported') (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
@@ -70,24 +70,31 @@ public:
70 // Destructor. 70 // Destructor.
71 virtual ~QOutputDev(); 71 virtual ~QOutputDev();
72 72
73 //---- get info about output device 73 //---- get info about output device
74 74
75 // Does this device use upside-down coordinates? 75 // Does this device use upside-down coordinates?
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.
88 virtual void endPage(); 95 virtual void endPage();
89 96
90 //----- link borders 97 //----- link borders
91 virtual void drawLink(Link *link, Catalog *catalog); 98 virtual void drawLink(Link *link, Catalog *catalog);
92 99
93 //----- save/restore graphics state 100 //----- save/restore graphics state
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,40 +1,47 @@
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.
11 - Fullscreen view added. 11 - Fullscreen view added.
12 12
13Changes in 20020407: 13Changes in 20020407:
14 - Crash with FontName == 0 fixed 14 - Crash with FontName == 0 fixed
15 - Cleanup 15 - Cleanup
16 - Prepare for CVS import 16 - Prepare for CVS import
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.
35 42
36 - No Font handling anymore - This means no embedded, no true-type, no type1- 43 - No Font handling anymore - This means no embedded, no true-type, no type1-
37 fonts. The task to choose the right font is up to the Qt QFont class. 44 fonts. The task to choose the right font is up to the Qt QFont class.
38 This works pretty well -- only Symbol fonts give problems. 45 This works pretty well -- only Symbol fonts give problems.
39 46
40 - Everything that should be rotated (fonts, images) is simply ignored, because 47 - Everything that should be rotated (fonts, images) is simply ignored, because
@@ -43,47 +50,31 @@ Changes to xpdf:
43 c) do you really need rotated images on your iPaq ? ;) 50 c) do you really need rotated images on your iPaq ? ;)
44 51
45 52
46ToDo: 53ToDo:
47 - Clipping has been deactivated, because Qt/E had problems with QPainter 54 - Clipping has been deactivated, because Qt/E had problems with QPainter
48 save/restore's with active clipping regions. I need to investigate this 55 save/restore's with active clipping regions. I need to investigate this
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
@@ -13,12 +13,26 @@
13static int mapUTF8 ( Unicode u, char *buf, int bufSize ) 13static int mapUTF8 ( Unicode u, char *buf, int bufSize )
14{ 14{
15 QCString utf = QString ( QChar ( u )). utf8 ( ); 15 QCString utf = QString ( QChar ( u )). utf8 ( );
16 int len = utf. length ( ); 16 int len = utf. length ( );
17 17
18 if ( len <= bufSize ) { 18 if ( len <= 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
@@ -7,45 +7,51 @@
7//======================================================================== 7//========================================================================
8 8
9#include "aconf.h" 9#include "aconf.h"
10#include "GString.h" 10#include "GString.h"
11#include "PDFDoc.h" 11#include "PDFDoc.h"
12#include "TextOutputDev.h" 12#include "TextOutputDev.h"
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>
31#include <qlineedit.h> 31#include <qlineedit.h>
32#include <qspinbox.h> 32#include <qspinbox.h>
33#include <qlayout.h> 33#include <qlayout.h>
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
46 globalParams = new GlobalParams ( "" ); 52 globalParams = new GlobalParams ( "" );
47 globalParams-> setErrQuiet ( true ); 53 globalParams-> setErrQuiet ( true );
48 54
49 QPdfDlg *dlg = new QPdfDlg ( ); 55 QPdfDlg *dlg = new QPdfDlg ( );
50 app. showMainDocumentWidget ( dlg ); 56 app. showMainDocumentWidget ( dlg );
51 57
@@ -72,25 +78,30 @@ QPdfDlg::QPdfDlg ( ) : QMainWindow ( )
72 m_renderok = false; 78 m_renderok = false;
73 79
74 80
75 setToolBarsMovable ( false ); 81 setToolBarsMovable ( false );
76 82
77 m_stack = new QWidgetStack ( this ); 83 m_stack = new QWidgetStack ( this );
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
91 QMenuBar *mb = new QMenuBar ( m_tb_menu ); 102 QMenuBar *mb = new QMenuBar ( m_tb_menu );
92 103
93 m_pm_zoom = new QPopupMenu ( mb ); 104 m_pm_zoom = new QPopupMenu ( mb );
94 m_pm_zoom-> setCheckable ( true ); 105 m_pm_zoom-> setCheckable ( true );
95 106
96 mb-> insertItem ( tr( "Zoom" ), m_pm_zoom ); 107 mb-> insertItem ( tr( "Zoom" ), m_pm_zoom );
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
@@ -1,25 +1,27 @@
1#ifndef __QPDF_H__ 1#ifndef __QPDF_H__
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
20 22
21public: 23public:
22 QPdfDlg ( ); 24 QPdfDlg ( );
23 virtual ~QPdfDlg ( ); 25 virtual ~QPdfDlg ( );
24 26
25public slots: 27public slots:
@@ -59,25 +61,30 @@ protected:
59 61
60 void setBusy ( bool b = true ); 62 void setBusy ( bool b = true );
61 bool busy ( ) const; 63 bool busy ( ) const;
62 64
63 void renderPage ( ); 65 void renderPage ( );
64 66
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;
78 85
79 bool m_fullscreen; 86 bool m_fullscreen;
80 87
81 bool m_busy; 88 bool m_busy;
82 bool m_renderok; 89 bool m_renderok;
83 90
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
@@ -4,38 +4,39 @@ CONFIG *= qt embedded release warn_off
4CONFIG -= warn_on 4CONFIG -= warn_on
5 5
6SOURCES = xpdf/Array.cc \ 6SOURCES = xpdf/Array.cc \
7 xpdf/BuiltinFont.cc \ 7 xpdf/BuiltinFont.cc \
8 xpdf/BuiltinFontTables.cc \ 8 xpdf/BuiltinFontTables.cc \
9 xpdf/CMap.cc \ 9 xpdf/CMap.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 \
23 xpdf/Link.cc \ 23 xpdf/Link.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 \
36 goo/GList.cc \ 37 goo/GList.cc \
37 QOutputDev.cpp \ 38 QOutputDev.cpp \
38 QPEOutputDev.cpp \ 39 QPEOutputDev.cpp \
39 qpdf.cpp \ 40 qpdf.cpp \
40 qbusybar.cpp \ 41 qbusybar.cpp \
41 gooStub.cpp 42 gooStub.cpp
@@ -43,18 +44,18 @@ SOURCES = xpdf/Array.cc \
43HEADERS = QOutputDev.h \ 44HEADERS = QOutputDev.h \
44 QPEOutputDev.h \ 45 QPEOutputDev.h \
45 qbusybar.h \ 46 qbusybar.h \
46 qpdf.h 47 qpdf.h
47 48
48INCLUDEPATH += . \ 49INCLUDEPATH += . \
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,35 +1,35 @@
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
30 if (dict->lookup("AP", &apObj)->isDict()) { 30 if (dict->lookup("AP", &apObj)->isDict()) {
31 if (dict->lookup("AS", &asObj)->isName()) { 31 if (dict->lookup("AS", &asObj)->isName()) {
32 if (apObj.dictLookup("N", &obj1)->isDict()) { 32 if (apObj.dictLookup("N", &obj1)->isDict()) {
33 if (obj1.dictLookupNF(asObj.getName(), &obj2)->isRef()) { 33 if (obj1.dictLookupNF(asObj.getName(), &obj2)->isRef()) {
34 obj2.copy(&appearance); 34 obj2.copy(&appearance);
35 ok = gTrue; 35 ok = gTrue;
@@ -68,72 +68,71 @@ FormWidget::FormWidget(XRef *xrefA, Dict *dict) {
68 } 68 }
69 if (yMin > yMax) { 69 if (yMin > yMax) {
70 t = yMin; yMin = yMax; yMax = t; 70 t = yMin; yMin = yMax; yMax = t;
71 } 71 }
72 } else { 72 } else {
73 //~ this should return an error 73 //~ this should return an error
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include "gmem.h" 15#include "gmem.h"
16#include "Object.h" 16#include "Object.h"
17#include "Array.h" 17#include "Array.h"
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "Object.h" 16#include "Object.h"
17 17
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17 17
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,17 +1,17 @@
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"
12#include "BuiltinFontTables.h" 12#include "BuiltinFontTables.h"
13 13
14static BuiltinFontWidth courierWidthsTab[] = { 14static BuiltinFontWidth courierWidthsTab[] = {
15 { "Ntilde", 600, NULL }, 15 { "Ntilde", 600, NULL },
16 { "comma", 600, NULL }, 16 { "comma", 600, NULL },
17 { "cedilla", 600, NULL }, 17 { "cedilla", 600, NULL },
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,17 +1,17 @@
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
12#include "BuiltinFont.h" 12#include "BuiltinFont.h"
13 13
14#define nBuiltinFonts 14 14#define nBuiltinFonts 14
15#define nBuiltinFontSubsts 12 15#define nBuiltinFontSubsts 12
16 16
17extern BuiltinFont builtinFonts[nBuiltinFonts]; 17extern BuiltinFont builtinFonts[nBuiltinFonts];
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,119 +1,139 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <stdlib.h> 15#include <stdlib.h>
16#include <string.h> 16#include <string.h>
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;
29 union { 30 union {
30 CMapVectorEntry *vector; 31 CMapVectorEntry *vector;
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);
52 } 58 }
53 if (!cMapNameA->cmp("Identity-V")) { 59 if (!cMapNameA->cmp("Identity-V")) {
54 return new CMap(collectionA->copy(), cMapNameA->copy(), 1); 60 return new CMap(collectionA->copy(), cMapNameA->copy(), 1);
55 } 61 }
56 62
57 error(-1, "Couldn't find '%s' CMap file for '%s' collection", 63 error(-1, "Couldn't find '%s' CMap file for '%s' collection",
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
114CMap::CMap(GString *collectionA, GString *cMapNameA) { 134CMap::CMap(GString *collectionA, GString *cMapNameA) {
115 int i; 135 int i;
116 136
117 collection = collectionA; 137 collection = collectionA;
118 cMapName = cMapNameA; 138 cMapName = cMapNameA;
119 wMode = 0; 139 wMode = 0;
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17#include "CharTypes.h" 17#include "CharTypes.h"
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include "gmem.h" 15#include "gmem.h"
16#include "Object.h" 16#include "Object.h"
17#include "XRef.h" 17#include "XRef.h"
@@ -137,25 +137,25 @@ Catalog::~Catalog() {
137 137
138GString *Catalog::readMetadata() { 138GString *Catalog::readMetadata() {
139 GString *s; 139 GString *s;
140 Dict *dict; 140 Dict *dict;
141 Object obj; 141 Object obj;
142 int c; 142 int c;
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) {
156 s->append(c); 156 s->append(c);
157 } 157 }
158 metadata.streamClose(); 158 metadata.streamClose();
159 return s; 159 return s;
160} 160}
161 161
@@ -256,28 +256,28 @@ LinkDest *Catalog::findDest(GString *name) {
256 if (!found && nameTree.isDict()) { 256 if (!found && nameTree.isDict()) {
257 if (!findDestInTree(&nameTree, name, &obj1)->isNull()) 257 if (!findDestInTree(&nameTree, name, &obj1)->isNull())
258 found = gTrue; 258 found = gTrue;
259 else 259 else
260 obj1.free(); 260 obj1.free();
261 } 261 }
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 }
278 obj1.free(); 278 obj1.free();
279 279
280 return dest; 280 return dest;
281} 281}
282 282
283Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) { 283Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) {
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16class XRef; 16class XRef;
17class Object; 17class Object;
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,46 +1,67 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
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
27struct CharCodeToUnicodeString { 28struct CharCodeToUnicodeString {
28 CharCode c; 29 CharCode c;
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;
41 CharCodeToUnicode *ctu; 62 CharCodeToUnicode *ctu;
42 63
43 if (!(f = globalParams->getCIDToUnicodeFile(collectionA))) { 64 if (!(f = globalParams->getCIDToUnicodeFile(collectionA))) {
44 error(-1, "Couldn't find cidToUnicode file for the '%s' collection", 65 error(-1, "Couldn't find cidToUnicode file for the '%s' collection",
45 collectionA->getCString()); 66 collectionA->getCString());
46 return NULL; 67 return NULL;
@@ -66,211 +87,186 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) {
66 } 87 }
67 88
68 ctu = new CharCodeToUnicode(collectionA->copy(), mapA, mapLenA, gTrue, 89 ctu = new CharCodeToUnicode(collectionA->copy(), mapA, mapLenA, gTrue,
69 NULL, 0); 90 NULL, 0);
70 gfree(mapA); 91 gfree(mapA);
71 return ctu; 92 return ctu;
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) {
170 sMapSize += 8; 176 sMapSize += 8;
171 sMap = (CharCodeToUnicodeString *) 177 sMap = (CharCodeToUnicodeString *)
172 grealloc(sMap, sMapSize * sizeof(CharCodeToUnicodeString)); 178 grealloc(sMap, sMapSize * sizeof(CharCodeToUnicodeString));
173 } 179 }
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 {
224 if (sMapLen + (int)(code2 - code1 + 1) > sMapSize) { 234 if (sMapLen + (int)(code2 - code1 + 1) > sMapSize) {
225 sMapSize = (sMapSize + (code2 - code1 + 1) + 7) & ~7; 235 sMapSize = (sMapSize + (code2 - code1 + 1) + 7) & ~7;
226 sMap = (CharCodeToUnicodeString *) 236 sMap = (CharCodeToUnicodeString *)
227 grealloc(sMap, sMapSize * sizeof(CharCodeToUnicodeString)); 237 grealloc(sMap, sMapSize * sizeof(CharCodeToUnicodeString));
228 } 238 }
229 for (i = 0; code1 <= code2; ++code1, ++i) { 239 for (i = 0; code1 <= code2; ++code1, ++i) {
230 map[code1] = 0; 240 map[code1] = 0;
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;
271 mapLen = 256; 267 mapLen = 256;
272 map = (Unicode *)gmalloc(mapLen * sizeof(Unicode)); 268 map = (Unicode *)gmalloc(mapLen * sizeof(Unicode));
273 for (i = 0; i < mapLen; ++i) { 269 for (i = 0; i < mapLen; ++i) {
274 map[i] = 0; 270 map[i] = 0;
275 } 271 }
276 sMap = NULL; 272 sMap = NULL;
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,19 +1,19 @@
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
14#ifdef __GNUC__ 14#ifdef __GNUC__
15#pragma interface 15#pragma interface
16#endif 16#endif
17 17
18#include "CharTypes.h" 18#include "CharTypes.h"
19 19
@@ -41,26 +41,25 @@ public:
41 41
42 void incRefCnt(); 42 void incRefCnt();
43 void decRefCnt(); 43 void decRefCnt();
44 44
45 // Return true if this mapping matches the specified <collectionA>. 45 // Return true if this mapping matches the specified <collectionA>.
46 GBool match(GString *collectionA); 46 GBool match(GString *collectionA);
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;
61 Unicode *map; 60 Unicode *map;
62 CharCode mapLen; 61 CharCode mapLen;
63 CharCodeToUnicodeString *sMap; 62 CharCodeToUnicodeString *sMap;
64 int sMapLen, sMapSize; 63 int sMapLen, sMapSize;
65 int refCnt; 64 int refCnt;
66}; 65};
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,17 +1,17 @@
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
12// Unicode character. 12// Unicode character.
13typedef unsigned int Unicode; 13typedef unsigned int Unicode;
14 14
15// Character ID for CID character collections. 15// Character ID for CID character collections.
16typedef unsigned int CID; 16typedef unsigned int CID;
17 17
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include "gmem.h" 14#include "gmem.h"
15#include "Decrypt.h" 15#include "Decrypt.h"
16 16
17static void rc4InitKey(Guchar *key, int keyLen, Guchar *state); 17static void rc4InitKey(Guchar *key, int keyLen, Guchar *state);
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17#include "GString.h" 17#include "GString.h"
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include <string.h> 15#include <string.h>
16#include "gmem.h" 16#include "gmem.h"
17#include "Object.h" 17#include "Object.h"
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "Object.h" 16#include "Object.h"
17 17
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,31 +1,31 @@
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"},
21 {"Helvetica-BoldOblique", "-*-helvetica-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 21 {"Helvetica-BoldOblique", "-*-helvetica-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
22 {"Helvetica-Oblique", "-*-helvetica-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, 22 {"Helvetica-Oblique", "-*-helvetica-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
23 {"Symbol", "-*-symbol-medium-r-normal-*-%s-*-*-*-*-*-adobe-fontspecific", "Symbol"}, 23 {"Symbol", "-*-symbol-medium-r-normal-*-%s-*-*-*-*-*-adobe-fontspecific", "Symbol"},
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <stddef.h> 15#include <stddef.h>
16#include <stdarg.h> 16#include <stdarg.h>
17#include "GlobalParams.h" 17#include "GlobalParams.h"
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include <stdio.h> 16#include <stdio.h>
17#include "config.h" 17#include "config.h"
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,17 +1,17 @@
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"
12 12
13char *macRomanEncoding[256] = { 13char *macRomanEncoding[256] = {
14 NULL, 14 NULL,
15 NULL, 15 NULL,
16 NULL, 16 NULL,
17 NULL, 17 NULL,
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,17 +1,17 @@
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
12extern char *macRomanEncoding[]; 12extern char *macRomanEncoding[];
13extern char *macExpertEncoding[]; 13extern char *macExpertEncoding[];
14extern char *winAnsiEncoding[]; 14extern char *winAnsiEncoding[];
15extern char *standardEncoding[]; 15extern char *standardEncoding[];
16extern char *expertEncoding[]; 16extern char *expertEncoding[];
17extern char *symbolEncoding[]; 17extern char *symbolEncoding[];
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdlib.h> 14#include <stdlib.h>
15#include <string.h> 15#include <string.h>
16#include <ctype.h> 16#include <ctype.h>
17#include <math.h> 17#include <math.h>
@@ -406,89 +406,98 @@ void SampledFunction::transform(fouble *in, fouble *out) {
406} 406}
407 407
408//------------------------------------------------------------------------ 408//------------------------------------------------------------------------
409// ExponentialFunction 409// ExponentialFunction
410//------------------------------------------------------------------------ 410//------------------------------------------------------------------------
411 411
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);
445 if (!obj2.isNum()) { 446 if (!obj2.isNum()) {
446 error(-1, "Illegal value in function C0 array"); 447 error(-1, "Illegal value in function C0 array");
447 goto err3; 448 goto err3;
448 } 449 }
449 c0[i] = obj2.getNum(); 450 c0[i] = obj2.getNum();
450 obj2.free(); 451 obj2.free();
451 } 452 }
452 } 453 }
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);
465 if (!obj2.isNum()) { 467 if (!obj2.isNum()) {
466 error(-1, "Illegal value in function C1 array"); 468 error(-1, "Illegal value in function C1 array");
467 goto err3; 469 goto err3;
468 } 470 }
469 c1[i] = obj2.getNum(); 471 c1[i] = obj2.getNum();
470 obj2.free(); 472 obj2.free();
471 } 473 }
472 } 474 }
473 obj1.free(); 475 obj1.free();
474 476
475 //----- N (exponent) 477 //----- N (exponent)
476 if (!dict->lookup("N", &obj1)->isNum()) { 478 if (!dict->lookup("N", &obj1)->isNum()) {
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:
489 obj1.free(); 498 obj1.free();
490 err1: 499 err1:
491 return; 500 return;
492} 501}
493 502
494ExponentialFunction::~ExponentialFunction() { 503ExponentialFunction::~ExponentialFunction() {
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17#include "Object.h" 17#include "Object.h"
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <stddef.h> 15#include <stddef.h>
16#include <string.h> 16#include <string.h>
17#include <math.h> 17#include <math.h>
@@ -21,34 +21,45 @@
21#include "Array.h" 21#include "Array.h"
22#include "Dict.h" 22#include "Dict.h"
23#include "Stream.h" 23#include "Stream.h"
24#include "Lexer.h" 24#include "Lexer.h"
25#include "Parser.h" 25#include "Parser.h"
26#include "GfxFont.h" 26#include "GfxFont.h"
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},
49 &Gfx::opMoveSetShowText}, 60 &Gfx::opMoveSetShowText},
50 {"'", 1, {tchkString}, 61 {"'", 1, {tchkString},
51 &Gfx::opMoveShowText}, 62 &Gfx::opMoveShowText},
52 {"B", 0, {tchkNone}, 63 {"B", 0, {tchkNone},
53 &Gfx::opFillStroke}, 64 &Gfx::opFillStroke},
54 {"B*", 0, {tchkNone}, 65 {"B*", 0, {tchkNone},
@@ -365,24 +376,25 @@ GBool GfxResources::lookupGState(char *name, Object *obj) {
365} 376}
366 377
367//------------------------------------------------------------------------ 378//------------------------------------------------------------------------
368// Gfx 379// Gfx
369//------------------------------------------------------------------------ 380//------------------------------------------------------------------------
370 381
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
383 out = outA; 395 out = outA;
384 state = new GfxState(dpi, box, rotate, out->upsideDown()); 396 state = new GfxState(dpi, box, rotate, out->upsideDown());
385 fontChanged = gFalse; 397 fontChanged = gFalse;
386 clip = clipNone; 398 clip = clipNone;
387 ignoreUndef = 0; 399 ignoreUndef = 0;
388 out->startPage(pageNum, state); 400 out->startPage(pageNum, state);
@@ -396,39 +408,72 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
396 if (crop) { 408 if (crop) {
397 state->moveTo(cropBox->x1, cropBox->y1); 409 state->moveTo(cropBox->x1, cropBox->y1);
398 state->lineTo(cropBox->x2, cropBox->y1); 410 state->lineTo(cropBox->x2, cropBox->y1);
399 state->lineTo(cropBox->x2, cropBox->y2); 411 state->lineTo(cropBox->x2, cropBox->y2);
400 state->lineTo(cropBox->x1, cropBox->y2); 412 state->lineTo(cropBox->x1, cropBox->y2);
401 state->closePath(); 413 state->closePath();
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
429 if (obj->isArray()) { 474 if (obj->isArray()) {
430 for (i = 0; i < obj->arrayGetLength(); ++i) { 475 for (i = 0; i < obj->arrayGetLength(); ++i) {
431 obj->arrayGet(i, &obj2); 476 obj->arrayGet(i, &obj2);
432 if (!obj2.isStream()) { 477 if (!obj2.isStream()) {
433 error(-1, "Weird page contents"); 478 error(-1, "Weird page contents");
434 obj2.free(); 479 obj2.free();
@@ -440,54 +485,54 @@ void Gfx::display(Object *obj, GBool topLevel) {
440 error(-1, "Weird page contents"); 485 error(-1, "Weird page contents");
441 return; 486 return;
442 } 487 }
443 parser = new Parser(xref, new Lexer(xref, obj)); 488 parser = new Parser(xref, new Lexer(xref, obj));
444 go(topLevel); 489 go(topLevel);
445 delete parser; 490 delete parser;
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()) {
463 if (printCommands) { 508 if (printCommands) {
464 obj.print(stdout); 509 obj.print(stdout);
465 for (i = 0; i < numArgs; ++i) { 510 for (i = 0; i < numArgs; ++i) {
466 printf(" "); 511 printf(" ");
467 args[i].print(stdout); 512 args[i].print(stdout);
468 } 513 }
469 printf("\n"); 514 printf("\n");
470 fflush(stdout); 515 fflush(stdout);
471 } 516 }
472 execOp(&obj, args, numArgs); 517 execOp(&obj, args, numArgs);
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
488 // too many arguments - something is wrong 533 // too many arguments - something is wrong
489 } else { 534 } else {
490 error(getPos(), "Too many args in content stream"); 535 error(getPos(), "Too many args in content stream");
491 if (printCommands) { 536 if (printCommands) {
492 printf("throwing away arg: "); 537 printf("throwing away arg: ");
493 obj.print(stdout); 538 obj.print(stdout);
@@ -510,25 +555,25 @@ void Gfx::go(GBool topLevel) {
510 for (i = 0; i < numArgs; ++i) { 555 for (i = 0; i < numArgs; ++i) {
511 printf(" "); 556 printf(" ");
512 args[i].print(stdout); 557 args[i].print(stdout);
513 } 558 }
514 printf("\n"); 559 printf("\n");
515 fflush(stdout); 560 fflush(stdout);
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;
529 char *name; 574 char *name;
530 int i; 575 int i;
531 576
532 // find operator 577 // find operator
533 name = cmd->getName(); 578 name = cmd->getName();
534 if (!(op = findOp(name))) { 579 if (!(op = findOp(name))) {
@@ -1129,25 +1174,25 @@ void Gfx::opCloseEOFillStroke(Object args[], int numArgs) {
1129 doEndPath(); 1174 doEndPath();
1130} 1175}
1131 1176
1132void Gfx::doPatternFill(GBool eoFill) { 1177void Gfx::doPatternFill(GBool eoFill) {
1133 GfxPatternColorSpace *patCS; 1178 GfxPatternColorSpace *patCS;
1134 GfxPattern *pattern; 1179 GfxPattern *pattern;
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
1148 // certainly don't contain any text 1193 // certainly don't contain any text
1149 if (!out->needNonText()) { 1194 if (!out->needNonText()) {
1150 return; 1195 return;
1151 } 1196 }
1152 1197
1153 // get color space 1198 // get color space
@@ -1180,33 +1225,24 @@ void Gfx::doPatternFill(GBool eoFill) {
1180 m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2]; 1225 m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2];
1181 m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3]; 1226 m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3];
1182 m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4]; 1227 m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4];
1183 m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5]; 1228 m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5];
1184 // m = m1 * iCTM = (PTM * BTM) * (iCTM) 1229 // m = m1 * iCTM = (PTM * BTM) * (iCTM)
1185 m[0] = m1[0] * ictm[0] + m1[1] * ictm[2]; 1230 m[0] = m1[0] * ictm[0] + m1[1] * ictm[2];
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;
1207 imb[4] = (m1[2] * m1[5] - m1[3] * m1[4]) * det; 1243 imb[4] = (m1[2] * m1[5] - m1[3] * m1[4]) * det;
1208 imb[5] = (m1[1] * m1[4] - m1[0] * m1[5]) * det; 1244 imb[5] = (m1[1] * m1[4] - m1[0] * m1[5]) * det;
1209 1245
1210 // save current graphics state 1246 // save current graphics state
1211 out->saveState(state); 1247 out->saveState(state);
1212 state = state->save(); 1248 state = state->save();
@@ -1322,98 +1358,52 @@ void Gfx::opShFill(Object args[], int numArgs) {
1322 out->clip(state); 1358 out->clip(state);
1323 state->clearPath(); 1359 state->clearPath();
1324 } 1360 }
1325 1361
1326 // set the color space 1362 // set the color space
1327 state->setFillColorSpace(shading->getColorSpace()->copy()); 1363 state->setFillColorSpace(shading->getColorSpace()->copy());
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;
1414 mul = 1 / (dx * dx + dy * dy); 1404 mul = 1 / (dx * dx + dy * dy);
1415 tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul; 1405 tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul;
1416 t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul; 1406 t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul;
1417 if (t < tMin) { 1407 if (t < tMin) {
1418 tMin = t; 1408 tMin = t;
1419 } else if (t > tMax) { 1409 } else if (t > tMax) {
@@ -1610,24 +1600,220 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
1610 state->clearPath(); 1600 state->clearPath();
1611 1601
1612 // set up for next region 1602 // set up for next region
1613 ux0 = ux1; 1603 ux0 = ux1;
1614 uy0 = uy1; 1604 uy0 = uy1;
1615 vx0 = vx1; 1605 vx0 = vx1;
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 {
1628 out->eoClip(state); 1814 out->eoClip(state);
1629 } 1815 }
1630 } 1816 }
1631 clip = clipNone; 1817 clip = clipNone;
1632 state->clearPath(); 1818 state->clearPath();
1633} 1819}
@@ -1791,192 +1977,229 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) {
1791 tx = state->getLineX(); 1977 tx = state->getLineX();
1792 ty = state->getLineY() - state->getLeading(); 1978 ty = state->getLineY() - state->getLeading();
1793 state->textMoveTo(tx, ty); 1979 state->textMoveTo(tx, ty);
1794 out->updateWordSpace(state); 1980 out->updateWordSpace(state);
1795 out->updateCharSpace(state); 1981 out->updateCharSpace(state);
1796 out->updateTextPos(state); 1982 out->updateTextPos(state);
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];
1857 newCTM[1] = mat[0] * oldCTM[1] + mat[1] * oldCTM[3]; 2051 newCTM[1] = mat[0] * oldCTM[1] + mat[1] * oldCTM[3];
1858 newCTM[2] = mat[2] * oldCTM[0] + mat[3] * oldCTM[2]; 2052 newCTM[2] = mat[2] * oldCTM[0] + mat[3] * oldCTM[2];
1859 newCTM[3] = mat[2] * oldCTM[1] + mat[3] * oldCTM[3]; 2053 newCTM[3] = mat[2] * oldCTM[1] + mat[3] * oldCTM[3];
1860 mat = font->getFontMatrix(); 2054 mat = font->getFontMatrix();
1861 newCTM[0] = mat[0] * newCTM[0] + mat[1] * newCTM[2]; 2055 newCTM[0] = mat[0] * newCTM[0] + mat[1] * newCTM[2];
1862 newCTM[1] = mat[0] * newCTM[1] + mat[1] * newCTM[3]; 2056 newCTM[1] = mat[0] * newCTM[1] + mat[1] * newCTM[3];
1863 newCTM[2] = mat[2] * newCTM[0] + mat[3] * newCTM[2]; 2057 newCTM[2] = mat[2] * newCTM[0] + mat[3] * newCTM[2];
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;
1941 while (len > 0) { 2151 while (len > 0) {
1942 n = font->getNextChar(p, len, &code, 2152 n = font->getNextChar(p, len, &code,
1943 u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, 2153 u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
1944 &dx2, &dy2, &originX, &originY); 2154 &dx2, &dy2, &originX, &originY);
1945 dx += dx2; 2155 dx += dx2;
1946 dy += dy2; 2156 dy += dy2;
1947 if (n == 1 && *p == ' ') { 2157 if (n == 1 && *p == ' ') {
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;
1977 } 2200 }
1978 if (!obj1.isStream()) { 2201 if (!obj1.isStream()) {
1979 error(getPos(), "XObject '%s' is wrong type", args[0].getName()); 2202 error(getPos(), "XObject '%s' is wrong type", args[0].getName());
1980 obj1.free(); 2203 obj1.free();
1981 return; 2204 return;
1982 } 2205 }
@@ -1984,24 +2207,28 @@ void Gfx::opXObject(Object args[], int numArgs) {
1984 obj1.streamGetDict()->lookup("OPI", &opiDict); 2207 obj1.streamGetDict()->lookup("OPI", &opiDict);
1985 if (opiDict.isDict()) { 2208 if (opiDict.isDict()) {
1986 out->opiBegin(state, opiDict.getDict()); 2209 out->opiBegin(state, opiDict.getDict());
1987 } 2210 }
1988#endif 2211#endif
1989 obj1.streamGetDict()->lookup("Subtype", &obj2); 2212 obj1.streamGetDict()->lookup("Subtype", &obj2);
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();
2002#if OPI_SUPPORT 2229#if OPI_SUPPORT
2003 if (opiDict.isDict()) { 2230 if (opiDict.isDict()) {
2004 out->opiEnd(state, opiDict.getDict()); 2231 out->opiEnd(state, opiDict.getDict());
2005 } 2232 }
2006 opiDict.free(); 2233 opiDict.free();
2007#endif 2234#endif
@@ -2139,24 +2366,29 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
2139 } 2366 }
2140 haveMask = gTrue; 2367 haveMask = gTrue;
2141 } 2368 }
2142 2369
2143 // draw it 2370 // draw it
2144 out->drawImage(state, ref, str, width, height, colorMap, 2371 out->drawImage(state, ref, str, width, height, colorMap,
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");
2157} 2389}
2158 2390
2159void Gfx::doForm(Object *str) { 2391void Gfx::doForm(Object *str) {
2160 Dict *dict; 2392 Dict *dict;
2161 Object matrixObj, bboxObj; 2393 Object matrixObj, bboxObj;
2162 fouble m[6], bbox[6]; 2394 fouble m[6], bbox[6];
@@ -2206,95 +2438,145 @@ void Gfx::doForm(Object *str) {
2206 matrixObj.free(); 2438 matrixObj.free();
2207 2439
2208 // get resources 2440 // get resources
2209 dict->lookup("Resources", &resObj); 2441 dict->lookup("Resources", &resObj);
2210 resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; 2442 resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL;
2211 2443
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 }
2237 for (i = 0; i < 4; ++i) { 2472 for (i = 0; i < 4; ++i) {
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();
2251 } 2486 }
2252 } else { 2487 } else {
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
2275 doForm1(str, resDict, m, bbox); 2558 doForm1(str, resDict, m, bbox);
2276 2559
2277 resObj.free(); 2560 resObj.free();
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
2295 oldParser = parser; 2577 oldParser = parser;
2296 2578
2297 // set form transformation matrix 2579 // set form transformation matrix
2298 state->concatCTM(matrix[0], matrix[1], matrix[2], 2580 state->concatCTM(matrix[0], matrix[1], matrix[2],
2299 matrix[3], matrix[4], matrix[5]); 2581 matrix[3], matrix[4], matrix[5]);
2300 out->updateCTM(state, matrix[0], matrix[1], matrix[2], 2582 out->updateCTM(state, matrix[0], matrix[1], matrix[2],
@@ -2323,29 +2605,39 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
2323 for (i = 0; i < 6; ++i) { 2605 for (i = 0; i < 6; ++i) {
2324 baseMatrix[i] = oldBaseMatrix[i]; 2606 baseMatrix[i] = oldBaseMatrix[i];
2325 } 2607 }
2326 2608
2327 // restore parser 2609 // restore parser
2328 parser = oldParser; 2610 parser = oldParser;
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
2346void Gfx::opBeginImage(Object args[], int numArgs) { 2638void Gfx::opBeginImage(Object args[], int numArgs) {
2347 Stream *str; 2639 Stream *str;
2348 int c1, c2; 2640 int c1, c2;
2349 2641
2350 // build dict/stream 2642 // build dict/stream
2351 str = buildImageStream(); 2643 str = buildImageStream();
@@ -2369,64 +2661,71 @@ Stream *Gfx::buildImageStream() {
2369 Object dict; 2661 Object dict;
2370 Object obj; 2662 Object obj;
2371 char *key; 2663 char *key;
2372 Stream *str; 2664 Stream *str;
2373 2665
2374 // build dictionary 2666 // build dictionary
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
2400 return str; 2697 return str;
2401} 2698}
2402 2699
2403void Gfx::opImageData(Object args[], int numArgs) { 2700void Gfx::opImageData(Object args[], int numArgs) {
2404 error(getPos(), "Internal: got 'ID' operator"); 2701 error(getPos(), "Internal: got 'ID' operator");
2405} 2702}
2406 2703
2407void Gfx::opEndImage(Object args[], int numArgs) { 2704void Gfx::opEndImage(Object args[], int numArgs) {
2408 error(getPos(), "Internal: got 'EI' operator"); 2705 error(getPos(), "Internal: got 'EI' operator");
2409} 2706}
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
2427void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) { 2726void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) {
2428 ++ignoreUndef; 2727 ++ignoreUndef;
2429} 2728}
2430 2729
2431void Gfx::opEndIgnoreUndef(Object args[], int numArgs) { 2730void Gfx::opEndIgnoreUndef(Object args[], int numArgs) {
2432 if (ignoreUndef > 0) 2731 if (ignoreUndef > 0)
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,41 +1,42 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17 17
18class GString; 18class GString;
19class XRef; 19class XRef;
20class Array; 20class Array;
21class Stream; 21class Stream;
22class Parser; 22class Parser;
23class Dict; 23class 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
36//------------------------------------------------------------------------ 37//------------------------------------------------------------------------
37 38
38enum GfxClipType { 39enum GfxClipType {
39 clipNone, 40 clipNone,
40 clipNormal, 41 clipNormal,
41 clipEO 42 clipEO
@@ -88,39 +89,49 @@ private:
88 Object gStateDict; 89 Object gStateDict;
89 GfxResources *next; 90 GfxResources *next;
90}; 91};
91 92
92class Gfx { 93class Gfx {
93public: 94public:
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
121 // page/form/pattern 132 // page/form/pattern
122 133
123 Parser *parser; // parser for page content stream(s) 134 Parser *parser; // parser for page content stream(s)
124 135
125 static Operator opTab[];// table of operators 136 static Operator opTab[];// table of operators
126 137
@@ -170,24 +181,25 @@ private:
170 void opEndPath(Object args[], int numArgs); 181 void opEndPath(Object args[], int numArgs);
171 void opStroke(Object args[], int numArgs); 182 void opStroke(Object args[], int numArgs);
172 void opCloseStroke(Object args[], int numArgs); 183 void opCloseStroke(Object args[], int numArgs);
173 void opFill(Object args[], int numArgs); 184 void opFill(Object args[], int numArgs);
174 void opEOFill(Object args[], int numArgs); 185 void opEOFill(Object args[], int numArgs);
175 void opFillStroke(Object args[], int numArgs); 186 void opFillStroke(Object args[], int numArgs);
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
188 // text object operators 200 // text object operators
189 void opBeginText(Object args[], int numArgs); 201 void opBeginText(Object args[], int numArgs);
190 void opEndText(Object args[], int numArgs); 202 void opEndText(Object args[], int numArgs);
191 203
192 // text state operators 204 // text state operators
193 void opSetCharSpacing(Object args[], int numArgs); 205 void opSetCharSpacing(Object args[], int numArgs);
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <stdlib.h> 15#include <stdlib.h>
16#include <string.h> 16#include <string.h>
17#include <ctype.h> 17#include <ctype.h>
@@ -445,31 +445,42 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
445 fontMat[0] = fontMat[3] = 1; 445 fontMat[0] = fontMat[3] = 1;
446 fontMat[1] = fontMat[2] = fontMat[4] = fontMat[5] = 0; 446 fontMat[1] = fontMat[2] = fontMat[4] = fontMat[5] = 0;
447 if (fontDict->lookup("FontMatrix", &obj1)->isArray()) { 447 if (fontDict->lookup("FontMatrix", &obj1)->isArray()) {
448 for (i = 0; i < 6 && i < obj1.arrayGetLength(); ++i) { 448 for (i = 0; i < 6 && i < obj1.arrayGetLength(); ++i) {
449 if (obj1.arrayGet(i, &obj2)->isNum()) { 449 if (obj1.arrayGet(i, &obj2)->isNum()) {
450 fontMat[i] = obj2.getNum(); 450 fontMat[i] = obj2.getNum();
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):
470 // 1. FontDict.Encoding or FontDict.Encoding.BaseEncoding 481 // 1. FontDict.Encoding or FontDict.Encoding.BaseEncoding
471 // - MacRoman / MacExpert / WinAnsi / Standard 482 // - MacRoman / MacExpert / WinAnsi / Standard
472 // 2. embedded or external font file 483 // 2. embedded or external font file
473 // 3. default: 484 // 3. default:
474 // - builtin --> builtin encoding 485 // - builtin --> builtin encoding
475 // - TrueType --> MacRomanEncoding 486 // - TrueType --> MacRomanEncoding
@@ -504,41 +515,46 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
504 } else if (obj1.isName("MacExpertEncoding")) { 515 } else if (obj1.isName("MacExpertEncoding")) {
505 hasEncoding = gTrue; 516 hasEncoding = gTrue;
506 baseEnc = macExpertEncoding; 517 baseEnc = macExpertEncoding;
507 } else if (obj1.isName("WinAnsiEncoding")) { 518 } else if (obj1.isName("WinAnsiEncoding")) {
508 hasEncoding = gTrue; 519 hasEncoding = gTrue;
509 baseEnc = winAnsiEncoding; 520 baseEnc = winAnsiEncoding;
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());
539 } 555 }
540 if (!baseEnc) { 556 if (!baseEnc) {
541 baseEnc = fontFile->getEncoding(); 557 baseEnc = fontFile->getEncoding();
542 baseEncFromFontFile = gTrue; 558 baseEncFromFontFile = gTrue;
543 } 559 }
544#endif 560#endif
@@ -560,24 +576,25 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
560 // copy the base encoding 576 // copy the base encoding
561 for (i = 0; i < 256; ++i) { 577 for (i = 0; i < 256; ++i) {
562 enc[i] = baseEnc[i]; 578 enc[i] = baseEnc[i];
563 if ((encFree[i] = baseEncFromFontFile) && enc[i]) { 579 if ((encFree[i] = baseEncFromFontFile) && enc[i]) {
564 enc[i] = copyString(baseEnc[i]); 580 enc[i] = copyString(baseEnc[i]);
565 } 581 }
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()) {
578 if (code < 256) { 595 if (code < 256) {
579 if (encFree[code]) { 596 if (encFree[code]) {
580 gfree(enc[code]); 597 gfree(enc[code]);
581 } 598 }
582 enc[code] = copyString(obj3.getName()); 599 enc[code] = copyString(obj3.getName());
583 encFree[code] = gTrue; 600 encFree[code] = gTrue;
@@ -627,44 +644,48 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
627 (charName[1] >= 'a' && charName[1] <= 'f') || 644 (charName[1] >= 'a' && charName[1] <= 'f') ||
628 (charName[1] >= 'A' && charName[1] <= 'F')))) { 645 (charName[1] >= 'A' && charName[1] <= 'F')))) {
629 hex = gTrue; 646 hex = gTrue;
630 } 647 }
631 missing = gTrue; 648 missing = gTrue;
632 } 649 }
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;
647 if (hex && n == 3 && isalpha(charName[0]) && 665 if (hex && n == 3 && isalpha(charName[0]) &&
648 isxdigit(charName[1]) && isxdigit(charName[2])) { 666 isxdigit(charName[1]) && isxdigit(charName[2])) {
649 sscanf(charName+1, "%x", &code2); 667 sscanf(charName+1, "%x", &code2);
650 } else if (hex && n == 2 && 668 } else if (hex && n == 2 &&
651 isxdigit(charName[0]) && isxdigit(charName[1])) { 669 isxdigit(charName[0]) && isxdigit(charName[1])) {
652 sscanf(charName, "%x", &code2); 670 sscanf(charName, "%x", &code2);
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 }
665 } 686 }
666 687
667 ctu = CharCodeToUnicode::make8BitToUnicode(toUnicode); 688 ctu = CharCodeToUnicode::make8BitToUnicode(toUnicode);
668 } 689 }
669 690
670 //----- get the character widths ----- 691 //----- get the character widths -----
@@ -675,28 +696,32 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
675 } 696 }
676 697
677 // use widths from font dict, if present 698 // use widths from font dict, if present
678 fontDict->lookup("FirstChar", &obj1); 699 fontDict->lookup("FirstChar", &obj1);
679 firstChar = obj1.isInt() ? obj1.getInt() : 0; 700 firstChar = obj1.isInt() ? obj1.getInt() : 0;
680 obj1.free(); 701 obj1.free();
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) {
697 // this is a kludge for broken PDF files that encode char 32 722 // this is a kludge for broken PDF files that encode char 32
698 // as .notdef 723 // as .notdef
699 if (builtinFont->widths->getWidth("space", &w)) { 724 if (builtinFont->widths->getWidth("space", &w)) {
700 widths[32] = 0.001 * w; 725 widths[32] = 0.001 * w;
701 } 726 }
702 for (code = 0; code < 256; ++code) { 727 for (code = 0; code < 256; ++code) {
@@ -743,52 +768,63 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
743Gfx8BitFont::~Gfx8BitFont() { 768Gfx8BitFont::~Gfx8BitFont() {
744 int i; 769 int i;
745 770
746 for (i = 0; i < 256; ++i) { 771 for (i = 0; i < 256; ++i) {
747 if (encFree[i] && enc[i]) { 772 if (encFree[i] && enc[i]) {
748 gfree(enc[i]); 773 gfree(enc[i]);
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;
761 789
762 *code = c = (CharCode)(*s & 0xff); 790 *code = c = (CharCode)(*s & 0xff);
763 *uLen = ctu->mapToUnicode(c, u, uSize); 791 *uLen = ctu->mapToUnicode(c, u, uSize);
764 *dx = widths[c]; 792 *dx = widths[c];
765 *dy = *ox = *oy = 0; 793 *dy = *ox = *oy = 0;
766 return 1; 794 return 1;
767} 795}
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 -
789 ((GfxFontCIDWidthExcep *)w2)->first; 825 ((GfxFontCIDWidthExcep *)w2)->first;
790} 826}
791 827
792static int cmpWidthExcepV(const void *w1, const void *w2) { 828static int cmpWidthExcepV(const void *w1, const void *w2) {
793 return ((GfxFontCIDWidthExcepV *)w1)->first - 829 return ((GfxFontCIDWidthExcepV *)w1)->first -
794 ((GfxFontCIDWidthExcepV *)w2)->first; 830 ((GfxFontCIDWidthExcepV *)w2)->first;
@@ -1177,24 +1213,28 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
1177 } 1213 }
1178 } 1214 }
1179 } 1215 }
1180 1216
1181 *dx = w; 1217 *dx = w;
1182 *dy = h; 1218 *dy = h;
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() {
1195 return cMap ? cMap->getCollection() : (GString *)NULL; 1235 return cMap ? cMap->getCollection() : (GString *)NULL;
1196} 1236}
1197 1237
1198//------------------------------------------------------------------------ 1238//------------------------------------------------------------------------
1199// GfxFontDict 1239// GfxFontDict
1200//------------------------------------------------------------------------ 1240//------------------------------------------------------------------------
@@ -1207,25 +1247,25 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
1207 fonts = (GfxFont **)gmalloc(numFonts * sizeof(GfxFont *)); 1247 fonts = (GfxFont **)gmalloc(numFonts * sizeof(GfxFont *));
1208 for (i = 0; i < numFonts; ++i) { 1248 for (i = 0; i < numFonts; ++i) {
1209 fontDict->getValNF(i, &obj1); 1249 fontDict->getValNF(i, &obj1);
1210 obj1.fetch(xref, &obj2); 1250 obj1.fetch(xref, &obj2);
1211 if (obj1.isRef() && obj2.isDict()) { 1251 if (obj1.isRef() && obj2.isDict()) {
1212 fonts[i] = GfxFont::makeFont(xref, fontDict->getKey(i), 1252 fonts[i] = GfxFont::makeFont(xref, fontDict->getKey(i),
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}
1226 1266
1227GfxFontDict::~GfxFontDict() { 1267GfxFontDict::~GfxFontDict() {
1228 int i; 1268 int i;
1229 1269
1230 for (i = 0; i < numFonts; ++i) { 1270 for (i = 0; i < numFonts; ++i) {
1231 if (fonts[i]) { 1271 if (fonts[i]) {
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17#include "GString.h" 17#include "GString.h"
@@ -104,78 +104,80 @@ public:
104 104
105 // Get font type. 105 // Get font type.
106 GfxFontType getType() { return type; } 106 GfxFontType getType() { return type; }
107 virtual GBool isCIDFont() { return gFalse; } 107 virtual GBool isCIDFont() { return gFalse; }
108 108
109 // Get embedded font ID, i.e., a ref for the font file stream. 109 // Get embedded font ID, i.e., a ref for the font file stream.
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.
124 GBool isFixedWidth() { return flags & fontFixedWidth; } 123 GBool isFixedWidth() { return flags & fontFixedWidth; }
125 GBool isSerif() { return flags & fontSerif; } 124 GBool isSerif() { return flags & fontSerif; }
126 GBool isSymbolic() { return flags & fontSymbolic; } 125 GBool isSymbolic() { return flags & fontSymbolic; }
127 GBool isItalic() { return flags & fontItalic; } 126 GBool isItalic() { return flags & fontItalic; }
128 GBool isBold() { return flags & fontBold; } 127 GBool isBold() { return flags & fontBold; }
129 128
130 // Return the font matrix. 129 // Return the font matrix.
131 fouble *getFontMatrix() { return fontMat; } 130 fouble *getFontMatrix() { return fontMat; }
132 131
133 // Return the font bounding box. 132 // Return the font bounding box.
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
146 // (<dx>, <dy>), and its origin offset vector (<ox>, <oy>). <uSize> 148 // (<dx>, <dy>), and its origin offset vector (<ox>, <oy>). <uSize>
147 // is the number of entries available in <u>, and <uLen> is set to 149 // is the number of entries available in <u>, and <uLen> is set to
148 // the number actually used. Returns the number of bytes used by 150 // the number actually used. Returns the number of bytes used by
149 // the char code. 151 // the char code.
150 virtual int getNextChar(char *s, int len, CharCode *code, 152 virtual int getNextChar(char *s, int len, CharCode *code,
151 Unicode *u, int uSize, int *uLen, 153 Unicode *u, int uSize, int *uLen,
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
176//------------------------------------------------------------------------ 178//------------------------------------------------------------------------
177// Gfx8BitFont 179// Gfx8BitFont
178//------------------------------------------------------------------------ 180//------------------------------------------------------------------------
179 181
180class Gfx8BitFont: public GfxFont { 182class Gfx8BitFont: public GfxFont {
181public: 183public:
@@ -195,56 +197,66 @@ public:
195 // Return the Unicode map. 197 // Return the Unicode map.
196 CharCodeToUnicode *getToUnicode(); 198 CharCodeToUnicode *getToUnicode();
197 199
198 // Return the character name associated with <code>. 200 // Return the character name associated with <code>.
199 char *getCharName(int code) { return enc[code]; } 201 char *getCharName(int code) { return enc[code]; }
200 202
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
225class GfxCIDFont: public GfxFont { 234class GfxCIDFont: public GfxFont {
226public: 235public:
227 236
228 GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA, 237 GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
229 Dict *fontDict); 238 Dict *fontDict);
230 239
231 virtual ~GfxCIDFont(); 240 virtual ~GfxCIDFont();
232 241
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
245 // Return the CID-to-GID mapping table. These should only be called 257 // Return the CID-to-GID mapping table. These should only be called
246 // if type is fontCIDType2. 258 // if type is fontCIDType2.
247 Gushort *getCIDToGID() { return cidToGID; } 259 Gushort *getCIDToGID() { return cidToGID; }
248 int getCIDToGIDLen() { return cidToGIDLen; } 260 int getCIDToGIDLen() { return cidToGIDLen; }
249 261
250private: 262private:
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include <math.h> 15#include <math.h>
16#include <string.h> // for memcpy() 16#include <string.h> // for memcpy()
17#include "gmem.h" 17#include "gmem.h"
@@ -399,27 +399,40 @@ GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() {
399GfxColorSpace *GfxDeviceCMYKColorSpace::copy() { 399GfxColorSpace *GfxDeviceCMYKColorSpace::copy() {
400 return new GfxDeviceCMYKColorSpace(); 400 return new GfxDeviceCMYKColorSpace();
401} 401}
402 402
403void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) { 403void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) {
404 *gray = clip01(1 - color->c[3] 404 *gray = clip01(1 - color->c[3]
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]);
420 cmyk->k = clip01(color->c[3]); 433 cmyk->k = clip01(color->c[3]);
421} 434}
422 435
423//------------------------------------------------------------------------ 436//------------------------------------------------------------------------
424// GfxLabColorSpace 437// GfxLabColorSpace
425//------------------------------------------------------------------------ 438//------------------------------------------------------------------------
@@ -1259,28 +1272,24 @@ GfxShading *GfxShading::parse(Object *obj) {
1259 int i; 1272 int i;
1260 1273
1261 shading = NULL; 1274 shading = NULL;
1262 if (obj->isDict()) { 1275 if (obj->isDict()) {
1263 1276
1264 if (!obj->dictLookup("ShadingType", &obj1)->isInt()) { 1277 if (!obj->dictLookup("ShadingType", &obj1)->isInt()) {
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;
1281 } 1290 }
1282 obj1.free(); 1291 obj1.free();
1283 1292
1284 for (i = 0; i < gfxColorMaxComps; ++i) { 1293 for (i = 0; i < gfxColorMaxComps; ++i) {
1285 backgroundA.c[i] = 0; 1294 backgroundA.c[i] = 0;
1286 } 1295 }
@@ -1308,25 +1317,35 @@ GfxShading *GfxShading::parse(Object *obj) {
1308 yMinA = obj1.arrayGet(1, &obj2)->getNum(); 1317 yMinA = obj1.arrayGet(1, &obj2)->getNum();
1309 obj2.free(); 1318 obj2.free();
1310 xMaxA = obj1.arrayGet(2, &obj2)->getNum(); 1319 xMaxA = obj1.arrayGet(2, &obj2)->getNum();
1311 obj2.free(); 1320 obj2.free();
1312 yMaxA = obj1.arrayGet(3, &obj2)->getNum(); 1321 yMaxA = obj1.arrayGet(3, &obj2)->getNum();
1313 obj2.free(); 1322 obj2.free();
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;
1327 shading->xMin = xMinA; 1346 shading->xMin = xMinA;
1328 shading->yMin = yMinA; 1347 shading->yMin = yMinA;
1329 shading->xMax = xMaxA; 1348 shading->xMax = xMaxA;
1330 shading->yMax = yMaxA; 1349 shading->yMax = yMaxA;
1331 shading->hasBBox = hasBBoxA; 1350 shading->hasBBox = hasBBoxA;
1332 } else { 1351 } else {
@@ -1448,24 +1467,146 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict) {
1448 return NULL; 1467 return NULL;
1449} 1468}
1450 1469
1451void GfxAxialShading::getColor(fouble t, GfxColor *color) { 1470void GfxAxialShading::getColor(fouble t, GfxColor *color) {
1452 int i; 1471 int i;
1453 1472
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;
1466 GfxSeparationColorSpace *sepCS; 1607 GfxSeparationColorSpace *sepCS;
1467 int maxPixel, indexHigh; 1608 int maxPixel, indexHigh;
1468 Guchar *lookup2; 1609 Guchar *lookup2;
1469 Function *sepFunc; 1610 Function *sepFunc;
1470 Object obj; 1611 Object obj;
1471 fouble x[gfxColorMaxComps]; 1612 fouble x[gfxColorMaxComps];
@@ -1909,24 +2050,85 @@ GfxState::GfxState(GfxState *state) {
1909 fillPattern = state->fillPattern->copy(); 2050 fillPattern = state->fillPattern->copy();
1910 } 2051 }
1911 if (strokePattern) { 2052 if (strokePattern) {
1912 strokePattern = state->strokePattern->copy(); 2053 strokePattern = state->strokePattern->copy();
1913 } 2054 }
1914 if (lineDashLength > 0) { 2055 if (lineDashLength > 0) {
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));
1927} 2129}
1928 2130
1929fouble GfxState::getTransformedFontSize() { 2131fouble GfxState::getTransformedFontSize() {
1930 fouble x1, y1, x2, y2; 2132 fouble x1, y1, x2, y2;
1931 2133
1932 x1 = textMat[2] * fontSize; 2134 x1 = textMat[2] * fontSize;
@@ -1937,45 +2139,66 @@ fouble GfxState::getTransformedFontSize() {
1937} 2139}
1938 2140
1939void GfxState::getFontTransMat(fouble *m11, fouble *m12, 2141void GfxState::getFontTransMat(fouble *m11, fouble *m12,
1940 fouble *m21, fouble *m22) { 2142 fouble *m21, fouble *m22) {
1941 *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize; 2143 *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize;
1942 *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize; 2144 *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize;
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 }
1976 fillColorSpace = colorSpace; 2199 fillColorSpace = colorSpace;
1977} 2200}
1978 2201
1979void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) { 2202void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) {
1980 if (strokeColorSpace) { 2203 if (strokeColorSpace) {
1981 delete strokeColorSpace; 2204 delete strokeColorSpace;
@@ -2042,28 +2265,28 @@ void GfxState::clip() {
2042 } 2265 }
2043 if (yMin > clipYMin) { 2266 if (yMin > clipYMin) {
2044 clipYMin = yMin; 2267 clipYMin = yMin;
2045 } 2268 }
2046 if (xMax < clipXMax) { 2269 if (xMax < clipXMax) {
2047 clipXMax = xMax; 2270 clipXMax = xMax;
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;
2064 curY += dy; 2287 curY += dy;
2065} 2288}
2066 2289
2067GfxState *GfxState::save() { 2290GfxState *GfxState::save() {
2068 GfxState *newState; 2291 GfxState *newState;
2069 2292
@@ -2086,12 +2309,13 @@ GfxState *GfxState::restore() {
2086 oldState->lineY = lineY; 2309 oldState->lineY = lineY;
2087 2310
2088 path = NULL; 2311 path = NULL;
2089 saved = NULL; 2312 saved = NULL;
2090 delete this; 2313 delete this;
2091 2314
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17#include "Object.h" 17#include "Object.h"
@@ -559,24 +559,58 @@ public:
559 GBool getExtend1() { return extend1; } 559 GBool getExtend1() { return extend1; }
560 560
561private: 561private:
562 562
563 fouble x0, y0, x1, y1; 563 fouble x0, y0, x1, y1;
564 fouble t0, t1; 564 fouble t0, t1;
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
577 // Constructor. 611 // Constructor.
578 GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA); 612 GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA);
579 613
580 // Destructor. 614 // Destructor.
581 ~GfxImageColorMap(); 615 ~GfxImageColorMap();
582 616
@@ -774,24 +808,25 @@ public:
774 fouble *getTextMat() { return textMat; } 808 fouble *getTextMat() { return textMat; }
775 fouble getCharSpace() { return charSpace; } 809 fouble getCharSpace() { return charSpace; }
776 fouble getWordSpace() { return wordSpace; } 810 fouble getWordSpace() { return wordSpace; }
777 fouble getHorizScaling() { return horizScaling; } 811 fouble getHorizScaling() { return horizScaling; }
778 fouble getLeading() { return leading; } 812 fouble getLeading() { return leading; }
779 fouble getRise() { return rise; } 813 fouble getRise() { return rise; }
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(); }
792 827
793 // Transforms. 828 // Transforms.
794 void transform(fouble x1, fouble y1, fouble *x2, fouble *y2) 829 void transform(fouble x1, fouble y1, fouble *x2, fouble *y2)
795 { *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4]; 830 { *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4];
796 *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5]; } 831 *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5]; }
797 void transformDelta(fouble x1, fouble y1, fouble *x2, fouble *y2) 832 void transformDelta(fouble x1, fouble y1, fouble *x2, fouble *y2)
@@ -856,25 +891,25 @@ public:
856 fouble x3, fouble y3) 891 fouble x3, fouble y3)
857 { path->curveTo(x1, y1, x2, y2, curX = x3, curY = y3); } 892 { path->curveTo(x1, y1, x2, y2, curX = x3, curY = y3); }
858 void closePath() 893 void closePath()
859 { path->close(); curX = path->getLastX(); curY = path->getLastY(); } 894 { path->close(); curX = path->getLastX(); curY = path->getLastY(); }
860 void clearPath(); 895 void clearPath();
861 896
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; }
875 910
876private: 911private:
877 912
878 fouble ctm[6]; // coord transform matrix 913 fouble ctm[6]; // coord transform matrix
879 fouble px1, py1, px2, py2;// page corners (user coords) 914 fouble px1, py1, px2, py2;// page corners (user coords)
880 fouble pageWidth, pageHeight;// page size (pixels) 915 fouble pageWidth, pageHeight;// page size (pixels)
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <string.h> 14#include <string.h>
15#include <ctype.h> 15#include <ctype.h>
16#if HAVE_PAPER_H 16#if HAVE_PAPER_H
17#include <paper.h> 17#include <paper.h>
@@ -87,94 +87,104 @@ DisplayFontParam::~DisplayFontParam() {
87 case displayFontTT: 87 case displayFontTT:
88 if (tt.fileName) { 88 if (tt.fileName) {
89 delete tt.fileName; 89 delete tt.fileName;
90 } 90 }
91 break; 91 break;
92 } 92 }
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();
135 cidToUnicodes = new GHash(gTrue); 138 cidToUnicodes = new GHash(gTrue);
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);
148 paperdone(); 152 paperdone();
149#else 153#else
150 psPaperWidth = defPaperWidth; 154 psPaperWidth = defPaperWidth;
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
175 cidToUnicodeCache = new CIDToUnicodeCache(); 185 cidToUnicodeCache = new CIDToUnicodeCache();
176 unicodeMapCache = new UnicodeMapCache(); 186 unicodeMapCache = new UnicodeMapCache();
177 cMapCache = new CMapCache(); 187 cMapCache = new CMapCache();
178 188
179 // set up the initial nameToUnicode table 189 // set up the initial nameToUnicode table
180 for (i = 0; nameToUnicodeTab[i].name; ++i) { 190 for (i = 0; nameToUnicodeTab[i].name; ++i) {
@@ -184,24 +194,26 @@ GlobalParams::GlobalParams(char *cfgFileName) {
184 // set up the residentUnicodeMaps table 194 // set up the residentUnicodeMaps table
185 map = new UnicodeMap("Latin1", latin1UnicodeMapRanges, latin1UnicodeMapLen); 195 map = new UnicodeMap("Latin1", latin1UnicodeMapRanges, latin1UnicodeMapLen);
186 residentUnicodeMaps->add(map->getEncodingName(), map); 196 residentUnicodeMaps->add(map->getEncodingName(), map);
187 map = new UnicodeMap("ASCII7", ascii7UnicodeMapRanges, ascii7UnicodeMapLen); 197 map = new UnicodeMap("ASCII7", ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
188 residentUnicodeMaps->add(map->getEncodingName(), map); 198 residentUnicodeMaps->add(map->getEncodingName(), map);
189 map = new UnicodeMap("Symbol", symbolUnicodeMapRanges, symbolUnicodeMapLen); 199 map = new UnicodeMap("Symbol", symbolUnicodeMapRanges, symbolUnicodeMapLen);
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);
202 displayFonts->add(dfp->name, dfp); 214 displayFonts->add(dfp->name, dfp);
203 } 215 }
204 216
205 // look for a user config file, then a system-wide config file 217 // look for a user config file, then a system-wide config file
206 f = NULL; 218 f = NULL;
207 fileName = NULL; 219 fileName = NULL;
@@ -210,131 +222,175 @@ GlobalParams::GlobalParams(char *cfgFileName) {
210 if (!(f = fopen(fileName->getCString(), "r"))) { 222 if (!(f = fopen(fileName->getCString(), "r"))) {
211 delete fileName; 223 delete fileName;
212 } 224 }
213 } 225 }
214 if (!f) { 226 if (!f) {
215 fileName = appendToPath(getHomeDir(), xpdfUserConfigFile); 227 fileName = appendToPath(getHomeDir(), xpdfUserConfigFile);
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);
228 appendToPath(fileName, xpdfSysConfigFile); 241 appendToPath(fileName, xpdfSysConfigFile);
229#else 242#else
230 fileName = new GString(xpdfSysConfigFile); 243 fileName = new GString(xpdfSysConfigFile);
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;
335 char *tok1, *tok2; 391 char *tok1, *tok2;
336 FILE *f; 392 FILE *f;
337 char buf[256]; 393 char buf[256];
338 int line2; 394 int line2;
339 Unicode u; 395 Unicode u;
340 396
@@ -417,25 +473,25 @@ void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
417} 473}
418 474
419void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName, 475void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
420 int line) { 476 int line) {
421 if (tokens->getLength() != 2) { 477 if (tokens->getLength() != 2) {
422 error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)", 478 error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
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;
436 } 492 }
437 param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind); 493 param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
438 494
439 switch (kind) { 495 switch (kind) {
440 case displayFontX: 496 case displayFontX:
441 if (tokens->getLength() != 4) { 497 if (tokens->getLength() != 4) {
@@ -449,41 +505,34 @@ void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
449 goto err2; 505 goto err2;
450 } 506 }
451 param->t1.fileName = ((GString *)tokens->get(2))->copy(); 507 param->t1.fileName = ((GString *)tokens->get(2))->copy();
452 break; 508 break;
453 case displayFontTT: 509 case displayFontTT:
454 if (tokens->getLength() != 3) { 510 if (tokens->getLength() != 3) {
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;
484 533
485 if (tokens->getLength() == 2) { 534 if (tokens->getLength() == 2) {
486 tok = (GString *)tokens->get(1); 535 tok = (GString *)tokens->get(1);
487 if (!setPSPaperSize(tok->getCString())) { 536 if (!setPSPaperSize(tok->getCString())) {
488 error(-1, "Bad 'psPaperSize' config file command (%s:%d)", 537 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
489 fileName->getCString(), line); 538 fileName->getCString(), line);
@@ -507,24 +556,28 @@ void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
507 fileName->getCString(), line); 556 fileName->getCString(), line);
508 return; 557 return;
509 } 558 }
510 tok = (GString *)tokens->get(1); 559 tok = (GString *)tokens->get(1);
511 if (!tok->cmp("level1")) { 560 if (!tok->cmp("level1")) {
512 psLevel = psLevel1; 561 psLevel = psLevel1;
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
525void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) { 578void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) {
526 if (tokens->getLength() != 2) { 579 if (tokens->getLength() != 2) {
527 error(-1, "Bad 'psFile' config file command (%s:%d)", 580 error(-1, "Bad 'psFile' config file command (%s:%d)",
528 fileName->getCString(), line); 581 fileName->getCString(), line);
529 return; 582 return;
530 } 583 }
@@ -533,29 +586,57 @@ void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) {
533 } 586 }
534 psFile = ((GString *)tokens->get(1))->copy(); 587 psFile = ((GString *)tokens->get(1))->copy();
535} 588}
536 589
537void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) { 590void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
538 PSFontParam *param; 591 PSFontParam *param;
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;
556 } 637 }
557 delete textEncoding; 638 delete textEncoding;
558 textEncoding = ((GString *)tokens->get(1))->copy(); 639 textEncoding = ((GString *)tokens->get(1))->copy();
559} 640}
560 641
561void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) { 642void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
@@ -579,54 +660,65 @@ void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
579 } 660 }
580} 661}
581 662
582void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) { 663void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
583 if (tokens->getLength() != 2) { 664 if (tokens->getLength() != 2) {
584 error(-1, "Bad 'fontDir' config file command (%s:%d)", 665 error(-1, "Bad 'fontDir' config file command (%s:%d)",
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;
608 687
609 if (tokens->getLength() != 2) { 688 if (tokens->getLength() != 2) {
610 error(-1, "Bad '%s' config file command (%s:%d)", 689 error(-1, "Bad '%s' config file command (%s:%d)",
611 cmdName, fileName->getCString(), line); 690 cmdName, fileName->getCString(), line);
612 return; 691 return;
613 } 692 }
614 tok = (GString *)tokens->get(1); 693 tok = (GString *)tokens->get(1);
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)",
627 cmdName, fileName->getCString(), line); 719 cmdName, fileName->getCString(), line);
628 return; 720 return;
629 } 721 }
630 tok = (GString *)tokens->get(1); 722 tok = (GString *)tokens->get(1);
631 if (!tok->cmp("yes")) { 723 if (!tok->cmp("yes")) {
632 *flag = gTrue; 724 *flag = gTrue;
@@ -645,30 +737,34 @@ GlobalParams::~GlobalParams() {
645 737
646 freeBuiltinFontTables(); 738 freeBuiltinFontTables();
647 739
648 delete macRomanReverseMap; 740 delete macRomanReverseMap;
649 741
650 delete nameToUnicode; 742 delete nameToUnicode;
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)) {
669 deleteGList(list, GString); 765 deleteGList(list, GString);
670 } 766 }
671 delete cMapDirs; 767 delete cMapDirs;
672 768
673 delete cidToUnicodeCache; 769 delete cidToUnicodeCache;
674 delete unicodeMapCache; 770 delete unicodeMapCache;
@@ -743,32 +839,68 @@ FILE *GlobalParams::findToUnicodeFile(GString *name) {
743 delete fileName; 839 delete fileName;
744 if (f) { 840 if (f) {
745 return f; 841 return f;
746 } 842 }
747 } 843 }
748 return NULL; 844 return NULL;
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
769 for (i = 0; i < fontDirs->getLength(); ++i) { 901 for (i = 0; i < fontDirs->getLength(); ++i) {
770 dir = (GString *)fontDirs->get(i); 902 dir = (GString *)fontDirs->get(i);
771 if (ext1) { 903 if (ext1) {
772 fileName = appendToPath(dir->copy(), fontName->getCString()); 904 fileName = appendToPath(dir->copy(), fontName->getCString());
773 fileName->append(ext1); 905 fileName->append(ext1);
774 if ((f = fopen(fileName->getCString(), "r"))) { 906 if ((f = fopen(fileName->getCString(), "r"))) {
@@ -857,46 +989,63 @@ void GlobalParams::setPSDuplex(GBool duplex) {
857void GlobalParams::setPSLevel(PSLevel level) { 989void GlobalParams::setPSLevel(PSLevel level) {
858 psLevel = level; 990 psLevel = level;
859} 991}
860 992
861void GlobalParams::setPSEmbedType1(GBool embed) { 993void GlobalParams::setPSEmbedType1(GBool embed) {
862 psEmbedType1 = embed; 994 psEmbedType1 = 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) {
879 if (!strcmp(s, "unix")) { 1023 if (!strcmp(s, "unix")) {
880 textEOL = eolUnix; 1024 textEOL = eolUnix;
881 } else if (!strcmp(s, "dos")) { 1025 } else if (!strcmp(s, "dos")) {
882 textEOL = eolDOS; 1026 textEOL = eolDOS;
883 } else if (!strcmp(s, "mac")) { 1027 } else if (!strcmp(s, "mac")) {
884 textEOL = eolMac; 1028 textEOL = eolMac;
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);
897} 1046}
898 1047
899GBool GlobalParams::setFontRastControl(FontRastControl *val, char *s) { 1048GBool GlobalParams::setFontRastControl(FontRastControl *val, char *s) {
900 if (!strcmp(s, "none")) { 1049 if (!strcmp(s, "none")) {
901 *val = fontRastNone; 1050 *val = fontRastNone;
902 } else if (!strcmp(s, "plain")) { 1051 } else if (!strcmp(s, "plain")) {
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include <stdio.h> 16#include <stdio.h>
17#include "gtypes.h" 17#include "gtypes.h"
@@ -36,26 +36,27 @@ extern GlobalParams *globalParams;
36 36
37//------------------------------------------------------------------------ 37//------------------------------------------------------------------------
38 38
39enum DisplayFontParamKind { 39enum DisplayFontParamKind {
40 displayFontX, 40 displayFontX,
41 displayFontT1, 41 displayFontT1,
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;
56 struct { 57 struct {
57 GString *fileName; 58 GString *fileName;
58 } t1; 59 } t1;
59 struct { 60 struct {
60 GString *fileName; 61 GString *fileName;
61 } tt; 62 } tt;
@@ -70,38 +71,46 @@ public:
70enum FontRastControl { 71enum FontRastControl {
71 fontRastNone, // don't use this rasterizer 72 fontRastNone, // don't use this rasterizer
72 fontRastPlain, // use it, without anti-aliasing 73 fontRastPlain, // use it, without anti-aliasing
73 fontRastAALow, // use it, with low-level anti-aliasing 74 fontRastAALow, // use it, with low-level anti-aliasing
74 fontRastAAHigh // use it, with high-level anti-aliasing 75 fontRastAAHigh // use it, with high-level anti-aliasing
75}; 76};
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
102 eolDOS, // CR+LF 111 eolDOS, // CR+LF
103 eolMac // CR 112 eolMac // CR
104}; 113};
105 114
106//------------------------------------------------------------------------ 115//------------------------------------------------------------------------
107 116
@@ -116,81 +125,95 @@ public:
116 125
117 //----- accessors 126 //----- accessors
118 127
119 CharCode getMacRomanCharCode(char *charName); 128 CharCode getMacRomanCharCode(char *charName);
120 129
121 Unicode mapNameToUnicode(char *charName); 130 Unicode mapNameToUnicode(char *charName);
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
147 CharCodeToUnicode *getCIDToUnicode(GString *collection); 161 CharCodeToUnicode *getCIDToUnicode(GString *collection);
148 UnicodeMap *getUnicodeMap(GString *encodingName); 162 UnicodeMap *getUnicodeMap(GString *encodingName);
149 CMap *getCMap(GString *collection, GString *cMapName); 163 CMap *getCMap(GString *collection, GString *cMapName);
150 UnicodeMap *getTextEncoding(); 164 UnicodeMap *getTextEncoding();
151 165
152 //----- functions to set parameters 166 //----- functions to set parameters
153 167
154 void setPSFile(char *file); 168 void setPSFile(char *file);
155 GBool setPSPaperSize(char *size); 169 GBool setPSPaperSize(char *size);
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);
191 214
192 //----- static tables 215 //----- static tables
193 216
194 NameToCharCode * // mapping from char name to 217 NameToCharCode * // mapping from char name to
195 macRomanReverseMap; // MacRomanEncoding index 218 macRomanReverseMap; // MacRomanEncoding index
196 219
@@ -203,39 +226,47 @@ private:
203 // [GString] 226 // [GString]
204 GHash *residentUnicodeMaps;// mappings from Unicode to char codes, 227 GHash *residentUnicodeMaps;// mappings from Unicode to char codes,
205 // indexed by encoding name [UnicodeMap] 228 // indexed by encoding name [UnicodeMap]
206 GHash *unicodeMaps; // files for mappings from Unicode to char 229 GHash *unicodeMaps; // files for mappings from Unicode to char
207 // codes, indexed by encoding name [GString] 230 // codes, indexed by encoding name [GString]
208 GHash *cMapDirs; // list of CMap dirs, indexed by collection 231 GHash *cMapDirs; // list of CMap dirs, indexed by collection
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?
236 267
237 CIDToUnicodeCache *cidToUnicodeCache; 268 CIDToUnicodeCache *cidToUnicodeCache;
238 UnicodeMapCache *unicodeMapCache; 269 UnicodeMapCache *unicodeMapCache;
239 CMapCache *cMapCache; 270 CMapCache *cMapCache;
240}; 271};
241 272
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdlib.h> 14#include <stdlib.h>
15#include <stddef.h> 15#include <stddef.h>
16#include <string.h> 16#include <string.h>
17#include <ctype.h> 17#include <ctype.h>
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "Object.h" 16#include "Object.h"
17#include "Stream.h" 17#include "Stream.h"
@@ -42,31 +42,32 @@ public:
42 Object *getObj(Object *obj); 42 Object *getObj(Object *obj);
43 43
44 // Skip to the beginning of the next line in the input stream. 44 // Skip to the beginning of the next line in the input stream.
45 void skipToNextLine(); 45 void skipToNextLine();
46 46
47 // Skip over one character. 47 // Skip over one character.
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
67 Array *streams; // array of input streams 68 Array *streams; // array of input streams
68 int strPtr; // index of current stream 69 int strPtr; // index of current stream
69 Object curStr; // current stream 70 Object curStr; // current stream
70 GBool freeArray; // should lexer free the streams array? 71 GBool freeArray; // should lexer free the streams array?
71 char tokBuf[tokBufSize];// temporary token buffer 72 char tokBuf[tokBufSize];// temporary token buffer
72}; 73};
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include <string.h> 15#include <string.h>
16#include "gmem.h" 16#include "gmem.h"
17#include "GString.h" 17#include "GString.h"
@@ -20,49 +20,45 @@
20#include "Array.h" 20#include "Array.h"
21#include "Dict.h" 21#include "Dict.h"
22#include "Link.h" 22#include "Link.h"
23 23
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25 25
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")) {
63 kind = destXYZ; 59 kind = destXYZ;
64 a->get(2, &obj2); 60 a->get(2, &obj2);
65 if (obj2.isNull()) { 61 if (obj2.isNull()) {
66 changeLeft = gFalse; 62 changeLeft = gFalse;
67 } else if (obj2.isNum()) { 63 } else if (obj2.isNum()) {
68 changeLeft = gTrue; 64 changeLeft = gTrue;
@@ -212,25 +208,25 @@ LinkDest::LinkDest(LinkDest *dest) {
212LinkGoTo::LinkGoTo(Object *destObj) { 208LinkGoTo::LinkGoTo(Object *destObj) {
213 dest = NULL; 209 dest = NULL;
214 namedDest = NULL; 210 namedDest = NULL;
215 211
216 // named destination 212 // named destination
217 if (destObj->isName()) { 213 if (destObj->isName()) {
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
231 } else { 227 } else {
232 error(-1, "Illegal annotation destination"); 228 error(-1, "Illegal annotation destination");
233 } 229 }
234} 230}
235 231
236LinkGoTo::~LinkGoTo() { 232LinkGoTo::~LinkGoTo() {
@@ -250,25 +246,25 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
250 246
251 // get file name 247 // get file name
252 fileName = getFileSpecName(fileSpecObj); 248 fileName = getFileSpecName(fileSpecObj);
253 249
254 // named destination 250 // named destination
255 if (destObj->isName()) { 251 if (destObj->isName()) {
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
269 } else { 265 } else {
270 error(-1, "Illegal annotation destination"); 266 error(-1, "Illegal annotation destination");
271 } 267 }
272} 268}
273 269
274LinkGoToR::~LinkGoToR() { 270LinkGoToR::~LinkGoToR() {
@@ -437,25 +433,25 @@ Link::Link(Dict *dict, GString *baseURI) {
437 if (x1 > x2) { 433 if (x1 > x2) {
438 t = x1; 434 t = x1;
439 x1 = x2; 435 x1 = x2;
440 x2 = t; 436 x2 = t;
441 } 437 }
442 if (y1 > y2) { 438 if (y1 > y2) {
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");
456 } 452 }
457 obj2.free(); 453 obj2.free();
458 } 454 }
459 } 455 }
460 obj1.free(); 456 obj1.free();
461 457
@@ -573,25 +569,25 @@ Links::Links(Object *annots, GString *baseURI) {
573 569
574Links::~Links() { 570Links::~Links() {
575 int i; 571 int i;
576 572
577 for (i = 0; i < numLinks; ++i) 573 for (i = 0; i < numLinks; ++i)
578 delete links[i]; 574 delete links[i];
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}
592 588
593GBool Links::onLink(fouble x, fouble y) { 589GBool Links::onLink(fouble x, fouble y) {
594 int i; 590 int i;
595 591
596 for (i = 0; i < numLinks; ++i) { 592 for (i = 0; i < numLinks; ++i) {
597 if (links[i]->inRect(x, y)) 593 if (links[i]->inRect(x, y))
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "Object.h" 16#include "Object.h"
17 17
@@ -54,28 +54,26 @@ enum LinkDestKind {
54 destFit, 54 destFit,
55 destFitH, 55 destFitH,
56 destFitV, 56 destFitV,
57 destFitR, 57 destFitR,
58 destFitB, 58 destFitB,
59 destFitBH, 59 destFitBH,
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; }
76 74
77 // Accessors. 75 // Accessors.
78 LinkDestKind getKind() { return kind; } 76 LinkDestKind getKind() { return kind; }
79 GBool isPageRef() { return pageIsRef; } 77 GBool isPageRef() { return pageIsRef; }
80 int getPageNum() { return pageNum; } 78 int getPageNum() { return pageNum; }
81 Ref getPageRef() { return pageRef; } 79 Ref getPageRef() { return pageRef; }
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <string.h> 14#include <string.h>
15#include "gmem.h" 15#include "gmem.h"
16#include "NameToCharCode.h" 16#include "NameToCharCode.h"
17 17
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "CharTypes.h" 16#include "CharTypes.h"
17 17
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,17 +1,17 @@
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;
12} nameToUnicodeTab[] = { 12} nameToUnicodeTab[] = {
13 {0x0041, "A"}, 13 {0x0041, "A"},
14 {0x00c6, "AE"}, 14 {0x00c6, "AE"},
15 {0x01fc, "AEacute"}, 15 {0x01fc, "AEacute"},
16 {0x00c6, "AEsmall"}, 16 {0x00c6, "AEsmall"},
17 {0x00c1, "Aacute"}, 17 {0x00c1, "Aacute"},
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include "Object.h" 15#include "Object.h"
16#include "Array.h" 16#include "Array.h"
17#include "Dict.h" 17#include "Dict.h"
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include <stdio.h> 16#include <stdio.h>
17#include <string.h> 17#include <string.h>
@@ -167,26 +167,26 @@ public:
167 Object *dictLookupNF(char *key, Object *obj); 167 Object *dictLookupNF(char *key, Object *obj);
168 char *dictGetKey(int i); 168 char *dictGetKey(int i);
169 Object *dictGetVal(int i, Object *obj); 169 Object *dictGetVal(int i, Object *obj);
170 Object *dictGetValNF(int i, Object *obj); 170 Object *dictGetValNF(int i, Object *obj);
171 171
172 // Stream accessors. 172 // Stream accessors.
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
187 // Memory testing. 187 // Memory testing.
188 static void memCheck(FILE *f); 188 static void memCheck(FILE *f);
189 189
190private: 190private:
191 191
192 ObjType type; // object type 192 ObjType type; // object type
@@ -278,22 +278,22 @@ inline void Object::streamReset()
278inline void Object::streamClose() 278inline void Object::streamClose()
279 { stream->close(); } 279 { stream->close(); }
280 280
281inline int Object::streamGetChar() 281inline int Object::streamGetChar()
282 { return stream->getChar(); } 282 { return stream->getChar(); }
283 283
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include "Object.h" 15#include "Object.h"
16#include "Stream.h" 16#include "Stream.h"
17#include "GfxState.h" 17#include "GfxState.h"
@@ -50,24 +50,29 @@ void OutputDev::cvtUserToDev(fouble ux, fouble uy, int *dx, int *dy) {
50void OutputDev::updateAll(GfxState *state) { 50void OutputDev::updateAll(GfxState *state) {
51 updateLineDash(state); 51 updateLineDash(state);
52 updateFlatness(state); 52 updateFlatness(state);
53 updateLineJoin(state); 53 updateLineJoin(state);
54 updateLineCap(state); 54 updateLineCap(state);
55 updateMiterLimit(state); 55 updateMiterLimit(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) {
68 str->reset(); 73 str->reset();
69 j = height * ((width + 7) / 8); 74 j = height * ((width + 7) / 8);
70 for (i = 0; i < j; ++i) 75 for (i = 0; i < j; ++i)
71 str->getChar(); 76 str->getChar();
72 str->close(); 77 str->close();
73 } 78 }
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17#include "CharTypes.h" 17#include "CharTypes.h"
@@ -37,24 +37,28 @@ public:
37 // Destructor. 37 // Destructor.
38 virtual ~OutputDev() {} 38 virtual ~OutputDev() {}
39 39
40 //----- get info about output device 40 //----- get info about output device
41 41
42 // Does this device use upside-down coordinates? 42 // Does this device use upside-down coordinates?
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.
55 virtual void setDefaultCTM(fouble *ctm); 59 virtual void setDefaultCTM(fouble *ctm);
56 60
57 // Start a page. 61 // Start a page.
58 virtual void startPage(int pageNum, GfxState *state) {} 62 virtual void startPage(int pageNum, GfxState *state) {}
59 63
60 // End a page. 64 // End a page.
@@ -110,34 +114,45 @@ public:
110 //----- path clipping 114 //----- path clipping
111 virtual void clip(GfxState *state) {} 115 virtual void clip(GfxState *state) {}
112 virtual void eoClip(GfxState *state) {} 116 virtual void eoClip(GfxState *state) {}
113 117
114 //----- text drawing 118 //----- text drawing
115 virtual void beginString(GfxState *state, GString *s) {} 119 virtual void beginString(GfxState *state, GString *s) {}
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,
128 int width, int height, GfxImageColorMap *colorMap, 135 int width, int height, GfxImageColorMap *colorMap,
129 int *maskColors, GBool inlineImg); 136 int *maskColors, GBool inlineImg);
130 137
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
143#endif 158#endif
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,124 +1,131 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <stdlib.h> 15#include <stdlib.h>
16#include <stddef.h> 16#include <stddef.h>
17#include <string.h> 17#include <string.h>
18#include "GString.h" 18#include "GString.h"
19#include "config.h" 19#include "config.h"
20#include "Page.h" 20#include "Page.h"
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
33 #define headerSearchSize 1024// read this many bytes at beginning of 34 #define headerSearchSize 1024// read this many bytes at beginning of
34 // file to look for '%PDF' 35 // file to look for '%PDF'
35 36
36//------------------------------------------------------------------------ 37//------------------------------------------------------------------------
37// PDFDoc 38// PDFDoc
38//------------------------------------------------------------------------ 39//------------------------------------------------------------------------
39 40
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;
52 printCommands = printCommandsA; 54 printCommands = printCommandsA;
53 55
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;
94 printCommands = printCommandsA; 99 printCommands = printCommandsA;
95 ok = setup(ownerPassword, userPassword); 100 ok = setup(ownerPassword, userPassword);
96} 101}
97 102
98GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) { 103GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
99 // check header 104 // check header
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}
119 126
120PDFDoc::~PDFDoc() { 127PDFDoc::~PDFDoc() {
121 if (catalog) { 128 if (catalog) {
122 delete catalog; 129 delete catalog;
123 } 130 }
124 if (xref) { 131 if (xref) {
@@ -195,26 +202,27 @@ void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
195 for (page = firstPage; page <= lastPage; ++page) { 202 for (page = firstPage; page <= lastPage; ++page) {
196 displayPage(out, page, zoom, rotate, doLinks); 203 displayPage(out, page, zoom, rotate, doLinks);
197 } 204 }
198} 205}
199 206
200GBool PDFDoc::isLinearized() { 207GBool 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()) {
215 obj4.dictLookup("Linearized", &obj5); 223 obj4.dictLookup("Linearized", &obj5);
216 if (obj5.isNum() && obj5.getNum() > 0) { 224 if (obj5.isNum() && obj5.getNum() > 0) {
217 lin = gTrue; 225 lin = gTrue;
218 } 226 }
219 obj5.free(); 227 obj5.free();
220 } 228 }
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include <stdio.h> 16#include <stdio.h>
17#include "XRef.h" 17#include "XRef.h"
@@ -33,24 +33,27 @@ class LinkDest;
33class PDFDoc { 33class PDFDoc {
34public: 34public:
35 35
36 PDFDoc(GString *fileNameA, GString *ownerPassword = NULL, 36 PDFDoc(GString *fileNameA, GString *ownerPassword = NULL,
37 GString *userPassword = NULL, GBool printCommandsA = gFalse); 37 GString *userPassword = NULL, GBool printCommandsA = gFalse);
38 PDFDoc(BaseStream *strA, GString *ownerPassword = NULL, 38 PDFDoc(BaseStream *strA, GString *ownerPassword = NULL,
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
51 // Get catalog. 54 // Get catalog.
52 Catalog *getCatalog() { return catalog; } 55 Catalog *getCatalog() { return catalog; }
53 56
54 // Get base stream. 57 // Get base stream.
55 BaseStream *getBaseStream() { return str; } 58 BaseStream *getBaseStream() { return str; }
56 59
@@ -128,15 +131,16 @@ private:
128 void getLinks(Page *page); 131 void getLinks(Page *page);
129 132
130 GString *fileName; 133 GString *fileName;
131 FILE *file; 134 FILE *file;
132 BaseStream *str; 135 BaseStream *str;
133 fouble pdfVersion; 136 fouble pdfVersion;
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,35 +1,35 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include "Object.h" 15#include "Object.h"
16#include "Array.h" 16#include "Array.h"
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
30//------------------------------------------------------------------------ 30//------------------------------------------------------------------------
31 31
32PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) { 32PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
33 Object obj1; 33 Object obj1;
34 fouble w, h; 34 fouble w, h;
35 35
@@ -84,34 +84,48 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
84 dict->lookup("Rotate", &obj1); 84 dict->lookup("Rotate", &obj1);
85 if (obj1.isInt()) { 85 if (obj1.isInt()) {
86 rotate = obj1.getInt(); 86 rotate = obj1.getInt();
87 } 87 }
88 obj1.free(); 88 obj1.free();
89 while (rotate < 0) { 89 while (rotate < 0) {
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;
112 GBool ok; 126 GBool ok;
113 127
114 dict->lookup(key, &obj1); 128 dict->lookup(key, &obj1);
115 if (obj1.isArray() && obj1.arrayGetLength() == 4) { 129 if (obj1.isArray() && obj1.arrayGetLength() == 4) {
116 ok = gTrue; 130 ok = gTrue;
117 obj1.arrayGet(0, &obj2); 131 obj1.arrayGet(0, &obj2);
@@ -200,25 +214,25 @@ Page::~Page() {
200 annots.free(); 214 annots.free();
201 contents.free(); 215 contents.free();
202} 216}
203 217
204void Page::display(OutputDev *out, fouble dpi, int rotate, 218void Page::display(OutputDev *out, fouble dpi, int rotate,
205 Links *links, Catalog *catalog) { 219 Links *links, Catalog *catalog) {
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",
219 box->x1, box->y1, box->x2, box->y2); 233 box->x1, box->y1, box->x2, box->y2);
220 if (isCropped()) { 234 if (isCropped()) {
221 printf("***** CropBox = ll:%g,%g ur:%g,%g\n", 235 printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
222 cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2); 236 cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2);
223 } 237 }
224 printf("***** Rotate = %d\n", attrs->getRotate()); 238 printf("***** Rotate = %d\n", attrs->getRotate());
@@ -238,30 +252,30 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
238 } 252 }
239 obj.free(); 253 obj.free();
240 254
241 // draw links 255 // draw links
242 if (links) { 256 if (links) {
243 for (i = 0; i < links->getNumLinks(); ++i) { 257 for (i = 0; i < links->getNumLinks(); ++i) {
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "Object.h" 16#include "Object.h"
17 17
@@ -42,39 +42,59 @@ public:
42 // Destructor. 42 // Destructor.
43 ~PageAttrs(); 43 ~PageAttrs();
44 44
45 // Accessors. 45 // Accessors.
46 PDFRectangle *getBox() { return limitToCropBox ? &cropBox : &mediaBox; } 46 PDFRectangle *getBox() { return limitToCropBox ? &cropBox : &mediaBox; }
47 PDFRectangle *getMediaBox() { return &mediaBox; } 47 PDFRectangle *getMediaBox() { return &mediaBox; }
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);
60 74
61 PDFRectangle mediaBox; 75 PDFRectangle mediaBox;
62 PDFRectangle cropBox; 76 PDFRectangle cropBox;
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//------------------------------------------------------------------------
75 95
76class Page { 96class Page {
77public: 97public:
78 98
79 // Constructor. 99 // Constructor.
80 Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA, 100 Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA,
@@ -88,24 +108,30 @@ public:
88 108
89 // Get page parameters. 109 // Get page parameters.
90 PDFRectangle *getBox() { return attrs->getBox(); } 110 PDFRectangle *getBox() { return attrs->getBox(); }
91 PDFRectangle *getMediaBox() { return attrs->getMediaBox(); } 111 PDFRectangle *getMediaBox() { return attrs->getMediaBox(); }
92 PDFRectangle *getCropBox() { return attrs->getCropBox(); } 112 PDFRectangle *getCropBox() { return attrs->getCropBox(); }
93 GBool isCropped() { return attrs->isCropped(); } 113 GBool isCropped() { return attrs->isCropped(); }
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); }
106 132
107 // Get contents. 133 // Get contents.
108 Object *getContents(Object *obj) { return contents.fetch(xref, obj); } 134 Object *getContents(Object *obj) { return contents.fetch(xref, obj); }
109 135
110 // Display a page. 136 // Display a page.
111 void display(OutputDev *out, fouble dpi, int rotate, 137 void display(OutputDev *out, fouble dpi, int rotate,
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stddef.h> 14#include <stddef.h>
15#include "Object.h" 15#include "Object.h"
16#include "Array.h" 16#include "Array.h"
17#include "Dict.h" 17#include "Dict.h"
@@ -146,48 +146,49 @@ Object *Parser::getObj(Object *obj) {
146 // simple object 146 // simple object
147 } else { 147 } else {
148 buf1.copy(obj); 148 buf1.copy(obj);
149 shift(); 149 shift();
150 } 150 }
151 151
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);
188 189
189 // refill token buffers and check for 'endstream' 190 // refill token buffers and check for 'endstream'
190 shift(); // kill '>>' 191 shift(); // kill '>>'
191 shift(); // kill 'stream' 192 shift(); // kill 'stream'
192 if (buf1.isCmd("endstream")) 193 if (buf1.isCmd("endstream"))
193 shift(); 194 shift();
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "Lexer.h" 16#include "Lexer.h"
17 17
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,19 +1,19 @@
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;
14}; 14};
15 15
16#define ccittEOL -2 16#define ccittEOL -2
17 17
18//------------------------------------------------------------------------ 18//------------------------------------------------------------------------
19// 2D codes 19// 2D codes
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <stdlib.h> 15#include <stdlib.h>
16#include <stddef.h> 16#include <stddef.h>
17#ifndef WIN32 17#ifndef WIN32
@@ -294,25 +294,25 @@ void BaseStream::doDecryption(Guchar *fileKey, int keyLength,
294 294
295FilterStream::FilterStream(Stream *strA) { 295FilterStream::FilterStream(Stream *strA) {
296 str = strA; 296 str = strA;
297} 297}
298 298
299FilterStream::~FilterStream() { 299FilterStream::~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//------------------------------------------------------------------------
313 313
314ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) { 314ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
315 int imgLineSize; 315 int imgLineSize;
316 316
317 str = strA; 317 str = strA;
318 width = widthA; 318 width = widthA;
@@ -545,145 +545,258 @@ GBool StreamPredictor::getNextLine() {
545 } 545 }
546 546
547 // reset to start of line 547 // reset to start of line
548 predIdx = pixBytes; 548 predIdx = pixBytes;
549 549
550 return gTrue; 550 return gTrue;
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;
611 if (bufPtr >= bufEnd) { 625 if (bufPtr >= bufEnd) {
612 return gFalse; 626 return gFalse;
613 } 627 }
614#ifndef NO_DECRYPTION 628#ifndef NO_DECRYPTION
615 if (decrypt) { 629 if (decrypt) {
616 for (p = buf; p < bufEnd; ++p) { 630 for (p = buf; p < bufEnd; ++p) {
617 *p = (char)decrypt->decryptByte((Guchar)*p); 631 *p = (char)decrypt->decryptByte((Guchar)*p);
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//------------------------------------------------------------------------
684 797
685ASCIIHexStream::ASCIIHexStream(Stream *strA): 798ASCIIHexStream::ASCIIHexStream(Stream *strA):
686 FilterStream(strA) { 799 FilterStream(strA) {
687 buf = EOF; 800 buf = EOF;
688 eof = gFalse; 801 eof = gFalse;
689} 802}
@@ -950,29 +1063,25 @@ void LZWStream::reset() {
950 NULL, NULL, kCreateFolderNever, 1063 NULL, NULL, kCreateFolderNever,
951 kDeleteOriginal, kTextConvertSmart); 1064 kDeleteOriginal, kTextConvertSmart);
952 } 1065 }
953 } 1066 }
954#elif defined(HAVE_POPEN) 1067#elif defined(HAVE_POPEN)
955 if (!(zPipe = popen(zCmd->getCString(), POPEN_READ_MODE))) { 1068 if (!(zPipe = popen(zCmd->getCString(), POPEN_READ_MODE))) {
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);
973 if (!(zPipe = fopen(zName->getCString(), "rb"))) { 1082 if (!(zPipe = fopen(zName->getCString(), "rb"))) {
974 error(getPos(), "Couldn't open uncompress file '%s'", zName->getCString()); 1083 error(getPos(), "Couldn't open uncompress file '%s'", zName->getCString());
975 unlink(zName->getCString()); 1084 unlink(zName->getCString());
976 delete zName; 1085 delete zName;
977 return; 1086 return;
978 } 1087 }
@@ -3278,24 +3387,74 @@ int FixedLengthEncoder::getChar() {
3278 return EOF; 3387 return EOF;
3279 ++count; 3388 ++count;
3280 return str->getChar(); 3389 return str->getChar();
3281} 3390}
3282 3391
3283int FixedLengthEncoder::lookChar() { 3392int 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;
3296 lineLen = 0; 3455 lineLen = 0;
3297 eof = gFalse; 3456 eof = gFalse;
3298} 3457}
3299 3458
3300ASCII85Encoder::~ASCII85Encoder() { 3459ASCII85Encoder::~ASCII85Encoder() {
3301 if (str->isEncoder()) 3460 if (str->isEncoder())
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,17 +1,17 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include <stdio.h> 16#include <stdio.h>
17#include "gtypes.h" 17#include "gtypes.h"
@@ -69,26 +69,28 @@ public:
69 virtual int lookChar() = 0; 69 virtual int lookChar() = 0;
70 70
71 // Get next char from stream without using the predictor. 71 // Get next char from stream without using the predictor.
72 // This is only used by StreamPredictor. 72 // This is only used by StreamPredictor.
73 virtual int getRawChar(); 73 virtual int getRawChar();
74 74
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;
89 91
90 // Get the BaseStream or EmbedStream of this stream. 92 // Get the BaseStream or EmbedStream of this stream.
91 virtual BaseStream *getBaseStream() = 0; 93 virtual BaseStream *getBaseStream() = 0;
92 94
93 // Get the dictionary associated with this stream. 95 // Get the dictionary associated with this stream.
94 virtual Dict *getDict() = 0; 96 virtual Dict *getDict() = 0;
@@ -109,36 +111,38 @@ private:
109 111
110//------------------------------------------------------------------------ 112//------------------------------------------------------------------------
111// BaseStream 113// BaseStream
112// 114//
113// This is the base class for all streams that read directly from a file. 115// This is the base class for all streams that read directly from a file.
114//------------------------------------------------------------------------ 116//------------------------------------------------------------------------
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;
139#endif 143#endif
140 144
141private: 145private:
142 146
143 Object dict; 147 Object dict;
144}; 148};
@@ -147,25 +151,25 @@ private:
147// FilterStream 151// FilterStream
148// 152//
149// This is the base class for all streams that filter another stream. 153// This is the base class for all streams that filter another stream.
150//------------------------------------------------------------------------ 154//------------------------------------------------------------------------
151 155
152class FilterStream: public Stream { 156class 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;
166}; 170};
167 171
168//------------------------------------------------------------------------ 172//------------------------------------------------------------------------
169// ImageStream 173// ImageStream
170//------------------------------------------------------------------------ 174//------------------------------------------------------------------------
171 175
@@ -233,78 +237,120 @@ private:
233 int predIdx; // current index in predLine 237 int predIdx; // current index in predLine
234}; 238};
235 239
236//------------------------------------------------------------------------ 240//------------------------------------------------------------------------
237// FileStream 241// FileStream
238//------------------------------------------------------------------------ 242//------------------------------------------------------------------------
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
279// images). It reads directly from the base stream -- after the 324// images). It reads directly from the base stream -- after the
280// EmbedStream is deleted, reads from the base stream will proceed where 325// EmbedStream is deleted, reads from the base stream will proceed where
281// the BaseStream left off. Note that this is very different behavior 326// the BaseStream left off. Note that this is very different behavior
282// that creating a new FileStream (using makeSubStream). 327// that creating a new FileStream (using makeSubStream).
283//------------------------------------------------------------------------ 328//------------------------------------------------------------------------
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};
305 351
306//------------------------------------------------------------------------ 352//------------------------------------------------------------------------
307// ASCIIHexStream 353// ASCIIHexStream
308//------------------------------------------------------------------------ 354//------------------------------------------------------------------------
309 355
310class ASCIIHexStream: public FilterStream { 356class ASCIIHexStream: public FilterStream {
@@ -650,24 +696,55 @@ public:
650 virtual int lookChar(); 696 virtual int lookChar();
651 virtual GString *getPSFilter(char *indent) { return NULL; } 697 virtual GString *getPSFilter(char *indent) { return NULL; }
652 virtual GBool isBinary(GBool last = gTrue) { return gFalse; } 698 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
653 virtual GBool isEncoder() { return gTrue; } 699 virtual GBool isEncoder() { return gTrue; }
654 700
655private: 701private:
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
668 ASCII85Encoder(Stream *strA); 745 ASCII85Encoder(Stream *strA);
669 virtual ~ASCII85Encoder(); 746 virtual ~ASCII85Encoder();
670 virtual StreamKind getKind() { return strWeird; } 747 virtual StreamKind getKind() { return strWeird; }
671 virtual void reset(); 748 virtual void reset();
672 virtual void close(); 749 virtual void close();
673 virtual int getChar() 750 virtual int getChar()
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <stdlib.h> 15#include <stdlib.h>
16#include <stddef.h> 16#include <stddef.h>
17#include <math.h> 17#include <math.h>
@@ -39,24 +39,30 @@ TextString::TextString(GfxState *state, fouble fontSize) {
39 fouble x, y; 39 fouble x, y;
40 40
41 state->transform(state->getCurX(), state->getCurY(), &x, &y); 41 state->transform(state->getCurX(), state->getCurY(), &x, &y);
42 if ((font = state->getFont())) { 42 if ((font = state->getFont())) {
43 yMin = y - font->getAscent() * fontSize; 43 yMin = y - font->getAscent() * fontSize;
44 yMax = y - font->getDescent() * fontSize; 44 yMax = y - font->getDescent() * 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;
57} 63}
58 64
59TextString::~TextString() { 65TextString::~TextString() {
60 gfree(text); 66 gfree(text);
61 gfree(xRight); 67 gfree(xRight);
62} 68}
@@ -90,43 +96,47 @@ TextPage::TextPage(GBool rawOrderA) {
90 nest = 0; 96 nest = 0;
91} 97}
92 98
93TextPage::~TextPage() { 99TextPage::~TextPage() {
94 clear(); 100 clear();
95} 101}
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
108 // base coordinate system used in the font is without actually 115 // base coordinate system used in the font is without actually
109 // rendering the font. This code tries to guess by looking at the 116 // rendering the font. This code tries to guess by looking at the
110 // width of the character 'm' (which breaks if the font is a 117 // width of the character 'm' (which breaks if the font is a
111 // subset that doesn't contain 'm'). 118 // subset that doesn't contain 'm').
112 for (code = 0; code < 256; ++code) { 119 for (code = 0; code < 256; ++code) {
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 }
127} 137}
128 138
129void TextPage::beginString(GfxState *state) { 139void TextPage::beginString(GfxState *state) {
130 // This check is needed because Type 3 characters can contain 140 // This check is needed because Type 3 characters can contain
131 // text-drawing operations. 141 // text-drawing operations.
132 if (curStr) { 142 if (curStr) {
@@ -145,26 +155,28 @@ void TextPage::addChar(GfxState *state, fouble x, fouble y,
145 state->transform(x, y, &x1, &y1); 155 state->transform(x, y, &x1, &y1);
146 n = curStr->len; 156 n = curStr->len;
147 if (n > 0 && 157 if (n > 0 &&
148 x1 - curStr->xRight[n-1] > 0.1 * (curStr->yMax - curStr->yMin)) { 158 x1 - curStr->xRight[n-1] > 0.1 * (curStr->yMax - curStr->yMin)) {
149 endString(); 159 endString();
150 beginString(state); 160 beginString(state);
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() {
165 TextString *p1, *p2; 177 TextString *p1, *p2;
166 fouble h, y1, y2; 178 fouble h, y1, y2;
167 179
168 // This check is needed because Type 3 characters can contain 180 // This check is needed because Type 3 characters can contain
169 // text-drawing operations. 181 // text-drawing operations.
170 if (nest > 0) { 182 if (nest > 0) {
@@ -420,25 +432,25 @@ GString *TextPage::getText(fouble xMin, fouble yMin,
420 } 432 }
421 xPrev = x2; 433 xPrev = x2;
422 yPrev = str1->yMax; 434 yPrev = str1->yMax;
423 } 435 }
424 } 436 }
425 if (multiLine) { 437 if (multiLine) {
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;
439 451
440 // get the output encoding 452 // get the output encoding
441 if (!(uMap = globalParams->getTextEncoding())) { 453 if (!(uMap = globalParams->getTextEncoding())) {
442 return; 454 return;
443 } 455 }
444 spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); 456 spaceLen = uMap->mapUnicode(0x20, space, sizeof(space));
@@ -489,74 +501,74 @@ void TextPage::dump(FILE *f) {
489 col2 = str2->col + 501 col2 = str2->col +
490 (int)(((str1->xMin - str2->xMin) / (str2->xMax - str2->xMin)) * 502 (int)(((str1->xMin - str2->xMin) / (str2->xMax - str2->xMin)) *
491 str2->len); 503 str2->len);
492 if (col2 > col1) { 504 if (col2 > col1) {
493 col1 = col2; 505 col1 = col2;
494 } 506 }
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
538 // update yMax for this line 550 // update yMax for this line
539 if (str1->yMax > yMax) { 551 if (str1->yMax > yMax) {
540 yMax = str1->yMax; 552 yMax = str1->yMax;
541 } 553 }
542 554
543 // if we've hit the end of the line... 555 // if we've hit the end of the line...
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;
557 for (str2 = str1->yxNext; str2; str2 = str2->yxNext) { 569 for (str2 = str1->yxNext; str2; str2 = str2->yxNext) {
558 if (str2->yMin < yMin) { 570 if (str2->yMin < yMin) {
559 yMin = str2->yMin; 571 yMin = str2->yMin;
560 } 572 }
561 if (!(str2->yxNext && str2->yxNext->yMin < str2->yMax && 573 if (!(str2->yxNext && str2->yxNext->yMin < str2->yMax &&
562 str2->yxNext->xMin >= str2->xMax)) 574 str2->yxNext->xMin >= str2->xMax))
@@ -564,107 +576,122 @@ void TextPage::dump(FILE *f) {
564 } 576 }
565 577
566 // print the space 578 // print the space
567 d = (int)((yMin - yMax) / (str1->yMax - str1->yMin) + 0.5); 579 d = (int)((yMin - yMax) / (str1->yMax - str1->yMin) + 0.5);
568 // various things (weird font matrices) can result in bogus 580 // various things (weird font matrices) can result in bogus
569 // values here, so do a sanity check 581 // values here, so do a sanity check
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;
596 608
597 if (curStr) { 609 if (curStr) {
598 delete curStr; 610 delete curStr;
599 curStr = NULL; 611 curStr = NULL;
600 } 612 }
601 for (p1 = yxStrings; p1; p1 = p2) { 613 for (p1 = yxStrings; p1; p1 = p2) {
602 p2 = p1->yxNext; 614 p2 = p1->yxNext;
603 delete p1; 615 delete p1;
604 } 616 }
605 yxStrings = NULL; 617 yxStrings = NULL;
606 xyStrings = NULL; 618 xyStrings = NULL;
607 yxCur1 = yxCur2 = NULL; 619 yxCur1 = yxCur2 = NULL;
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}
665 692
666void TextOutputDev::beginString(GfxState *state, GString *s) { 693void TextOutputDev::beginString(GfxState *state, GString *s) {
667 text->beginString(state); 694 text->beginString(state);
668} 695}
669 696
670void TextOutputDev::endString(GfxState *state) { 697void TextOutputDev::endString(GfxState *state) {
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,36 +1,40 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include <stdio.h> 16#include <stdio.h>
17#include "gtypes.h" 17#include "gtypes.h"
18#include "GfxFont.h" 18#include "GfxFont.h"
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
31 // Constructor. 35 // Constructor.
32 TextString(GfxState *state, fouble fontSize); 36 TextString(GfxState *state, fouble fontSize);
33 37
34 // Destructor. 38 // Destructor.
35 ~TextString(); 39 ~TextString();
36 40
@@ -88,25 +92,25 @@ public:
88 // <xMax>,<yMax>. If found, sets the text bounding rectange and 92 // <xMax>,<yMax>. If found, sets the text bounding rectange and
89 // returns true; otherwise returns false. 93 // returns true; otherwise returns false.
90 GBool findText(Unicode *s, int len, 94 GBool findText(Unicode *s, int len,
91 GBool top, GBool bottom, 95 GBool top, GBool bottom,
92 fouble *xMin, fouble *yMin, 96 fouble *xMin, fouble *yMin,
93 fouble *xMax, fouble *yMax); 97 fouble *xMax, fouble *yMax);
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
107 GBool rawOrder; // keep strings in content stream order 111 GBool rawOrder; // keep strings in content stream order
108 112
109 TextString *curStr; // currently active string 113 TextString *curStr; // currently active string
110 fouble fontSize; // current font size 114 fouble fontSize; // current font size
111 115
112 TextString *yxStrings;// strings in y-major order 116 TextString *yxStrings;// strings in y-major order
@@ -119,39 +123,47 @@ private:
119//------------------------------------------------------------------------ 123//------------------------------------------------------------------------
120// TextOutputDev 124// TextOutputDev
121//------------------------------------------------------------------------ 125//------------------------------------------------------------------------
122 126
123class TextOutputDev: public OutputDev { 127class TextOutputDev: public OutputDev {
124public: 128public:
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
137 //---- get info about output device 145 //---- get info about output device
138 146
139 // Does this device use upside-down coordinates? 147 // Does this device use upside-down coordinates?
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.
152 virtual void startPage(int pageNum, GfxState *state); 164 virtual void startPage(int pageNum, GfxState *state);
153 165
154 // End a page. 166 // End a page.
155 virtual void endPage(); 167 virtual void endPage();
156 168
157 //----- update text state 169 //----- update text state
@@ -170,20 +182,22 @@ public:
170 // Find a string. If <top> is true, starts looking at top of page; 182 // Find a string. If <top> is true, starts looking at top of page;
171 // otherwise starts looking at <xMin>,<yMin>. If <bottom> is true, 183 // otherwise starts looking at <xMin>,<yMin>. If <bottom> is true,
172 // stops looking at bottom of page; otherwise stops looking at 184 // stops looking at bottom of page; otherwise stops looking at
173 // <xMax>,<yMax>. If found, sets the text bounding rectange and 185 // <xMax>,<yMax>. If found, sets the text bounding rectange and
174 // returns true; otherwise returns false. 186 // returns true; otherwise returns false.
175 GBool findText(Unicode *s, int len, 187 GBool findText(Unicode *s, int len,
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,17 +1,17 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <string.h> 15#include <string.h>
16#include "gmem.h" 16#include "gmem.h"
17#include "gfile.h" 17#include "gfile.h"
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,19 +1,19 @@
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
14#ifdef __GNUC__ 14#ifdef __GNUC__
15#pragma interface 15#pragma interface
16#endif 16#endif
17 17
18#include "gtypes.h" 18#include "gtypes.h"
19#include "CharTypes.h" 19#include "CharTypes.h"
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,27 +1,29 @@
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 },
22 { 0x0161, 0x0161, 0x73, 1 }, 24 { 0x0161, 0x0161, 0x73, 1 },
23 { 0x0178, 0x0178, 0x59, 1 }, 25 { 0x0178, 0x0178, 0x59, 1 },
24 { 0x017d, 0x017d, 0x5a, 1 }, 26 { 0x017d, 0x017d, 0x5a, 1 },
25 { 0x017e, 0x017e, 0x7a, 1 }, 27 { 0x017e, 0x017e, 0x7a, 1 },
26 { 0x02c6, 0x02c6, 0x5e, 1 }, 28 { 0x02c6, 0x02c6, 0x5e, 1 },
27 { 0x02da, 0x02da, 0xb0, 1 }, 29 { 0x02da, 0x02da, 0xb0, 1 },
@@ -32,24 +34,41 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
32 { 0x2019, 0x2019, 0x27, 1 }, 34 { 0x2019, 0x2019, 0x27, 1 },
33 { 0x201a, 0x201a, 0x2c, 1 }, 35 { 0x201a, 0x201a, 0x2c, 1 },
34 { 0x201c, 0x201c, 0x22, 1 }, 36 { 0x201c, 0x201c, 0x22, 1 },
35 { 0x201d, 0x201d, 0x22, 1 }, 37 { 0x201d, 0x201d, 0x22, 1 },
36 { 0x201e, 0x201e, 0x2c2c, 2 }, 38 { 0x201e, 0x201e, 0x2c2c, 2 },
37 { 0x2022, 0x2022, 0xb7, 1 }, 39 { 0x2022, 0x2022, 0xb7, 1 },
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};
50#define latin1UnicodeMapLen (sizeof(latin1UnicodeMapRanges) / sizeof(UnicodeMapRange)) 69#define latin1UnicodeMapLen (sizeof(latin1UnicodeMapRanges) / sizeof(UnicodeMapRange))
51 70
52static UnicodeMapRange ascii7UnicodeMapRanges[] = { 71static UnicodeMapRange ascii7UnicodeMapRanges[] = {
53 { 0x000a, 0x000a, 0x0a, 1 }, 72 { 0x000a, 0x000a, 0x0a, 1 },
54 { 0x000c, 0x000d, 0x0c, 1 }, 73 { 0x000c, 0x000d, 0x0c, 1 },
55 { 0x0020, 0x005f, 0x20, 1 }, 74 { 0x0020, 0x005f, 0x20, 1 },
@@ -126,24 +145,63 @@ static UnicodeMapRange ascii7UnicodeMapRanges[] = {
126 { 0x0178, 0x0178, 0x59, 1 }, 145 { 0x0178, 0x0178, 0x59, 1 },
127 { 0x017d, 0x017d, 0x5a, 1 }, 146 { 0x017d, 0x017d, 0x5a, 1 },
128 { 0x2013, 0x2013, 0x2d, 1 }, 147 { 0x2013, 0x2013, 0x2d, 1 },
129 { 0x2014, 0x2014, 0x2d2d, 2 }, 148 { 0x2014, 0x2014, 0x2d2d, 2 },
130 { 0x2018, 0x2018, 0x60, 1 }, 149 { 0x2018, 0x2018, 0x60, 1 },
131 { 0x2019, 0x2019, 0x27, 1 }, 150 { 0x2019, 0x2019, 0x27, 1 },
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};
144#define ascii7UnicodeMapLen (sizeof(ascii7UnicodeMapRanges) / sizeof(UnicodeMapRange)) 202#define ascii7UnicodeMapLen (sizeof(ascii7UnicodeMapRanges) / sizeof(UnicodeMapRange))
145 203
146static UnicodeMapRange symbolUnicodeMapRanges[] = { 204static UnicodeMapRange symbolUnicodeMapRanges[] = {
147 { 0x0020, 0x0021, 0x20, 1 }, 205 { 0x0020, 0x0021, 0x20, 1 },
148 { 0x0023, 0x0023, 0x23, 1 }, 206 { 0x0023, 0x0023, 0x23, 1 },
149 { 0x0025, 0x0026, 0x25, 1 }, 207 { 0x0025, 0x0026, 0x25, 1 },
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,156 +1,162 @@
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
12 12
13#include <aconf.h> 13#include <aconf.h>
14#include <stdlib.h> 14#include <stdlib.h>
15#include <stddef.h> 15#include <stddef.h>
16#include <string.h> 16#include <string.h>
17#include <ctype.h> 17#include <ctype.h>
18#include "gmem.h" 18#include "gmem.h"
19#include "Object.h" 19#include "Object.h"
20#include "Stream.h" 20#include "Stream.h"
21#include "Lexer.h" 21#include "Lexer.h"
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'
34 35
35#ifndef NO_DECRYPTION 36#ifndef NO_DECRYPTION
36//------------------------------------------------------------------------ 37//------------------------------------------------------------------------
37// Permission bits 38// Permission bits
38//------------------------------------------------------------------------ 39//------------------------------------------------------------------------
39 40
40#define permPrint (1<<2) 41#define permPrint (1<<2)
41#define permChange (1<<3) 42#define permChange (1<<3)
42#define permCopy (1<<4) 43#define permCopy (1<<4)
43#define permNotes (1<<5) 44#define permNotes (1<<5)
44#define defPermFlags 0xfffc 45#define defPermFlags 0xfffc
45#endif 46#endif
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
62 str = strA; 64 str = strA;
63 start = str->getStart(); 65 start = str->getStart();
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
95 // indirect objects from it 99 // indirect objects from it
96 trailerDict.getDict()->setXRef(this); 100 trailerDict.getDict()->setXRef(this);
97 101
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);
110 trailerDict.free(); 115 trailerDict.free();
111 if (streamEnds) { 116 if (streamEnds) {
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';
135 141
136 // find startxref 142 // find startxref
137 for (i = n - 9; i >= 0; --i) { 143 for (i = n - 9; i >= 0; --i) {
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)
151 buf[i] = str->getChar(); 157 buf[i] = str->getChar();
152 if (strncmp(buf, "xref", 4)) 158 if (strncmp(buf, "xref", 4))
153 return 0; 159 return 0;
154 pos1 = pos + 4; 160 pos1 = pos + 4;
155 while (1) { 161 while (1) {
156 str->setPos(start + pos1); 162 str->setPos(start + pos1);
@@ -167,26 +173,27 @@ int XRef::readTrailer() {
167 while (isspace(*p)) ++p; 173 while (isspace(*p)) ++p;
168 n = atoi(p); 174 n = atoi(p);
169 while ('0' <= *p && *p <= '9') ++p; 175 while ('0' <= *p && *p <= '9') ++p;
170 while (isspace(*p)) ++p; 176 while (isspace(*p)) ++p;
171 if (p == buf) 177 if (p == buf)
172 return 0; 178 return 0;
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
187 pos = 0; 194 pos = 0;
188 obj.free(); 195 obj.free();
189 trailerDict.dictLookupNF("Root", &obj); 196 trailerDict.dictLookupNF("Root", &obj);
190 if (obj.isRef()) { 197 if (obj.isRef()) {
191 rootNum = obj.getRefNum(); 198 rootNum = obj.getRefNum();
192 rootGen = obj.getRefGen(); 199 rootGen = obj.getRefGen();
@@ -195,25 +202,25 @@ int XRef::readTrailer() {
195 } 202 }
196 obj.free(); 203 obj.free();
197 } else { 204 } else {
198 pos = 0; 205 pos = 0;
199 } 206 }
200 delete parser; 207 delete parser;
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;
214 221
215 // seek to xref in stream 222 // seek to xref in stream
216 str->setPos(start + *pos); 223 str->setPos(start + *pos);
217 224
218 // make sure it's an xref table 225 // make sure it's an xref table
219 while ((c = str->getChar()) != EOF && isspace(c)) ; 226 while ((c = str->getChar()) != EOF && isspace(c)) ;
@@ -252,125 +259,127 @@ GBool XRef::readXRef(int *pos) {
252 } 259 }
253 s[i] = '\0'; 260 s[i] = '\0';
254 n = atoi(s); 261 n = atoi(s);
255 while ((c = str->lookChar()) != EOF && isspace(c)) { 262 while ((c = str->lookChar()) != EOF && isspace(c)) {
256 str->getChar(); 263 str->getChar();
257 } 264 }
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;
285 } else { 292 } else {
286 goto err2; 293 goto err2;
287 } 294 }
288 // PDF files of patents from the IBM Intellectual Property 295 // PDF files of patents from the IBM Intellectual Property
289 // Network have a bug: the xref table claims to start at 1 296 // Network have a bug: the xref table claims to start at 1
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();
324 332
325 delete parser; 333 delete parser;
326 return more; 334 return more;
327 335
328 err1: 336 err1:
329 obj.free(); 337 obj.free();
330 err2: 338 err2:
331 ok = gFalse; 339 ok = gFalse;
332 return gFalse; 340 return gFalse;
333} 341}
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;
347 355
348 error(0, "PDF file is damaged - attempting to reconstruct xref table..."); 356 error(0, "PDF file is damaged - attempting to reconstruct xref table...");
349 gotRoot = gFalse; 357 gotRoot = gFalse;
350 streamEndsLen = streamEndsSize = 0; 358 streamEndsLen = streamEndsSize = 0;
351 359
352 str->reset(); 360 str->reset();
353 while (1) { 361 while (1) {
354 pos = str->getPos(); 362 pos = str->getPos();
355 if (!str->getLine(buf, 256)) { 363 if (!str->getLine(buf, 256)) {
356 break; 364 break;
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()) {
371 rootNum = obj.getRefNum(); 380 rootNum = obj.getRefNum();
372 rootGen = obj.getRefGen(); 381 rootGen = obj.getRefGen();
373 gotRoot = gTrue; 382 gotRoot = gTrue;
374 } 383 }
375 obj.free(); 384 obj.free();
376 } else { 385 } else {
@@ -394,43 +403,44 @@ GBool XRef::constructXRef() {
394 ++p; 403 ++p;
395 } while (*p && isdigit(*p)); 404 } while (*p && isdigit(*p));
396 if (isspace(*p)) { 405 if (isspace(*p)) {
397 do { 406 do {
398 ++p; 407 ++p;
399 } while (*p && isspace(*p)); 408 } while (*p && isspace(*p));
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;
413 entries[num].gen = gen; 422 entries[num].gen = gen;
414 entries[num].used = gTrue; 423 entries[num].used = gTrue;
415 } 424 }
416 } 425 }
417 } 426 }
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)
431 return gTrue; 441 return gTrue;
432 442
433 error(-1, "Couldn't find trailer dictionary"); 443 error(-1, "Couldn't find trailer dictionary");
434 return gFalse; 444 return gFalse;
435} 445}
436 446
@@ -571,28 +581,29 @@ GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {
571Object *XRef::fetch(int num, int gen, Object *obj) { 581Object *XRef::fetch(int num, int gen, Object *obj) {
572 XRefEntry *e; 582 XRefEntry *e;
573 Parser *parser; 583 Parser *parser;
574 Object obj1, obj2, obj3; 584 Object obj1, obj2, obj3;
575 585
576 // check for bogus ref - this can happen in corrupted PDF files 586 // check for bogus ref - this can happen in corrupted PDF files
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")) {
593#ifndef NO_DECRYPTION 604#ifndef NO_DECRYPTION
594 parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength, 605 parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength,
595 num, gen); 606 num, gen);
596#else 607#else
597 parser->getObj(obj); 608 parser->getObj(obj);
598#endif 609#endif
@@ -609,33 +620,46 @@ Object *XRef::fetch(int num, int gen, Object *obj) {
609 return obj; 620 return obj;
610} 621}
611 622
612Object *XRef::getDocInfo(Object *obj) { 623Object *XRef::getDocInfo(Object *obj) {
613 return trailerDict.dictLookup("Info", obj); 624 return trailerDict.dictLookup("Info", obj);
614} 625}
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) {
633 m = (a + b) / 2; 644 m = (a + b) / 2;
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,55 +1,58 @@
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
12#ifdef __GNUC__ 12#ifdef __GNUC__
13#pragma interface 13#pragma interface
14#endif 14#endif
15 15
16#include "gtypes.h" 16#include "gtypes.h"
17#include "Object.h" 17#include "Object.h"
18 18
19class Dict; 19class Dict;
20class Stream; 20class 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:
34 34
35 // Constructor. Read xref table from stream. 35 // Constructor. Read xref table from stream.
36 XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword); 36 XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword);
37 37
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
50 53
51 // Check various permissions. 54 // Check various permissions.
52 GBool okToPrint(GBool ignoreOwnerPW = gFalse); 55 GBool okToPrint(GBool ignoreOwnerPW = gFalse);
53 GBool okToChange(GBool ignoreOwnerPW = gFalse); 56 GBool okToChange(GBool ignoreOwnerPW = gFalse);
54 GBool okToCopy(GBool ignoreOwnerPW = gFalse); 57 GBool okToCopy(GBool ignoreOwnerPW = gFalse);
55 GBool okToAddNotes(GBool ignoreOwnerPW = gFalse); 58 GBool okToAddNotes(GBool ignoreOwnerPW = gFalse);
@@ -59,53 +62,55 @@ public:
59 62
60 // Fetch an indirect reference. 63 // Fetch an indirect reference.
61 Object *fetch(int num, int gen, Object *obj); 64 Object *fetch(int num, int gen, Object *obj);
62 65
63 // Return the document's Info dictionary (if any). 66 // Return the document's Info dictionary (if any).
64 Object *getDocInfo(Object *obj); 67 Object *getDocInfo(Object *obj);
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